micrel.c (13fe7056bebb4015c6231a07a1be4d3aebbfe979) micrel.c (bff5b4b3737219195ca0caef4ff7884303cb5dc1)
1/*
2 * drivers/net/phy/micrel.c
3 *
4 * Driver for Micrel PHYs
5 *
6 * Author: David J. Choi
7 *
8 * Copyright (c) 2010-2013 Micrel, Inc.
9 * Copyright (c) 2014 Johan Hovold <johan@kernel.org>
10 *
11 * This program is free software; you can redistribute it and/or modify it
12 * under the terms of the GNU General Public License as published by the
13 * Free Software Foundation; either version 2 of the License, or (at your
14 * option) any later version.
15 *
16 * Support : Micrel Phys:
1/*
2 * drivers/net/phy/micrel.c
3 *
4 * Driver for Micrel PHYs
5 *
6 * Author: David J. Choi
7 *
8 * Copyright (c) 2010-2013 Micrel, Inc.
9 * Copyright (c) 2014 Johan Hovold <johan@kernel.org>
10 *
11 * This program is free software; you can redistribute it and/or modify it
12 * under the terms of the GNU General Public License as published by the
13 * Free Software Foundation; either version 2 of the License, or (at your
14 * option) any later version.
15 *
16 * Support : Micrel Phys:
17 * Giga phys: ksz9021, ksz9031
17 * Giga phys: ksz9021, ksz9031, ksz9131
18 * 100/10 Phys : ksz8001, ksz8721, ksz8737, ksz8041
19 * ksz8021, ksz8031, ksz8051,
20 * ksz8081, ksz8091,
21 * ksz8061,
22 * Switch : ksz8873, ksz886x
23 * ksz9477
24 */
25

--- 578 unchanged lines hidden (view full) ---

604
605 return ksz9031_center_flp_timing(phydev);
606
607err_force_master:
608 phydev_err(phydev, "failed to force the phy to master mode\n");
609 return result;
610}
611
18 * 100/10 Phys : ksz8001, ksz8721, ksz8737, ksz8041
19 * ksz8021, ksz8031, ksz8051,
20 * ksz8081, ksz8091,
21 * ksz8061,
22 * Switch : ksz8873, ksz886x
23 * ksz9477
24 */
25

--- 578 unchanged lines hidden (view full) ---

