diff options
author | Raghu Vatsavayi <rvatsavayi@caviumnetworks.com> | 2016-09-01 14:16:11 -0400 |
---|---|---|
committer | David S. Miller <davem@davemloft.net> | 2016-09-02 20:11:31 -0400 |
commit | 30136395a2f63e1aca9a62bfd631feb3eb213428 (patch) | |
tree | 74d57d429db3f6502ac0e11211fb30c5ea092f5c | |
parent | 9ded1a512f9de8d47074d208b41dead3c267fcee (diff) |
liquidio:CN23XX pause frame support
Adds support for pause frame and priv flag for cn23xx
device.
Signed-off-by: Derek Chickles <derek.chickles@caviumnetworks.com>
Signed-off-by: Satanand Burla <satananda.burla@caviumnetworks.com>
Signed-off-by: Felix Manlunas <felix.manlunas@caviumnetworks.com>
Signed-off-by: Raghu Vatsavayi <raghu.vatsavayi@caviumnetworks.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
-rw-r--r-- | drivers/net/ethernet/cavium/liquidio/lio_ethtool.c | 110 | ||||
-rw-r--r-- | drivers/net/ethernet/cavium/liquidio/lio_main.c | 12 | ||||
-rw-r--r-- | drivers/net/ethernet/cavium/liquidio/octeon_device.h | 11 |
3 files changed, 126 insertions, 7 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, |
diff --git a/drivers/net/ethernet/cavium/liquidio/lio_main.c b/drivers/net/ethernet/cavium/liquidio/lio_main.c index a2460e52fca9..afc6f9dc8119 100644 --- a/drivers/net/ethernet/cavium/liquidio/lio_main.c +++ b/drivers/net/ethernet/cavium/liquidio/lio_main.c | |||
@@ -2184,7 +2184,7 @@ static void if_cfg_callback(struct octeon_device *oct, | |||
2184 | struct liquidio_if_cfg_context *ctx; | 2184 | struct liquidio_if_cfg_context *ctx; |
2185 | 2185 | ||
2186 | resp = (struct liquidio_if_cfg_resp *)sc->virtrptr; | 2186 | resp = (struct liquidio_if_cfg_resp *)sc->virtrptr; |
2187 | ctx = (struct liquidio_if_cfg_context *)sc->ctxptr; | 2187 | ctx = (struct liquidio_if_cfg_context *)sc->ctxptr; |
2188 | 2188 | ||
2189 | oct = lio_get_device(ctx->octeon_id); | 2189 | oct = lio_get_device(ctx->octeon_id); |
2190 | if (resp->status) | 2190 | if (resp->status) |
@@ -3934,7 +3934,10 @@ static int setup_nic_devices(struct octeon_device *octeon_dev) | |||
3934 | 3934 | ||
3935 | /* Register ethtool support */ | 3935 | /* Register ethtool support */ |
3936 | liquidio_set_ethtool_ops(netdev); | 3936 | liquidio_set_ethtool_ops(netdev); |
3937 | octeon_dev->priv_flags = 0x0; | 3937 | if (lio->oct_dev->chip_id == OCTEON_CN23XX_PF_VID) |
3938 | octeon_dev->priv_flags = OCT_PRIV_FLAG_DEFAULT; | ||
3939 | else | ||
3940 | octeon_dev->priv_flags = 0x0; | ||
3938 | 3941 | ||
3939 | if (netdev->features & NETIF_F_LRO) | 3942 | if (netdev->features & NETIF_F_LRO) |
3940 | liquidio_set_feature(netdev, OCTNET_CMD_LRO_ENABLE, | 3943 | liquidio_set_feature(netdev, OCTNET_CMD_LRO_ENABLE, |
@@ -4015,8 +4018,7 @@ static int liquidio_init_nic_module(struct octeon_device *oct) | |||
4015 | /* run port_config command for each port */ | 4018 | /* run port_config command for each port */ |
4016 | oct->ifcount = num_nic_ports; | 4019 | oct->ifcount = num_nic_ports; |
4017 | 4020 | ||
4018 | memset(oct->props, 0, | 4021 | memset(oct->props, 0, sizeof(struct octdev_props) * num_nic_ports); |
4019 | sizeof(struct octdev_props) * num_nic_ports); | ||
4020 | 4022 | ||
4021 | for (i = 0; i < MAX_OCTEON_LINKS; i++) | 4023 | for (i = 0; i < MAX_OCTEON_LINKS; i++) |
4022 | oct->props[i].gmxport = -1; | 4024 | oct->props[i].gmxport = -1; |
@@ -4032,7 +4034,7 @@ static int liquidio_init_nic_module(struct octeon_device *oct) | |||
4032 | /* Initialize interrupt moderation params */ | 4034 | /* Initialize interrupt moderation params */ |
4033 | intrmod_cfg = &((struct octeon_device *)oct)->intrmod; | 4035 | intrmod_cfg = &((struct octeon_device *)oct)->intrmod; |
4034 | intrmod_cfg->rx_enable = 1; | 4036 | intrmod_cfg->rx_enable = 1; |
4035 | intrmod_cfg->check_intrvl = LIO_INTRMOD_CHECK_INTERVAL; | 4037 | intrmod_cfg->check_intrvl = LIO_INTRMOD_CHECK_INTERVAL; |
4036 | intrmod_cfg->maxpkt_ratethr = LIO_INTRMOD_MAXPKT_RATETHR; | 4038 | intrmod_cfg->maxpkt_ratethr = LIO_INTRMOD_MAXPKT_RATETHR; |
4037 | intrmod_cfg->minpkt_ratethr = LIO_INTRMOD_MINPKT_RATETHR; | 4039 | intrmod_cfg->minpkt_ratethr = LIO_INTRMOD_MINPKT_RATETHR; |
4038 | intrmod_cfg->rx_maxcnt_trigger = LIO_INTRMOD_RXMAXCNT_TRIGGER; | 4040 | intrmod_cfg->rx_maxcnt_trigger = LIO_INTRMOD_RXMAXCNT_TRIGGER; |
diff --git a/drivers/net/ethernet/cavium/liquidio/octeon_device.h b/drivers/net/ethernet/cavium/liquidio/octeon_device.h index 6062ff332ad2..da15c2ae9330 100644 --- a/drivers/net/ethernet/cavium/liquidio/octeon_device.h +++ b/drivers/net/ethernet/cavium/liquidio/octeon_device.h | |||
@@ -755,8 +755,15 @@ enum { | |||
755 | OCT_PRIV_FLAG_TX_BYTES = 0, /* Tx interrupts by pending byte count */ | 755 | OCT_PRIV_FLAG_TX_BYTES = 0, /* Tx interrupts by pending byte count */ |
756 | }; | 756 | }; |
757 | 757 | ||
758 | static inline void lio_set_priv_flag(struct octeon_device *octdev, u32 flag, | 758 | #define OCT_PRIV_FLAG_DEFAULT 0x0 |
759 | u32 val) | 759 | |
760 | static inline u32 lio_get_priv_flag(struct octeon_device *octdev, u32 flag) | ||
761 | { | ||
762 | return !!(octdev->priv_flags & (0x1 << flag)); | ||
763 | } | ||
764 | |||
765 | static inline void lio_set_priv_flag(struct octeon_device *octdev, | ||
766 | u32 flag, u32 val) | ||
760 | { | 767 | { |
761 | if (val) | 768 | if (val) |
762 | octdev->priv_flags |= (0x1 << flag); | 769 | octdev->priv_flags |= (0x1 << flag); |