aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/net/arm
diff options
context:
space:
mode:
authorBen Hutchings <bhutchings@solarflare.com>2011-01-13 02:50:14 -0500
committerDavid S. Miller <davem@davemloft.net>2011-01-14 00:48:27 -0500
commitc3d2a7309c95021f143c94a16ea9becc0c9b9d23 (patch)
tree3339bb16e0fc43d8884cfebd8f32c417cfd880da /drivers/net/arm
parent9e56790ad31d72a5a44142af462d047c0c897b29 (diff)
ks8695net: Disable non-working ethtool operations
Some ethtool operations can only be implemented for the WAN port, and not all such operations are allowed to return an error code such as -EOPNOTSUPP. Therefore, define two separate ethtool_ops structures for WAN and non-WAN ports; simplify and rename the WAN-only functions. This is completely untested as I don't have an ARM build environment. Signed-off-by: Ben Hutchings <bhutchings@solarflare.com> Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'drivers/net/arm')
-rw-r--r--drivers/net/arm/ks8695net.c282
1 files changed, 99 insertions, 183 deletions
diff --git a/drivers/net/arm/ks8695net.c b/drivers/net/arm/ks8695net.c
index 54c6d849cf25..8820fcdca10b 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,50 @@ 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 cmd->speed = (ctrl & WMC_WSS) ? SPEED_100 : SPEED_10;
895 cmd->duplex = (ctrl & WMC_WDS) ?
896 DUPLEX_FULL : DUPLEX_HALF;
897 } else {
898 /* auto-negotiation is disabled */
899 cmd->autoneg = AUTONEG_DISABLE;
892 900
893 ctrl = readl(ksp->phyiface_regs + KS8695_WMC); 901 cmd->speed = (ctrl & WMC_WANF100) ?
894 if ((ctrl & WMC_WAND) == 0) { 902 SPEED_100 : SPEED_10;
895 /* auto-negotiation is enabled */ 903 cmd->duplex = (ctrl & WMC_WANFF) ?
896 cmd->advertising |= ADVERTISED_Autoneg; 904 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 } 905 }
925 906
926 return 0; 907 return 0;
927} 908}
928 909
929/** 910/**
930 * ks8695_set_settings - Set device-specific settings. 911 * ks8695_wan_set_settings - Set device-specific settings.
931 * @ndev: The network device to configure 912 * @ndev: The network device to configure
932 * @cmd: The settings to configure 913 * @cmd: The settings to configure
933 */ 914 */
934static int 915static int
935ks8695_set_settings(struct net_device *ndev, struct ethtool_cmd *cmd) 916ks8695_wan_set_settings(struct net_device *ndev, struct ethtool_cmd *cmd)
936{ 917{
937 struct ks8695_priv *ksp = netdev_priv(ndev); 918 struct ks8695_priv *ksp = netdev_priv(ndev);
938 u32 ctrl; 919 u32 ctrl;
@@ -956,171 +937,99 @@ ks8695_set_settings(struct net_device *ndev, struct ethtool_cmd *cmd)
956 ADVERTISED_100baseT_Full)) == 0) 937 ADVERTISED_100baseT_Full)) == 0)
957 return -EINVAL; 938 return -EINVAL;
958 939
959 switch (ksp->dtype) { 940 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 941
942 ctrl &= ~(WMC_WAND | WMC_WANA100F | WMC_WANA100H |
943 WMC_WANA10F | WMC_WANA10H);
944 if (cmd->advertising & ADVERTISED_100baseT_Full)
945 ctrl |= WMC_WANA100F;
946 if (cmd->advertising & ADVERTISED_100baseT_Half)
947 ctrl |= WMC_WANA100H;
948 if (cmd->advertising & ADVERTISED_10baseT_Full)
949 ctrl |= WMC_WANA10F;
950 if (cmd->advertising & ADVERTISED_10baseT_Half)
951 ctrl |= WMC_WANA10H;
952
953 /* force a re-negotiation */
954 ctrl |= WMC_WANR;
955 writel(ctrl, ksp->phyiface_regs + KS8695_WMC);
985 } else { 956 } else {
986 switch (ksp->dtype) { 957 ctrl = readl(ksp->phyiface_regs + KS8695_WMC);
987 case KS8695_DTYPE_HPNA: 958
988 /* BUG: dtype_hpna implies no phy registers */ 959 /* disable auto-negotiation */
989 /* 960 ctrl |= WMC_WAND;
990 ctrl = __raw_readl(KS8695_MISC_VA + KS8695_HMC); 961 ctrl &= ~(WMC_WANF100 | WMC_WANFF);
991 962
992 ctrl &= ~(HMC_HSS | HMC_HDS); 963 if (cmd->speed == SPEED_100)
993 if (cmd->speed == SPEED_100) 964 ctrl |= WMC_WANF100;
994 ctrl |= HMC_HSS; 965 if (cmd->duplex == DUPLEX_FULL)
995 if (cmd->duplex == DUPLEX_FULL) 966 ctrl |= WMC_WANFF;
996 ctrl |= HMC_HDS; 967
997 968 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 } 969 }
1019 970
1020 return 0; 971 return 0;
1021} 972}
1022 973
1023/** 974/**
1024 * ks8695_nwayreset - Restart the autonegotiation on the port. 975 * ks8695_wan_nwayreset - Restart the autonegotiation on the port.
1025 * @ndev: The network device to restart autoneotiation on 976 * @ndev: The network device to restart autoneotiation on
1026 */ 977 */
1027static int 978static int
1028ks8695_nwayreset(struct net_device *ndev) 979ks8695_wan_nwayreset(struct net_device *ndev)
1029{ 980{
1030 struct ks8695_priv *ksp = netdev_priv(ndev); 981 struct ks8695_priv *ksp = netdev_priv(ndev);
1031 u32 ctrl; 982 u32 ctrl;
1032 983
1033 switch (ksp->dtype) { 984 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 985
1040 if ((ctrl & WMC_WAND) == 0) 986 if ((ctrl & WMC_WAND) == 0)
1041 writel(ctrl | WMC_WANR, 987 writel(ctrl | WMC_WANR,
1042 ksp->phyiface_regs + KS8695_WMC); 988 ksp->phyiface_regs + KS8695_WMC);
1043 else 989 else
1044 /* auto-negotiation not enabled */ 990 /* auto-negotiation not enabled */
1045 return -EINVAL; 991 return -EINVAL;
1046 break;
1047 case KS8695_DTYPE_LAN:
1048 return -EOPNOTSUPP;
1049 }
1050 992
1051 return 0; 993 return 0;
1052} 994}
1053 995
1054/** 996/**
1055 * ks8695_get_link - Retrieve link status of network interface 997 * ks8695_wan_get_link - Retrieve link status of network interface
1056 * @ndev: The network interface to retrive the link status of. 998 * @ndev: The network interface to retrive the link status of.
1057 */ 999 */
1058static u32 1000static u32
1059ks8695_get_link(struct net_device *ndev) 1001ks8695_wan_get_link(struct net_device *ndev)
1060{ 1002{
1061 struct ks8695_priv *ksp = netdev_priv(ndev); 1003 struct ks8695_priv *ksp = netdev_priv(ndev);
1062 u32 ctrl; 1004 u32 ctrl;
1063 1005
1064 switch (ksp->dtype) { 1006 ctrl = readl(ksp->phyiface_regs + KS8695_WMC);
1065 case KS8695_DTYPE_HPNA: 1007 return ctrl & WMC_WLS;
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;
1076} 1008}
1077 1009
1078/** 1010/**
1079 * ks8695_get_pause - Retrieve network pause/flow-control advertising 1011 * ks8695_wan_get_pause - Retrieve network pause/flow-control advertising
1080 * @ndev: The device to retrieve settings from 1012 * @ndev: The device to retrieve settings from
1081 * @param: The structure to fill out with the information 1013 * @param: The structure to fill out with the information
1082 */ 1014 */
1083static void 1015static void
1084ks8695_get_pause(struct net_device *ndev, struct ethtool_pauseparam *param) 1016ks8695_wan_get_pause(struct net_device *ndev, struct ethtool_pauseparam *param)
1085{ 1017{
1086 struct ks8695_priv *ksp = netdev_priv(ndev); 1018 struct ks8695_priv *ksp = netdev_priv(ndev);
1087 u32 ctrl; 1019 u32 ctrl;
1088 1020
1089 switch (ksp->dtype) { 1021 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 1022
1099 /* current Rx Flow-control */ 1023 /* advertise Pause */
1100 ctrl = ks8695_readreg(ksp, KS8695_DRXC); 1024 param->autoneg = (ctrl & WMC_WANAP);
1101 param->rx_pause = (ctrl & DRXC_RFCE);
1102 1025
1103 /* current Tx Flow-control */ 1026 /* current Rx Flow-control */
1104 ctrl = ks8695_readreg(ksp, KS8695_DTXC); 1027 ctrl = ks8695_readreg(ksp, KS8695_DRXC);
1105 param->tx_pause = (ctrl & DTXC_TFCE); 1028 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 1029
1113/** 1030 /* current Tx Flow-control */
1114 * ks8695_set_pause - Configure pause/flow-control 1031 ctrl = ks8695_readreg(ksp, KS8695_DTXC);
1115 * @ndev: The device to configure 1032 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} 1033}
1125 1034
1126/** 1035/**
@@ -1140,12 +1049,17 @@ ks8695_get_drvinfo(struct net_device *ndev, struct ethtool_drvinfo *info)
1140static const struct ethtool_ops ks8695_ethtool_ops = { 1049static const struct ethtool_ops ks8695_ethtool_ops = {
1141 .get_msglevel = ks8695_get_msglevel, 1050 .get_msglevel = ks8695_get_msglevel,
1142 .set_msglevel = ks8695_set_msglevel, 1051 .set_msglevel = ks8695_set_msglevel,
1143 .get_settings = ks8695_get_settings, 1052 .get_drvinfo = ks8695_get_drvinfo,
1144 .set_settings = ks8695_set_settings, 1053};
1145 .nway_reset = ks8695_nwayreset, 1054
1146 .get_link = ks8695_get_link, 1055static const struct ethtool_ops ks8695_wan_ethtool_ops = {
1147 .get_pauseparam = ks8695_get_pause, 1056 .get_msglevel = ks8695_get_msglevel,
1148 .set_pauseparam = ks8695_set_pause, 1057 .set_msglevel = ks8695_set_msglevel,
1058 .get_settings = ks8695_wan_get_settings,
1059 .set_settings = ks8695_wan_set_settings,
1060 .nway_reset = ks8695_wan_nwayreset,
1061 .get_link = ks8695_wan_get_link,
1062 .get_pauseparam = ks8695_wan_get_pause,
1149 .get_drvinfo = ks8695_get_drvinfo, 1063 .get_drvinfo = ks8695_get_drvinfo,
1150}; 1064};
1151 1065
@@ -1541,7 +1455,6 @@ ks8695_probe(struct platform_device *pdev)
1541 1455
1542 /* driver system setup */ 1456 /* driver system setup */
1543 ndev->netdev_ops = &ks8695_netdev_ops; 1457 ndev->netdev_ops = &ks8695_netdev_ops;
1544 SET_ETHTOOL_OPS(ndev, &ks8695_ethtool_ops);
1545 ndev->watchdog_timeo = msecs_to_jiffies(watchdog); 1458 ndev->watchdog_timeo = msecs_to_jiffies(watchdog);
1546 1459
1547 netif_napi_add(ndev, &ksp->napi, ks8695_poll, NAPI_WEIGHT); 1460 netif_napi_add(ndev, &ksp->napi, ks8695_poll, NAPI_WEIGHT);
@@ -1608,12 +1521,15 @@ ks8695_probe(struct platform_device *pdev)
1608 if (ksp->phyiface_regs && ksp->link_irq == -1) { 1521 if (ksp->phyiface_regs && ksp->link_irq == -1) {
1609 ks8695_init_switch(ksp); 1522 ks8695_init_switch(ksp);
1610 ksp->dtype = KS8695_DTYPE_LAN; 1523 ksp->dtype = KS8695_DTYPE_LAN;
1524 SET_ETHTOOL_OPS(ndev, &ks8695_ethtool_ops);
1611 } else if (ksp->phyiface_regs && ksp->link_irq != -1) { 1525 } else if (ksp->phyiface_regs && ksp->link_irq != -1) {
1612 ks8695_init_wan_phy(ksp); 1526 ks8695_init_wan_phy(ksp);
1613 ksp->dtype = KS8695_DTYPE_WAN; 1527 ksp->dtype = KS8695_DTYPE_WAN;
1528 SET_ETHTOOL_OPS(ndev, &ks8695_wan_ethtool_ops);
1614 } else { 1529 } else {
1615 /* No initialisation since HPNA does not have a PHY */ 1530 /* No initialisation since HPNA does not have a PHY */
1616 ksp->dtype = KS8695_DTYPE_HPNA; 1531 ksp->dtype = KS8695_DTYPE_HPNA;
1532 SET_ETHTOOL_OPS(ndev, &ks8695_ethtool_ops);
1617 } 1533 }
1618 1534
1619 /* And bring up the net_device with the net core */ 1535 /* And bring up the net_device with the net core */