0001
0002
0003
0004
0005
0006
0007 #include <linux/kernel.h>
0008 #include <linux/string.h>
0009 #include <linux/errno.h>
0010 #include <linux/unistd.h>
0011 #include <linux/interrupt.h>
0012 #include <linux/init.h>
0013 #include <linux/delay.h>
0014 #include <linux/netdevice.h>
0015 #include <linux/etherdevice.h>
0016 #include <linux/skbuff.h>
0017 #include <linux/spinlock.h>
0018 #include <linux/mm.h>
0019 #include <linux/module.h>
0020 #include <linux/mii.h>
0021 #include <linux/ethtool.h>
0022 #include <linux/phy.h>
0023 #include <linux/property.h>
0024
0025 #include <asm/io.h>
0026 #include <asm/irq.h>
0027 #include <linux/uaccess.h>
0028
0029 MODULE_DESCRIPTION("ICPlus IP175C/IP101A/IP101G/IC1001 PHY drivers");
0030 MODULE_AUTHOR("Michael Barkowski");
0031 MODULE_LICENSE("GPL");
0032
0033
0034 #define IP10XX_SPEC_CTRL_STATUS 16
0035 #define IP1001_RXPHASE_SEL BIT(0)
0036 #define IP1001_TXPHASE_SEL BIT(1)
0037 #define IP1001_SPEC_CTRL_STATUS_2 20
0038 #define IP1001_APS_ON 11
0039 #define IP101A_G_APS_ON BIT(1)
0040 #define IP101A_G_AUTO_MDIX_DIS BIT(11)
0041 #define IP101A_G_IRQ_CONF_STATUS 0x11
0042 #define IP101A_G_IRQ_PIN_USED BIT(15)
0043 #define IP101A_G_IRQ_ALL_MASK BIT(11)
0044 #define IP101A_G_IRQ_SPEED_CHANGE BIT(2)
0045 #define IP101A_G_IRQ_DUPLEX_CHANGE BIT(1)
0046 #define IP101A_G_IRQ_LINK_CHANGE BIT(0)
0047 #define IP101A_G_PHY_STATUS 18
0048 #define IP101A_G_MDIX BIT(9)
0049 #define IP101A_G_PHY_SPEC_CTRL 30
0050 #define IP101A_G_FORCE_MDIX BIT(3)
0051
0052 #define IP101G_PAGE_CONTROL 0x14
0053 #define IP101G_PAGE_CONTROL_MASK GENMASK(4, 0)
0054 #define IP101G_DIGITAL_IO_SPEC_CTRL 0x1d
0055 #define IP101G_DIGITAL_IO_SPEC_CTRL_SEL_INTR32 BIT(2)
0056
0057 #define IP101G_DEFAULT_PAGE 16
0058
0059 #define IP101G_P1_CNT_CTRL 17
0060 #define CNT_CTRL_RX_EN BIT(13)
0061 #define IP101G_P8_CNT_CTRL 17
0062 #define CNT_CTRL_RDCLR_EN BIT(15)
0063 #define IP101G_CNT_REG 18
0064
0065 #define IP175C_PHY_ID 0x02430d80
0066 #define IP1001_PHY_ID 0x02430d90
0067 #define IP101A_PHY_ID 0x02430c54
0068
0069
0070
0071
0072
0073 enum ip101gr_sel_intr32 {
0074 IP101GR_SEL_INTR32_KEEP,
0075 IP101GR_SEL_INTR32_INTR,
0076 IP101GR_SEL_INTR32_RXER,
0077 };
0078
0079 struct ip101g_hw_stat {
0080 const char *name;
0081 int page;
0082 };
0083
0084 static struct ip101g_hw_stat ip101g_hw_stats[] = {
0085 { "phy_crc_errors", 1 },
0086 { "phy_symbol_errors", 11, },
0087 };
0088
0089 struct ip101a_g_phy_priv {
0090 enum ip101gr_sel_intr32 sel_intr32;
0091 u64 stats[ARRAY_SIZE(ip101g_hw_stats)];
0092 };
0093
0094 static int ip175c_config_init(struct phy_device *phydev)
0095 {
0096 int err, i;
0097 static int full_reset_performed;
0098
0099 if (full_reset_performed == 0) {
0100
0101
0102 err = mdiobus_write(phydev->mdio.bus, 30, 0, 0x175c);
0103 if (err < 0)
0104 return err;
0105
0106
0107 err = mdiobus_read(phydev->mdio.bus, 30, 0);
0108
0109
0110 mdelay(2);
0111
0112
0113 err = mdiobus_write(phydev->mdio.bus, 29, 31, 0x175c);
0114 if (err < 0)
0115 return err;
0116
0117
0118 err = mdiobus_write(phydev->mdio.bus, 29, 22, 0x420);
0119 if (err < 0)
0120 return err;
0121
0122
0123 for (i = 0; i < 5; i++) {
0124 err = mdiobus_write(phydev->mdio.bus, i,
0125 MII_BMCR, BMCR_RESET);
0126 if (err < 0)
0127 return err;
0128 }
0129
0130 for (i = 0; i < 5; i++)
0131 err = mdiobus_read(phydev->mdio.bus, i, MII_BMCR);
0132
0133 mdelay(2);
0134
0135 full_reset_performed = 1;
0136 }
0137
0138 if (phydev->mdio.addr != 4) {
0139 phydev->state = PHY_RUNNING;
0140 phydev->speed = SPEED_100;
0141 phydev->duplex = DUPLEX_FULL;
0142 phydev->link = 1;
0143 netif_carrier_on(phydev->attached_dev);
0144 }
0145
0146 return 0;
0147 }
0148
0149 static int ip1001_config_init(struct phy_device *phydev)
0150 {
0151 int c;
0152
0153
0154 c = phy_read(phydev, IP1001_SPEC_CTRL_STATUS_2);
0155 if (c < 0)
0156 return c;
0157 c |= IP1001_APS_ON;
0158 c = phy_write(phydev, IP1001_SPEC_CTRL_STATUS_2, c);
0159 if (c < 0)
0160 return c;
0161
0162 if (phy_interface_is_rgmii(phydev)) {
0163
0164 c = phy_read(phydev, IP10XX_SPEC_CTRL_STATUS);
0165 if (c < 0)
0166 return c;
0167
0168 c &= ~(IP1001_RXPHASE_SEL | IP1001_TXPHASE_SEL);
0169
0170 if (phydev->interface == PHY_INTERFACE_MODE_RGMII_ID)
0171 c |= (IP1001_RXPHASE_SEL | IP1001_TXPHASE_SEL);
0172 else if (phydev->interface == PHY_INTERFACE_MODE_RGMII_RXID)
0173 c |= IP1001_RXPHASE_SEL;
0174 else if (phydev->interface == PHY_INTERFACE_MODE_RGMII_TXID)
0175 c |= IP1001_TXPHASE_SEL;
0176
0177 c = phy_write(phydev, IP10XX_SPEC_CTRL_STATUS, c);
0178 if (c < 0)
0179 return c;
0180 }
0181
0182 return 0;
0183 }
0184
0185 static int ip175c_read_status(struct phy_device *phydev)
0186 {
0187 if (phydev->mdio.addr == 4)
0188 genphy_read_status(phydev);
0189 else
0190
0191 phydev->irq = PHY_MAC_INTERRUPT;
0192
0193 return 0;
0194 }
0195
0196 static int ip175c_config_aneg(struct phy_device *phydev)
0197 {
0198 if (phydev->mdio.addr == 4)
0199 genphy_config_aneg(phydev);
0200
0201 return 0;
0202 }
0203
0204 static int ip101a_g_probe(struct phy_device *phydev)
0205 {
0206 struct device *dev = &phydev->mdio.dev;
0207 struct ip101a_g_phy_priv *priv;
0208
0209 priv = devm_kzalloc(dev, sizeof(*priv), GFP_KERNEL);
0210 if (!priv)
0211 return -ENOMEM;
0212
0213
0214
0215
0216 if (device_property_read_bool(dev, "icplus,select-rx-error") &&
0217 device_property_read_bool(dev, "icplus,select-interrupt")) {
0218 dev_err(dev,
0219 "RXER and INTR mode cannot be selected together\n");
0220 return -EINVAL;
0221 }
0222
0223 if (device_property_read_bool(dev, "icplus,select-rx-error"))
0224 priv->sel_intr32 = IP101GR_SEL_INTR32_RXER;
0225 else if (device_property_read_bool(dev, "icplus,select-interrupt"))
0226 priv->sel_intr32 = IP101GR_SEL_INTR32_INTR;
0227 else
0228 priv->sel_intr32 = IP101GR_SEL_INTR32_KEEP;
0229
0230 phydev->priv = priv;
0231
0232 return 0;
0233 }
0234
0235 static int ip101a_g_config_intr_pin(struct phy_device *phydev)
0236 {
0237 struct ip101a_g_phy_priv *priv = phydev->priv;
0238 int oldpage, err = 0;
0239
0240 oldpage = phy_select_page(phydev, IP101G_DEFAULT_PAGE);
0241 if (oldpage < 0)
0242 goto out;
0243
0244
0245 switch (priv->sel_intr32) {
0246 case IP101GR_SEL_INTR32_RXER:
0247 err = __phy_modify(phydev, IP101G_DIGITAL_IO_SPEC_CTRL,
0248 IP101G_DIGITAL_IO_SPEC_CTRL_SEL_INTR32, 0);
0249 if (err < 0)
0250 goto out;
0251 break;
0252
0253 case IP101GR_SEL_INTR32_INTR:
0254 err = __phy_modify(phydev, IP101G_DIGITAL_IO_SPEC_CTRL,
0255 IP101G_DIGITAL_IO_SPEC_CTRL_SEL_INTR32,
0256 IP101G_DIGITAL_IO_SPEC_CTRL_SEL_INTR32);
0257 if (err < 0)
0258 goto out;
0259 break;
0260
0261 default:
0262
0263
0264
0265
0266
0267
0268
0269 break;
0270 }
0271
0272 out:
0273 return phy_restore_page(phydev, oldpage, err);
0274 }
0275
0276 static int ip101a_config_init(struct phy_device *phydev)
0277 {
0278 int ret;
0279
0280
0281 ret = phy_set_bits(phydev, IP10XX_SPEC_CTRL_STATUS, IP101A_G_APS_ON);
0282 if (ret)
0283 return ret;
0284
0285 return ip101a_g_config_intr_pin(phydev);
0286 }
0287
0288 static int ip101g_config_init(struct phy_device *phydev)
0289 {
0290 int ret;
0291
0292
0293 ret = phy_modify_paged(phydev, 1, IP101G_P1_CNT_CTRL,
0294 CNT_CTRL_RX_EN, CNT_CTRL_RX_EN);
0295 if (ret)
0296 return ret;
0297
0298
0299 ret = phy_modify_paged(phydev, 8, IP101G_P8_CNT_CTRL,
0300 CNT_CTRL_RDCLR_EN, CNT_CTRL_RDCLR_EN);
0301 if (ret)
0302 return ret;
0303
0304 return ip101a_g_config_intr_pin(phydev);
0305 }
0306
0307 static int ip101a_g_read_status(struct phy_device *phydev)
0308 {
0309 int oldpage, ret, stat1, stat2;
0310
0311 ret = genphy_read_status(phydev);
0312 if (ret)
0313 return ret;
0314
0315 oldpage = phy_select_page(phydev, IP101G_DEFAULT_PAGE);
0316 if (oldpage < 0)
0317 goto out;
0318
0319 ret = __phy_read(phydev, IP10XX_SPEC_CTRL_STATUS);
0320 if (ret < 0)
0321 goto out;
0322 stat1 = ret;
0323
0324 ret = __phy_read(phydev, IP101A_G_PHY_SPEC_CTRL);
0325 if (ret < 0)
0326 goto out;
0327 stat2 = ret;
0328
0329 if (stat1 & IP101A_G_AUTO_MDIX_DIS) {
0330 if (stat2 & IP101A_G_FORCE_MDIX)
0331 phydev->mdix_ctrl = ETH_TP_MDI_X;
0332 else
0333 phydev->mdix_ctrl = ETH_TP_MDI;
0334 } else {
0335 phydev->mdix_ctrl = ETH_TP_MDI_AUTO;
0336 }
0337
0338 if (stat2 & IP101A_G_MDIX)
0339 phydev->mdix = ETH_TP_MDI_X;
0340 else
0341 phydev->mdix = ETH_TP_MDI;
0342
0343 ret = 0;
0344
0345 out:
0346 return phy_restore_page(phydev, oldpage, ret);
0347 }
0348
0349 static int ip101a_g_config_mdix(struct phy_device *phydev)
0350 {
0351 u16 ctrl = 0, ctrl2 = 0;
0352 int oldpage;
0353 int ret = 0;
0354
0355 switch (phydev->mdix_ctrl) {
0356 case ETH_TP_MDI:
0357 ctrl = IP101A_G_AUTO_MDIX_DIS;
0358 break;
0359 case ETH_TP_MDI_X:
0360 ctrl = IP101A_G_AUTO_MDIX_DIS;
0361 ctrl2 = IP101A_G_FORCE_MDIX;
0362 break;
0363 case ETH_TP_MDI_AUTO:
0364 break;
0365 default:
0366 return 0;
0367 }
0368
0369 oldpage = phy_select_page(phydev, IP101G_DEFAULT_PAGE);
0370 if (oldpage < 0)
0371 goto out;
0372
0373 ret = __phy_modify(phydev, IP10XX_SPEC_CTRL_STATUS,
0374 IP101A_G_AUTO_MDIX_DIS, ctrl);
0375 if (ret)
0376 goto out;
0377
0378 ret = __phy_modify(phydev, IP101A_G_PHY_SPEC_CTRL,
0379 IP101A_G_FORCE_MDIX, ctrl2);
0380
0381 out:
0382 return phy_restore_page(phydev, oldpage, ret);
0383 }
0384
0385 static int ip101a_g_config_aneg(struct phy_device *phydev)
0386 {
0387 int ret;
0388
0389 ret = ip101a_g_config_mdix(phydev);
0390 if (ret)
0391 return ret;
0392
0393 return genphy_config_aneg(phydev);
0394 }
0395
0396 static int ip101a_g_ack_interrupt(struct phy_device *phydev)
0397 {
0398 int err;
0399
0400 err = phy_read_paged(phydev, IP101G_DEFAULT_PAGE,
0401 IP101A_G_IRQ_CONF_STATUS);
0402 if (err < 0)
0403 return err;
0404
0405 return 0;
0406 }
0407
0408 static int ip101a_g_config_intr(struct phy_device *phydev)
0409 {
0410 u16 val;
0411 int err;
0412
0413 if (phydev->interrupts == PHY_INTERRUPT_ENABLED) {
0414 err = ip101a_g_ack_interrupt(phydev);
0415 if (err)
0416 return err;
0417
0418
0419 val = IP101A_G_IRQ_PIN_USED;
0420 err = phy_write_paged(phydev, IP101G_DEFAULT_PAGE,
0421 IP101A_G_IRQ_CONF_STATUS, val);
0422 } else {
0423 val = IP101A_G_IRQ_ALL_MASK;
0424 err = phy_write_paged(phydev, IP101G_DEFAULT_PAGE,
0425 IP101A_G_IRQ_CONF_STATUS, val);
0426 if (err)
0427 return err;
0428
0429 err = ip101a_g_ack_interrupt(phydev);
0430 }
0431
0432 return err;
0433 }
0434
0435 static irqreturn_t ip101a_g_handle_interrupt(struct phy_device *phydev)
0436 {
0437 int irq_status;
0438
0439 irq_status = phy_read_paged(phydev, IP101G_DEFAULT_PAGE,
0440 IP101A_G_IRQ_CONF_STATUS);
0441 if (irq_status < 0) {
0442 phy_error(phydev);
0443 return IRQ_NONE;
0444 }
0445
0446 if (!(irq_status & (IP101A_G_IRQ_SPEED_CHANGE |
0447 IP101A_G_IRQ_DUPLEX_CHANGE |
0448 IP101A_G_IRQ_LINK_CHANGE)))
0449 return IRQ_NONE;
0450
0451 phy_trigger_machine(phydev);
0452
0453 return IRQ_HANDLED;
0454 }
0455
0456
0457
0458
0459 static int ip101a_read_page(struct phy_device *phydev)
0460 {
0461 return IP101G_DEFAULT_PAGE;
0462 }
0463
0464 static int ip101a_write_page(struct phy_device *phydev, int page)
0465 {
0466 WARN_ONCE(page != IP101G_DEFAULT_PAGE, "wrong page selected\n");
0467
0468 return 0;
0469 }
0470
0471 static int ip101g_read_page(struct phy_device *phydev)
0472 {
0473 return __phy_read(phydev, IP101G_PAGE_CONTROL);
0474 }
0475
0476 static int ip101g_write_page(struct phy_device *phydev, int page)
0477 {
0478 return __phy_write(phydev, IP101G_PAGE_CONTROL, page);
0479 }
0480
0481 static int ip101a_g_has_page_register(struct phy_device *phydev)
0482 {
0483 int oldval, val, ret;
0484
0485 oldval = phy_read(phydev, IP101G_PAGE_CONTROL);
0486 if (oldval < 0)
0487 return oldval;
0488
0489 ret = phy_write(phydev, IP101G_PAGE_CONTROL, 0xffff);
0490 if (ret)
0491 return ret;
0492
0493 val = phy_read(phydev, IP101G_PAGE_CONTROL);
0494 if (val < 0)
0495 return val;
0496
0497 ret = phy_write(phydev, IP101G_PAGE_CONTROL, oldval);
0498 if (ret)
0499 return ret;
0500
0501 return val == IP101G_PAGE_CONTROL_MASK;
0502 }
0503
0504 static int ip101a_g_match_phy_device(struct phy_device *phydev, bool ip101a)
0505 {
0506 int ret;
0507
0508 if (phydev->phy_id != IP101A_PHY_ID)
0509 return 0;
0510
0511
0512
0513
0514
0515
0516 ret = ip101a_g_has_page_register(phydev);
0517 if (ret < 0)
0518 return ret;
0519
0520 return ip101a == !ret;
0521 }
0522
0523 static int ip101a_match_phy_device(struct phy_device *phydev)
0524 {
0525 return ip101a_g_match_phy_device(phydev, true);
0526 }
0527
0528 static int ip101g_match_phy_device(struct phy_device *phydev)
0529 {
0530 return ip101a_g_match_phy_device(phydev, false);
0531 }
0532
0533 static int ip101g_get_sset_count(struct phy_device *phydev)
0534 {
0535 return ARRAY_SIZE(ip101g_hw_stats);
0536 }
0537
0538 static void ip101g_get_strings(struct phy_device *phydev, u8 *data)
0539 {
0540 int i;
0541
0542 for (i = 0; i < ARRAY_SIZE(ip101g_hw_stats); i++)
0543 strscpy(data + i * ETH_GSTRING_LEN,
0544 ip101g_hw_stats[i].name, ETH_GSTRING_LEN);
0545 }
0546
0547 static u64 ip101g_get_stat(struct phy_device *phydev, int i)
0548 {
0549 struct ip101g_hw_stat stat = ip101g_hw_stats[i];
0550 struct ip101a_g_phy_priv *priv = phydev->priv;
0551 int val;
0552 u64 ret;
0553
0554 val = phy_read_paged(phydev, stat.page, IP101G_CNT_REG);
0555 if (val < 0) {
0556 ret = U64_MAX;
0557 } else {
0558 priv->stats[i] += val;
0559 ret = priv->stats[i];
0560 }
0561
0562 return ret;
0563 }
0564
0565 static void ip101g_get_stats(struct phy_device *phydev,
0566 struct ethtool_stats *stats, u64 *data)
0567 {
0568 int i;
0569
0570 for (i = 0; i < ARRAY_SIZE(ip101g_hw_stats); i++)
0571 data[i] = ip101g_get_stat(phydev, i);
0572 }
0573
0574 static struct phy_driver icplus_driver[] = {
0575 {
0576 PHY_ID_MATCH_MODEL(IP175C_PHY_ID),
0577 .name = "ICPlus IP175C",
0578
0579 .config_init = ip175c_config_init,
0580 .config_aneg = ip175c_config_aneg,
0581 .read_status = ip175c_read_status,
0582 .suspend = genphy_suspend,
0583 .resume = genphy_resume,
0584 }, {
0585 PHY_ID_MATCH_MODEL(IP1001_PHY_ID),
0586 .name = "ICPlus IP1001",
0587
0588 .config_init = ip1001_config_init,
0589 .soft_reset = genphy_soft_reset,
0590 .suspend = genphy_suspend,
0591 .resume = genphy_resume,
0592 }, {
0593 .name = "ICPlus IP101A",
0594 .match_phy_device = ip101a_match_phy_device,
0595 .probe = ip101a_g_probe,
0596 .read_page = ip101a_read_page,
0597 .write_page = ip101a_write_page,
0598 .config_intr = ip101a_g_config_intr,
0599 .handle_interrupt = ip101a_g_handle_interrupt,
0600 .config_init = ip101a_config_init,
0601 .config_aneg = ip101a_g_config_aneg,
0602 .read_status = ip101a_g_read_status,
0603 .soft_reset = genphy_soft_reset,
0604 .suspend = genphy_suspend,
0605 .resume = genphy_resume,
0606 }, {
0607 .name = "ICPlus IP101G",
0608 .match_phy_device = ip101g_match_phy_device,
0609 .probe = ip101a_g_probe,
0610 .read_page = ip101g_read_page,
0611 .write_page = ip101g_write_page,
0612 .config_intr = ip101a_g_config_intr,
0613 .handle_interrupt = ip101a_g_handle_interrupt,
0614 .config_init = ip101g_config_init,
0615 .config_aneg = ip101a_g_config_aneg,
0616 .read_status = ip101a_g_read_status,
0617 .soft_reset = genphy_soft_reset,
0618 .get_sset_count = ip101g_get_sset_count,
0619 .get_strings = ip101g_get_strings,
0620 .get_stats = ip101g_get_stats,
0621 .suspend = genphy_suspend,
0622 .resume = genphy_resume,
0623 } };
0624
0625 module_phy_driver(icplus_driver);
0626
0627 static struct mdio_device_id __maybe_unused icplus_tbl[] = {
0628 { PHY_ID_MATCH_MODEL(IP175C_PHY_ID) },
0629 { PHY_ID_MATCH_MODEL(IP1001_PHY_ID) },
0630 { PHY_ID_MATCH_EXACT(IP101A_PHY_ID) },
0631 { }
0632 };
0633
0634 MODULE_DEVICE_TABLE(mdio, icplus_tbl);