diff options
Diffstat (limited to 'drivers/net/ethernet/cavium/liquidio/lio_ethtool.c')
-rw-r--r-- | drivers/net/ethernet/cavium/liquidio/lio_ethtool.c | 110 |
1 files changed, 110 insertions, 0 deletions
diff --git a/drivers/net/ethernet/cavium/liquidio/lio_ethtool.c b/drivers/net/ethernet/cavium/liquidio/lio_ethtool.c index fb29a64b9e51..f163e0abbeb2 100644 --- a/drivers/net/ethernet/cavium/liquidio/lio_ethtool.c +++ b/drivers/net/ethernet/cavium/liquidio/lio_ethtool.c | |||
@@ -190,6 +190,10 @@ static const char oct_droq_stats_strings[][ETH_GSTRING_LEN] = { | |||
190 | "buffer_alloc_failure", | 190 | "buffer_alloc_failure", |
191 | }; | 191 | }; |
192 | 192 | ||
193 | /* LiquidIO driver private flags */ | ||
194 | static const char oct_priv_flags_strings[][ETH_GSTRING_LEN] = { | ||
195 | }; | ||
196 | |||
193 | #define OCTNIC_NCMD_AUTONEG_ON 0x1 | 197 | #define OCTNIC_NCMD_AUTONEG_ON 0x1 |
194 | #define OCTNIC_NCMD_PHY_ON 0x2 | 198 | #define OCTNIC_NCMD_PHY_ON 0x2 |
195 | 199 | ||
@@ -658,6 +662,69 @@ lio_get_pauseparam(struct net_device *netdev, struct ethtool_pauseparam *pause) | |||
658 | pause->rx_pause = oct->rx_pause; | 662 | pause->rx_pause = oct->rx_pause; |
659 | } | 663 | } |
660 | 664 | ||
665 | static int | ||
666 | lio_set_pauseparam(struct net_device *netdev, struct ethtool_pauseparam *pause) | ||
667 | { | ||
668 | /* Notes: Not supporting any auto negotiation in these | ||
669 | * drivers. | ||
670 | */ | ||
671 | struct lio *lio = GET_LIO(netdev); | ||
672 | struct octeon_device *oct = lio->oct_dev; | ||
673 | struct octnic_ctrl_pkt nctrl; | ||
674 | struct oct_link_info *linfo = &lio->linfo; | ||
675 | |||
676 | int ret = 0; | ||
677 | |||
678 | if (oct->chip_id != OCTEON_CN23XX_PF_VID) | ||
679 | return -EINVAL; | ||
680 | |||
681 | if (linfo->link.s.duplex == 0) { | ||
682 | /*no flow control for half duplex*/ | ||
683 | if (pause->rx_pause || pause->tx_pause) | ||
684 | return -EINVAL; | ||
685 | } | ||
686 | |||
687 | /*do not support autoneg of link flow control*/ | ||
688 | if (pause->autoneg == AUTONEG_ENABLE) | ||
689 | return -EINVAL; | ||
690 | |||
691 | memset(&nctrl, 0, sizeof(struct octnic_ctrl_pkt)); | ||
692 | |||
693 | nctrl.ncmd.u64 = 0; | ||
694 | nctrl.ncmd.s.cmd = OCTNET_CMD_SET_FLOW_CTL; | ||
695 | nctrl.iq_no = lio->linfo.txpciq[0].s.q_no; | ||
696 | nctrl.wait_time = 100; | ||
697 | nctrl.netpndev = (u64)netdev; | ||
698 | nctrl.cb_fn = liquidio_link_ctrl_cmd_completion; | ||
699 | |||
700 | if (pause->rx_pause) { | ||
701 | /*enable rx pause*/ | ||
702 | nctrl.ncmd.s.param1 = 1; | ||
703 | } else { | ||
704 | /*disable rx pause*/ | ||
705 | nctrl.ncmd.s.param1 = 0; | ||
706 | } | ||
707 | |||
708 | if (pause->tx_pause) { | ||
709 | /*enable tx pause*/ | ||
710 | nctrl.ncmd.s.param2 = 1; | ||
711 | } else { | ||
712 | /*disable tx pause*/ | ||
713 | nctrl.ncmd.s.param2 = 0; | ||
714 | } | ||
715 | |||
716 | ret = octnet_send_nic_ctrl_pkt(lio->oct_dev, &nctrl); | ||
717 | if (ret < 0) { | ||
718 | dev_err(&oct->pci_dev->dev, "Failed to set pause parameter\n"); | ||
719 | return -EINVAL; | ||
720 | } | ||
721 | |||
722 | oct->rx_pause = pause->rx_pause; | ||
723 | oct->tx_pause = pause->tx_pause; | ||
724 | |||
725 | return 0; | ||
726 | } | ||
727 | |||
661 | static void | 728 | static void |
662 | lio_get_ethtool_stats(struct net_device *netdev, | 729 | lio_get_ethtool_stats(struct net_device *netdev, |
663 | struct ethtool_stats *stats __attribute__((unused)), | 730 | struct ethtool_stats *stats __attribute__((unused)), |
@@ -925,6 +992,27 @@ lio_get_ethtool_stats(struct net_device *netdev, | |||
925 | } | 992 | } |
926 | } | 993 | } |
927 | 994 | ||
995 | static void lio_get_priv_flags_strings(struct lio *lio, u8 *data) | ||
996 | { | ||
997 | struct octeon_device *oct_dev = lio->oct_dev; | ||
998 | int i; | ||
999 | |||
1000 | switch (oct_dev->chip_id) { | ||
1001 | case OCTEON_CN23XX_PF_VID: | ||
1002 | for (i = 0; i < ARRAY_SIZE(oct_priv_flags_strings); i++) { | ||
1003 | sprintf(data, "%s", oct_priv_flags_strings[i]); | ||
1004 | data += ETH_GSTRING_LEN; | ||
1005 | } | ||
1006 | break; | ||
1007 | case OCTEON_CN68XX: | ||
1008 | case OCTEON_CN66XX: | ||
1009 | break; | ||
1010 | default: | ||
1011 | netif_info(lio, drv, lio->netdev, "Unknown Chip !!\n"); | ||
1012 | break; | ||
1013 | } | ||
1014 | } | ||
1015 | |||
928 | static void lio_get_strings(struct net_device *netdev, u32 stringset, u8 *data) | 1016 | static void lio_get_strings(struct net_device *netdev, u32 stringset, u8 *data) |
929 | { | 1017 | { |
930 | struct lio *lio = GET_LIO(netdev); | 1018 | struct lio *lio = GET_LIO(netdev); |
@@ -964,12 +1052,31 @@ static void lio_get_strings(struct net_device *netdev, u32 stringset, u8 *data) | |||
964 | } | 1052 | } |
965 | break; | 1053 | break; |
966 | 1054 | ||
1055 | case ETH_SS_PRIV_FLAGS: | ||
1056 | lio_get_priv_flags_strings(lio, data); | ||
1057 | break; | ||
967 | default: | 1058 | default: |
968 | netif_info(lio, drv, lio->netdev, "Unknown Stringset !!\n"); | 1059 | netif_info(lio, drv, lio->netdev, "Unknown Stringset !!\n"); |
969 | break; | 1060 | break; |
970 | } | 1061 | } |
971 | } | 1062 | } |
972 | 1063 | ||
1064 | static int lio_get_priv_flags_ss_count(struct lio *lio) | ||
1065 | { | ||
1066 | struct octeon_device *oct_dev = lio->oct_dev; | ||
1067 | |||
1068 | switch (oct_dev->chip_id) { | ||
1069 | case OCTEON_CN23XX_PF_VID: | ||
1070 | return ARRAY_SIZE(oct_priv_flags_strings); | ||
1071 | case OCTEON_CN68XX: | ||
1072 | case OCTEON_CN66XX: | ||
1073 | return -EOPNOTSUPP; | ||
1074 | default: | ||
1075 | netif_info(lio, drv, lio->netdev, "Unknown Chip !!\n"); | ||
1076 | return -EOPNOTSUPP; | ||
1077 | } | ||
1078 | } | ||
1079 | |||
973 | static int lio_get_sset_count(struct net_device *netdev, int sset) | 1080 | static int lio_get_sset_count(struct net_device *netdev, int sset) |
974 | { | 1081 | { |
975 | struct lio *lio = GET_LIO(netdev); | 1082 | struct lio *lio = GET_LIO(netdev); |
@@ -980,6 +1087,8 @@ static int lio_get_sset_count(struct net_device *netdev, int sset) | |||
980 | return (ARRAY_SIZE(oct_stats_strings) + | 1087 | return (ARRAY_SIZE(oct_stats_strings) + |
981 | ARRAY_SIZE(oct_iq_stats_strings) * oct_dev->num_iqs + | 1088 | ARRAY_SIZE(oct_iq_stats_strings) * oct_dev->num_iqs + |
982 | ARRAY_SIZE(oct_droq_stats_strings) * oct_dev->num_oqs); | 1089 | ARRAY_SIZE(oct_droq_stats_strings) * oct_dev->num_oqs); |
1090 | case ETH_SS_PRIV_FLAGS: | ||
1091 | return lio_get_priv_flags_ss_count(lio); | ||
983 | default: | 1092 | default: |
984 | return -EOPNOTSUPP; | 1093 | return -EOPNOTSUPP; |
985 | } | 1094 | } |
@@ -2096,6 +2205,7 @@ static const struct ethtool_ops lio_ethtool_ops = { | |||
2096 | .get_strings = lio_get_strings, | 2205 | .get_strings = lio_get_strings, |
2097 | .get_ethtool_stats = lio_get_ethtool_stats, | 2206 | .get_ethtool_stats = lio_get_ethtool_stats, |
2098 | .get_pauseparam = lio_get_pauseparam, | 2207 | .get_pauseparam = lio_get_pauseparam, |
2208 | .set_pauseparam = lio_set_pauseparam, | ||
2099 | .get_regs_len = lio_get_regs_len, | 2209 | .get_regs_len = lio_get_regs_len, |
2100 | .get_regs = lio_get_regs, | 2210 | .get_regs = lio_get_regs, |
2101 | .get_msglevel = lio_get_msglevel, | 2211 | .get_msglevel = lio_get_msglevel, |