Skip to content

Commit 8443c1a

Browse files
h-shimamotoJeff Kirsher
authored andcommitted
ixgbe, ixgbevf: Add new mbox API xcast mode
The limitation of the number of multicast address for VF is not enough for the large scale server with SR-IOV feature. IPv6 requires the multicast MAC address for each IP address to handle the Neighbor Solicitation message. We couldn't assign over 30 IPv6 addresses to a single VF. This patch introduces the new mailbox API, IXGBE_VF_UPDATE_XCAST_MODE, to update multicast mode of VF. This adds 3 modes; - NONE only L2 exact match addresses or Flow Director enabled - MULTI BAM and ROMPE set - ALLMULTI BAM, ROMPE and MPE set If a guest VF user wants over 30 MAC multicast addresses, set IFF_ALLMULTI to request PF to update xcast mode to enable VF multicast promiscuous mode. On the other hand, enabling VF multicast promiscuous mode may affect security and performance in the network of the NIC. Only trusted VF can enable multicast promiscuous mode. The behavior of untrusted VF is the same as previous version. Signed-off-by: Hiroshi Shimamoto <[email protected]> Tested-by: Krishneil Singh <[email protected]> Signed-off-by: Jeff Kirsher <[email protected]>
1 parent 54011e4 commit 8443c1a

File tree

8 files changed

+126
-0
lines changed

8 files changed

+126
-0
lines changed

drivers/net/ethernet/intel/ixgbe/ixgbe.h

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -153,9 +153,16 @@ struct vf_data_storage {
153153
u8 spoofchk_enabled;
154154
bool rss_query_enabled;
155155
u8 trusted;
156+
int xcast_mode;
156157
unsigned int vf_api;
157158
};
158159

