Skip to content

Commit 5cb8db4

Browse files
Alexander DuyckJeff Kirsher
authored andcommitted
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>
1 parent b651957 commit 5cb8db4

9 files changed

Lines changed: 837 additions & 4 deletions

File tree

drivers/net/ethernet/intel/fm10k/Makefile

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -28,5 +28,5 @@
2828
obj-$(CONFIG_FM10K) += fm10k.o
2929

3030
fm10k-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 \
3232
fm10k_mbx.o fm10k_tlv.o

drivers/net/ethernet/intel/fm10k/fm10k.h

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,7 @@
2828
#include <linux/pci.h>
2929

3030
#include "fm10k_pf.h"
31+
#include "fm10k_vf.h"
3132

3233
#define FM10K_MAX_JUMBO_FRAME_SIZE 15358 /* Maximum supported size 15K */
3334

@@ -180,12 +181,13 @@ static inline struct netdev_queue *txring_txq(const struct fm10k_ring *ring)
180181
#define MIN_Q_VECTORS 1
181182
enum fm10k_non_q_vectors {
182183
FM10K_MBX_VECTOR,
184+
#define NON_Q_VECTORS_VF NON_Q_VECTORS_PF
183185
NON_Q_VECTORS_PF
184186
};
185187

186188
#define NON_Q_VECTORS(hw) (((hw)->mac.type == fm10k_mac_pf) ? \
187189
NON_Q_VECTORS_PF : \
188-
0)
190+
NON_Q_VECTORS_VF)
189191
#define MIN_MSIX_COUNT(hw) (MIN_Q_VECTORS + NON_Q_VECTORS(hw))
190192

