diff options
author | Alexander Duyck <alexander.h.duyck@intel.com> | 2014-09-20 19:51:40 -0400 |
---|---|---|
committer | Jeff Kirsher <jeffrey.t.kirsher@intel.com> | 2014-09-23 06:59:20 -0400 |
commit | 5cb8db4a4cbc6dff56959a6331e9d62fd461f719 (patch) | |
tree | 97048030bc0582a4a023e543c13e12cb6e5b4a53 /drivers/net/ethernet/intel/fm10k/fm10k_ethtool.c | |
parent | b651957c202cabc8d5abfc5ad1ddc2607daf6a4f (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.c | 114 |
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 | ||
105 | static 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 | |||
111 | enum fm10k_self_test_types { | ||
112 | FM10K_TEST_MBX, | ||
113 | FM10K_TEST_MAX = FM10K_TEST_LEN | ||
114 | }; | ||
115 | |||
105 | static void fm10k_get_strings(struct net_device *dev, u32 stringset, | 116 | static 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, | |||
138 | static int fm10k_get_sset_count(struct net_device *dev, int sset) | 153 | static 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 | ||
300 | static int fm10k_get_regs_len(struct net_device *netdev) | 341 | static 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 | ||
780 | static 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 | |||
826 | err_out: | ||
827 | *data = err < 0 ? (attr_flag) : (err > 0); | ||
828 | return err; | ||
829 | } | ||
830 | |||
831 | static 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 | |||
737 | static u32 fm10k_get_reta_size(struct net_device *netdev) | 850 | static 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, |