160+
enum ixgbevf_xcast_modes {
161+
IXGBEVF_XCAST_MODE_NONE = 0,
162+
IXGBEVF_XCAST_MODE_MULTI,
163+
IXGBEVF_XCAST_MODE_ALLMULTI,
164+
};
165+
159166
struct vf_macvlans {
160167
struct list_head l;
161168
int vf;

drivers/net/ethernet/intel/ixgbe/ixgbe_mbx.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -102,6 +102,8 @@ enum ixgbe_pfvf_api_rev {
102102
#define IXGBE_VF_GET_RETA 0x0a /* VF request for RETA */
103103
#define IXGBE_VF_GET_RSS_KEY 0x0b /* get RSS key */
104104

105+
#define IXGBE_VF_UPDATE_XCAST_MODE 0x0c
106+
105107
/* length of permanent address message returned from PF */
106108
#define IXGBE_VF_PERMADDR_MSG_LEN 4
107109
/* word in permanent address message with the current multicast type */

drivers/net/ethernet/intel/ixgbe/ixgbe_sriov.c

Lines changed: 59 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -119,6 +119,9 @@ static int __ixgbe_enable_sriov(struct ixgbe_adapter *adapter)
119119

120120
/* Untrust all VFs */
121121
adapter->vfinfo[i].trusted = false;
122+
123+
/* set the default xcast mode */
124+
adapter->vfinfo[i].xcast_mode = IXGBEVF_XCAST_MODE_NONE;
122125
}
123126

124127
return 0;
@@ -1004,6 +1007,59 @@ static int ixgbe_get_vf_rss_key(struct ixgbe_adapter *adapter,
10041007
return 0;
10051008
}
10061009

1010+
static int ixgbe_update_vf_xcast_mode(struct ixgbe_adapter *adapter,
1011+
u32 *msgbuf, u32 vf)
1012+
{
1013+
struct ixgbe_hw *hw = &adapter->hw;
1014+
int xcast_mode = msgbuf[1];
1015+
u32 vmolr, disable, enable;
1016+
1017+
/* verify the PF is supporting the correct APIs */
1018+
switch (adapter->vfinfo[vf].vf_api) {
1019+
case ixgbe_mbox_api_12:
1020+
break;
1021+
default:
1022+
return -EOPNOTSUPP;
1023+
}
1024+
1025+
if (xcast_mode > IXGBEVF_XCAST_MODE_MULTI &&
1026+
!adapter->vfinfo[vf].trusted) {
1027+
xcast_mode = IXGBEVF_XCAST_MODE_MULTI;
1028+
}
1029+
1030+
if (adapter->vfinfo[vf].xcast_mode == xcast_mode)
1031+
goto out;
1032+
1033+
switch (xcast_mode) {
1034+
case IXGBEVF_XCAST_MODE_NONE:
1035+
disable = IXGBE_VMOLR_BAM | IXGBE_VMOLR_ROMPE | IXGBE_VMOLR_MPE;
1036+
enable = 0;
1037+
break;
1038+
case IXGBEVF_XCAST_MODE_MULTI:
1039+
disable = IXGBE_VMOLR_MPE;
1040+
enable = IXGBE_VMOLR_BAM | IXGBE_VMOLR_ROMPE;
1041+
break;
1042+
case IXGBEVF_XCAST_MODE_ALLMULTI:
1043+
disable = 0;
1044+
enable = IXGBE_VMOLR_BAM | IXGBE_VMOLR_ROMPE | IXGBE_VMOLR_MPE;
1045+
break;
1046+
default:
1047+
return -EOPNOTSUPP;
1048+
}
1049+
1050+
vmolr = IXGBE_READ_REG(hw, IXGBE_VMOLR(vf));
1051+
vmolr &= ~disable;
1052+
vmolr |= enable;
1053+
IXGBE_WRITE_REG(hw, IXGBE_VMOLR(vf), vmolr);
1054+
1055+
adapter->vfinfo[vf].xcast_mode = xcast_mode;
1056+
1057+
out:
1058+
msgbuf[1] = xcast_mode;
1059+
1060+
return 0;
1061+
}
1062+
10071063
static int ixgbe_rcv_msg_from_vf(struct ixgbe_adapter *adapter, u32 vf)
10081064
{
10091065
u32 mbx_size = IXGBE_VFMAILBOX_SIZE;
@@ -1066,6 +1122,9 @@ static int ixgbe_rcv_msg_from_vf(struct ixgbe_adapter *adapter, u32 vf)
10661122
case IXGBE_VF_GET_RSS_KEY:
10671123
retval = ixgbe_get_vf_rss_key(adapter, msgbuf, vf);
10681124
break;
1125+
case IXGBE_VF_UPDATE_XCAST_MODE:
1126+
retval = ixgbe_update_vf_xcast_mode(adapter, msgbuf, vf);
1127+
break;
10691128
default:
10701129
e_err(drv, "Unhandled Msg %8.8x\n", msgbuf[0]);
10711130
retval = IXGBE_ERR_MBX;

drivers/net/ethernet/intel/ixgbevf/ixgbevf.h

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -471,6 +471,12 @@ enum ixgbevf_boards {
471471
board_X550EM_x_vf,
472472
};
473473

474+
enum ixgbevf_xcast_modes {
475+
IXGBEVF_XCAST_MODE_NONE = 0,
476+
IXGBEVF_XCAST_MODE_MULTI,
477+
IXGBEVF_XCAST_MODE_ALLMULTI,
478+
};
479+
474480
extern const struct ixgbevf_info ixgbevf_82599_vf_info;
475481
extern const struct ixgbevf_info ixgbevf_X540_vf_info;
476482
extern const struct ixgbevf_info ixgbevf_X550_vf_info;

drivers/net/ethernet/intel/ixgbevf/ixgbevf_main.c

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1894,9 +1894,17 @@ static void ixgbevf_set_rx_mode(struct net_device *netdev)
18941894
{
18951895
struct ixgbevf_adapter *adapter = netdev_priv(netdev);
18961896
struct ixgbe_hw *hw = &adapter->hw;
1897+
unsigned int flags = netdev->flags;
1898+
int xcast_mode;
1899+
1900+
xcast_mode = (flags & IFF_ALLMULTI) ? IXGBEVF_XCAST_MODE_ALLMULTI :
1901+
(flags & (IFF_BROADCAST | IFF_MULTICAST)) ?
1902+
IXGBEVF_XCAST_MODE_MULTI : IXGBEVF_XCAST_MODE_NONE;
18971903

18981904
spin_lock_bh(&adapter->mbx_lock);
18991905

1906+
hw->mac.ops.update_xcast_mode(hw, netdev, xcast_mode);
1907+
19001908
/* reprogram multicast list */
19011909
hw->mac.ops.update_mc_addr_list(hw, netdev);
19021910

drivers/net/ethernet/intel/ixgbevf/mbx.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -112,6 +112,8 @@ enum ixgbe_pfvf_api_rev {
112112
#define IXGBE_VF_GET_RETA 0x0a /* VF request for RETA */
113113
#define IXGBE_VF_GET_RSS_KEY 0x0b /* get RSS hash key */
114114

115+
#define IXGBE_VF_UPDATE_XCAST_MODE 0x0c
116+
115117
/* length of permanent address message returned from PF */
116118
#define IXGBE_VF_PERMADDR_MSG_LEN 4
117119
/* word in permanent address message with the current multicast type */

drivers/net/ethernet/intel/ixgbevf/vf.c

Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -468,6 +468,46 @@ static s32 ixgbevf_update_mc_addr_list_vf(struct ixgbe_hw *hw,
468468
return 0;
469469
}
470470

471+
/**
472+
* ixgbevf_update_xcast_mode - Update Multicast mode
473+
* @hw: pointer to the HW structure
474+
* @netdev: pointer to net device structure
475+
* @xcast_mode: new multicast mode
476+
*
477+
* Updates the Multicast Mode of VF.
478+
**/
479+
static s32 ixgbevf_update_xcast_mode(struct ixgbe_hw *hw,
480+
struct net_device *netdev, int xcast_mode)
481+
{
482+
struct ixgbe_mbx_info *mbx = &hw->mbx;
483+
u32 msgbuf[2];
484+
s32 err;
485+
486+
switch (hw->api_version) {
487+
case ixgbe_mbox_api_12:
488+
break;
489+
default:
490+
return -EOPNOTSUPP;
491+
}
492+
493+
msgbuf[0] = IXGBE_VF_UPDATE_XCAST_MODE;
494+
msgbuf[1] = xcast_mode;
495+
496+
err = mbx->ops.write_posted(hw, msgbuf, 2);
497+
if (err)
498+
return err;
499+
500+
err = mbx->ops.read_posted(hw, msgbuf, 2);
501+
if (err)
502+
return err;
503+
504+
msgbuf[0] &= ~IXGBE_VT_MSGTYPE_CTS;
505+
if (msgbuf[0] == (IXGBE_VF_UPDATE_XCAST_MODE | IXGBE_VT_MSGTYPE_NACK))
506+
return -EPERM;
507+
508+
return 0;
509+
}
510+
471511
/**
472512
* ixgbevf_set_vfta_vf - Set/Unset VLAN filter table address
473513
* @hw: pointer to the HW structure
@@ -727,6 +767,7 @@ static const struct ixgbe_mac_operations ixgbevf_mac_ops = {
727767
.check_link = ixgbevf_check_mac_link_vf,
728768
.set_rar = ixgbevf_set_rar_vf,
729769
.update_mc_addr_list = ixgbevf_update_mc_addr_list_vf,
770+
.update_xcast_mode = ixgbevf_update_xcast_mode,
730771
.set_uc_addr = ixgbevf_set_uc_addr_vf,
731772
.set_vfta = ixgbevf_set_vfta_vf,
732773
};

drivers/net/ethernet/intel/ixgbevf/vf.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -63,6 +63,7 @@ struct ixgbe_mac_operations {
6363
s32 (*set_uc_addr)(struct ixgbe_hw *, u32, u8 *);
6464
s32 (*init_rx_addrs)(struct ixgbe_hw *);
6565
s32 (*update_mc_addr_list)(struct ixgbe_hw *, struct net_device *);
66+
s32 (*update_xcast_mode)(struct ixgbe_hw *, struct net_device *, int);
6667
s32 (*enable_mc)(struct ixgbe_hw *);
6768
s32 (*disable_mc)(struct ixgbe_hw *);
6869
s32 (*clear_vfta)(struct ixgbe_hw *);

0 commit comments

Comments
 (0)