diff options
author | Williams, Mitch A <mitch.a.williams@intel.com> | 2010-02-09 20:44:24 -0500 |
---|---|---|
committer | David S. Miller <davem@davemloft.net> | 2010-02-12 19:56:09 -0500 |
commit | 8151d2948e088c20b7d29c793cf1fd744b6a2699 (patch) | |
tree | a92553bd15f1ee88f0d18b8975f90222303e38f1 /drivers/net/igb | |
parent | ebc08a6f47ee76ecad8e9f26c26e6ec9b46ca659 (diff) |
igb: support for VF configuration tools
Add support to the igb driver for VF configuration mechanisms through the
PF interface.
Signed-off-by: Mitch Williams <mitch.a.williams@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/igb')
-rw-r--r-- | drivers/net/igb/e1000_82575.h | 3 | ||||
-rw-r--r-- | drivers/net/igb/e1000_regs.h | 1 | ||||
-rw-r--r-- | drivers/net/igb/igb.h | 3 | ||||
-rw-r--r-- | drivers/net/igb/igb_main.c | 130 |
4 files changed, 126 insertions, 11 deletions
diff --git a/drivers/net/igb/e1000_82575.h b/drivers/net/igb/e1000_82575.h index d51c9927c819..bb53083ec61f 100644 --- a/drivers/net/igb/e1000_82575.h +++ b/drivers/net/igb/e1000_82575.h | |||
@@ -219,6 +219,9 @@ struct e1000_adv_tx_context_desc { | |||
219 | #define E1000_VLVF_LVLAN 0x00100000 | 219 | #define E1000_VLVF_LVLAN 0x00100000 |
220 | #define E1000_VLVF_VLANID_ENABLE 0x80000000 | 220 | #define E1000_VLVF_VLANID_ENABLE 0x80000000 |
221 | 221 | ||
222 | #define E1000_VMVIR_VLANA_DEFAULT 0x40000000 /* Always use default VLAN */ | ||
223 | #define E1000_VMVIR_VLANA_NEVER 0x80000000 /* Never insert VLAN tag */ | ||
224 | |||
222 | #define E1000_IOVCTL 0x05BBC | 225 | #define E1000_IOVCTL 0x05BBC |
223 | #define E1000_IOVCTL_REUSE_VFQ 0x00000001 | 226 | #define E1000_IOVCTL_REUSE_VFQ 0x00000001 |
224 | 227 | ||
diff --git a/drivers/net/igb/e1000_regs.h b/drivers/net/igb/e1000_regs.h index dd4e6ffd29f5..abb7333a1fbf 100644 --- a/drivers/net/igb/e1000_regs.h +++ b/drivers/net/igb/e1000_regs.h | |||
@@ -310,6 +310,7 @@ | |||
310 | #define E1000_VMOLR(_n) (0x05AD0 + (4 * (_n))) | 310 | #define E1000_VMOLR(_n) (0x05AD0 + (4 * (_n))) |
311 | #define E1000_VLVF(_n) (0x05D00 + (4 * (_n))) /* VLAN Virtual Machine | 311 | #define E1000_VLVF(_n) (0x05D00 + (4 * (_n))) /* VLAN Virtual Machine |
312 | * Filter - RW */ | 312 | * Filter - RW */ |
313 | #define E1000_VMVIR(_n) (0x03700 + (4 * (_n))) | ||
313 | 314 | ||
314 | #define wr32(reg, value) (writel(value, hw->hw_addr + reg)) | 315 | #define wr32(reg, value) (writel(value, hw->hw_addr + reg)) |
315 | #define rd32(reg) (readl(hw->hw_addr + reg)) | 316 | #define rd32(reg) (readl(hw->hw_addr + reg)) |
diff --git a/drivers/net/igb/igb.h b/drivers/net/igb/igb.h index b1c1eb88893f..83ea11701f45 100644 --- a/drivers/net/igb/igb.h +++ b/drivers/net/igb/igb.h | |||
@@ -75,11 +75,14 @@ struct vf_data_storage { | |||
75 | u16 vlans_enabled; | 75 | u16 vlans_enabled; |
76 | u32 flags; | 76 | u32 flags; |
77 | unsigned long last_nack; | 77 | unsigned long last_nack; |
78 | u16 pf_vlan; /* When set, guest VLAN config not allowed. */ | ||
79 | u16 pf_qos; | ||
78 | }; | 80 | }; |
79 | 81 | ||
80 | #define IGB_VF_FLAG_CTS 0x00000001 /* VF is clear to send data */ | 82 | #define IGB_VF_FLAG_CTS 0x00000001 /* VF is clear to send data */ |
81 | #define IGB_VF_FLAG_UNI_PROMISC 0x00000002 /* VF has unicast promisc */ | 83 | #define IGB_VF_FLAG_UNI_PROMISC 0x00000002 /* VF has unicast promisc */ |
82 | #define IGB_VF_FLAG_MULTI_PROMISC 0x00000004 /* VF has multicast promisc */ | 84 | #define IGB_VF_FLAG_MULTI_PROMISC 0x00000004 /* VF has multicast promisc */ |
85 | #define IGB_VF_FLAG_PF_SET_MAC 0x00000008 /* PF has set MAC address */ | ||
83 | 86 | ||
84 | /* RX descriptor control thresholds. | 87 | /* RX descriptor control thresholds. |
85 | * PTHRESH - MAC will consider prefetch if it has fewer than this number of | 88 | * PTHRESH - MAC will consider prefetch if it has fewer than this number of |
diff --git a/drivers/net/igb/igb_main.c b/drivers/net/igb/igb_main.c index 28371d648208..4fe7b0ba6310 100644 --- a/drivers/net/igb/igb_main.c +++ b/drivers/net/igb/igb_main.c | |||
@@ -133,6 +133,12 @@ static void igb_msg_task(struct igb_adapter *); | |||
133 | static void igb_vmm_control(struct igb_adapter *); | 133 | static void igb_vmm_control(struct igb_adapter *); |
134 | static int igb_set_vf_mac(struct igb_adapter *, int, unsigned char *); | 134 | static int igb_set_vf_mac(struct igb_adapter *, int, unsigned char *); |
135 | static void igb_restore_vf_multicasts(struct igb_adapter *adapter); | 135 | static void igb_restore_vf_multicasts(struct igb_adapter *adapter); |
136 | static int igb_ndo_set_vf_mac(struct net_device *netdev, int vf, u8 *mac); | ||
137 | static int igb_ndo_set_vf_vlan(struct net_device *netdev, | ||
138 | int vf, u16 vlan, u8 qos); | ||
139 | static int igb_ndo_set_vf_bw(struct net_device *netdev, int vf, int tx_rate); | ||
140 | static int igb_ndo_get_vf_config(struct net_device *netdev, int vf, | ||
141 | struct ifla_vf_info *ivi); | ||
136 | 142 | ||
137 | #ifdef CONFIG_PM | 143 | #ifdef CONFIG_PM |
138 | static int igb_suspend(struct pci_dev *, pm_message_t); | 144 | static int igb_suspend(struct pci_dev *, pm_message_t); |
@@ -1352,6 +1358,10 @@ static const struct net_device_ops igb_netdev_ops = { | |||
1352 | .ndo_vlan_rx_register = igb_vlan_rx_register, | 1358 | .ndo_vlan_rx_register = igb_vlan_rx_register, |
1353 | .ndo_vlan_rx_add_vid = igb_vlan_rx_add_vid, | 1359 | .ndo_vlan_rx_add_vid = igb_vlan_rx_add_vid, |
1354 | .ndo_vlan_rx_kill_vid = igb_vlan_rx_kill_vid, | 1360 | .ndo_vlan_rx_kill_vid = igb_vlan_rx_kill_vid, |
1361 | .ndo_set_vf_mac = igb_ndo_set_vf_mac, | ||
1362 | .ndo_set_vf_vlan = igb_ndo_set_vf_vlan, | ||
1363 | .ndo_set_vf_tx_rate = igb_ndo_set_vf_bw, | ||
1364 | .ndo_get_vf_config = igb_ndo_get_vf_config, | ||
1355 | #ifdef CONFIG_NET_POLL_CONTROLLER | 1365 | #ifdef CONFIG_NET_POLL_CONTROLLER |
1356 | .ndo_poll_controller = igb_netpoll, | 1366 | .ndo_poll_controller = igb_netpoll, |
1357 | #endif | 1367 | #endif |
@@ -2479,7 +2489,8 @@ static void igb_rlpml_set(struct igb_adapter *adapter) | |||
2479 | wr32(E1000_RLPML, max_frame_size); | 2489 | wr32(E1000_RLPML, max_frame_size); |
2480 | } | 2490 | } |
2481 | 2491 | ||
2482 | static inline void igb_set_vmolr(struct igb_adapter *adapter, int vfn) | 2492 | static inline void igb_set_vmolr(struct igb_adapter *adapter, |
2493 | int vfn, bool aupe) | ||
2483 | { | 2494 | { |
2484 | struct e1000_hw *hw = &adapter->hw; | 2495 | struct e1000_hw *hw = &adapter->hw; |
2485 | u32 vmolr; | 2496 | u32 vmolr; |
@@ -2492,8 +2503,11 @@ static inline void igb_set_vmolr(struct igb_adapter *adapter, int vfn) | |||
2492 | return; | 2503 | return; |
2493 | 2504 | ||
2494 | vmolr = rd32(E1000_VMOLR(vfn)); | 2505 | vmolr = rd32(E1000_VMOLR(vfn)); |
2495 | vmolr |= E1000_VMOLR_AUPE | /* Accept untagged packets */ | 2506 | vmolr |= E1000_VMOLR_STRVLAN; /* Strip vlan tags */ |
2496 | E1000_VMOLR_STRVLAN; /* Strip vlan tags */ | 2507 | if (aupe) |
2508 | vmolr |= E1000_VMOLR_AUPE; /* Accept untagged packets */ | ||
2509 | else | ||
2510 | vmolr &= ~(E1000_VMOLR_AUPE); /* Tagged packets ONLY */ | ||
2497 | 2511 | ||
2498 | /* clear all bits that might not be set */ | 2512 | /* clear all bits that might not be set */ |
2499 | vmolr &= ~(E1000_VMOLR_BAM | E1000_VMOLR_RSSE); | 2513 | vmolr &= ~(E1000_VMOLR_BAM | E1000_VMOLR_RSSE); |
@@ -2564,7 +2578,7 @@ void igb_configure_rx_ring(struct igb_adapter *adapter, | |||
2564 | wr32(E1000_SRRCTL(reg_idx), srrctl); | 2578 | wr32(E1000_SRRCTL(reg_idx), srrctl); |
2565 | 2579 | ||
2566 | /* set filtering for VMDQ pools */ | 2580 | /* set filtering for VMDQ pools */ |
2567 | igb_set_vmolr(adapter, reg_idx & 0x7); | 2581 | igb_set_vmolr(adapter, reg_idx & 0x7, true); |
2568 | 2582 | ||
2569 | /* enable receive descriptor fetching */ | 2583 | /* enable receive descriptor fetching */ |
2570 | rxdctl = rd32(E1000_RXDCTL(reg_idx)); | 2584 | rxdctl = rd32(E1000_RXDCTL(reg_idx)); |
@@ -4490,10 +4504,57 @@ static s32 igb_vlvf_set(struct igb_adapter *adapter, u32 vid, bool add, u32 vf) | |||
4490 | reg |= size; | 4504 | reg |= size; |
4491 | wr32(E1000_VMOLR(vf), reg); | 4505 | wr32(E1000_VMOLR(vf), reg); |
4492 | } | 4506 | } |
4493 | return 0; | ||
4494 | } | 4507 | } |
4495 | } | 4508 | } |
4496 | return -1; | 4509 | return 0; |
4510 | } | ||
4511 | |||
4512 | static void igb_set_vmvir(struct igb_adapter *adapter, u32 vid, u32 vf) | ||
4513 | { | ||
4514 | struct e1000_hw *hw = &adapter->hw; | ||
4515 | |||
4516 | if (vid) | ||
4517 | wr32(E1000_VMVIR(vf), (vid | E1000_VMVIR_VLANA_DEFAULT)); | ||
4518 | else | ||
4519 | wr32(E1000_VMVIR(vf), 0); | ||
4520 | } | ||
4521 | |||
4522 | static int igb_ndo_set_vf_vlan(struct net_device *netdev, | ||
4523 | int vf, u16 vlan, u8 qos) | ||
4524 | { | ||
4525 | int err = 0; | ||
4526 | struct igb_adapter *adapter = netdev_priv(netdev); | ||
4527 | |||
4528 | if ((vf >= adapter->vfs_allocated_count) || (vlan > 4095) || (qos > 7)) | ||
4529 | return -EINVAL; | ||
4530 | if (vlan || qos) { | ||
4531 | err = igb_vlvf_set(adapter, vlan, !!vlan, vf); | ||
4532 | if (err) | ||
4533 | goto out; | ||
4534 | igb_set_vmvir(adapter, vlan | (qos << VLAN_PRIO_SHIFT), vf); | ||
4535 | igb_set_vmolr(adapter, vf, !vlan); | ||
4536 | adapter->vf_data[vf].pf_vlan = vlan; | ||
4537 | adapter->vf_data[vf].pf_qos = qos; | ||
4538 | dev_info(&adapter->pdev->dev, | ||
4539 | "Setting VLAN %d, QOS 0x%x on VF %d\n", vlan, qos, vf); | ||
4540 | if (test_bit(__IGB_DOWN, &adapter->state)) { | ||
4541 | dev_warn(&adapter->pdev->dev, | ||
4542 | "The VF VLAN has been set," | ||
4543 | " but the PF device is not up.\n"); | ||
4544 | dev_warn(&adapter->pdev->dev, | ||
4545 | "Bring the PF device up before" | ||
4546 | " attempting to use the VF device.\n"); | ||
4547 | } | ||
4548 | } else { | ||
4549 | igb_vlvf_set(adapter, adapter->vf_data[vf].pf_vlan, | ||
4550 | false, vf); | ||
4551 | igb_set_vmvir(adapter, vlan, vf); | ||
4552 | igb_set_vmolr(adapter, vf, true); | ||
4553 | adapter->vf_data[vf].pf_vlan = 0; | ||
4554 | adapter->vf_data[vf].pf_qos = 0; | ||
4555 | } | ||
4556 | out: | ||
4557 | return err; | ||
4497 | } | 4558 | } |
4498 | 4559 | ||
4499 | static int igb_set_vf_vlan(struct igb_adapter *adapter, u32 *msgbuf, u32 vf) | 4560 | static int igb_set_vf_vlan(struct igb_adapter *adapter, u32 *msgbuf, u32 vf) |
@@ -4506,15 +4567,21 @@ static int igb_set_vf_vlan(struct igb_adapter *adapter, u32 *msgbuf, u32 vf) | |||
4506 | 4567 | ||
4507 | static inline void igb_vf_reset(struct igb_adapter *adapter, u32 vf) | 4568 | static inline void igb_vf_reset(struct igb_adapter *adapter, u32 vf) |
4508 | { | 4569 | { |
4509 | /* clear all flags */ | 4570 | /* clear flags */ |
4510 | adapter->vf_data[vf].flags = 0; | 4571 | adapter->vf_data[vf].flags &= ~(IGB_VF_FLAG_PF_SET_MAC); |
4511 | adapter->vf_data[vf].last_nack = jiffies; | 4572 | adapter->vf_data[vf].last_nack = jiffies; |
4512 | 4573 | ||
4513 | /* reset offloads to defaults */ | 4574 | /* reset offloads to defaults */ |
4514 | igb_set_vmolr(adapter, vf); | 4575 | igb_set_vmolr(adapter, vf, true); |
4515 | 4576 | ||
4516 | /* reset vlans for device */ | 4577 | /* reset vlans for device */ |
4517 | igb_clear_vf_vfta(adapter, vf); | 4578 | igb_clear_vf_vfta(adapter, vf); |
4579 | if (adapter->vf_data[vf].pf_vlan) | ||
4580 | igb_ndo_set_vf_vlan(adapter->netdev, vf, | ||
4581 | adapter->vf_data[vf].pf_vlan, | ||
4582 | adapter->vf_data[vf].pf_qos); | ||
4583 | else | ||
4584 | igb_clear_vf_vfta(adapter, vf); | ||
4518 | 4585 | ||
4519 | /* reset multicast table array for vf */ | 4586 | /* reset multicast table array for vf */ |
4520 | adapter->vf_data[vf].num_vf_mc_hashes = 0; | 4587 | adapter->vf_data[vf].num_vf_mc_hashes = 0; |
@@ -4528,7 +4595,8 @@ static void igb_vf_reset_event(struct igb_adapter *adapter, u32 vf) | |||
4528 | unsigned char *vf_mac = adapter->vf_data[vf].vf_mac_addresses; | 4595 | unsigned char *vf_mac = adapter->vf_data[vf].vf_mac_addresses; |
4529 | 4596 | ||
4530 | /* generate a new mac address as we were hotplug removed/added */ | 4597 | /* generate a new mac address as we were hotplug removed/added */ |
4531 | random_ether_addr(vf_mac); | 4598 | if (!(adapter->vf_data[vf].flags & IGB_VF_FLAG_PF_SET_MAC)) |
4599 | random_ether_addr(vf_mac); | ||
4532 | 4600 | ||
4533 | /* process remaining reset events */ | 4601 | /* process remaining reset events */ |
4534 | igb_vf_reset(adapter, vf); | 4602 | igb_vf_reset(adapter, vf); |
@@ -4641,7 +4709,10 @@ static void igb_rcv_msg_from_vf(struct igb_adapter *adapter, u32 vf) | |||
4641 | retval = igb_set_vf_rlpml(adapter, msgbuf[1], vf); | 4709 | retval = igb_set_vf_rlpml(adapter, msgbuf[1], vf); |
4642 | break; | 4710 | break; |
4643 | case E1000_VF_SET_VLAN: | 4711 | case E1000_VF_SET_VLAN: |
4644 | retval = igb_set_vf_vlan(adapter, msgbuf, vf); | 4712 | if (adapter->vf_data[vf].pf_vlan) |
4713 | retval = -1; | ||
4714 | else | ||
4715 | retval = igb_set_vf_vlan(adapter, msgbuf, vf); | ||
4645 | break; | 4716 | break; |
4646 | default: | 4717 | default: |
4647 | dev_err(&pdev->dev, "Unhandled Msg %08x\n", msgbuf[0]); | 4718 | dev_err(&pdev->dev, "Unhandled Msg %08x\n", msgbuf[0]); |
@@ -6003,6 +6074,43 @@ static int igb_set_vf_mac(struct igb_adapter *adapter, | |||
6003 | return 0; | 6074 | return 0; |
6004 | } | 6075 | } |
6005 | 6076 | ||
6077 | static int igb_ndo_set_vf_mac(struct net_device *netdev, int vf, u8 *mac) | ||
6078 | { | ||
6079 | struct igb_adapter *adapter = netdev_priv(netdev); | ||
6080 | if (!is_valid_ether_addr(mac) || (vf >= adapter->vfs_allocated_count)) | ||
6081 | return -EINVAL; | ||
6082 | adapter->vf_data[vf].flags |= IGB_VF_FLAG_PF_SET_MAC; | ||
6083 | dev_info(&adapter->pdev->dev, "setting MAC %pM on VF %d\n", mac, vf); | ||
6084 | dev_info(&adapter->pdev->dev, "Reload the VF driver to make this" | ||
6085 | " change effective."); | ||
6086 | if (test_bit(__IGB_DOWN, &adapter->state)) { | ||
6087 | dev_warn(&adapter->pdev->dev, "The VF MAC address has been set," | ||
6088 | " but the PF device is not up.\n"); | ||
6089 | dev_warn(&adapter->pdev->dev, "Bring the PF device up before" | ||
6090 | " attempting to use the VF device.\n"); | ||
6091 | } | ||
6092 | return igb_set_vf_mac(adapter, vf, mac); | ||
6093 | } | ||
6094 | |||
6095 | static int igb_ndo_set_vf_bw(struct net_device *netdev, int vf, int tx_rate) | ||
6096 | { | ||
6097 | return -EOPNOTSUPP; | ||
6098 | } | ||
6099 | |||
6100 | static int igb_ndo_get_vf_config(struct net_device *netdev, | ||
6101 | int vf, struct ifla_vf_info *ivi) | ||
6102 | { | ||
6103 | struct igb_adapter *adapter = netdev_priv(netdev); | ||
6104 | if (vf >= adapter->vfs_allocated_count) | ||
6105 | return -EINVAL; | ||
6106 | ivi->vf = vf; | ||
6107 | memcpy(&ivi->mac, adapter->vf_data[vf].vf_mac_addresses, ETH_ALEN); | ||
6108 | ivi->tx_rate = 0; | ||
6109 | ivi->vlan = adapter->vf_data[vf].pf_vlan; | ||
6110 | ivi->qos = adapter->vf_data[vf].pf_qos; | ||
6111 | return 0; | ||
6112 | } | ||
6113 | |||
6006 | static void igb_vmm_control(struct igb_adapter *adapter) | 6114 | static void igb_vmm_control(struct igb_adapter *adapter) |
6007 | { | 6115 | { |
6008 | struct e1000_hw *hw = &adapter->hw; | 6116 | struct e1000_hw *hw = &adapter->hw; |