@@ -1127,16 +1127,93 @@ static int phylink_mii_emul_read(struct net_device *ndev, unsigned int reg,
1127
1127
return val ;
1128
1128
}
1129
1129
1130
+ static int phylink_phy_read (struct phylink * pl , unsigned int phy_id ,
1131
+ unsigned int reg )
1132
+ {
1133
+ struct phy_device * phydev = pl -> phydev ;
1134
+ int prtad , devad ;
1135
+
1136
+ if (mdio_phy_id_is_c45 (phy_id )) {
1137
+ prtad = mdio_phy_id_prtad (phy_id );
1138
+ devad = mdio_phy_id_devad (phy_id );
1139
+ devad = MII_ADDR_C45 | devad << 16 | reg ;
1140
+ } else if (phydev -> is_c45 ) {
1141
+ switch (reg ) {
1142
+ case MII_BMCR :
1143
+ case MII_BMSR :
1144
+ case MII_PHYSID1 :
1145
+ case MII_PHYSID2 :
1146
+ devad = __ffs (phydev -> c45_ids .devices_in_package );
1147
+ break ;
1148
+ case MII_ADVERTISE :
1149
+ case MII_LPA :
1150
+ if (!(phydev -> c45_ids .devices_in_package & MDIO_DEVS_AN ))
1151
+ return - EINVAL ;
1152
+ devad = MDIO_MMD_AN ;
1153
+ if (reg == MII_ADVERTISE )
1154
+ reg = MDIO_AN_ADVERTISE ;
1155
+ else
1156
+ reg = MDIO_AN_LPA ;
1157
+ break ;
1158
+ default :
1159
+ return - EINVAL ;
1160
+ }
1161
+ prtad = phy_id ;
1162
+ devad = MII_ADDR_C45 | devad << 16 | reg ;
1163
+ } else {
1164
+ prtad = phy_id ;
1165
+ devad = reg ;
1166
+ }
1167
+ return mdiobus_read (pl -> phydev -> mdio .bus , prtad , devad );
1168
+ }
1169
+
1170
+ static int phylink_phy_write (struct phylink * pl , unsigned int phy_id ,
1171
+ unsigned int reg , unsigned int val )
1172
+ {
1173
+ struct phy_device * phydev = pl -> phydev ;
1174
+ int prtad , devad ;
1175
+
1176
+ if (mdio_phy_id_is_c45 (phy_id )) {
1177
+ prtad = mdio_phy_id_prtad (phy_id );
1178
+ devad = mdio_phy_id_devad (phy_id );
1179
+ devad = MII_ADDR_C45 | devad << 16 | reg ;
1180
+ } else if (phydev -> is_c45 ) {
1181
+ switch (reg ) {
1182
+ case MII_BMCR :
1183
+ case MII_BMSR :
1184
+ case MII_PHYSID1 :
1185
+ case MII_PHYSID2 :
1186
+ devad = __ffs (phydev -> c45_ids .devices_in_package );
1187
+ break ;
1188
+ case MII_ADVERTISE :
1189
+ case MII_LPA :
1190
+ if (!(phydev -> c45_ids .devices_in_package & MDIO_DEVS_AN ))
1191
+ return - EINVAL ;
1192
+ devad = MDIO_MMD_AN ;
1193
+ if (reg == MII_ADVERTISE )
1194
+ reg = MDIO_AN_ADVERTISE ;
1195
+ else
1196
+ reg = MDIO_AN_LPA ;
1197
+ break ;
1198
+ default :
1199
+ return - EINVAL ;
1200
+ }
1201
+ prtad = phy_id ;
1202
+ devad = MII_ADDR_C45 | devad << 16 | reg ;
1203
+ } else {
1204
+ prtad = phy_id ;
1205
+ devad = reg ;
1206
+ }
1207
+
1208
+ return mdiobus_write (phydev -> mdio .bus , prtad , devad , val );
1209
+ }
1210
+
1130
1211
static int phylink_mii_read (struct phylink * pl , unsigned int phy_id ,
1131
1212
unsigned int reg )
1132
1213
{
1133
1214
struct phylink_link_state state ;
1134
1215
int val = 0xffff ;
1135
1216
1136
- /* PHYs only exist for MLO_AN_PHY and MLO_AN_SGMII */
1137
- if (pl -> phydev )
1138
- return mdiobus_read (pl -> phydev -> mdio .bus , phy_id , reg );
1139
-
1140
1217
switch (pl -> link_an_mode ) {
1141
1218
case MLO_AN_FIXED :
1142
1219
if (phy_id == 0 ) {
@@ -1169,12 +1246,6 @@ static int phylink_mii_read(struct phylink *pl, unsigned int phy_id,
1169
1246
static int phylink_mii_write (struct phylink * pl , unsigned int phy_id ,
1170
1247
unsigned int reg , unsigned int val )
1171
1248
{
1172
- /* PHYs only exist for MLO_AN_PHY and MLO_AN_SGMII */
1173
- if (pl -> phydev ) {
1174
- mdiobus_write (pl -> phydev -> mdio .bus , phy_id , reg , val );
1175
- return 0 ;
1176
- }
1177
-
1178
1249
switch (pl -> link_an_mode ) {
1179
1250
case MLO_AN_FIXED :
1180
1251
break ;
@@ -1193,36 +1264,56 @@ static int phylink_mii_write(struct phylink *pl, unsigned int phy_id,
1193
1264
1194
1265
int phylink_mii_ioctl (struct phylink * pl , struct ifreq * ifr , int cmd )
1195
1266
{
1196
- struct mii_ioctl_data * mii_data = if_mii (ifr );
1197
- int val , ret ;
1267
+ struct mii_ioctl_data * mii = if_mii (ifr );
1268
+ int ret ;
1198
1269
1199
1270
WARN_ON (!lockdep_rtnl_is_held ());
1200
1271
1201
- switch (cmd ) {
1202
- case SIOCGMIIPHY :
1203
- mii_data -> phy_id = pl -> phydev ? pl -> phydev -> mdio .addr : 0 ;
1204
- /* fallthrough */
1272
+ if (pl -> phydev ) {
1273
+ /* PHYs only exist for MLO_AN_PHY and MLO_AN_SGMII */
1274
+ switch (cmd ) {
1275
+ case SIOCGMIIPHY :
1276
+ mii -> phy_id = pl -> phydev -> mdio .addr ;
1277
+
1278
+ case SIOCGMIIREG :
1279
+ ret = phylink_phy_read (pl , mii -> phy_id , mii -> reg_num );
1280
+ if (ret >= 0 ) {
1281
+ mii -> val_out = ret ;
1282
+ ret = 0 ;
1283
+ }
1284
+ break ;
1205
1285
1206
- case SIOCGMIIREG :
1207
- val = phylink_mii_read (pl , mii_data -> phy_id , mii_data -> reg_num );
1208
- if (val < 0 ) {
1209
- ret = val ;
1210
- } else {
1211
- mii_data -> val_out = val ;
1212
- ret = 0 ;
1286
+ case SIOCSMIIREG :
1287
+ ret = phylink_phy_write (pl , mii -> phy_id , mii -> reg_num ,
1288
+ mii -> val_in );
1289
+ break ;
1290
+
1291
+ default :
1292
+ ret = phy_mii_ioctl (pl -> phydev , ifr , cmd );
1293
+ break ;
1213
1294
}
1214
- break ;
1295
+ } else {
1296
+ switch (cmd ) {
1297
+ case SIOCGMIIPHY :
1298
+ mii -> phy_id = 0 ;
1299
+
1300
+ case SIOCGMIIREG :
1301
+ ret = phylink_mii_read (pl , mii -> phy_id , mii -> reg_num );
1302
+ if (ret >= 0 ) {
1303
+ mii -> val_out = ret ;
1304
+ ret = 0 ;
1305
+ }
1306
+ break ;
1215
1307
1216
- case SIOCSMIIREG :
1217
- ret = phylink_mii_write (pl , mii_data -> phy_id , mii_data -> reg_num ,
1218
- mii_data -> val_in );
1219
- break ;
1308
+ case SIOCSMIIREG :
1309
+ ret = phylink_mii_write (pl , mii -> phy_id , mii -> reg_num ,
1310
+ mii -> val_in );
1311
+ break ;
1220
1312
1221
- default :
1222
- ret = - EOPNOTSUPP ;
1223
- if (pl -> phydev )
1224
- ret = phy_mii_ioctl (pl -> phydev , ifr , cmd );
1225
- break ;
1313
+ default :
1314
+ ret = - EOPNOTSUPP ;
1315
+ break ;
1316
+ }
1226
1317
}
1227
1318
1228
1319
return ret ;
0 commit comments