aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/net/ixgbe
diff options
context:
space:
mode:
authorGreg Rose <gregory.v.rose@intel.com>2010-05-04 18:12:06 -0400
committerDavid S. Miller <davem@davemloft.net>2010-05-06 00:15:33 -0400
commit7f01648aa32185b8047aea384237ad58e430e07f (patch)
tree3dbf1d4eb0e103e1dd4d01f2d622ff75d025db01 /drivers/net/ixgbe
parentf04127760e582a9dccb22dfceb41cd1dad676794 (diff)
ixgbe: Add support for VF MAC and VLAN configuration
Add support for the "ip link set" and "ip link show" commands that allow configuration of the virtual functions' MAC and port VLAN via user space command line. Signed-off-by: Greg Rose <gregory.v.rose@intel.com> Signed-off-by: Jeff Kirsher <jeffrey.t.kirsher@intel.com> Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'drivers/net/ixgbe')
-rw-r--r--drivers/net/ixgbe/ixgbe.h3
-rw-r--r--drivers/net/ixgbe/ixgbe_main.c4
-rw-r--r--drivers/net/ixgbe/ixgbe_sriov.c104
-rw-r--r--drivers/net/ixgbe/ixgbe_sriov.h6
-rw-r--r--drivers/net/ixgbe/ixgbe_type.h5
5 files changed, 118 insertions, 4 deletions
diff --git a/drivers/net/ixgbe/ixgbe.h b/drivers/net/ixgbe/ixgbe.h
index 79c35ae3718c..d0ea3d6dea95 100644
--- a/drivers/net/ixgbe/ixgbe.h
+++ b/drivers/net/ixgbe/ixgbe.h
@@ -111,7 +111,10 @@ struct vf_data_storage {
111 u16 default_vf_vlan_id; 111 u16 default_vf_vlan_id;
112 u16 vlans_enabled; 112 u16 vlans_enabled;
113 bool clear_to_send; 113 bool clear_to_send;
114 bool pf_set_mac;
114 int rar; 115 int rar;
116 u16 pf_vlan; /* When set, guest VLAN config not allowed. */
117 u16 pf_qos;
115}; 118};
116 119
117/* wrapper around a pointer to a socket buffer, 120/* wrapper around a pointer to a socket buffer,
diff --git a/drivers/net/ixgbe/ixgbe_main.c b/drivers/net/ixgbe/ixgbe_main.c
index 0a0e90e80025..d1a1868df817 100644
--- a/drivers/net/ixgbe/ixgbe_main.c
+++ b/drivers/net/ixgbe/ixgbe_main.c
@@ -6311,6 +6311,10 @@ static const struct net_device_ops ixgbe_netdev_ops = {
6311 .ndo_vlan_rx_add_vid = ixgbe_vlan_rx_add_vid, 6311 .ndo_vlan_rx_add_vid = ixgbe_vlan_rx_add_vid,
6312 .ndo_vlan_rx_kill_vid = ixgbe_vlan_rx_kill_vid, 6312 .ndo_vlan_rx_kill_vid = ixgbe_vlan_rx_kill_vid,
6313 .ndo_do_ioctl = ixgbe_ioctl, 6313 .ndo_do_ioctl = ixgbe_ioctl,
6314 .ndo_set_vf_mac = ixgbe_ndo_set_vf_mac,
6315 .ndo_set_vf_vlan = ixgbe_ndo_set_vf_vlan,
6316 .ndo_set_vf_tx_rate = ixgbe_ndo_set_vf_bw,
6317 .ndo_get_vf_config = ixgbe_ndo_get_vf_config,
6314#ifdef CONFIG_NET_POLL_CONTROLLER 6318#ifdef CONFIG_NET_POLL_CONTROLLER
6315 .ndo_poll_controller = ixgbe_netpoll, 6319 .ndo_poll_controller = ixgbe_netpoll,
6316#endif 6320#endif
diff --git a/drivers/net/ixgbe/ixgbe_sriov.c b/drivers/net/ixgbe/ixgbe_sriov.c
index 53f364d57739..221b2ca994e6 100644
--- a/drivers/net/ixgbe/ixgbe_sriov.c
+++ b/drivers/net/ixgbe/ixgbe_sriov.c
@@ -126,13 +126,34 @@ void ixgbe_set_vmolr(struct ixgbe_hw *hw, u32 vf, bool aupe)
126 IXGBE_WRITE_REG(hw, IXGBE_VMOLR(vf), vmolr); 126 IXGBE_WRITE_REG(hw, IXGBE_VMOLR(vf), vmolr);
127} 127}
128 128
129static void ixgbe_set_vmvir(struct ixgbe_adapter *adapter, u32 vid, u32 vf)
130{
131 struct ixgbe_hw *hw = &adapter->hw;
132
133 if (vid)
134 IXGBE_WRITE_REG(hw, IXGBE_VMVIR(vf),
135 (vid | IXGBE_VMVIR_VLANA_DEFAULT));
136 else
137 IXGBE_WRITE_REG(hw, IXGBE_VMVIR(vf), 0);
138}
139
129inline void ixgbe_vf_reset_event(struct ixgbe_adapter *adapter, u32 vf) 140inline void ixgbe_vf_reset_event(struct ixgbe_adapter *adapter, u32 vf)
130{ 141{
131 struct ixgbe_hw *hw = &adapter->hw; 142 struct ixgbe_hw *hw = &adapter->hw;
132 143
133 /* reset offloads to defaults */ 144 /* reset offloads to defaults */
134 ixgbe_set_vmolr(hw, vf, true); 145 if (adapter->vfinfo[vf].pf_vlan) {
135 146 ixgbe_set_vf_vlan(adapter, true,
147 adapter->vfinfo[vf].pf_vlan, vf);
148 ixgbe_set_vmvir(adapter,
149 (adapter->vfinfo[vf].pf_vlan |
150 (adapter->vfinfo[vf].pf_qos <<
151 VLAN_PRIO_SHIFT)), vf);
152 ixgbe_set_vmolr(hw, vf, false);
153 } else {
154 ixgbe_set_vmvir(adapter, 0, vf);
155 ixgbe_set_vmolr(hw, vf, true);
156 }
136 157
137 /* reset multicast table array for vf */ 158 /* reset multicast table array for vf */
138 adapter->vfinfo[vf].num_vf_mc_hashes = 0; 159 adapter->vfinfo[vf].num_vf_mc_hashes = 0;
@@ -266,10 +287,12 @@ static int ixgbe_rcv_msg_from_vf(struct ixgbe_adapter *adapter, u32 vf)
266 case IXGBE_VF_SET_MAC_ADDR: 287 case IXGBE_VF_SET_MAC_ADDR:
267 { 288 {
268 u8 *new_mac = ((u8 *)(&msgbuf[1])); 289 u8 *new_mac = ((u8 *)(&msgbuf[1]));
269 if (is_valid_ether_addr(new_mac)) 290 if (is_valid_ether_addr(new_mac) &&
291 !adapter->vfinfo[vf].pf_set_mac)
270 ixgbe_set_vf_mac(adapter, vf, new_mac); 292 ixgbe_set_vf_mac(adapter, vf, new_mac);
271 else 293 else
272 retval = -1; 294 ixgbe_set_vf_mac(adapter,
295 vf, adapter->vfinfo[vf].vf_mac_addresses);
273 } 296 }
274 break; 297 break;
275 case IXGBE_VF_SET_MULTICAST: 298 case IXGBE_VF_SET_MULTICAST:
@@ -363,3 +386,76 @@ void ixgbe_ping_all_vfs(struct ixgbe_adapter *adapter)
363 } 386 }
364} 387}
365 388
389int ixgbe_ndo_set_vf_mac(struct net_device *netdev, int vf, u8 *mac)
390{
391 struct ixgbe_adapter *adapter = netdev_priv(netdev);
392 if (!is_valid_ether_addr(mac) || (vf >= adapter->num_vfs))
393 return -EINVAL;
394 adapter->vfinfo[vf].pf_set_mac = true;
395 dev_info(&adapter->pdev->dev, "setting MAC %pM on VF %d\n", mac, vf);
396 dev_info(&adapter->pdev->dev, "Reload the VF driver to make this"
397 " change effective.");
398 if (test_bit(__IXGBE_DOWN, &adapter->state)) {
399 dev_warn(&adapter->pdev->dev, "The VF MAC address has been set,"
400 " but the PF device is not up.\n");
401 dev_warn(&adapter->pdev->dev, "Bring the PF device up before"
402 " attempting to use the VF device.\n");
403 }
404 return ixgbe_set_vf_mac(adapter, vf, mac);
405}
406
407int ixgbe_ndo_set_vf_vlan(struct net_device *netdev, int vf, u16 vlan, u8 qos)
408{
409 int err = 0;
410 struct ixgbe_adapter *adapter = netdev_priv(netdev);
411
412 if ((vf >= adapter->num_vfs) || (vlan > 4095) || (qos > 7))
413 return -EINVAL;
414 if (vlan || qos) {
415 err = ixgbe_set_vf_vlan(adapter, true, vlan, vf);
416 if (err)
417 goto out;
418 ixgbe_set_vmvir(adapter, vlan | (qos << VLAN_PRIO_SHIFT), vf);
419 ixgbe_set_vmolr(&adapter->hw, vf, false);
420 adapter->vfinfo[vf].pf_vlan = vlan;
421 adapter->vfinfo[vf].pf_qos = qos;
422 dev_info(&adapter->pdev->dev,
423 "Setting VLAN %d, QOS 0x%x on VF %d\n", vlan, qos, vf);
424 if (test_bit(__IXGBE_DOWN, &adapter->state)) {
425 dev_warn(&adapter->pdev->dev,
426 "The VF VLAN has been set,"
427 " but the PF device is not up.\n");
428 dev_warn(&adapter->pdev->dev,
429 "Bring the PF device up before"
430 " attempting to use the VF device.\n");
431 }
432 } else {
433 err = ixgbe_set_vf_vlan(adapter, false,
434 adapter->vfinfo[vf].pf_vlan, vf);
435 ixgbe_set_vmvir(adapter, vlan, vf);
436 ixgbe_set_vmolr(&adapter->hw, vf, true);
437 adapter->vfinfo[vf].pf_vlan = 0;
438 adapter->vfinfo[vf].pf_qos = 0;
439 }
440out:
441 return err;
442}
443
444int ixgbe_ndo_set_vf_bw(struct net_device *netdev, int vf, int tx_rate)
445{
446 return -EOPNOTSUPP;
447}
448
449int ixgbe_ndo_get_vf_config(struct net_device *netdev,
450 int vf, struct ifla_vf_info *ivi)
451{
452 struct ixgbe_adapter *adapter = netdev_priv(netdev);
453 if (vf >= adapter->num_vfs)
454 return -EINVAL;
455 ivi->vf = vf;
456 memcpy(&ivi->mac, adapter->vfinfo[vf].vf_mac_addresses, ETH_ALEN);
457 ivi->tx_rate = 0;
458 ivi->vlan = adapter->vfinfo[vf].pf_vlan;
459 ivi->qos = adapter->vfinfo[vf].pf_qos;
460 return 0;
461}
diff --git a/drivers/net/ixgbe/ixgbe_sriov.h b/drivers/net/ixgbe/ixgbe_sriov.h
index 7fb12885cf5d..184730ecdfb6 100644
--- a/drivers/net/ixgbe/ixgbe_sriov.h
+++ b/drivers/net/ixgbe/ixgbe_sriov.h
@@ -42,6 +42,12 @@ int ixgbe_vf_configuration(struct pci_dev *pdev, unsigned int event_mask);
42void ixgbe_disable_tx_rx(struct ixgbe_adapter *adapter); 42void ixgbe_disable_tx_rx(struct ixgbe_adapter *adapter);
43void ixgbe_ping_all_vfs(struct ixgbe_adapter *adapter); 43void ixgbe_ping_all_vfs(struct ixgbe_adapter *adapter);
44void ixgbe_dump_registers(struct ixgbe_adapter *adapter); 44void ixgbe_dump_registers(struct ixgbe_adapter *adapter);
45int ixgbe_ndo_set_vf_mac(struct net_device *netdev, int queue, u8 *mac);
46int ixgbe_ndo_set_vf_vlan(struct net_device *netdev, int queue, u16 vlan,
47 u8 qos);
48int ixgbe_ndo_set_vf_bw(struct net_device *netdev, int vf, int tx_rate);
49int ixgbe_ndo_get_vf_config(struct net_device *netdev,
50 int vf, struct ifla_vf_info *ivi);
45 51
46#endif /* _IXGBE_SRIOV_H_ */ 52#endif /* _IXGBE_SRIOV_H_ */
47 53
diff --git a/drivers/net/ixgbe/ixgbe_type.h b/drivers/net/ixgbe/ixgbe_type.h
index a0f9084c81cd..4277cbbb8126 100644
--- a/drivers/net/ixgbe/ixgbe_type.h
+++ b/drivers/net/ixgbe/ixgbe_type.h
@@ -219,6 +219,7 @@
219#define IXGBE_MTQC 0x08120 219#define IXGBE_MTQC 0x08120
220#define IXGBE_VLVF(_i) (0x0F100 + ((_i) * 4)) /* 64 of these (0-63) */ 220#define IXGBE_VLVF(_i) (0x0F100 + ((_i) * 4)) /* 64 of these (0-63) */
221#define IXGBE_VLVFB(_i) (0x0F200 + ((_i) * 4)) /* 128 of these (0-127) */ 221#define IXGBE_VLVFB(_i) (0x0F200 + ((_i) * 4)) /* 128 of these (0-127) */
222#define IXGBE_VMVIR(_i) (0x08000 + ((_i) * 4)) /* 64 of these (0-63) */
222#define IXGBE_VT_CTL 0x051B0 223#define IXGBE_VT_CTL 0x051B0
223#define IXGBE_VFRE(_i) (0x051E0 + ((_i) * 4)) 224#define IXGBE_VFRE(_i) (0x051E0 + ((_i) * 4))
224#define IXGBE_VFTE(_i) (0x08110 + ((_i) * 4)) 225#define IXGBE_VFTE(_i) (0x08110 + ((_i) * 4))
@@ -1311,6 +1312,10 @@
1311#define IXGBE_VLVF_ENTRIES 64 1312#define IXGBE_VLVF_ENTRIES 64
1312#define IXGBE_VLVF_VLANID_MASK 0x00000FFF 1313#define IXGBE_VLVF_VLANID_MASK 0x00000FFF
1313 1314
1315/* Per VF Port VLAN insertion rules */
1316#define IXGBE_VMVIR_VLANA_DEFAULT 0x40000000 /* Always use default VLAN */
1317#define IXGBE_VMVIR_VLANA_NEVER 0x80000000 /* Never insert VLAN tag */
1318
1314#define IXGBE_ETHERNET_IEEE_VLAN_TYPE 0x8100 /* 802.1q protocol */ 1319#define IXGBE_ETHERNET_IEEE_VLAN_TYPE 0x8100 /* 802.1q protocol */
1315 1320
1316/* STATUS Bit Masks */ 1321/* STATUS Bit Masks */