aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/net/ixgbe/ixgbe_sriov.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/net/ixgbe/ixgbe_sriov.c')
-rw-r--r--drivers/net/ixgbe/ixgbe_sriov.c137
1 files changed, 117 insertions, 20 deletions
diff --git a/drivers/net/ixgbe/ixgbe_sriov.c b/drivers/net/ixgbe/ixgbe_sriov.c
index d4cd20f30199..f6cee94ec8e8 100644
--- a/drivers/net/ixgbe/ixgbe_sriov.c
+++ b/drivers/net/ixgbe/ixgbe_sriov.c
@@ -48,7 +48,11 @@ int ixgbe_set_vf_multicasts(struct ixgbe_adapter *adapter,
48 int entries, u16 *hash_list, u32 vf) 48 int entries, u16 *hash_list, u32 vf)
49{ 49{
50 struct vf_data_storage *vfinfo = &adapter->vfinfo[vf]; 50 struct vf_data_storage *vfinfo = &adapter->vfinfo[vf];
51 struct ixgbe_hw *hw = &adapter->hw;
51 int i; 52 int i;
53 u32 vector_bit;
54 u32 vector_reg;
55 u32 mta_reg;
52 56
53 /* only so many hash values supported */ 57 /* only so many hash values supported */
54 entries = min(entries, IXGBE_MAX_VF_MC_ENTRIES); 58 entries = min(entries, IXGBE_MAX_VF_MC_ENTRIES);
@@ -68,8 +72,13 @@ int ixgbe_set_vf_multicasts(struct ixgbe_adapter *adapter,
68 vfinfo->vf_mc_hashes[i] = hash_list[i];; 72 vfinfo->vf_mc_hashes[i] = hash_list[i];;
69 } 73 }
70 74
71 /* Flush and reset the mta with the new values */ 75 for (i = 0; i < vfinfo->num_vf_mc_hashes; i++) {
72 ixgbe_set_rx_mode(adapter->netdev); 76 vector_reg = (vfinfo->vf_mc_hashes[i] >> 5) & 0x7F;
77 vector_bit = vfinfo->vf_mc_hashes[i] & 0x1F;
78 mta_reg = IXGBE_READ_REG(hw, IXGBE_MTA(vector_reg));
79 mta_reg |= (1 << vector_bit);
80 IXGBE_WRITE_REG(hw, IXGBE_MTA(vector_reg), mta_reg);
81 }
73 82
74 return 0; 83 return 0;
75} 84}
@@ -98,38 +107,51 @@ void ixgbe_restore_vf_multicasts(struct ixgbe_adapter *adapter)
98 107
99int ixgbe_set_vf_vlan(struct ixgbe_adapter *adapter, int add, int vid, u32 vf) 108int ixgbe_set_vf_vlan(struct ixgbe_adapter *adapter, int add, int vid, u32 vf)
100{ 109{
101 u32 ctrl;
102
103 /* Check if global VLAN already set, if not set it */
104 ctrl = IXGBE_READ_REG(&adapter->hw, IXGBE_VLNCTRL);
105 if (!(ctrl & IXGBE_VLNCTRL_VFE)) {
106 /* enable VLAN tag insert/strip */
107 ctrl |= IXGBE_VLNCTRL_VFE;
108 ctrl &= ~IXGBE_VLNCTRL_CFIEN;
109 IXGBE_WRITE_REG(&adapter->hw, IXGBE_VLNCTRL, ctrl);
110 }
111
112 return adapter->hw.mac.ops.set_vfta(&adapter->hw, vid, vf, (bool)add); 110 return adapter->hw.mac.ops.set_vfta(&adapter->hw, vid, vf, (bool)add);
113} 111}
114 112
115 113
116void ixgbe_set_vmolr(struct ixgbe_hw *hw, u32 vf) 114void ixgbe_set_vmolr(struct ixgbe_hw *hw, u32 vf, bool aupe)
117{ 115{
118 u32 vmolr = IXGBE_READ_REG(hw, IXGBE_VMOLR(vf)); 116 u32 vmolr = IXGBE_READ_REG(hw, IXGBE_VMOLR(vf));
119 vmolr |= (IXGBE_VMOLR_AUPE | 117 vmolr |= (IXGBE_VMOLR_ROMPE |
120 IXGBE_VMOLR_ROMPE |
121 IXGBE_VMOLR_ROPE | 118 IXGBE_VMOLR_ROPE |
122 IXGBE_VMOLR_BAM); 119 IXGBE_VMOLR_BAM);
120 if (aupe)
121 vmolr |= IXGBE_VMOLR_AUPE;
122 else
123 vmolr &= ~IXGBE_VMOLR_AUPE;
123 IXGBE_WRITE_REG(hw, IXGBE_VMOLR(vf), vmolr); 124 IXGBE_WRITE_REG(hw, IXGBE_VMOLR(vf), vmolr);
124} 125}
125 126
127static void ixgbe_set_vmvir(struct ixgbe_adapter *adapter, u32 vid, u32 vf)
128{
129 struct ixgbe_hw *hw = &adapter->hw;
130
131 if (vid)
132 IXGBE_WRITE_REG(hw, IXGBE_VMVIR(vf),
133 (vid | IXGBE_VMVIR_VLANA_DEFAULT));
134 else
135 IXGBE_WRITE_REG(hw, IXGBE_VMVIR(vf), 0);
136}
137
126inline void ixgbe_vf_reset_event(struct ixgbe_adapter *adapter, u32 vf) 138inline void ixgbe_vf_reset_event(struct ixgbe_adapter *adapter, u32 vf)
127{ 139{
128 struct ixgbe_hw *hw = &adapter->hw; 140 struct ixgbe_hw *hw = &adapter->hw;
129 141
130 /* reset offloads to defaults */ 142 /* reset offloads to defaults */
131 ixgbe_set_vmolr(hw, vf); 143 if (adapter->vfinfo[vf].pf_vlan) {
132 144 ixgbe_set_vf_vlan(adapter, true,
145 adapter->vfinfo[vf].pf_vlan, vf);
146 ixgbe_set_vmvir(adapter,
147 (adapter->vfinfo[vf].pf_vlan |
148 (adapter->vfinfo[vf].pf_qos <<
149 VLAN_PRIO_SHIFT)), vf);
150 ixgbe_set_vmolr(hw, vf, false);
151 } else {
152 ixgbe_set_vmvir(adapter, 0, vf);
153 ixgbe_set_vmolr(hw, vf, true);
154 }
133 155
134 /* reset multicast table array for vf */ 156 /* reset multicast table array for vf */
135 adapter->vfinfo[vf].num_vf_mc_hashes = 0; 157 adapter->vfinfo[vf].num_vf_mc_hashes = 0;
@@ -263,10 +285,12 @@ static int ixgbe_rcv_msg_from_vf(struct ixgbe_adapter *adapter, u32 vf)
263 case IXGBE_VF_SET_MAC_ADDR: 285 case IXGBE_VF_SET_MAC_ADDR:
264 { 286 {
265 u8 *new_mac = ((u8 *)(&msgbuf[1])); 287 u8 *new_mac = ((u8 *)(&msgbuf[1]));
266 if (is_valid_ether_addr(new_mac)) 288 if (is_valid_ether_addr(new_mac) &&
289 !adapter->vfinfo[vf].pf_set_mac)
267 ixgbe_set_vf_mac(adapter, vf, new_mac); 290 ixgbe_set_vf_mac(adapter, vf, new_mac);
268 else 291 else
269 retval = -1; 292 ixgbe_set_vf_mac(adapter,
293 vf, adapter->vfinfo[vf].vf_mac_addresses);
270 } 294 }
271 break; 295 break;
272 case IXGBE_VF_SET_MULTICAST: 296 case IXGBE_VF_SET_MULTICAST:
@@ -360,3 +384,76 @@ void ixgbe_ping_all_vfs(struct ixgbe_adapter *adapter)
360 } 384 }
361} 385}
362 386
387int ixgbe_ndo_set_vf_mac(struct net_device *netdev, int vf, u8 *mac)
388{
389 struct ixgbe_adapter *adapter = netdev_priv(netdev);
390 if (!is_valid_ether_addr(mac) || (vf >= adapter->num_vfs))
391 return -EINVAL;
392 adapter->vfinfo[vf].pf_set_mac = true;
393 dev_info(&adapter->pdev->dev, "setting MAC %pM on VF %d\n", mac, vf);
394 dev_info(&adapter->pdev->dev, "Reload the VF driver to make this"
395 " change effective.");
396 if (test_bit(__IXGBE_DOWN, &adapter->state)) {
397 dev_warn(&adapter->pdev->dev, "The VF MAC address has been set,"
398 " but the PF device is not up.\n");
399 dev_warn(&adapter->pdev->dev, "Bring the PF device up before"
400 " attempting to use the VF device.\n");
401 }
402 return ixgbe_set_vf_mac(adapter, vf, mac);
403}
404
405int ixgbe_ndo_set_vf_vlan(struct net_device *netdev, int vf, u16 vlan, u8 qos)
406{
407 int err = 0;
408 struct ixgbe_adapter *adapter = netdev_priv(netdev);
409
410 if ((vf >= adapter->num_vfs) || (vlan > 4095) || (qos > 7))
411 return -EINVAL;
412 if (vlan || qos) {
413 err = ixgbe_set_vf_vlan(adapter, true, vlan, vf);
414 if (err)
415 goto out;
416 ixgbe_set_vmvir(adapter, vlan | (qos << VLAN_PRIO_SHIFT), vf);
417 ixgbe_set_vmolr(&adapter->hw, vf, false);
418 adapter->vfinfo[vf].pf_vlan = vlan;
419 adapter->vfinfo[vf].pf_qos = qos;
420 dev_info(&adapter->pdev->dev,
421 "Setting VLAN %d, QOS 0x%x on VF %d\n", vlan, qos, vf);
422 if (test_bit(__IXGBE_DOWN, &adapter->state)) {
423 dev_warn(&adapter->pdev->dev,
424 "The VF VLAN has been set,"
425 " but the PF device is not up.\n");
426 dev_warn(&adapter->pdev->dev,
427 "Bring the PF device up before"
428 " attempting to use the VF device.\n");
429 }
430 } else {
431 err = ixgbe_set_vf_vlan(adapter, false,
432 adapter->vfinfo[vf].pf_vlan, vf);
433 ixgbe_set_vmvir(adapter, vlan, vf);
434 ixgbe_set_vmolr(&adapter->hw, vf, true);
435 adapter->vfinfo[vf].pf_vlan = 0;
436 adapter->vfinfo[vf].pf_qos = 0;
437 }
438out:
439 return err;
440}
441
442int ixgbe_ndo_set_vf_bw(struct net_device *netdev, int vf, int tx_rate)
443{
444 return -EOPNOTSUPP;
445}
446
447int ixgbe_ndo_get_vf_config(struct net_device *netdev,
448 int vf, struct ifla_vf_info *ivi)
449{
450 struct ixgbe_adapter *adapter = netdev_priv(netdev);
451 if (vf >= adapter->num_vfs)
452 return -EINVAL;
453 ivi->vf = vf;
454 memcpy(&ivi->mac, adapter->vfinfo[vf].vf_mac_addresses, ETH_ALEN);
455 ivi->tx_rate = 0;
456 ivi->vlan = adapter->vfinfo[vf].pf_vlan;
457 ivi->qos = adapter->vfinfo[vf].pf_qos;
458 return 0;
459}