0001
0002
0003
0004
0005
0006
0007
0008 #ifndef __LINUX_MII_H__
0009 #define __LINUX_MII_H__
0010
0011
0012 #include <linux/if.h>
0013 #include <linux/linkmode.h>
0014 #include <uapi/linux/mii.h>
0015
0016 struct ethtool_cmd;
0017
0018 struct mii_if_info {
0019 int phy_id;
0020 int advertising;
0021 int phy_id_mask;
0022 int reg_num_mask;
0023
0024 unsigned int full_duplex : 1;
0025 unsigned int force_media : 1;
0026 unsigned int supports_gmii : 1;
0027
0028 struct net_device *dev;
0029 int (*mdio_read) (struct net_device *dev, int phy_id, int location);
0030 void (*mdio_write) (struct net_device *dev, int phy_id, int location, int val);
0031 };
0032
0033 extern int mii_link_ok (struct mii_if_info *mii);
0034 extern int mii_nway_restart (struct mii_if_info *mii);
0035 extern void mii_ethtool_gset(struct mii_if_info *mii, struct ethtool_cmd *ecmd);
0036 extern void mii_ethtool_get_link_ksettings(
0037 struct mii_if_info *mii, struct ethtool_link_ksettings *cmd);
0038 extern int mii_ethtool_sset(struct mii_if_info *mii, struct ethtool_cmd *ecmd);
0039 extern int mii_ethtool_set_link_ksettings(
0040 struct mii_if_info *mii, const struct ethtool_link_ksettings *cmd);
0041 extern int mii_check_gmii_support(struct mii_if_info *mii);
0042 extern void mii_check_link (struct mii_if_info *mii);
0043 extern unsigned int mii_check_media (struct mii_if_info *mii,
0044 unsigned int ok_to_print,
0045 unsigned int init_media);
0046 extern int generic_mii_ioctl(struct mii_if_info *mii_if,
0047 struct mii_ioctl_data *mii_data, int cmd,
0048 unsigned int *duplex_changed);
0049
0050
0051 static inline struct mii_ioctl_data *if_mii(struct ifreq *rq)
0052 {
0053 return (struct mii_ioctl_data *) &rq->ifr_ifru;
0054 }
0055
0056
0057
0058
0059
0060
0061
0062
0063
0064
0065
0066
0067
0068
0069
0070 static inline unsigned int mii_nway_result (unsigned int negotiated)
0071 {
0072 unsigned int ret;
0073
0074 if (negotiated & LPA_100FULL)
0075 ret = LPA_100FULL;
0076 else if (negotiated & LPA_100BASE4)
0077 ret = LPA_100BASE4;
0078 else if (negotiated & LPA_100HALF)
0079 ret = LPA_100HALF;
0080 else if (negotiated & LPA_10FULL)
0081 ret = LPA_10FULL;
0082 else
0083 ret = LPA_10HALF;
0084
0085 return ret;
0086 }
0087
0088
0089
0090
0091
0092
0093
0094
0095
0096
0097 static inline unsigned int mii_duplex (unsigned int duplex_lock,
0098 unsigned int negotiated)
0099 {
0100 if (duplex_lock)
0101 return 1;
0102 if (mii_nway_result(negotiated) & LPA_DUPLEX)
0103 return 1;
0104 return 0;
0105 }
0106
0107
0108
0109
0110
0111
0112
0113
0114
0115 static inline u32 ethtool_adv_to_mii_adv_t(u32 ethadv)
0116 {
0117 u32 result = 0;
0118
0119 if (ethadv & ADVERTISED_10baseT_Half)
0120 result |= ADVERTISE_10HALF;
0121 if (ethadv & ADVERTISED_10baseT_Full)
0122 result |= ADVERTISE_10FULL;
0123 if (ethadv & ADVERTISED_100baseT_Half)
0124 result |= ADVERTISE_100HALF;
0125 if (ethadv & ADVERTISED_100baseT_Full)
0126 result |= ADVERTISE_100FULL;
0127 if (ethadv & ADVERTISED_Pause)
0128 result |= ADVERTISE_PAUSE_CAP;
0129 if (ethadv & ADVERTISED_Asym_Pause)
0130 result |= ADVERTISE_PAUSE_ASYM;
0131
0132 return result;
0133 }
0134
0135
0136
0137
0138
0139
0140
0141
0142
0143 static inline u32 linkmode_adv_to_mii_adv_t(unsigned long *advertising)
0144 {
0145 u32 result = 0;
0146
0147 if (linkmode_test_bit(ETHTOOL_LINK_MODE_10baseT_Half_BIT, advertising))
0148 result |= ADVERTISE_10HALF;
0149 if (linkmode_test_bit(ETHTOOL_LINK_MODE_10baseT_Full_BIT, advertising))
0150 result |= ADVERTISE_10FULL;
0151 if (linkmode_test_bit(ETHTOOL_LINK_MODE_100baseT_Half_BIT, advertising))
0152 result |= ADVERTISE_100HALF;
0153 if (linkmode_test_bit(ETHTOOL_LINK_MODE_100baseT_Full_BIT, advertising))
0154 result |= ADVERTISE_100FULL;
0155 if (linkmode_test_bit(ETHTOOL_LINK_MODE_Pause_BIT, advertising))
0156 result |= ADVERTISE_PAUSE_CAP;
0157 if (linkmode_test_bit(ETHTOOL_LINK_MODE_Asym_Pause_BIT, advertising))
0158 result |= ADVERTISE_PAUSE_ASYM;
0159
0160 return result;
0161 }
0162
0163
0164
0165
0166
0167
0168
0169
0170 static inline u32 mii_adv_to_ethtool_adv_t(u32 adv)
0171 {
0172 u32 result = 0;
0173
0174 if (adv & ADVERTISE_10HALF)
0175 result |= ADVERTISED_10baseT_Half;
0176 if (adv & ADVERTISE_10FULL)
0177 result |= ADVERTISED_10baseT_Full;
0178 if (adv & ADVERTISE_100HALF)
0179 result |= ADVERTISED_100baseT_Half;
0180 if (adv & ADVERTISE_100FULL)
0181 result |= ADVERTISED_100baseT_Full;
0182 if (adv & ADVERTISE_PAUSE_CAP)
0183 result |= ADVERTISED_Pause;
0184 if (adv & ADVERTISE_PAUSE_ASYM)
0185 result |= ADVERTISED_Asym_Pause;
0186
0187 return result;
0188 }
0189
0190
0191
0192
0193
0194
0195
0196
0197
0198 static inline u32 ethtool_adv_to_mii_ctrl1000_t(u32 ethadv)
0199 {
0200 u32 result = 0;
0201
0202 if (ethadv & ADVERTISED_1000baseT_Half)
0203 result |= ADVERTISE_1000HALF;
0204 if (ethadv & ADVERTISED_1000baseT_Full)
0205 result |= ADVERTISE_1000FULL;
0206
0207 return result;
0208 }
0209
0210
0211
0212
0213
0214
0215
0216
0217
0218 static inline u32 linkmode_adv_to_mii_ctrl1000_t(unsigned long *advertising)
0219 {
0220 u32 result = 0;
0221
0222 if (linkmode_test_bit(ETHTOOL_LINK_MODE_1000baseT_Half_BIT,
0223 advertising))
0224 result |= ADVERTISE_1000HALF;
0225 if (linkmode_test_bit(ETHTOOL_LINK_MODE_1000baseT_Full_BIT,
0226 advertising))
0227 result |= ADVERTISE_1000FULL;
0228
0229 return result;
0230 }
0231
0232
0233
0234
0235
0236
0237
0238
0239
0240 static inline u32 mii_ctrl1000_to_ethtool_adv_t(u32 adv)
0241 {
0242 u32 result = 0;
0243
0244 if (adv & ADVERTISE_1000HALF)
0245 result |= ADVERTISED_1000baseT_Half;
0246 if (adv & ADVERTISE_1000FULL)
0247 result |= ADVERTISED_1000baseT_Full;
0248
0249 return result;
0250 }
0251
0252
0253
0254
0255
0256
0257
0258
0259
0260 static inline u32 mii_lpa_to_ethtool_lpa_t(u32 lpa)
0261 {
0262 u32 result = 0;
0263
0264 if (lpa & LPA_LPACK)
0265 result |= ADVERTISED_Autoneg;
0266
0267 return result | mii_adv_to_ethtool_adv_t(lpa);
0268 }
0269
0270
0271
0272
0273
0274
0275
0276
0277
0278 static inline u32 mii_stat1000_to_ethtool_lpa_t(u32 lpa)
0279 {
0280 u32 result = 0;
0281
0282 if (lpa & LPA_1000HALF)
0283 result |= ADVERTISED_1000baseT_Half;
0284 if (lpa & LPA_1000FULL)
0285 result |= ADVERTISED_1000baseT_Full;
0286
0287 return result;
0288 }
0289
0290
0291
0292
0293
0294
0295
0296
0297
0298
0299 static inline void mii_stat1000_mod_linkmode_lpa_t(unsigned long *advertising,
0300 u32 lpa)
0301 {
0302 linkmode_mod_bit(ETHTOOL_LINK_MODE_1000baseT_Half_BIT,
0303 advertising, lpa & LPA_1000HALF);
0304
0305 linkmode_mod_bit(ETHTOOL_LINK_MODE_1000baseT_Full_BIT,
0306 advertising, lpa & LPA_1000FULL);
0307 }
0308
0309
0310
0311
0312
0313
0314
0315
0316
0317 static inline u32 ethtool_adv_to_mii_adv_x(u32 ethadv)
0318 {
0319 u32 result = 0;
0320
0321 if (ethadv & ADVERTISED_1000baseT_Half)
0322 result |= ADVERTISE_1000XHALF;
0323 if (ethadv & ADVERTISED_1000baseT_Full)
0324 result |= ADVERTISE_1000XFULL;
0325 if (ethadv & ADVERTISED_Pause)
0326 result |= ADVERTISE_1000XPAUSE;
0327 if (ethadv & ADVERTISED_Asym_Pause)
0328 result |= ADVERTISE_1000XPSE_ASYM;
0329
0330 return result;
0331 }
0332
0333
0334
0335
0336
0337
0338
0339
0340
0341 static inline u32 mii_adv_to_ethtool_adv_x(u32 adv)
0342 {
0343 u32 result = 0;
0344
0345 if (adv & ADVERTISE_1000XHALF)
0346 result |= ADVERTISED_1000baseT_Half;
0347 if (adv & ADVERTISE_1000XFULL)
0348 result |= ADVERTISED_1000baseT_Full;
0349 if (adv & ADVERTISE_1000XPAUSE)
0350 result |= ADVERTISED_Pause;
0351 if (adv & ADVERTISE_1000XPSE_ASYM)
0352 result |= ADVERTISED_Asym_Pause;
0353
0354 return result;
0355 }
0356
0357
0358
0359
0360
0361
0362
0363
0364
0365 static inline void mii_adv_mod_linkmode_adv_t(unsigned long *advertising,
0366 u32 adv)
0367 {
0368 linkmode_mod_bit(ETHTOOL_LINK_MODE_10baseT_Half_BIT,
0369 advertising, adv & ADVERTISE_10HALF);
0370
0371 linkmode_mod_bit(ETHTOOL_LINK_MODE_10baseT_Full_BIT,
0372 advertising, adv & ADVERTISE_10FULL);
0373
0374 linkmode_mod_bit(ETHTOOL_LINK_MODE_100baseT_Half_BIT,
0375 advertising, adv & ADVERTISE_100HALF);
0376
0377 linkmode_mod_bit(ETHTOOL_LINK_MODE_100baseT_Full_BIT,
0378 advertising, adv & ADVERTISE_100FULL);
0379
0380 linkmode_mod_bit(ETHTOOL_LINK_MODE_Pause_BIT, advertising,
0381 adv & ADVERTISE_PAUSE_CAP);
0382
0383 linkmode_mod_bit(ETHTOOL_LINK_MODE_Asym_Pause_BIT,
0384 advertising, adv & ADVERTISE_PAUSE_ASYM);
0385 }
0386
0387
0388
0389
0390
0391
0392
0393
0394
0395
0396 static inline void mii_adv_to_linkmode_adv_t(unsigned long *advertising,
0397 u32 adv)
0398 {
0399 linkmode_zero(advertising);
0400
0401 mii_adv_mod_linkmode_adv_t(advertising, adv);
0402 }
0403
0404
0405
0406
0407
0408
0409
0410
0411
0412 static inline void mii_lpa_to_linkmode_lpa_t(unsigned long *lp_advertising,
0413 u32 lpa)
0414 {
0415 mii_adv_to_linkmode_adv_t(lp_advertising, lpa);
0416
0417 if (lpa & LPA_LPACK)
0418 linkmode_set_bit(ETHTOOL_LINK_MODE_Autoneg_BIT,
0419 lp_advertising);
0420
0421 }
0422
0423
0424
0425
0426
0427
0428
0429
0430
0431 static inline void mii_lpa_mod_linkmode_lpa_t(unsigned long *lp_advertising,
0432 u32 lpa)
0433 {
0434 mii_adv_mod_linkmode_adv_t(lp_advertising, lpa);
0435
0436 linkmode_mod_bit(ETHTOOL_LINK_MODE_Autoneg_BIT,
0437 lp_advertising, lpa & LPA_LPACK);
0438 }
0439
0440 static inline void mii_ctrl1000_mod_linkmode_adv_t(unsigned long *advertising,
0441 u32 ctrl1000)
0442 {
0443 linkmode_mod_bit(ETHTOOL_LINK_MODE_1000baseT_Half_BIT, advertising,
0444 ctrl1000 & ADVERTISE_1000HALF);
0445 linkmode_mod_bit(ETHTOOL_LINK_MODE_1000baseT_Full_BIT, advertising,
0446 ctrl1000 & ADVERTISE_1000FULL);
0447 }
0448
0449
0450
0451
0452
0453
0454
0455
0456 static inline u32 linkmode_adv_to_lcl_adv_t(unsigned long *advertising)
0457 {
0458 u32 lcl_adv = 0;
0459
0460 if (linkmode_test_bit(ETHTOOL_LINK_MODE_Pause_BIT,
0461 advertising))
0462 lcl_adv |= ADVERTISE_PAUSE_CAP;
0463 if (linkmode_test_bit(ETHTOOL_LINK_MODE_Asym_Pause_BIT,
0464 advertising))
0465 lcl_adv |= ADVERTISE_PAUSE_ASYM;
0466
0467 return lcl_adv;
0468 }
0469
0470
0471
0472
0473
0474
0475
0476 static inline void mii_lpa_mod_linkmode_x(unsigned long *linkmodes, u16 lpa,
0477 int fd_bit)
0478 {
0479 linkmode_mod_bit(ETHTOOL_LINK_MODE_Autoneg_BIT, linkmodes,
0480 lpa & LPA_LPACK);
0481 linkmode_mod_bit(ETHTOOL_LINK_MODE_Pause_BIT, linkmodes,
0482 lpa & LPA_1000XPAUSE);
0483 linkmode_mod_bit(ETHTOOL_LINK_MODE_Asym_Pause_BIT, linkmodes,
0484 lpa & LPA_1000XPAUSE_ASYM);
0485 linkmode_mod_bit(fd_bit, linkmodes,
0486 lpa & LPA_1000XFULL);
0487 }
0488
0489
0490
0491
0492
0493
0494 static inline u16 linkmode_adv_to_mii_adv_x(const unsigned long *linkmodes,
0495 int fd_bit)
0496 {
0497 u16 adv = 0;
0498
0499 if (linkmode_test_bit(fd_bit, linkmodes))
0500 adv |= ADVERTISE_1000XFULL;
0501 if (linkmode_test_bit(ETHTOOL_LINK_MODE_Pause_BIT, linkmodes))
0502 adv |= ADVERTISE_1000XPAUSE;
0503 if (linkmode_test_bit(ETHTOOL_LINK_MODE_Asym_Pause_BIT, linkmodes))
0504 adv |= ADVERTISE_1000XPSE_ASYM;
0505
0506 return adv;
0507 }
0508
0509
0510
0511
0512
0513 static inline u16 mii_advertise_flowctrl(int cap)
0514 {
0515 u16 adv = 0;
0516
0517 if (cap & FLOW_CTRL_RX)
0518 adv = ADVERTISE_PAUSE_CAP | ADVERTISE_PAUSE_ASYM;
0519 if (cap & FLOW_CTRL_TX)
0520 adv ^= ADVERTISE_PAUSE_ASYM;
0521
0522 return adv;
0523 }
0524
0525
0526
0527
0528
0529
0530
0531
0532 static inline u8 mii_resolve_flowctrl_fdx(u16 lcladv, u16 rmtadv)
0533 {
0534 u8 cap = 0;
0535
0536 if (lcladv & rmtadv & ADVERTISE_PAUSE_CAP) {
0537 cap = FLOW_CTRL_TX | FLOW_CTRL_RX;
0538 } else if (lcladv & rmtadv & ADVERTISE_PAUSE_ASYM) {
0539 if (lcladv & ADVERTISE_PAUSE_CAP)
0540 cap = FLOW_CTRL_RX;
0541 else if (rmtadv & ADVERTISE_PAUSE_CAP)
0542 cap = FLOW_CTRL_TX;
0543 }
0544
0545 return cap;
0546 }
0547
0548
0549
0550
0551
0552
0553
0554
0555
0556
0557 static inline u16 mii_bmcr_encode_fixed(int speed, int duplex)
0558 {
0559 u16 bmcr;
0560
0561 switch (speed) {
0562 case SPEED_2500:
0563 case SPEED_1000:
0564 bmcr = BMCR_SPEED1000;
0565 break;
0566
0567 case SPEED_100:
0568 bmcr = BMCR_SPEED100;
0569 break;
0570
0571 case SPEED_10:
0572 default:
0573 bmcr = BMCR_SPEED10;
0574 break;
0575 }
0576
0577 if (duplex == DUPLEX_FULL)
0578 bmcr |= BMCR_FULLDPLX;
0579
0580 return bmcr;
0581 }
0582
0583 #endif