604
605 return ksz9031_center_flp_timing(phydev);
606
607err_force_master:
608 phydev_err(phydev, "failed to force the phy to master mode\n");
609 return result;
610}
611
612#define KSZ9131_SKEW_5BIT_MAX 2400
613#define KSZ9131_SKEW_4BIT_MAX 800
614#define KSZ9131_OFFSET 700
615#define KSZ9131_STEP 100
616
617static int ksz9131_of_load_skew_values(struct phy_device *phydev,
618 struct device_node *of_node,
619 u16 reg, size_t field_sz,
620 char *field[], u8 numfields)
621{
622 int val[4] = {-(1 + KSZ9131_OFFSET), -(2 + KSZ9131_OFFSET),
623 -(3 + KSZ9131_OFFSET), -(4 + KSZ9131_OFFSET)};
624 int skewval, skewmax = 0;
625 int matches = 0;
626 u16 maxval;
627 u16 newval;
628 u16 mask;
629 int i;
630
631 /* psec properties in dts should mean x pico seconds */
632 if (field_sz == 5)
633 skewmax = KSZ9131_SKEW_5BIT_MAX;
634 else
635 skewmax = KSZ9131_SKEW_4BIT_MAX;
636
637 for (i = 0; i < numfields; i++)
638 if (!of_property_read_s32(of_node, field[i], &skewval)) {
639 if (skewval < -KSZ9131_OFFSET)
640 skewval = -KSZ9131_OFFSET;
641 else if (skewval > skewmax)
642 skewval = skewmax;
643
644 val[i] = skewval + KSZ9131_OFFSET;
645 matches++;
646 }
647
648 if (!matches)
649 return 0;
650
651 if (matches < numfields)
652 newval = ksz9031_extended_read(phydev, OP_DATA, 2, reg);
653 else
654 newval = 0;
655
656 maxval = (field_sz == 4) ? 0xf : 0x1f;
657 for (i = 0; i < numfields; i++)
658 if (val[i] != -(i + 1 + KSZ9131_OFFSET)) {
659 mask = 0xffff;
660 mask ^= maxval << (field_sz * i);
661 newval = (newval & mask) |
662 (((val[i] / KSZ9131_STEP) & maxval)
663 << (field_sz * i));
664 }
665
666 return ksz9031_extended_write(phydev, OP_DATA, 2, reg, newval);
667}
668
669static int ksz9131_config_init(struct phy_device *phydev)
670{
671 const struct device *dev = &phydev->mdio.dev;
672 struct device_node *of_node = dev->of_node;
673 char *clk_skews[2] = {"rxc-skew-psec", "txc-skew-psec"};
674 char *rx_data_skews[4] = {
675 "rxd0-skew-psec", "rxd1-skew-psec",
676 "rxd2-skew-psec", "rxd3-skew-psec"
677 };
678 char *tx_data_skews[4] = {
679 "txd0-skew-psec", "txd1-skew-psec",
680 "txd2-skew-psec", "txd3-skew-psec"
681 };
682 char *control_skews[2] = {"txen-skew-psec", "rxdv-skew-psec"};
683 const struct device *dev_walker;
684 int ret;
685
686 dev_walker = &phydev->mdio.dev;
687 do {
688 of_node = dev_walker->of_node;
689 dev_walker = dev_walker->parent;
690 } while (!of_node && dev_walker);
691
692 if (!of_node)
693 return 0;
694
695 ret = ksz9131_of_load_skew_values(phydev, of_node,
696 MII_KSZ9031RN_CLK_PAD_SKEW, 5,
697 clk_skews, 2);
698 if (ret < 0)
699 return ret;
700
701 ret = ksz9131_of_load_skew_values(phydev, of_node,
702 MII_KSZ9031RN_CONTROL_PAD_SKEW, 4,
703 control_skews, 2);
704 if (ret < 0)
705 return ret;
706
707 ret = ksz9131_of_load_skew_values(phydev, of_node,
708 MII_KSZ9031RN_RX_DATA_PAD_SKEW, 4,
709 rx_data_skews, 4);
710 if (ret < 0)
711 return ret;
712
713 ret = ksz9131_of_load_skew_values(phydev, of_node,
714 MII_KSZ9031RN_TX_DATA_PAD_SKEW, 4,
715 tx_data_skews, 4);
716 if (ret < 0)
717 return ret;
718
719 return 0;
720}
721
612#define KSZ8873MLL_GLOBAL_CONTROL_4 0x06
613#define KSZ8873MLL_GLOBAL_CONTROL_4_DUPLEX BIT(6)
614#define KSZ8873MLL_GLOBAL_CONTROL_4_SPEED BIT(4)
615static int ksz8873mll_read_status(struct phy_device *phydev)
616{
617 int regval;
618
619 /* dummy read */

--- 56 unchanged lines hidden (view full) ---

676 int i;
677
678 for (i = 0; i < ARRAY_SIZE(kszphy_hw_stats); i++) {
679 strlcpy(data + i * ETH_GSTRING_LEN,
680 kszphy_hw_stats[i].string, ETH_GSTRING_LEN);
681 }
682}
683
722#define KSZ8873MLL_GLOBAL_CONTROL_4 0x06
723#define KSZ8873MLL_GLOBAL_CONTROL_4_DUPLEX BIT(6)
724#define KSZ8873MLL_GLOBAL_CONTROL_4_SPEED BIT(4)
725static int ksz8873mll_read_status(struct phy_device *phydev)
726{
727 int regval;
728
729 /* dummy read */

--- 56 unchanged lines hidden (view full) ---

786 int i;
787
788 for (i = 0; i < ARRAY_SIZE(kszphy_hw_stats); i++) {
789 strlcpy(data + i * ETH_GSTRING_LEN,
790 kszphy_hw_stats[i].string, ETH_GSTRING_LEN);
791 }
792}
793
684#ifndef UINT64_MAX
685#define UINT64_MAX (u64)(~((u64)0))
686#endif
687static u64 kszphy_get_stat(struct phy_device *phydev, int i)
688{
689 struct kszphy_hw_stat stat = kszphy_hw_stats[i];
690 struct kszphy_priv *priv = phydev->priv;
691 int val;
692 u64 ret;
693
694 val = phy_read(phydev, stat.reg);
695 if (val < 0) {
794static u64 kszphy_get_stat(struct phy_device *phydev, int i)
795{
796 struct kszphy_hw_stat stat = kszphy_hw_stats[i];
797 struct kszphy_priv *priv = phydev->priv;
798 int val;
799 u64 ret;
800
801 val = phy_read(phydev, stat.reg);
802 if (val < 0) {
696 ret = UINT64_MAX;
803 ret = U64_MAX;
697 } else {
698 val = val & ((1 << stat.bits) - 1);
699 priv->stats[i] += val;
700 ret = priv->stats[i];
701 }
702
703 return ret;
704}

--- 268 unchanged lines hidden (view full) ---

973 .ack_interrupt = kszphy_ack_interrupt,
974 .config_intr = kszphy_config_intr,
975 .get_sset_count = kszphy_get_sset_count,
976 .get_strings = kszphy_get_strings,
977 .get_stats = kszphy_get_stats,
978 .suspend = genphy_suspend,
979 .resume = kszphy_resume,
980}, {
804 } else {
805 val = val & ((1 << stat.bits) - 1);
806 priv->stats[i] += val;
807 ret = priv->stats[i];
808 }
809
810 return ret;
811}

--- 268 unchanged lines hidden (view full) ---

