aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorRaghu Vatsavayi <rvatsavayi@caviumnetworks.com>2016-09-01 14:16:11 -0400
committerDavid S. Miller <davem@davemloft.net>2016-09-02 20:11:31 -0400
commit30136395a2f63e1aca9a62bfd631feb3eb213428 (patch)
tree74d57d429db3f6502ac0e11211fb30c5ea092f5c
parent9ded1a512f9de8d47074d208b41dead3c267fcee (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.c110
-rw-r--r--drivers/net/ethernet/cavium/liquidio/lio_main.c12
-rw-r--r--drivers/net/ethernet/cavium/liquidio/octeon_device.h11
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 */
194static 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
665static int
666lio_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
661static void 728static void
662lio_get_ethtool_stats(struct net_device *netdev, 729lio_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
995static 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
928static void lio_get_strings(struct net_device *netdev, u32 stringset, u8 *data) 1016static 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
1064static 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
973static int lio_get_sset_count(struct net_device *netdev, int sset) 1080static 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
758static inline void lio_set_priv_flag(struct octeon_device *octdev, u32 flag, 758#define OCT_PRIV_FLAG_DEFAULT 0x0
759 u32 val) 759
760static inline u32 lio_get_priv_flag(struct octeon_device *octdev, u32 flag)
761{
762 return !!(octdev->priv_flags & (0x1 << flag));
763}
764
765static 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);