aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/net/arm/ks8695net.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/net/arm/ks8695net.c')
-rw-r--r--drivers/net/arm/ks8695net.c291
1 files changed, 97 insertions, 194 deletions
diff --git a/drivers/net/arm/ks8695net.c b/drivers/net/arm/ks8695net.c
index 54c6d849cf25..a7b0caa18179 100644
--- a/drivers/net/arm/ks8695net.c
+++ b/drivers/net/arm/ks8695net.c
@@ -854,12 +854,12 @@ ks8695_set_msglevel(struct net_device *ndev, u32 value)
854} 854}
855 855
856/** 856/**
857 * ks8695_get_settings - Get device-specific settings. 857 * ks8695_wan_get_settings - Get device-specific settings.
858 * @ndev: The network device to read settings from 858 * @ndev: The network device to read settings from
859 * @cmd: The ethtool structure to read into 859 * @cmd: The ethtool structure to read into
860 */ 860 */
861static int 861static int
862ks8695_get_settings(struct net_device *ndev, struct ethtool_cmd *cmd) 862ks8695_wan_get_settings(struct net_device *ndev, struct ethtool_cmd *cmd)
863{ 863{
864 struct ks8695_priv *ksp = netdev_priv(ndev); 864 struct ks8695_priv *ksp = netdev_priv(ndev);
865 u32 ctrl; 865 u32 ctrl;
@@ -870,69 +870,51 @@ ks8695_get_settings(struct net_device *ndev, struct ethtool_cmd *cmd)
870 SUPPORTED_TP | SUPPORTED_MII); 870 SUPPORTED_TP | SUPPORTED_MII);
871 cmd->transceiver = XCVR_INTERNAL; 871 cmd->transceiver = XCVR_INTERNAL;
872 872
873 /* Port specific extras */ 873 cmd->advertising = ADVERTISED_TP | ADVERTISED_MII;
874 switch (ksp->dtype) { 874 cmd->port = PORT_MII;
875 case KS8695_DTYPE_HPNA: 875 cmd->supported |= (SUPPORTED_Autoneg | SUPPORTED_Pause);
876 cmd->phy_address = 0; 876 cmd->phy_address = 0;
877 /* not supported for HPNA */
878 cmd->autoneg = AUTONEG_DISABLE;
879 877
880 /* BUG: Erm, dtype hpna implies no phy regs */ 878 ctrl = readl(ksp->phyiface_regs + KS8695_WMC);
881 /* 879 if ((ctrl & WMC_WAND) == 0) {
882 ctrl = readl(KS8695_MISC_VA + KS8695_HMC); 880 /* auto-negotiation is enabled */
883 cmd->speed = (ctrl & HMC_HSS) ? SPEED_100 : SPEED_10; 881 cmd->advertising |= ADVERTISED_Autoneg;
884 cmd->duplex = (ctrl & HMC_HDS) ? DUPLEX_FULL : DUPLEX_HALF; 882 if (ctrl & WMC_WANA100F)
885 */ 883 cmd->advertising |= ADVERTISED_100baseT_Full;
886 return -EOPNOTSUPP; 884 if (ctrl & WMC_WANA100H)
887 case KS8695_DTYPE_WAN: 885 cmd->advertising |= ADVERTISED_100baseT_Half;
888 cmd->advertising = ADVERTISED_TP | ADVERTISED_MII; 886 if (ctrl & WMC_WANA10F)
889 cmd->port = PORT_MII; 887 cmd->advertising |= ADVERTISED_10baseT_Full;
890 cmd->supported |= (SUPPORTED_Autoneg | SUPPORTED_Pause); 888 if (ctrl & WMC_WANA10H)
891 cmd->phy_address = 0; 889 cmd->advertising |= ADVERTISED_10baseT_Half;
890 if (ctrl & WMC_WANAP)
891 cmd->advertising |= ADVERTISED_Pause;
892 cmd->autoneg = AUTONEG_ENABLE;
893
894 ethtool_cmd_speed_set(cmd,
895 (ctrl & WMC_WSS) ? SPEED_100 : SPEED_10);
896 cmd->duplex = (ctrl & WMC_WDS) ?
897 DUPLEX_FULL : DUPLEX_HALF;
898 } else {
899 /* auto-negotiation is disabled */
900 cmd->autoneg = AUTONEG_DISABLE;
892 901
893 ctrl = readl(ksp->phyiface_regs + KS8695_WMC); 902 ethtool_cmd_speed_set(cmd, ((ctrl & WMC_WANF100) ?
894 if ((ctrl & WMC_WAND) == 0) { 903 SPEED_100 : SPEED_10));
895 /* auto-negotiation is enabled */ 904 cmd->duplex = (ctrl & WMC_WANFF) ?
896 cmd->advertising |= ADVERTISED_Autoneg; 905 DUPLEX_FULL : DUPLEX_HALF;
897 if (ctrl & WMC_WANA100F)
898 cmd->advertising |= ADVERTISED_100baseT_Full;
899 if (ctrl & WMC_WANA100H)
900 cmd->advertising |= ADVERTISED_100baseT_Half;
901 if (ctrl & WMC_WANA10F)
902 cmd->advertising |= ADVERTISED_10baseT_Full;
903 if (ctrl & WMC_WANA10H)
904 cmd->advertising |= ADVERTISED_10baseT_Half;
905 if (ctrl & WMC_WANAP)
906 cmd->advertising |= ADVERTISED_Pause;
907 cmd->autoneg = AUTONEG_ENABLE;
908
909 cmd->speed = (ctrl & WMC_WSS) ? SPEED_100 : SPEED_10;
910 cmd->duplex = (ctrl & WMC_WDS) ?
911 DUPLEX_FULL : DUPLEX_HALF;
912 } else {
913 /* auto-negotiation is disabled */
914 cmd->autoneg = AUTONEG_DISABLE;
915
916 cmd->speed = (ctrl & WMC_WANF100) ?
917 SPEED_100 : SPEED_10;
918 cmd->duplex = (ctrl & WMC_WANFF) ?
919 DUPLEX_FULL : DUPLEX_HALF;
920 }
921 break;
922 case KS8695_DTYPE_LAN:
923 return -EOPNOTSUPP;
924 } 906 }
925 907
926 return 0; 908 return 0;
927} 909}
928 910
929/** 911/**
930 * ks8695_set_settings - Set device-specific settings. 912 * ks8695_wan_set_settings - Set device-specific settings.
931 * @ndev: The network device to configure 913 * @ndev: The network device to configure
932 * @cmd: The settings to configure 914 * @cmd: The settings to configure
933 */ 915 */
934static int 916static int
935ks8695_set_settings(struct net_device *ndev, struct ethtool_cmd *cmd) 917ks8695_wan_set_settings(struct net_device *ndev, struct ethtool_cmd *cmd)
936{ 918{
937 struct ks8695_priv *ksp = netdev_priv(ndev); 919 struct ks8695_priv *ksp = netdev_priv(ndev);
938 u32 ctrl; 920 u32 ctrl;
@@ -956,171 +938,85 @@ ks8695_set_settings(struct net_device *ndev, struct ethtool_cmd *cmd)
956 ADVERTISED_100baseT_Full)) == 0) 938 ADVERTISED_100baseT_Full)) == 0)
957 return -EINVAL; 939 return -EINVAL;
958 940
959 switch (ksp->dtype) { 941 ctrl = readl(ksp->phyiface_regs + KS8695_WMC);
960 case KS8695_DTYPE_HPNA:
961 /* HPNA does not support auto-negotiation. */
962 return -EINVAL;
963 case KS8695_DTYPE_WAN:
964 ctrl = readl(ksp->phyiface_regs + KS8695_WMC);
965
966 ctrl &= ~(WMC_WAND | WMC_WANA100F | WMC_WANA100H |
967 WMC_WANA10F | WMC_WANA10H);
968 if (cmd->advertising & ADVERTISED_100baseT_Full)
969 ctrl |= WMC_WANA100F;
970 if (cmd->advertising & ADVERTISED_100baseT_Half)
971 ctrl |= WMC_WANA100H;
972 if (cmd->advertising & ADVERTISED_10baseT_Full)
973 ctrl |= WMC_WANA10F;
974 if (cmd->advertising & ADVERTISED_10baseT_Half)
975 ctrl |= WMC_WANA10H;
976
977 /* force a re-negotiation */
978 ctrl |= WMC_WANR;
979 writel(ctrl, ksp->phyiface_regs + KS8695_WMC);
980 break;
981 case KS8695_DTYPE_LAN:
982 return -EOPNOTSUPP;
983 }
984 942
943 ctrl &= ~(WMC_WAND | WMC_WANA100F | WMC_WANA100H |
944 WMC_WANA10F | WMC_WANA10H);
945 if (cmd->advertising & ADVERTISED_100baseT_Full)
946 ctrl |= WMC_WANA100F;
947 if (cmd->advertising & ADVERTISED_100baseT_Half)
948 ctrl |= WMC_WANA100H;
949 if (cmd->advertising & ADVERTISED_10baseT_Full)
950 ctrl |= WMC_WANA10F;
951 if (cmd->advertising & ADVERTISED_10baseT_Half)
952 ctrl |= WMC_WANA10H;
953
954 /* force a re-negotiation */
955 ctrl |= WMC_WANR;
956 writel(ctrl, ksp->phyiface_regs + KS8695_WMC);
985 } else { 957 } else {
986 switch (ksp->dtype) { 958 ctrl = readl(ksp->phyiface_regs + KS8695_WMC);
987 case KS8695_DTYPE_HPNA: 959
988 /* BUG: dtype_hpna implies no phy registers */ 960 /* disable auto-negotiation */
989 /* 961 ctrl |= WMC_WAND;
990 ctrl = __raw_readl(KS8695_MISC_VA + KS8695_HMC); 962 ctrl &= ~(WMC_WANF100 | WMC_WANFF);
991 963
992 ctrl &= ~(HMC_HSS | HMC_HDS); 964 if (cmd->speed == SPEED_100)
993 if (cmd->speed == SPEED_100) 965 ctrl |= WMC_WANF100;
994 ctrl |= HMC_HSS; 966 if (cmd->duplex == DUPLEX_FULL)
995 if (cmd->duplex == DUPLEX_FULL) 967 ctrl |= WMC_WANFF;
996 ctrl |= HMC_HDS; 968
997 969 writel(ctrl, ksp->phyiface_regs + KS8695_WMC);
998 __raw_writel(ctrl, KS8695_MISC_VA + KS8695_HMC);
999 */
1000 return -EOPNOTSUPP;
1001 case KS8695_DTYPE_WAN:
1002 ctrl = readl(ksp->phyiface_regs + KS8695_WMC);
1003
1004 /* disable auto-negotiation */
1005 ctrl |= WMC_WAND;
1006 ctrl &= ~(WMC_WANF100 | WMC_WANFF);
1007
1008 if (cmd->speed == SPEED_100)
1009 ctrl |= WMC_WANF100;
1010 if (cmd->duplex == DUPLEX_FULL)
1011 ctrl |= WMC_WANFF;
1012
1013 writel(ctrl, ksp->phyiface_regs + KS8695_WMC);
1014 break;
1015 case KS8695_DTYPE_LAN:
1016 return -EOPNOTSUPP;
1017 }
1018 } 970 }
1019 971
1020 return 0; 972 return 0;
1021} 973}
1022 974
1023/** 975/**
1024 * ks8695_nwayreset - Restart the autonegotiation on the port. 976 * ks8695_wan_nwayreset - Restart the autonegotiation on the port.
1025 * @ndev: The network device to restart autoneotiation on 977 * @ndev: The network device to restart autoneotiation on
1026 */ 978 */
1027static int 979static int
1028ks8695_nwayreset(struct net_device *ndev) 980ks8695_wan_nwayreset(struct net_device *ndev)
1029{ 981{
1030 struct ks8695_priv *ksp = netdev_priv(ndev); 982 struct ks8695_priv *ksp = netdev_priv(ndev);
1031 u32 ctrl; 983 u32 ctrl;
1032 984
1033 switch (ksp->dtype) { 985 ctrl = readl(ksp->phyiface_regs + KS8695_WMC);
1034 case KS8695_DTYPE_HPNA:
1035 /* No phy means no autonegotiation on hpna */
1036 return -EINVAL;
1037 case KS8695_DTYPE_WAN:
1038 ctrl = readl(ksp->phyiface_regs + KS8695_WMC);
1039
1040 if ((ctrl & WMC_WAND) == 0)
1041 writel(ctrl | WMC_WANR,
1042 ksp->phyiface_regs + KS8695_WMC);
1043 else
1044 /* auto-negotiation not enabled */
1045 return -EINVAL;
1046 break;
1047 case KS8695_DTYPE_LAN:
1048 return -EOPNOTSUPP;
1049 }
1050
1051 return 0;
1052}
1053 986
1054/** 987 if ((ctrl & WMC_WAND) == 0)
1055 * ks8695_get_link - Retrieve link status of network interface 988 writel(ctrl | WMC_WANR,
1056 * @ndev: The network interface to retrive the link status of. 989 ksp->phyiface_regs + KS8695_WMC);
1057 */ 990 else
1058static u32 991 /* auto-negotiation not enabled */
1059ks8695_get_link(struct net_device *ndev) 992 return -EINVAL;
1060{
1061 struct ks8695_priv *ksp = netdev_priv(ndev);
1062 u32 ctrl;
1063 993
1064 switch (ksp->dtype) {
1065 case KS8695_DTYPE_HPNA:
1066 /* HPNA always has link */
1067 return 1;
1068 case KS8695_DTYPE_WAN:
1069 /* WAN we can read the PHY for */
1070 ctrl = readl(ksp->phyiface_regs + KS8695_WMC);
1071 return ctrl & WMC_WLS;
1072 case KS8695_DTYPE_LAN:
1073 return -EOPNOTSUPP;
1074 }
1075 return 0; 994 return 0;
1076} 995}
1077 996
1078/** 997/**
1079 * ks8695_get_pause - Retrieve network pause/flow-control advertising 998 * ks8695_wan_get_pause - Retrieve network pause/flow-control advertising
1080 * @ndev: The device to retrieve settings from 999 * @ndev: The device to retrieve settings from
1081 * @param: The structure to fill out with the information 1000 * @param: The structure to fill out with the information
1082 */ 1001 */
1083static void 1002static void
1084ks8695_get_pause(struct net_device *ndev, struct ethtool_pauseparam *param) 1003ks8695_wan_get_pause(struct net_device *ndev, struct ethtool_pauseparam *param)
1085{ 1004{
1086 struct ks8695_priv *ksp = netdev_priv(ndev); 1005 struct ks8695_priv *ksp = netdev_priv(ndev);
1087 u32 ctrl; 1006 u32 ctrl;
1088 1007
1089 switch (ksp->dtype) { 1008 ctrl = readl(ksp->phyiface_regs + KS8695_WMC);
1090 case KS8695_DTYPE_HPNA:
1091 /* No phy link on hpna to configure */
1092 return;
1093 case KS8695_DTYPE_WAN:
1094 ctrl = readl(ksp->phyiface_regs + KS8695_WMC);
1095
1096 /* advertise Pause */
1097 param->autoneg = (ctrl & WMC_WANAP);
1098 1009
1099 /* current Rx Flow-control */ 1010 /* advertise Pause */
1100 ctrl = ks8695_readreg(ksp, KS8695_DRXC); 1011 param->autoneg = (ctrl & WMC_WANAP);
1101 param->rx_pause = (ctrl & DRXC_RFCE);
1102 1012
1103 /* current Tx Flow-control */ 1013 /* current Rx Flow-control */
1104 ctrl = ks8695_readreg(ksp, KS8695_DTXC); 1014 ctrl = ks8695_readreg(ksp, KS8695_DRXC);
1105 param->tx_pause = (ctrl & DTXC_TFCE); 1015 param->rx_pause = (ctrl & DRXC_RFCE);
1106 break;
1107 case KS8695_DTYPE_LAN:
1108 /* The LAN's "phy" is a direct-attached switch */
1109 return;
1110 }
1111}
1112 1016
1113/** 1017 /* current Tx Flow-control */
1114 * ks8695_set_pause - Configure pause/flow-control 1018 ctrl = ks8695_readreg(ksp, KS8695_DTXC);
1115 * @ndev: The device to configure 1019 param->tx_pause = (ctrl & DTXC_TFCE);
1116 * @param: The pause parameters to set
1117 *
1118 * TODO: Implement this
1119 */
1120static int
1121ks8695_set_pause(struct net_device *ndev, struct ethtool_pauseparam *param)
1122{
1123 return -EOPNOTSUPP;
1124} 1020}
1125 1021
1126/** 1022/**
@@ -1140,12 +1036,17 @@ ks8695_get_drvinfo(struct net_device *ndev, struct ethtool_drvinfo *info)
1140static const struct ethtool_ops ks8695_ethtool_ops = { 1036static const struct ethtool_ops ks8695_ethtool_ops = {
1141 .get_msglevel = ks8695_get_msglevel, 1037 .get_msglevel = ks8695_get_msglevel,
1142 .set_msglevel = ks8695_set_msglevel, 1038 .set_msglevel = ks8695_set_msglevel,
1143 .get_settings = ks8695_get_settings, 1039 .get_drvinfo = ks8695_get_drvinfo,
1144 .set_settings = ks8695_set_settings, 1040};
1145 .nway_reset = ks8695_nwayreset, 1041
1146 .get_link = ks8695_get_link, 1042static const struct ethtool_ops ks8695_wan_ethtool_ops = {
1147 .get_pauseparam = ks8695_get_pause, 1043 .get_msglevel = ks8695_get_msglevel,
1148 .set_pauseparam = ks8695_set_pause, 1044 .set_msglevel = ks8695_set_msglevel,
1045 .get_settings = ks8695_wan_get_settings,
1046 .set_settings = ks8695_wan_set_settings,
1047 .nway_reset = ks8695_wan_nwayreset,
1048 .get_link = ethtool_op_get_link,
1049 .get_pauseparam = ks8695_wan_get_pause,
1149 .get_drvinfo = ks8695_get_drvinfo, 1050 .get_drvinfo = ks8695_get_drvinfo,
1150}; 1051};
1151 1052
@@ -1541,7 +1442,6 @@ ks8695_probe(struct platform_device *pdev)
1541 1442
1542 /* driver system setup */ 1443 /* driver system setup */
1543 ndev->netdev_ops = &ks8695_netdev_ops; 1444 ndev->netdev_ops = &ks8695_netdev_ops;
1544 SET_ETHTOOL_OPS(ndev, &ks8695_ethtool_ops);
1545 ndev->watchdog_timeo = msecs_to_jiffies(watchdog); 1445 ndev->watchdog_timeo = msecs_to_jiffies(watchdog);
1546 1446
1547 netif_napi_add(ndev, &ksp->napi, ks8695_poll, NAPI_WEIGHT); 1447 netif_napi_add(ndev, &ksp->napi, ks8695_poll, NAPI_WEIGHT);
@@ -1608,12 +1508,15 @@ ks8695_probe(struct platform_device *pdev)
1608 if (ksp->phyiface_regs && ksp->link_irq == -1) { 1508 if (ksp->phyiface_regs && ksp->link_irq == -1) {
1609 ks8695_init_switch(ksp); 1509 ks8695_init_switch(ksp);
1610 ksp->dtype = KS8695_DTYPE_LAN; 1510 ksp->dtype = KS8695_DTYPE_LAN;
1511 SET_ETHTOOL_OPS(ndev, &ks8695_ethtool_ops);
1611 } else if (ksp->phyiface_regs && ksp->link_irq != -1) { 1512 } else if (ksp->phyiface_regs && ksp->link_irq != -1) {
1612 ks8695_init_wan_phy(ksp); 1513 ks8695_init_wan_phy(ksp);
1613 ksp->dtype = KS8695_DTYPE_WAN; 1514 ksp->dtype = KS8695_DTYPE_WAN;
1515 SET_ETHTOOL_OPS(ndev, &ks8695_wan_ethtool_ops);
1614 } else { 1516 } else {
1615 /* No initialisation since HPNA does not have a PHY */ 1517 /* No initialisation since HPNA does not have a PHY */
1616 ksp->dtype = KS8695_DTYPE_HPNA; 1518 ksp->dtype = KS8695_DTYPE_HPNA;
1519 SET_ETHTOOL_OPS(ndev, &ks8695_ethtool_ops);
1617 } 1520 }
1618 1521
1619 /* And bring up the net_device with the net core */ 1522 /* And bring up the net_device with the net core */
@@ -1742,7 +1645,7 @@ ks8695_cleanup(void)
1742module_init(ks8695_init); 1645module_init(ks8695_init);
1743module_exit(ks8695_cleanup); 1646module_exit(ks8695_cleanup);
1744 1647
1745MODULE_AUTHOR("Simtec Electronics") 1648MODULE_AUTHOR("Simtec Electronics");
1746MODULE_DESCRIPTION("Micrel KS8695 (Centaur) Ethernet driver"); 1649MODULE_DESCRIPTION("Micrel KS8695 (Centaur) Ethernet driver");
1747MODULE_LICENSE("GPL"); 1650MODULE_LICENSE("GPL");
1748MODULE_ALIAS("platform:" MODULENAME); 1651MODULE_ALIAS("platform:" MODULENAME);