1080 .ack_interrupt = kszphy_ack_interrupt,
1081 .config_intr = kszphy_config_intr,
1082 .get_sset_count = kszphy_get_sset_count,
1083 .get_strings = kszphy_get_strings,
1084 .get_stats = kszphy_get_stats,
1085 .suspend = genphy_suspend,
1086 .resume = kszphy_resume,
1087}, {
1088 .phy_id = PHY_ID_KSZ9131,
1089 .phy_id_mask = MICREL_PHY_ID_MASK,
1090 .name = "Microchip KSZ9131 Gigabit PHY",
1091 .features = PHY_GBIT_FEATURES,
1092 .flags = PHY_HAS_INTERRUPT,
1093 .driver_data = &ksz9021_type,
1094 .probe = kszphy_probe,
1095 .config_init = ksz9131_config_init,
1096 .read_status = ksz9031_read_status,
1097 .ack_interrupt = kszphy_ack_interrupt,
1098 .config_intr = kszphy_config_intr,
1099 .get_sset_count = kszphy_get_sset_count,
1100 .get_strings = kszphy_get_strings,
1101 .get_stats = kszphy_get_stats,
1102 .suspend = genphy_suspend,
1103 .resume = kszphy_resume,
1104}, {
981 .phy_id = PHY_ID_KSZ8873MLL,
982 .phy_id_mask = MICREL_PHY_ID_MASK,
983 .name = "Micrel KSZ8873MLL Switch",
984 .config_init = kszphy_config_init,
985 .config_aneg = ksz8873mll_config_aneg,
986 .read_status = ksz8873mll_read_status,
987 .suspend = genphy_suspend,
988 .resume = genphy_resume,

--- 31 unchanged lines hidden (view full) ---

1020
1021MODULE_DESCRIPTION("Micrel PHY driver");
1022MODULE_AUTHOR("David J. Choi");
1023MODULE_LICENSE("GPL");
1024
1025static struct mdio_device_id __maybe_unused micrel_tbl[] = {
1026 { PHY_ID_KSZ9021, 0x000ffffe },
1027 { PHY_ID_KSZ9031, MICREL_PHY_ID_MASK },
1105 .phy_id = PHY_ID_KSZ8873MLL,
1106 .phy_id_mask = MICREL_PHY_ID_MASK,
1107 .name = "Micrel KSZ8873MLL Switch",
1108 .config_init = kszphy_config_init,
1109 .config_aneg = ksz8873mll_config_aneg,
1110 .read_status = ksz8873mll_read_status,
1111 .suspend = genphy_suspend,
1112 .resume = genphy_resume,

--- 31 unchanged lines hidden (view full) ---

1144
1145MODULE_DESCRIPTION("Micrel PHY driver");
1146MODULE_AUTHOR("David J. Choi");
1147MODULE_LICENSE("GPL");
1148
1149static struct mdio_device_id __maybe_unused micrel_tbl[] = {
1150 { PHY_ID_KSZ9021, 0x000ffffe },
1151 { PHY_ID_KSZ9031, MICREL_PHY_ID_MASK },
1152 { PHY_ID_KSZ9131, MICREL_PHY_ID_MASK },
1028 { PHY_ID_KSZ8001, 0x00fffffc },
1029 { PHY_ID_KS8737, MICREL_PHY_ID_MASK },
1030 { PHY_ID_KSZ8021, 0x00ffffff },
1031 { PHY_ID_KSZ8031, 0x00ffffff },
1032 { PHY_ID_KSZ8041, MICREL_PHY_ID_MASK },
1033 { PHY_ID_KSZ8051, MICREL_PHY_ID_MASK },
1034 { PHY_ID_KSZ8061, MICREL_PHY_ID_MASK },
1035 { PHY_ID_KSZ8081, MICREL_PHY_ID_MASK },
1036 { PHY_ID_KSZ8873MLL, MICREL_PHY_ID_MASK },
1037 { PHY_ID_KSZ886X, MICREL_PHY_ID_MASK },
1038 { }
1039};
1040
1041MODULE_DEVICE_TABLE(mdio, micrel_tbl);
1153 { PHY_ID_KSZ8001, 0x00fffffc },
1154 { PHY_ID_KS8737, MICREL_PHY_ID_MASK },
1155 { PHY_ID_KSZ8021, 0x00ffffff },
1156 { PHY_ID_KSZ8031, 0x00ffffff },
1157 { PHY_ID_KSZ8041, MICREL_PHY_ID_MASK },
1158 { PHY_ID_KSZ8051, MICREL_PHY_ID_MASK },
1159 { PHY_ID_KSZ8061, MICREL_PHY_ID_MASK },
1160 { PHY_ID_KSZ8081, MICREL_PHY_ID_MASK },
1161 { PHY_ID_KSZ8873MLL, MICREL_PHY_ID_MASK },
1162 { PHY_ID_KSZ886X, MICREL_PHY_ID_MASK },
1163 { }
1164};
1165
1166MODULE_DEVICE_TABLE(mdio, micrel_tbl);