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); |