191193
struct fm10k_q_vector {

drivers/net/ethernet/intel/fm10k/fm10k_ethtool.c

Lines changed: 114 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -102,13 +102,28 @@ static const struct fm10k_stats fm10k_gstrings_stats[] = {
102102
FM10K_NETDEV_STATS_LEN + \
103103
FM10K_QUEUE_STATS_LEN)
104104

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+
105116
static void fm10k_get_strings(struct net_device *dev, u32 stringset,
106117
u8 *data)
107118
{
108119
char *p = (char *)data;
109120
int i;
110121

111122
switch (stringset) {
123+
case ETH_SS_TEST:
124+
memcpy(data, *fm10k_gstrings_test,
125+
FM10K_TEST_LEN * ETH_GSTRING_LEN);
126+
break;
112127
case ETH_SS_STATS:
113128
for (i = 0; i < FM10K_NETDEV_STATS_LEN; i++) {
114129
memcpy(p, fm10k_gstrings_net_stats[i].stat_string,
@@ -138,6 +153,8 @@ static void fm10k_get_strings(struct net_device *dev, u32 stringset,
138153
static int fm10k_get_sset_count(struct net_device *dev, int sset)
139154
{
140155
switch (sset) {
156+
case ETH_SS_TEST:
157+
return FM10K_TEST_LEN;
141158
case ETH_SS_STATS:
142159
return FM10K_STATS_LEN;
143160
default:
@@ -287,6 +304,28 @@ static void fm10k_get_regs(struct net_device *netdev,
287304
for (i = 0; i < 130; i++)
288305
*(buff++) = fm10k_read_reg(hw, FM10K_ITR(i));
289306

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+
290329
break;
291330
default:
292331
return;
@@ -296,6 +335,8 @@ static void fm10k_get_regs(struct net_device *netdev,
296335
/* If function above adds more registers these define need to be updated */
297336
#define FM10K_REGS_LEN_PF \
298337
(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))
299340

300341
static int fm10k_get_regs_len(struct net_device *netdev)
301342
{
@@ -305,6 +346,8 @@ static int fm10k_get_regs_len(struct net_device *netdev)
305346
switch (hw->mac.type) {
306347
case fm10k_mac_pf:
307348
return FM10K_REGS_LEN_PF * sizeof(u32);
349+
case fm10k_mac_vf:
350+
return FM10K_REGS_LEN_VF * sizeof(u32);
308351
default:
309352
return 0;
310353
}
@@ -734,6 +777,76 @@ static int fm10k_set_rxnfc(struct net_device *dev, struct ethtool_rxnfc *cmd)
734777
return ret;
735778
}
736779

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+
737850
static u32 fm10k_get_reta_size(struct net_device *netdev)
738851
{
739852
return FM10K_RETA_SIZE * FM10K_RETA_ENTRIES_PER_REG;
@@ -911,6 +1024,7 @@ static const struct ethtool_ops fm10k_ethtool_ops = {
9111024
.set_rxnfc = fm10k_set_rxnfc,
9121025
.get_regs = fm10k_get_regs,
9131026
.get_regs_len = fm10k_get_regs_len,
1027+
.self_test = fm10k_self_test,
9141028
.get_rxfh_indir_size = fm10k_get_reta_size,
9151029
.get_rxfh_key_size = fm10k_get_rssrk_size,
9161030
.get_rxfh = fm10k_get_rssh,

drivers/net/ethernet/intel/fm10k/fm10k_mbx.c

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1517,6 +1517,10 @@ s32 fm10k_pfvf_mbx_init(struct fm10k_hw *hw, struct fm10k_mbx_info *mbx,
15171517
{
15181518
/* initialize registers */
15191519
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;
15201524
case fm10k_mac_pf:
15211525
/* there are only 64 VF <-> PF mailboxes */
15221526
if (id < 64) {

drivers/net/ethernet/intel/fm10k/fm10k_netdev.c

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -976,6 +976,21 @@ void fm10k_restore_rx_state(struct fm10k_intfc *interface)
976976
int xcast_mode;
977977
u16 vid, glort;
978978

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+
979994
/* record glort for this interface */
980995
glort = interface->glort;
981996

drivers/net/ethernet/intel/fm10k/fm10k_pci.c

Lines changed: 100 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,7 @@
2525

2626
static const struct fm10k_info *fm10k_info_tbl[] = {
2727
[fm10k_device_pf] = &fm10k_pf_info,
28+
[fm10k_device_vf] = &fm10k_vf_info,
2829
};
2930

3031
/**
@@ -38,6 +39,7 @@ static const struct fm10k_info *fm10k_info_tbl[] = {
3839
*/
3940
static const struct pci_device_id fm10k_pci_tbl[] = {
4041
{ PCI_VDEVICE(INTEL, FM10K_DEV_ID_PF), fm10k_device_pf },
42+
{ PCI_VDEVICE(INTEL, FM10K_DEV_ID_VF), fm10k_device_vf },
4143
/* required last entry */
4244
{ 0, }
4345
};
@@ -805,6 +807,28 @@ static irqreturn_t fm10k_msix_clean_rings(int irq, void *data)
805807
return IRQ_HANDLED;
806808
}
807809

810+
static 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+
808832
#define FM10K_ERR_MSG(type) case (type): error = #type; break
809833
static void fm10k_print_fault(struct fm10k_intfc *interface, int type,
810834
struct fm10k_fault *fault)
@@ -996,13 +1020,42 @@ void fm10k_mbx_free_irq(struct fm10k_intfc *interface)
9961020
FM10K_EIMR_DISABLE(VFLR) |
9971021
FM10K_EIMR_DISABLE(MAXHOLDTIME));
9981022
itr_reg = FM10K_ITR(FM10K_MBX_VECTOR);
1023+
} else {
1024+
itr_reg = FM10K_VFITR(FM10K_MBX_VECTOR);
9991025
}
10001026

10011027
fm10k_write_reg(hw, itr_reg, FM10K_ITR_MASK_SET);
10021028

10031029
free_irq(entry->vector, interface);
10041030
}
10051031

1032+
static 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+
10061059
/* generic error handler for mailbox issues */
10071060
static s32 fm10k_mbx_error(struct fm10k_hw *hw, u32 **results,
10081061
struct fm10k_mbx_info *mbx)
@@ -1019,6 +1072,46 @@ static s32 fm10k_mbx_error(struct fm10k_hw *hw, u32 **results,
10191072
return 0;
10201073
}
10211074

1075+
static 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+
1082+
static 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+
10221115
static s32 fm10k_lport_map(struct fm10k_hw *hw, u32 **results,
10231116
struct fm10k_mbx_info *mbx)
10241117
{
@@ -1142,7 +1235,10 @@ int fm10k_mbx_request_irq(struct fm10k_intfc *interface)
11421235
int err;
11431236

11441237
/* 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);
11461242

11471243
/* connect mailbox */
11481244
if (!err)
@@ -1220,7 +1316,9 @@ int fm10k_qv_request_irq(struct fm10k_intfc *interface)
12201316
}
12211317

12221318
/* 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)];
12241322

12251323
/* request the IRQ */
12261324
err = request_irq(entry->vector, &fm10k_msix_clean_rings, 0,

0 commit comments

Comments
 (0)