aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/net/ethernet/intel/fm10k
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
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')
-rw-r--r--drivers/net/ethernet/intel/fm10k/Makefile2
-rw-r--r--drivers/net/ethernet/intel/fm10k/fm10k.h4
-rw-r--r--drivers/net/ethernet/intel/fm10k/fm10k_ethtool.c114
-rw-r--r--drivers/net/ethernet/intel/fm10k/fm10k_mbx.c4
-rw-r--r--drivers/net/ethernet/intel/fm10k/fm10k_netdev.c15
-rw-r--r--drivers/net/ethernet/intel/fm10k/fm10k_pci.c102
-rw-r--r--drivers/net/ethernet/intel/fm10k/fm10k_type.h9
-rw-r--r--drivers/net/ethernet/intel/fm10k/fm10k_vf.c523
-rw-r--r--drivers/net/ethernet/intel/fm10k/fm10k_vf.h68
9 files changed, 837 insertions, 4 deletions
diff --git a/drivers/net/ethernet/intel/fm10k/Makefile b/drivers/net/ethernet/intel/fm10k/Makefile
index b72815e45604..f70893a880c5 100644
--- a/drivers/net/ethernet/intel/fm10k/Makefile
+++ b/drivers/net/ethernet/intel/fm10k/Makefile
@@ -28,5 +28,5 @@
28obj-$(CONFIG_FM10K) += fm10k.o 28obj-$(CONFIG_FM10K) += fm10k.o
29 29
30fm10k-objs := fm10k_main.o fm10k_common.o fm10k_pci.o \ 30fm10k-objs := fm10k_main.o fm10k_common.o fm10k_pci.o \
31 fm10k_netdev.o fm10k_ethtool.o fm10k_pf.o \ 31 fm10k_netdev.o fm10k_ethtool.o fm10k_pf.o fm10k_vf.o \
32 fm10k_mbx.o fm10k_tlv.o 32 fm10k_mbx.o fm10k_tlv.o
diff --git a/drivers/net/ethernet/intel/fm10k/fm10k.h b/drivers/net/ethernet/intel/fm10k/fm10k.h
index 58c1475ade7c..639698c7c108 100644
--- a/drivers/net/ethernet/intel/fm10k/fm10k.h
+++ b/drivers/net/ethernet/intel/fm10k/fm10k.h
@@ -28,6 +28,7 @@
28#include <linux/pci.h> 28#include <linux/pci.h>
29 29
30#include "fm10k_pf.h" 30#include "fm10k_pf.h"
31#include "fm10k_vf.h"
31 32
32#define FM10K_MAX_JUMBO_FRAME_SIZE 15358 /* Maximum supported size 15K */ 33#define FM10K_MAX_JUMBO_FRAME_SIZE 15358 /* Maximum supported size 15K */
33 34
@@ -180,12 +181,13 @@ static inline struct netdev_queue *txring_txq(const struct fm10k_ring *ring)
180#define MIN_Q_VECTORS 1 181#define MIN_Q_VECTORS 1
181enum fm10k_non_q_vectors { 182enum fm10k_non_q_vectors {
182 FM10K_MBX_VECTOR, 183 FM10K_MBX_VECTOR,
184#define NON_Q_VECTORS_VF NON_Q_VECTORS_PF
183 NON_Q_VECTORS_PF 185 NON_Q_VECTORS_PF
184}; 186};
185 187
186#define NON_Q_VECTORS(hw) (((hw)->mac.type == fm10k_mac_pf) ? \ 188#define NON_Q_VECTORS(hw) (((hw)->mac.type == fm10k_mac_pf) ? \
187 NON_Q_VECTORS_PF : \ 189 NON_Q_VECTORS_PF : \
188 0) 190 NON_Q_VECTORS_VF)
189#define MIN_MSIX_COUNT(hw) (MIN_Q_VECTORS + NON_Q_VECTORS(hw)) 191#define MIN_MSIX_COUNT(hw) (MIN_Q_VECTORS + NON_Q_VECTORS(hw))
190 192
191struct fm10k_q_vector { 193struct fm10k_q_vector {
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,
diff --git a/drivers/net/ethernet/intel/fm10k/fm10k_mbx.c b/drivers/net/ethernet/intel/fm10k/fm10k_mbx.c
index a6a66fd9e2c2..14a4ea795c01 100644
--- a/drivers/net/ethernet/intel/fm10k/fm10k_mbx.c
+++ b/drivers/net/ethernet/intel/fm10k/fm10k_mbx.c
@@ -1517,6 +1517,10 @@ s32 fm10k_pfvf_mbx_init(struct fm10k_hw *hw, struct fm10k_mbx_info *mbx,
1517{ 1517{
1518 /* initialize registers */ 1518 /* initialize registers */
1519 switch (hw->mac.type) { 1519 switch (hw->mac.type) {
1520 case fm10k_mac_vf:
1521 mbx->mbx_reg = FM10K_VFMBX;
1522 mbx->mbmem_reg = FM10K_VFMBMEM(FM10K_VFMBMEM_VF_XOR);
1523 break;
1520 case fm10k_mac_pf: 1524 case fm10k_mac_pf:
1521 /* there are only 64 VF <-> PF mailboxes */ 1525 /* there are only 64 VF <-> PF mailboxes */
1522 if (id < 64) { 1526 if (id < 64) {
diff --git a/drivers/net/ethernet/intel/fm10k/fm10k_netdev.c b/drivers/net/ethernet/intel/fm10k/fm10k_netdev.c
index 268966bfe019..c0d6758ea16e 100644
--- a/drivers/net/ethernet/intel/fm10k/fm10k_netdev.c
+++ b/drivers/net/ethernet/intel/fm10k/fm10k_netdev.c
@@ -976,6 +976,21 @@ void fm10k_restore_rx_state(struct fm10k_intfc *interface)
976 int xcast_mode; 976 int xcast_mode;
977 u16 vid, glort; 977 u16 vid, glort;
978 978
979 /* restore our address if perm_addr is set */
980 if (hw->mac.type == fm10k_mac_vf) {
981 if (is_valid_ether_addr(hw->mac.perm_addr)) {
982 ether_addr_copy(hw->mac.addr, hw->mac.perm_addr);
983 ether_addr_copy(netdev->perm_addr, hw->mac.perm_addr);
984 ether_addr_copy(netdev->dev_addr, hw->mac.perm_addr);
985 netdev->addr_assign_type &= ~NET_ADDR_RANDOM;
986 }
987
988 if (hw->mac.vlan_override)
989 netdev->features &= ~NETIF_F_HW_VLAN_CTAG_RX;
990 else
991 netdev->features |= NETIF_F_HW_VLAN_CTAG_RX;
992 }
993
979 /* record glort for this interface */ 994 /* record glort for this interface */
980 glort = interface->glort; 995 glort = interface->glort;
981 996
diff --git a/drivers/net/ethernet/intel/fm10k/fm10k_pci.c b/drivers/net/ethernet/intel/fm10k/fm10k_pci.c
index d647814550f1..9cc4d627eb75 100644
--- a/drivers/net/ethernet/intel/fm10k/fm10k_pci.c
+++ b/drivers/net/ethernet/intel/fm10k/fm10k_pci.c
@@ -25,6 +25,7 @@
25 25
26static const struct fm10k_info *fm10k_info_tbl[] = { 26static const struct fm10k_info *fm10k_info_tbl[] = {
27 [fm10k_device_pf] = &fm10k_pf_info, 27 [fm10k_device_pf] = &fm10k_pf_info,
28 [fm10k_device_vf] = &fm10k_vf_info,
28}; 29};
29 30
30/** 31/**
@@ -38,6 +39,7 @@ static const struct fm10k_info *fm10k_info_tbl[] = {
38 */ 39 */
39static const struct pci_device_id fm10k_pci_tbl[] = { 40static const struct pci_device_id fm10k_pci_tbl[] = {
40 { PCI_VDEVICE(INTEL, FM10K_DEV_ID_PF), fm10k_device_pf }, 41 { PCI_VDEVICE(INTEL, FM10K_DEV_ID_PF), fm10k_device_pf },
42 { PCI_VDEVICE(INTEL, FM10K_DEV_ID_VF), fm10k_device_vf },
41 /* required last entry */ 43 /* required last entry */
42 { 0, } 44 { 0, }
43}; 45};
@@ -805,6 +807,28 @@ static irqreturn_t fm10k_msix_clean_rings(int irq, void *data)
805 return IRQ_HANDLED; 807 return IRQ_HANDLED;
806} 808}
807 809
810static irqreturn_t fm10k_msix_mbx_vf(int irq, void *data)
811{
812 struct fm10k_intfc *interface = data;
813 struct fm10k_hw *hw = &interface->hw;
814 struct fm10k_mbx_info *mbx = &hw->mbx;
815
816 /* re-enable mailbox interrupt and indicate 20us delay */
817 fm10k_write_reg(hw, FM10K_VFITR(FM10K_MBX_VECTOR),
818 FM10K_ITR_ENABLE | FM10K_MBX_INT_DELAY);
819
820 /* service upstream mailbox */
821 if (fm10k_mbx_trylock(interface)) {
822 mbx->ops.process(hw, mbx);
823 fm10k_mbx_unlock(interface);
824 }
825
826 hw->mac.get_host_state = 1;
827 fm10k_service_event_schedule(interface);
828
829 return IRQ_HANDLED;
830}
831
808#define FM10K_ERR_MSG(type) case (type): error = #type; break 832#define FM10K_ERR_MSG(type) case (type): error = #type; break
809static void fm10k_print_fault(struct fm10k_intfc *interface, int type, 833static void fm10k_print_fault(struct fm10k_intfc *interface, int type,
810 struct fm10k_fault *fault) 834 struct fm10k_fault *fault)
@@ -996,6 +1020,8 @@ void fm10k_mbx_free_irq(struct fm10k_intfc *interface)
996 FM10K_EIMR_DISABLE(VFLR) | 1020 FM10K_EIMR_DISABLE(VFLR) |
997 FM10K_EIMR_DISABLE(MAXHOLDTIME)); 1021 FM10K_EIMR_DISABLE(MAXHOLDTIME));
998 itr_reg = FM10K_ITR(FM10K_MBX_VECTOR); 1022 itr_reg = FM10K_ITR(FM10K_MBX_VECTOR);
1023 } else {
1024 itr_reg = FM10K_VFITR(FM10K_MBX_VECTOR);
999 } 1025 }
1000 1026
1001 fm10k_write_reg(hw, itr_reg, FM10K_ITR_MASK_SET); 1027 fm10k_write_reg(hw, itr_reg, FM10K_ITR_MASK_SET);
@@ -1003,6 +1029,33 @@ void fm10k_mbx_free_irq(struct fm10k_intfc *interface)
1003 free_irq(entry->vector, interface); 1029 free_irq(entry->vector, interface);
1004} 1030}
1005 1031
1032static s32 fm10k_mbx_mac_addr(struct fm10k_hw *hw, u32 **results,
1033 struct fm10k_mbx_info *mbx)
1034{
1035 bool vlan_override = hw->mac.vlan_override;
1036 u16 default_vid = hw->mac.default_vid;
1037 struct fm10k_intfc *interface;
1038 s32 err;
1039
1040 err = fm10k_msg_mac_vlan_vf(hw, results, mbx);
1041 if (err)
1042 return err;
1043
1044 interface = container_of(hw, struct fm10k_intfc, hw);
1045
1046 /* MAC was changed so we need reset */
1047 if (is_valid_ether_addr(hw->mac.perm_addr) &&
1048 memcmp(hw->mac.perm_addr, hw->mac.addr, ETH_ALEN))
1049 interface->flags |= FM10K_FLAG_RESET_REQUESTED;
1050
1051 /* VLAN override was changed, or default VLAN changed */
1052 if ((vlan_override != hw->mac.vlan_override) ||
1053 (default_vid != hw->mac.default_vid))
1054 interface->flags |= FM10K_FLAG_RESET_REQUESTED;
1055
1056 return 0;
1057}
1058
1006/* generic error handler for mailbox issues */ 1059/* generic error handler for mailbox issues */
1007static s32 fm10k_mbx_error(struct fm10k_hw *hw, u32 **results, 1060static s32 fm10k_mbx_error(struct fm10k_hw *hw, u32 **results,
1008 struct fm10k_mbx_info *mbx) 1061 struct fm10k_mbx_info *mbx)
@@ -1019,6 +1072,46 @@ static s32 fm10k_mbx_error(struct fm10k_hw *hw, u32 **results,
1019 return 0; 1072 return 0;
1020} 1073}
1021 1074
1075static const struct fm10k_msg_data vf_mbx_data[] = {
1076 FM10K_TLV_MSG_TEST_HANDLER(fm10k_tlv_msg_test),
1077 FM10K_VF_MSG_MAC_VLAN_HANDLER(fm10k_mbx_mac_addr),
1078 FM10K_VF_MSG_LPORT_STATE_HANDLER(fm10k_msg_lport_state_vf),
1079 FM10K_TLV_MSG_ERROR_HANDLER(fm10k_mbx_error),
1080};
1081
1082static int fm10k_mbx_request_irq_vf(struct fm10k_intfc *interface)
1083{
1084 struct msix_entry *entry = &interface->msix_entries[FM10K_MBX_VECTOR];
1085 struct net_device *dev = interface->netdev;
1086 struct fm10k_hw *hw = &interface->hw;
1087 int err;
1088
1089 /* Use timer0 for interrupt moderation on the mailbox */
1090 u32 itr = FM10K_INT_MAP_TIMER0 | entry->entry;
1091
1092 /* register mailbox handlers */
1093 err = hw->mbx.ops.register_handlers(&hw->mbx, vf_mbx_data);
1094 if (err)
1095 return err;
1096
1097 /* request the IRQ */
1098 err = request_irq(entry->vector, fm10k_msix_mbx_vf, 0,
1099 dev->name, interface);
1100 if (err) {
1101 netif_err(interface, probe, dev,
1102 "request_irq for msix_mbx failed: %d\n", err);
1103 return err;
1104 }
1105
1106 /* map all of the interrupt sources */
1107 fm10k_write_reg(hw, FM10K_VFINT_MAP, itr);
1108
1109 /* enable interrupt */
1110 fm10k_write_reg(hw, FM10K_VFITR(entry->entry), FM10K_ITR_ENABLE);
1111
1112 return 0;
1113}
1114
1022static s32 fm10k_lport_map(struct fm10k_hw *hw, u32 **results, 1115static s32 fm10k_lport_map(struct fm10k_hw *hw, u32 **results,
1023 struct fm10k_mbx_info *mbx) 1116 struct fm10k_mbx_info *mbx)
1024{ 1117{
@@ -1142,7 +1235,10 @@ int fm10k_mbx_request_irq(struct fm10k_intfc *interface)
1142 int err; 1235 int err;
1143 1236
1144 /* enable Mailbox cause */ 1237 /* enable Mailbox cause */
1145 err = fm10k_mbx_request_irq_pf(interface); 1238 if (hw->mac.type == fm10k_mac_pf)
1239 err = fm10k_mbx_request_irq_pf(interface);
1240 else
1241 err = fm10k_mbx_request_irq_vf(interface);
1146 1242
1147 /* connect mailbox */ 1243 /* connect mailbox */
1148 if (!err) 1244 if (!err)
@@ -1220,7 +1316,9 @@ int fm10k_qv_request_irq(struct fm10k_intfc *interface)
1220 } 1316 }
1221 1317
1222 /* Assign ITR register to q_vector */ 1318 /* Assign ITR register to q_vector */
1223 q_vector->itr = &interface->uc_addr[FM10K_ITR(entry->entry)]; 1319 q_vector->itr = (hw->mac.type == fm10k_mac_pf) ?
1320 &interface->uc_addr[FM10K_ITR(entry->entry)] :
1321 &interface->uc_addr[FM10K_VFITR(entry->entry)];
1224 1322
1225 /* request the IRQ */ 1323 /* request the IRQ */
1226 err = request_irq(entry->vector, &fm10k_msix_clean_rings, 0, 1324 err = request_irq(entry->vector, &fm10k_msix_clean_rings, 0,
diff --git a/drivers/net/ethernet/intel/fm10k/fm10k_type.h b/drivers/net/ethernet/intel/fm10k/fm10k_type.h
index eda0c7cfd861..cc1df60d8552 100644
--- a/drivers/net/ethernet/intel/fm10k/fm10k_type.h
+++ b/drivers/net/ethernet/intel/fm10k/fm10k_type.h
@@ -351,6 +351,13 @@ struct fm10k_hw;
351#define FM10K_QUEUE_DISABLE_TIMEOUT 100 351#define FM10K_QUEUE_DISABLE_TIMEOUT 100
352#define FM10K_RESET_TIMEOUT 100 352#define FM10K_RESET_TIMEOUT 100
353 353
354/* VF registers */
355#define FM10K_VFCTRL 0x00000
356#define FM10K_VFCTRL_RST 0x00000008
357#define FM10K_VFINT_MAP 0x00030
358#define FM10K_VFSYSTIME 0x00040
359#define FM10K_VFITR(_n) ((_n) + 0x00060)
360
354enum fm10k_int_source { 361enum fm10k_int_source {
355 fm10k_int_Mailbox = 0, 362 fm10k_int_Mailbox = 0,
356 fm10k_int_PCIeFault = 1, 363 fm10k_int_PCIeFault = 1,
@@ -522,6 +529,7 @@ struct fm10k_mac_ops {
522enum fm10k_mac_type { 529enum fm10k_mac_type {
523 fm10k_mac_unknown = 0, 530 fm10k_mac_unknown = 0,
524 fm10k_mac_pf, 531 fm10k_mac_pf,
532 fm10k_mac_vf,
525 fm10k_num_macs 533 fm10k_num_macs
526}; 534};
527 535
@@ -561,6 +569,7 @@ enum fm10k_xcast_modes {
561 569
562enum fm10k_devices { 570enum fm10k_devices {
563 fm10k_device_pf, 571 fm10k_device_pf,
572 fm10k_device_vf,
564}; 573};
565 574
566struct fm10k_info { 575struct fm10k_info {
diff --git a/drivers/net/ethernet/intel/fm10k/fm10k_vf.c b/drivers/net/ethernet/intel/fm10k/fm10k_vf.c
new file mode 100644
index 000000000000..25c23fce60f8
--- /dev/null
+++ b/drivers/net/ethernet/intel/fm10k/fm10k_vf.c
@@ -0,0 +1,523 @@
1/* Intel Ethernet Switch Host Interface Driver
2 * Copyright(c) 2013 - 2014 Intel Corporation.
3 *
4 * This program is free software; you can redistribute it and/or modify it
5 * under the terms and conditions of the GNU General Public License,
6 * version 2, as published by the Free Software Foundation.
7 *
8 * This program is distributed in the hope it will be useful, but WITHOUT
9 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
10 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
11 * more details.
12 *
13 * The full GNU General Public License is included in this distribution in
14 * the file called "COPYING".
15 *
16 * Contact Information:
17 * e1000-devel Mailing List <e1000-devel@lists.sourceforge.net>
18 * Intel Corporation, 5200 N.E. Elam Young Parkway, Hillsboro, OR 97124-6497
19 */
20
21#include "fm10k_vf.h"
22
23/**
24 * fm10k_stop_hw_vf - Stop Tx/Rx units
25 * @hw: pointer to hardware structure
26 *
27 **/
28static s32 fm10k_stop_hw_vf(struct fm10k_hw *hw)
29{
30 u8 *perm_addr = hw->mac.perm_addr;
31 u32 bal = 0, bah = 0;
32 s32 err;
33 u16 i;
34
35 /* we need to disable the queues before taking further steps */
36 err = fm10k_stop_hw_generic(hw);
37 if (err)
38 return err;
39
40 /* If permenant address is set then we need to restore it */
41 if (is_valid_ether_addr(perm_addr)) {
42 bal = (((u32)perm_addr[3]) << 24) |
43 (((u32)perm_addr[4]) << 16) |
44 (((u32)perm_addr[5]) << 8);
45 bah = (((u32)0xFF) << 24) |
46 (((u32)perm_addr[0]) << 16) |
47 (((u32)perm_addr[1]) << 8) |
48 ((u32)perm_addr[2]);
49 }
50
51 /* The queues have already been disabled so we just need to
52 * update their base address registers
53 */
54 for (i = 0; i < hw->mac.max_queues; i++) {
55 fm10k_write_reg(hw, FM10K_TDBAL(i), bal);
56 fm10k_write_reg(hw, FM10K_TDBAH(i), bah);
57 fm10k_write_reg(hw, FM10K_RDBAL(i), bal);
58 fm10k_write_reg(hw, FM10K_RDBAH(i), bah);
59 }
60
61 return 0;
62}
63
64/**
65 * fm10k_reset_hw_vf - VF hardware reset
66 * @hw: pointer to hardware structure
67 *
68 * This function should return the hardare to a state similar to the
69 * one it is in after just being initialized.
70 **/
71static s32 fm10k_reset_hw_vf(struct fm10k_hw *hw)
72{
73 s32 err;
74
75 /* shut down queues we own and reset DMA configuration */
76 err = fm10k_stop_hw_vf(hw);
77 if (err)
78 return err;
79
80 /* Inititate VF reset */
81 fm10k_write_reg(hw, FM10K_VFCTRL, FM10K_VFCTRL_RST);
82
83 /* Flush write and allow 100us for reset to complete */
84 fm10k_write_flush(hw);
85 udelay(FM10K_RESET_TIMEOUT);
86
87 /* Clear reset bit and verify it was cleared */
88 fm10k_write_reg(hw, FM10K_VFCTRL, 0);
89 if (fm10k_read_reg(hw, FM10K_VFCTRL) & FM10K_VFCTRL_RST)
90 err = FM10K_ERR_RESET_FAILED;
91
92 return err;
93}
94
95/**
96 * fm10k_init_hw_vf - VF hardware initialization
97 * @hw: pointer to hardware structure
98 *
99 **/
100static s32 fm10k_init_hw_vf(struct fm10k_hw *hw)
101{
102 u32 tqdloc, tqdloc0 = ~fm10k_read_reg(hw, FM10K_TQDLOC(0));
103 s32 err;
104 u16 i;
105
106 /* assume we always have at least 1 queue */
107 for (i = 1; tqdloc0 && (i < FM10K_MAX_QUEUES_POOL); i++) {
108 /* verify the Descriptor cache offsets are increasing */
109 tqdloc = ~fm10k_read_reg(hw, FM10K_TQDLOC(i));
110 if (!tqdloc || (tqdloc == tqdloc0))
111 break;
112
113 /* check to verify the PF doesn't own any of our queues */
114 if (!~fm10k_read_reg(hw, FM10K_TXQCTL(i)) ||
115 !~fm10k_read_reg(hw, FM10K_RXQCTL(i)))
116 break;
117 }
118
119 /* shut down queues we own and reset DMA configuration */
120 err = fm10k_disable_queues_generic(hw, i);
121 if (err)
122 return err;
123
124 /* record maximum queue count */
125 hw->mac.max_queues = i;
126
127 return 0;
128}
129
130/**
131 * fm10k_is_slot_appropriate_vf - Indicate appropriate slot for this SKU
132 * @hw: pointer to hardware structure
133 *
134 * Looks at the PCIe bus info to confirm whether or not this slot can support
135 * the necessary bandwidth for this device. Since the VF has no control over
136 * the "slot" it is in, always indicate that the slot is appropriate.
137 **/
138static bool fm10k_is_slot_appropriate_vf(struct fm10k_hw *hw)
139{
140 return true;
141}
142
143/* This structure defines the attibutes to be parsed below */
144const struct fm10k_tlv_attr fm10k_mac_vlan_msg_attr[] = {
145 FM10K_TLV_ATTR_U32(FM10K_MAC_VLAN_MSG_VLAN),
146 FM10K_TLV_ATTR_BOOL(FM10K_MAC_VLAN_MSG_SET),
147 FM10K_TLV_ATTR_MAC_ADDR(FM10K_MAC_VLAN_MSG_MAC),
148 FM10K_TLV_ATTR_MAC_ADDR(FM10K_MAC_VLAN_MSG_DEFAULT_MAC),
149 FM10K_TLV_ATTR_MAC_ADDR(FM10K_MAC_VLAN_MSG_MULTICAST),
150 FM10K_TLV_ATTR_LAST
151};
152
153/**
154 * fm10k_update_vlan_vf - Update status of VLAN ID in VLAN filter table
155 * @hw: pointer to hardware structure
156 * @vid: VLAN ID to add to table
157 * @vsi: Reserved, should always be 0
158 * @set: Indicates if this is a set or clear operation
159 *
160 * This function adds or removes the corresponding VLAN ID from the VLAN
161 * filter table for this VF.
162 **/
163static s32 fm10k_update_vlan_vf(struct fm10k_hw *hw, u32 vid, u8 vsi, bool set)
164{
165 struct fm10k_mbx_info *mbx = &hw->mbx;
166 u32 msg[4];
167
168 /* verify the index is not set */
169 if (vsi)
170 return FM10K_ERR_PARAM;
171
172 /* verify upper 4 bits of vid and length are 0 */
173 if ((vid << 16 | vid) >> 28)
174 return FM10K_ERR_PARAM;
175
176 /* encode set bit into the VLAN ID */
177 if (!set)
178 vid |= FM10K_VLAN_CLEAR;
179
180 /* generate VLAN request */
181 fm10k_tlv_msg_init(msg, FM10K_VF_MSG_ID_MAC_VLAN);
182 fm10k_tlv_attr_put_u32(msg, FM10K_MAC_VLAN_MSG_VLAN, vid);
183
184 /* load onto outgoing mailbox */
185 return mbx->ops.enqueue_tx(hw, mbx, msg);
186}
187
188/**
189 * fm10k_msg_mac_vlan_vf - Read device MAC address from mailbox message
190 * @hw: pointer to the HW structure
191 * @results: Attributes for message
192 * @mbx: unused mailbox data
193 *
194 * This function should determine the MAC address for the VF
195 **/
196s32 fm10k_msg_mac_vlan_vf(struct fm10k_hw *hw, u32 **results,
197 struct fm10k_mbx_info *mbx)
198{
199 u8 perm_addr[ETH_ALEN];
200 u16 vid;
201 s32 err;
202
203 /* record MAC address requested */
204 err = fm10k_tlv_attr_get_mac_vlan(
205 results[FM10K_MAC_VLAN_MSG_DEFAULT_MAC],
206 perm_addr, &vid);
207 if (err)
208 return err;
209
210 ether_addr_copy(hw->mac.perm_addr, perm_addr);
211 hw->mac.default_vid = vid & (FM10K_VLAN_TABLE_VID_MAX - 1);
212 hw->mac.vlan_override = !!(vid & FM10K_VLAN_CLEAR);
213
214 return 0;
215}
216
217/**
218 * fm10k_read_mac_addr_vf - Read device MAC address
219 * @hw: pointer to the HW structure
220 *
221 * This function should determine the MAC address for the VF
222 **/
223static s32 fm10k_read_mac_addr_vf(struct fm10k_hw *hw)
224{
225 u8 perm_addr[ETH_ALEN];
226 u32 base_addr;
227
228 base_addr = fm10k_read_reg(hw, FM10K_TDBAL(0));
229
230 /* last byte should be 0 */
231 if (base_addr << 24)
232 return FM10K_ERR_INVALID_MAC_ADDR;
233
234 perm_addr[3] = (u8)(base_addr >> 24);
235 perm_addr[4] = (u8)(base_addr >> 16);
236 perm_addr[5] = (u8)(base_addr >> 8);
237
238 base_addr = fm10k_read_reg(hw, FM10K_TDBAH(0));
239
240 /* first byte should be all 1's */
241 if ((~base_addr) >> 24)
242 return FM10K_ERR_INVALID_MAC_ADDR;
243
244 perm_addr[0] = (u8)(base_addr >> 16);
245 perm_addr[1] = (u8)(base_addr >> 8);
246 perm_addr[2] = (u8)(base_addr);
247
248 ether_addr_copy(hw->mac.perm_addr, perm_addr);
249 ether_addr_copy(hw->mac.addr, perm_addr);
250
251 return 0;
252}
253
254/**
255 * fm10k_update_uc_addr_vf - Update device unicast address
256 * @hw: pointer to the HW structure
257 * @glort: unused
258 * @mac: MAC address to add/remove from table
259 * @vid: VLAN ID to add/remove from table
260 * @add: Indicates if this is an add or remove operation
261 * @flags: flags field to indicate add and secure - unused
262 *
263 * This function is used to add or remove unicast MAC addresses for
264 * the VF.
265 **/
266static s32 fm10k_update_uc_addr_vf(struct fm10k_hw *hw, u16 glort,
267 const u8 *mac, u16 vid, bool add, u8 flags)
268{
269 struct fm10k_mbx_info *mbx = &hw->mbx;
270 u32 msg[7];
271
272 /* verify VLAN ID is valid */
273 if (vid >= FM10K_VLAN_TABLE_VID_MAX)
274 return FM10K_ERR_PARAM;
275
276 /* verify MAC address is valid */
277 if (!is_valid_ether_addr(mac))
278 return FM10K_ERR_PARAM;
279
280 /* verify we are not locked down on the MAC address */
281 if (is_valid_ether_addr(hw->mac.perm_addr) &&
282 memcmp(hw->mac.perm_addr, mac, ETH_ALEN))
283 return FM10K_ERR_PARAM;
284
285 /* add bit to notify us if this is a set of clear operation */
286 if (!add)
287 vid |= FM10K_VLAN_CLEAR;
288
289 /* generate VLAN request */
290 fm10k_tlv_msg_init(msg, FM10K_VF_MSG_ID_MAC_VLAN);
291 fm10k_tlv_attr_put_mac_vlan(msg, FM10K_MAC_VLAN_MSG_MAC, mac, vid);
292
293 /* load onto outgoing mailbox */
294 return mbx->ops.enqueue_tx(hw, mbx, msg);
295}
296
297/**
298 * fm10k_update_mc_addr_vf - Update device multicast address
299 * @hw: pointer to the HW structure
300 * @glort: unused
301 * @mac: MAC address to add/remove from table
302 * @vid: VLAN ID to add/remove from table
303 * @add: Indicates if this is an add or remove operation
304 *
305 * This function is used to add or remove multicast MAC addresses for
306 * the VF.
307 **/
308static s32 fm10k_update_mc_addr_vf(struct fm10k_hw *hw, u16 glort,
309 const u8 *mac, u16 vid, bool add)
310{
311 struct fm10k_mbx_info *mbx = &hw->mbx;
312 u32 msg[7];
313
314 /* verify VLAN ID is valid */
315 if (vid >= FM10K_VLAN_TABLE_VID_MAX)
316 return FM10K_ERR_PARAM;
317
318 /* verify multicast address is valid */
319 if (!is_multicast_ether_addr(mac))
320 return FM10K_ERR_PARAM;
321
322 /* add bit to notify us if this is a set of clear operation */
323 if (!add)
324 vid |= FM10K_VLAN_CLEAR;
325
326 /* generate VLAN request */
327 fm10k_tlv_msg_init(msg, FM10K_VF_MSG_ID_MAC_VLAN);
328 fm10k_tlv_attr_put_mac_vlan(msg, FM10K_MAC_VLAN_MSG_MULTICAST,
329 mac, vid);
330
331 /* load onto outgoing mailbox */
332 return mbx->ops.enqueue_tx(hw, mbx, msg);
333}
334
335/**
336 * fm10k_update_int_moderator_vf - Request update of interrupt moderator list
337 * @hw: pointer to hardware structure
338 *
339 * This function will issue a request to the PF to rescan our MSI-X table
340 * and to update the interrupt moderator linked list.
341 **/
342static void fm10k_update_int_moderator_vf(struct fm10k_hw *hw)
343{
344 struct fm10k_mbx_info *mbx = &hw->mbx;
345 u32 msg[1];
346
347 /* generate MSI-X request */
348 fm10k_tlv_msg_init(msg, FM10K_VF_MSG_ID_MSIX);
349
350 /* load onto outgoing mailbox */
351 mbx->ops.enqueue_tx(hw, mbx, msg);
352}
353
354/* This structure defines the attibutes to be parsed below */
355const struct fm10k_tlv_attr fm10k_lport_state_msg_attr[] = {
356 FM10K_TLV_ATTR_BOOL(FM10K_LPORT_STATE_MSG_DISABLE),
357 FM10K_TLV_ATTR_U8(FM10K_LPORT_STATE_MSG_XCAST_MODE),
358 FM10K_TLV_ATTR_BOOL(FM10K_LPORT_STATE_MSG_READY),
359 FM10K_TLV_ATTR_LAST
360};
361
362/**
363 * fm10k_msg_lport_state_vf - Message handler for lport_state message from PF
364 * @hw: Pointer to hardware structure
365 * @results: pointer array containing parsed data
366 * @mbx: Pointer to mailbox information structure
367 *
368 * This handler is meant to capture the indication from the PF that we
369 * are ready to bring up the interface.
370 **/
371s32 fm10k_msg_lport_state_vf(struct fm10k_hw *hw, u32 **results,
372 struct fm10k_mbx_info *mbx)
373{
374 hw->mac.dglort_map = !results[FM10K_LPORT_STATE_MSG_READY] ?
375 FM10K_DGLORTMAP_NONE : FM10K_DGLORTMAP_ZERO;
376
377 return 0;
378}
379
380/**
381 * fm10k_update_lport_state_vf - Update device state in lower device
382 * @hw: pointer to the HW structure
383 * @glort: unused
384 * @count: number of logical ports to enable - unused (always 1)
385 * @enable: boolean value indicating if this is an enable or disable request
386 *
387 * Notify the lower device of a state change. If the lower device is
388 * enabled we can add filters, if it is disabled all filters for this
389 * logical port are flushed.
390 **/
391static s32 fm10k_update_lport_state_vf(struct fm10k_hw *hw, u16 glort,
392 u16 count, bool enable)
393{
394 struct fm10k_mbx_info *mbx = &hw->mbx;
395 u32 msg[2];
396
397 /* reset glort mask 0 as we have to wait to be enabled */
398 hw->mac.dglort_map = FM10K_DGLORTMAP_NONE;
399
400 /* generate port state request */
401 fm10k_tlv_msg_init(msg, FM10K_VF_MSG_ID_LPORT_STATE);
402 if (!enable)
403 fm10k_tlv_attr_put_bool(msg, FM10K_LPORT_STATE_MSG_DISABLE);
404
405 /* load onto outgoing mailbox */
406 return mbx->ops.enqueue_tx(hw, mbx, msg);
407}
408
409/**
410 * fm10k_update_xcast_mode_vf - Request update of multicast mode
411 * @hw: pointer to hardware structure
412 * @glort: unused
413 * @mode: integer value indicating mode being requested
414 *
415 * This function will attempt to request a higher mode for the port
416 * so that it can enable either multicast, multicast promiscuous, or
417 * promiscuous mode of operation.
418 **/
419static s32 fm10k_update_xcast_mode_vf(struct fm10k_hw *hw, u16 glort, u8 mode)
420{
421 struct fm10k_mbx_info *mbx = &hw->mbx;
422 u32 msg[3];
423
424 if (mode > FM10K_XCAST_MODE_NONE)
425 return FM10K_ERR_PARAM;
426 /* generate message requesting to change xcast mode */
427 fm10k_tlv_msg_init(msg, FM10K_VF_MSG_ID_LPORT_STATE);
428 fm10k_tlv_attr_put_u8(msg, FM10K_LPORT_STATE_MSG_XCAST_MODE, mode);
429
430 /* load onto outgoing mailbox */
431 return mbx->ops.enqueue_tx(hw, mbx, msg);
432}
433
434/**
435 * fm10k_update_hw_stats_vf - Updates hardware related statistics of VF
436 * @hw: pointer to hardware structure
437 * @stats: pointer to statistics structure
438 *
439 * This function collects and aggregates per queue hardware statistics.
440 **/
441static void fm10k_update_hw_stats_vf(struct fm10k_hw *hw,
442 struct fm10k_hw_stats *stats)
443{
444 fm10k_update_hw_stats_q(hw, stats->q, 0, hw->mac.max_queues);
445}
446
447/**
448 * fm10k_rebind_hw_stats_vf - Resets base for hardware statistics of VF
449 * @hw: pointer to hardware structure
450 * @stats: pointer to the stats structure to update
451 *
452 * This function resets the base for queue hardware statistics.
453 **/
454static void fm10k_rebind_hw_stats_vf(struct fm10k_hw *hw,
455 struct fm10k_hw_stats *stats)
456{
457 /* Unbind Queue Statistics */
458 fm10k_unbind_hw_stats_q(stats->q, 0, hw->mac.max_queues);
459
460 /* Reinitialize bases for all stats */
461 fm10k_update_hw_stats_vf(hw, stats);
462}
463
464/**
465 * fm10k_configure_dglort_map_vf - Configures GLORT entry and queues
466 * @hw: pointer to hardware structure
467 * @dglort: pointer to dglort configuration structure
468 *
469 * Reads the configuration structure contained in dglort_cfg and uses
470 * that information to then populate a DGLORTMAP/DEC entry and the queues
471 * to which it has been assigned.
472 **/
473static s32 fm10k_configure_dglort_map_vf(struct fm10k_hw *hw,
474 struct fm10k_dglort_cfg *dglort)
475{
476 /* verify the dglort pointer */
477 if (!dglort)
478 return FM10K_ERR_PARAM;
479
480 /* stub for now until we determine correct message for this */
481
482 return 0;
483}
484
485static const struct fm10k_msg_data fm10k_msg_data_vf[] = {
486 FM10K_TLV_MSG_TEST_HANDLER(fm10k_tlv_msg_test),
487 FM10K_VF_MSG_MAC_VLAN_HANDLER(fm10k_msg_mac_vlan_vf),
488 FM10K_VF_MSG_LPORT_STATE_HANDLER(fm10k_msg_lport_state_vf),
489 FM10K_TLV_MSG_ERROR_HANDLER(fm10k_tlv_msg_error),
490};
491
492static struct fm10k_mac_ops mac_ops_vf = {
493 .get_bus_info = &fm10k_get_bus_info_generic,
494 .reset_hw = &fm10k_reset_hw_vf,
495 .init_hw = &fm10k_init_hw_vf,
496 .start_hw = &fm10k_start_hw_generic,
497 .stop_hw = &fm10k_stop_hw_vf,
498 .is_slot_appropriate = &fm10k_is_slot_appropriate_vf,
499 .update_vlan = &fm10k_update_vlan_vf,
500 .read_mac_addr = &fm10k_read_mac_addr_vf,
501 .update_uc_addr = &fm10k_update_uc_addr_vf,
502 .update_mc_addr = &fm10k_update_mc_addr_vf,
503 .update_xcast_mode = &fm10k_update_xcast_mode_vf,
504 .update_int_moderator = &fm10k_update_int_moderator_vf,
505 .update_lport_state = &fm10k_update_lport_state_vf,
506 .update_hw_stats = &fm10k_update_hw_stats_vf,
507 .rebind_hw_stats = &fm10k_rebind_hw_stats_vf,
508 .configure_dglort_map = &fm10k_configure_dglort_map_vf,
509 .get_host_state = &fm10k_get_host_state_generic,
510};
511
512static s32 fm10k_get_invariants_vf(struct fm10k_hw *hw)
513{
514 fm10k_get_invariants_generic(hw);
515
516 return fm10k_pfvf_mbx_init(hw, &hw->mbx, fm10k_msg_data_vf, 0);
517}
518
519struct fm10k_info fm10k_vf_info = {
520 .mac = fm10k_mac_vf,
521 .get_invariants = &fm10k_get_invariants_vf,
522 .mac_ops = &mac_ops_vf,
523};
diff --git a/drivers/net/ethernet/intel/fm10k/fm10k_vf.h b/drivers/net/ethernet/intel/fm10k/fm10k_vf.h
new file mode 100644
index 000000000000..8e96ee53c147
--- /dev/null
+++ b/drivers/net/ethernet/intel/fm10k/fm10k_vf.h
@@ -0,0 +1,68 @@
1/* Intel Ethernet Switch Host Interface Driver
2 * Copyright(c) 2013 - 2014 Intel Corporation.
3 *
4 * This program is free software; you can redistribute it and/or modify it
5 * under the terms and conditions of the GNU General Public License,
6 * version 2, as published by the Free Software Foundation.
7 *
8 * This program is distributed in the hope it will be useful, but WITHOUT
9 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
10 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
11 * more details.
12 *
13 * The full GNU General Public License is included in this distribution in
14 * the file called "COPYING".
15 *
16 * Contact Information:
17 * e1000-devel Mailing List <e1000-devel@lists.sourceforge.net>
18 * Intel Corporation, 5200 N.E. Elam Young Parkway, Hillsboro, OR 97124-6497
19 */
20
21#ifndef _FM10K_VF_H_
22#define _FM10K_VF_H_
23
24#include "fm10k_type.h"
25#include "fm10k_common.h"
26
27enum fm10k_vf_tlv_msg_id {
28 FM10K_VF_MSG_ID_TEST = 0, /* msg ID reserved for testing */
29 FM10K_VF_MSG_ID_MSIX,
30 FM10K_VF_MSG_ID_MAC_VLAN,
31 FM10K_VF_MSG_ID_LPORT_STATE,
32 FM10K_VF_MSG_ID_MAX,
33};
34
35enum fm10k_tlv_mac_vlan_attr_id {
36 FM10K_MAC_VLAN_MSG_VLAN,
37 FM10K_MAC_VLAN_MSG_SET,
38 FM10K_MAC_VLAN_MSG_MAC,
39 FM10K_MAC_VLAN_MSG_DEFAULT_MAC,
40 FM10K_MAC_VLAN_MSG_MULTICAST,
41 FM10K_MAC_VLAN_MSG_ID_MAX
42};
43
44enum fm10k_tlv_lport_state_attr_id {
45 FM10K_LPORT_STATE_MSG_DISABLE,
46 FM10K_LPORT_STATE_MSG_XCAST_MODE,
47 FM10K_LPORT_STATE_MSG_READY,
48 FM10K_LPORT_STATE_MSG_MAX
49};
50
51#define FM10K_VF_MSG_MSIX_HANDLER(func) \
52 FM10K_MSG_HANDLER(FM10K_VF_MSG_ID_MSIX, NULL, func)
53
54s32 fm10k_msg_mac_vlan_vf(struct fm10k_hw *, u32 **, struct fm10k_mbx_info *);
55extern const struct fm10k_tlv_attr fm10k_mac_vlan_msg_attr[];
56#define FM10K_VF_MSG_MAC_VLAN_HANDLER(func) \
57 FM10K_MSG_HANDLER(FM10K_VF_MSG_ID_MAC_VLAN, \
58 fm10k_mac_vlan_msg_attr, func)
59
60s32 fm10k_msg_lport_state_vf(struct fm10k_hw *, u32 **,
61 struct fm10k_mbx_info *);
62extern const struct fm10k_tlv_attr fm10k_lport_state_msg_attr[];
63#define FM10K_VF_MSG_LPORT_STATE_HANDLER(func) \
64 FM10K_MSG_HANDLER(FM10K_VF_MSG_ID_LPORT_STATE, \
65 fm10k_lport_state_msg_attr, func)
66
67extern struct fm10k_info fm10k_vf_info;
68#endif /* _FM10K_VF_H */