aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/net/ethernet/intel/fm10k/fm10k_ethtool.c
diff options
context:
space:
mode:
authorAlexander Duyck <alexander.h.duyck@intel.com>2014-09-20 19:51:40 -0400
committerJeff Kirsher <jeffrey.t.kirsher@intel.com>2014-09-23 06:59:20 -0400
commit5cb8db4a4cbc6dff56959a6331e9d62fd461f719 (patch)
tree97048030bc0582a4a023e543c13e12cb6e5b4a53 /drivers/net/ethernet/intel/fm10k/fm10k_ethtool.c
parentb651957c202cabc8d5abfc5ad1ddc2607daf6a4f (diff)
fm10k: Add support for VF
This patch provides the functions necessary to configure the VF making use of the same API pointers as the PF. Signed-off-by: Alexander Duyck <alexander.h.duyck@intel.com> Signed-off-by: Jeff Kirsher <jeffrey.t.kirsher@intel.com>
Diffstat (limited to 'drivers/net/ethernet/intel/fm10k/fm10k_ethtool.c')
-rw-r--r--drivers/net/ethernet/intel/fm10k/fm10k_ethtool.c114
1 files changed, 114 insertions, 0 deletions
diff --git a/drivers/net/ethernet/intel/fm10k/fm10k_ethtool.c b/drivers/net/ethernet/intel/fm10k/fm10k_ethtool.c
index 54e8ebd9fbe4..42beb89ae15d 100644
--- a/drivers/net/ethernet/intel/fm10k/fm10k_ethtool.c
+++ b/drivers/net/ethernet/intel/fm10k/fm10k_ethtool.c
@@ -102,6 +102,17 @@ static const struct fm10k_stats fm10k_gstrings_stats[] = {
102 FM10K_NETDEV_STATS_LEN + \ 102 FM10K_NETDEV_STATS_LEN + \
103 FM10K_QUEUE_STATS_LEN) 103 FM10K_QUEUE_STATS_LEN)
104 104
105static const char fm10k_gstrings_test[][ETH_GSTRING_LEN] = {
106 "Mailbox test (on/offline)"
107};
108
109#define FM10K_TEST_LEN (sizeof(fm10k_gstrings_test) / ETH_GSTRING_LEN)
110
111enum fm10k_self_test_types {
112 FM10K_TEST_MBX,
113 FM10K_TEST_MAX = FM10K_TEST_LEN
114};
115
105static void fm10k_get_strings(struct net_device *dev, u32 stringset, 116static void fm10k_get_strings(struct net_device *dev, u32 stringset,
106 u8 *data) 117 u8 *data)
107{ 118{
@@ -109,6 +120,10 @@ static void fm10k_get_strings(struct net_device *dev, u32 stringset,
109 int i; 120 int i;
110 121
111 switch (stringset) { 122 switch (stringset) {
123 case ETH_SS_TEST:
124 memcpy(data, *fm10k_gstrings_test,
125 FM10K_TEST_LEN * ETH_GSTRING_LEN);
126 break;
112 case ETH_SS_STATS: 127 case ETH_SS_STATS:
113 for (i = 0; i < FM10K_NETDEV_STATS_LEN; i++) { 128 for (i = 0; i < FM10K_NETDEV_STATS_LEN; i++) {
114 memcpy(p, fm10k_gstrings_net_stats[i].stat_string, 129 memcpy(p, fm10k_gstrings_net_stats[i].stat_string,
@@ -138,6 +153,8 @@ static void fm10k_get_strings(struct net_device *dev, u32 stringset,
138static int fm10k_get_sset_count(struct net_device *dev, int sset) 153static int fm10k_get_sset_count(struct net_device *dev, int sset)
139{ 154{
140 switch (sset) { 155 switch (sset) {
156 case ETH_SS_TEST:
157 return FM10K_TEST_LEN;
141 case ETH_SS_STATS: 158 case ETH_SS_STATS:
142 return FM10K_STATS_LEN; 159 return FM10K_STATS_LEN;
143 default: 160 default:
@@ -288,6 +305,28 @@ static void fm10k_get_regs(struct net_device *netdev,
288 *(buff++) = fm10k_read_reg(hw, FM10K_ITR(i)); 305 *(buff++) = fm10k_read_reg(hw, FM10K_ITR(i));
289 306
290 break; 307 break;
308 case fm10k_mac_vf:
309 /* General VF registers */
310 *(buff++) = fm10k_read_reg(hw, FM10K_VFCTRL);
311 *(buff++) = fm10k_read_reg(hw, FM10K_VFINT_MAP);
312 *(buff++) = fm10k_read_reg(hw, FM10K_VFSYSTIME);
313
314 /* Interrupt Throttling Registers */
315 for (i = 0; i < 8; i++)
316 *(buff++) = fm10k_read_reg(hw, FM10K_VFITR(i));
317
318 fm10k_get_reg_vsi(hw, buff, 0);
319 buff += FM10K_REGS_LEN_VSI;
320
321 for (i = 0; i < FM10K_MAX_QUEUES_POOL; i++) {
322 if (i < hw->mac.max_queues)
323 fm10k_get_reg_q(hw, buff, i);
324 else
325 memset(buff, 0, sizeof(u32) * FM10K_REGS_LEN_Q);
326 buff += FM10K_REGS_LEN_Q;
327 }
328
329 break;
291 default: 330 default:
292 return; 331 return;
293 } 332 }
@@ -296,6 +335,8 @@ static void fm10k_get_regs(struct net_device *netdev,
296/* If function above adds more registers these define need to be updated */ 335/* If function above adds more registers these define need to be updated */
297#define FM10K_REGS_LEN_PF \ 336#define FM10K_REGS_LEN_PF \
298(162 + (65 * FM10K_REGS_LEN_VSI) + (FM10K_MAX_QUEUES_PF * FM10K_REGS_LEN_Q)) 337(162 + (65 * FM10K_REGS_LEN_VSI) + (FM10K_MAX_QUEUES_PF * FM10K_REGS_LEN_Q))
338#define FM10K_REGS_LEN_VF \
339(11 + FM10K_REGS_LEN_VSI + (FM10K_MAX_QUEUES_POOL * FM10K_REGS_LEN_Q))
299 340
300static int fm10k_get_regs_len(struct net_device *netdev) 341static int fm10k_get_regs_len(struct net_device *netdev)
301{ 342{
@@ -305,6 +346,8 @@ static int fm10k_get_regs_len(struct net_device *netdev)
305 switch (hw->mac.type) { 346 switch (hw->mac.type) {
306 case fm10k_mac_pf: 347 case fm10k_mac_pf:
307 return FM10K_REGS_LEN_PF * sizeof(u32); 348 return FM10K_REGS_LEN_PF * sizeof(u32);
349 case fm10k_mac_vf:
350 return FM10K_REGS_LEN_VF * sizeof(u32);
308 default: 351 default:
309 return 0; 352 return 0;
310 } 353 }
@@ -734,6 +777,76 @@ static int fm10k_set_rxnfc(struct net_device *dev, struct ethtool_rxnfc *cmd)
734 return ret; 777 return ret;
735} 778}
736 779
780static int fm10k_mbx_test(struct fm10k_intfc *interface, u64 *data)
781{
782 struct fm10k_hw *hw = &interface->hw;
783 struct fm10k_mbx_info *mbx = &hw->mbx;
784 u32 attr_flag, test_msg[6];
785 unsigned long timeout;
786 int err;
787
788 /* For now this is a VF only feature */
789 if (hw->mac.type != fm10k_mac_vf)
790 return 0;
791
792 /* loop through both nested and unnested attribute types */
793 for (attr_flag = (1 << FM10K_TEST_MSG_UNSET);
794 attr_flag < (1 << (2 * FM10K_TEST_MSG_NESTED));
795 attr_flag += attr_flag) {
796 /* generate message to be tested */
797 fm10k_tlv_msg_test_create(test_msg, attr_flag);
798
799 fm10k_mbx_lock(interface);
800 mbx->test_result = FM10K_NOT_IMPLEMENTED;
801 err = mbx->ops.enqueue_tx(hw, mbx, test_msg);
802 fm10k_mbx_unlock(interface);
803
804 /* wait up to 1 second for response */
805 timeout = jiffies + HZ;
806 do {
807 if (err < 0)
808 goto err_out;
809
810 usleep_range(500, 1000);
811
812 fm10k_mbx_lock(interface);
813 mbx->ops.process(hw, mbx);
814 fm10k_mbx_unlock(interface);
815
816 err = mbx->test_result;
817 if (!err)
818 break;
819 } while (time_is_after_jiffies(timeout));
820
821 /* reporting errors */
822 if (err)
823 goto err_out;
824 }
825
826err_out:
827 *data = err < 0 ? (attr_flag) : (err > 0);
828 return err;
829}
830
831static void fm10k_self_test(struct net_device *dev,
832 struct ethtool_test *eth_test, u64 *data)
833{
834 struct fm10k_intfc *interface = netdev_priv(dev);
835 struct fm10k_hw *hw = &interface->hw;
836
837 memset(data, 0, sizeof(*data) * FM10K_TEST_LEN);
838
839 if (FM10K_REMOVED(hw)) {
840 netif_err(interface, drv, dev,
841 "Interface removed - test blocked\n");
842 eth_test->flags |= ETH_TEST_FL_FAILED;
843 return;
844 }
845
846 if (fm10k_mbx_test(interface, &data[FM10K_TEST_MBX]))
847 eth_test->flags |= ETH_TEST_FL_FAILED;
848}
849
737static u32 fm10k_get_reta_size(struct net_device *netdev) 850static u32 fm10k_get_reta_size(struct net_device *netdev)
738{ 851{
739 return FM10K_RETA_SIZE * FM10K_RETA_ENTRIES_PER_REG; 852 return FM10K_RETA_SIZE * FM10K_RETA_ENTRIES_PER_REG;
@@ -911,6 +1024,7 @@ static const struct ethtool_ops fm10k_ethtool_ops = {
911 .set_rxnfc = fm10k_set_rxnfc, 1024 .set_rxnfc = fm10k_set_rxnfc,
912 .get_regs = fm10k_get_regs, 1025 .get_regs = fm10k_get_regs,
913 .get_regs_len = fm10k_get_regs_len, 1026 .get_regs_len = fm10k_get_regs_len,
1027 .self_test = fm10k_self_test,
914 .get_rxfh_indir_size = fm10k_get_reta_size, 1028 .get_rxfh_indir_size = fm10k_get_reta_size,
915 .get_rxfh_key_size = fm10k_get_rssrk_size, 1029 .get_rxfh_key_size = fm10k_get_rssrk_size,
916 .get_rxfh = fm10k_get_rssh, 1030 .get_rxfh = fm10k_get_rssh,