Commit | Line | Data |
---|---|---|
17367270 GR |
1 | /******************************************************************************* |
2 | ||
3 | Intel 10 Gigabit PCI Express Linux driver | |
4 | Copyright(c) 1999 - 2009 Intel Corporation. | |
5 | ||
6 | This program is free software; you can redistribute it and/or modify it | |
7 | under the terms and conditions of the GNU General Public License, | |
8 | version 2, as published by the Free Software Foundation. | |
9 | ||
10 | This program is distributed in the hope it will be useful, but WITHOUT | |
11 | ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or | |
12 | FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for | |
13 | more details. | |
14 | ||
15 | You should have received a copy of the GNU General Public License along with | |
16 | this program; if not, write to the Free Software Foundation, Inc., | |
17 | 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA. | |
18 | ||
19 | The full GNU General Public License is included in this distribution in | |
20 | the file called "COPYING". | |
21 | ||
22 | Contact Information: | |
23 | e1000-devel Mailing List <e1000-devel@lists.sourceforge.net> | |
24 | Intel Corporation, 5200 N.E. Elam Young Parkway, Hillsboro, OR 97124-6497 | |
25 | ||
26 | *******************************************************************************/ | |
27 | ||
28 | ||
29 | #include <linux/types.h> | |
30 | #include <linux/module.h> | |
31 | #include <linux/pci.h> | |
32 | #include <linux/netdevice.h> | |
33 | #include <linux/vmalloc.h> | |
34 | #include <linux/string.h> | |
35 | #include <linux/in.h> | |
36 | #include <linux/ip.h> | |
37 | #include <linux/tcp.h> | |
38 | #include <linux/ipv6.h> | |
39 | #ifdef NETIF_F_HW_VLAN_TX | |
40 | #include <linux/if_vlan.h> | |
41 | #endif | |
42 | ||
43 | #include "ixgbe.h" | |
44 | ||
45 | #include "ixgbe_sriov.h" | |
46 | ||
47 | int ixgbe_set_vf_multicasts(struct ixgbe_adapter *adapter, | |
48 | int entries, u16 *hash_list, u32 vf) | |
49 | { | |
50 | struct vf_data_storage *vfinfo = &adapter->vfinfo[vf]; | |
51 | int i; | |
52 | ||
53 | /* only so many hash values supported */ | |
54 | entries = min(entries, IXGBE_MAX_VF_MC_ENTRIES); | |
55 | ||
56 | /* | |
57 | * salt away the number of multi cast addresses assigned | |
58 | * to this VF for later use to restore when the PF multi cast | |
59 | * list changes | |
60 | */ | |
61 | vfinfo->num_vf_mc_hashes = entries; | |
62 | ||
63 | /* | |
64 | * VFs are limited to using the MTA hash table for their multicast | |
65 | * addresses | |
66 | */ | |
67 | for (i = 0; i < entries; i++) { | |
68 | vfinfo->vf_mc_hashes[i] = hash_list[i];; | |
69 | } | |
70 | ||
71 | /* Flush and reset the mta with the new values */ | |
72 | ixgbe_set_rx_mode(adapter->netdev); | |
73 | ||
74 | return 0; | |
75 | } | |
76 | ||
77 | void ixgbe_restore_vf_multicasts(struct ixgbe_adapter *adapter) | |
78 | { | |
79 | struct ixgbe_hw *hw = &adapter->hw; | |
80 | struct vf_data_storage *vfinfo; | |
81 | int i, j; | |
82 | u32 vector_bit; | |
83 | u32 vector_reg; | |
84 | u32 mta_reg; | |
85 | ||
86 | for (i = 0; i < adapter->num_vfs; i++) { | |
87 | vfinfo = &adapter->vfinfo[i]; | |
88 | for (j = 0; j < vfinfo->num_vf_mc_hashes; j++) { | |
89 | hw->addr_ctrl.mta_in_use++; | |
90 | vector_reg = (vfinfo->vf_mc_hashes[j] >> 5) & 0x7F; | |
91 | vector_bit = vfinfo->vf_mc_hashes[j] & 0x1F; | |
92 | mta_reg = IXGBE_READ_REG(hw, IXGBE_MTA(vector_reg)); | |
93 | mta_reg |= (1 << vector_bit); | |
94 | IXGBE_WRITE_REG(hw, IXGBE_MTA(vector_reg), mta_reg); | |
95 | } | |
96 | } | |
97 | } | |
98 | ||
99 | int ixgbe_set_vf_vlan(struct ixgbe_adapter *adapter, int add, int vid, u32 vf) | |
100 | { | |
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); | |
113 | } | |
114 | ||
115 | ||
116 | void ixgbe_set_vmolr(struct ixgbe_hw *hw, u32 vf) | |
117 | { | |
118 | u32 vmolr = IXGBE_READ_REG(hw, IXGBE_VMOLR(vf)); | |
119 | vmolr |= (IXGBE_VMOLR_AUPE | | |
120 | IXGBE_VMOLR_ROMPE | | |
121 | IXGBE_VMOLR_ROPE | | |
122 | IXGBE_VMOLR_BAM); | |
123 | IXGBE_WRITE_REG(hw, IXGBE_VMOLR(vf), vmolr); | |
124 | } | |
125 | ||
126 | inline void ixgbe_vf_reset_event(struct ixgbe_adapter *adapter, u32 vf) | |
127 | { | |
128 | struct ixgbe_hw *hw = &adapter->hw; | |
129 | ||
130 | /* reset offloads to defaults */ | |
131 | ixgbe_set_vmolr(hw, vf); | |
132 | ||
133 | ||
134 | /* reset multicast table array for vf */ | |
135 | adapter->vfinfo[vf].num_vf_mc_hashes = 0; | |
136 | ||
137 | /* Flush and reset the mta with the new values */ | |
138 | ixgbe_set_rx_mode(adapter->netdev); | |
139 | ||
140 | if (adapter->vfinfo[vf].rar > 0) { | |
141 | adapter->hw.mac.ops.clear_rar(&adapter->hw, | |
142 | adapter->vfinfo[vf].rar); | |
143 | adapter->vfinfo[vf].rar = -1; | |
144 | } | |
145 | } | |
146 | ||
147 | int ixgbe_set_vf_mac(struct ixgbe_adapter *adapter, | |
148 | int vf, unsigned char *mac_addr) | |
149 | { | |
150 | struct ixgbe_hw *hw = &adapter->hw; | |
151 | ||
152 | adapter->vfinfo[vf].rar = hw->mac.ops.set_rar(hw, vf + 1, mac_addr, | |
153 | vf, IXGBE_RAH_AV); | |
154 | if (adapter->vfinfo[vf].rar < 0) { | |
155 | DPRINTK(DRV, ERR, "Could not set MAC Filter for VF %d\n", vf); | |
156 | return -1; | |
157 | } | |
158 | ||
159 | memcpy(adapter->vfinfo[vf].vf_mac_addresses, mac_addr, 6); | |
160 | ||
161 | return 0; | |
162 | } | |
163 | ||
164 | int ixgbe_vf_configuration(struct pci_dev *pdev, unsigned int event_mask) | |
165 | { | |
166 | unsigned char vf_mac_addr[6]; | |
167 | struct net_device *netdev = pci_get_drvdata(pdev); | |
168 | struct ixgbe_adapter *adapter = netdev_priv(netdev); | |
169 | unsigned int vfn = (event_mask & 0x3f); | |
170 | ||
171 | bool enable = ((event_mask & 0x10000000U) != 0); | |
172 | ||
173 | if (enable) { | |
174 | random_ether_addr(vf_mac_addr); | |
175 | DPRINTK(PROBE, INFO, "IOV: VF %d is enabled " | |
176 | "mac %02X:%02X:%02X:%02X:%02X:%02X\n", | |
177 | vfn, | |
178 | vf_mac_addr[0], vf_mac_addr[1], vf_mac_addr[2], | |
179 | vf_mac_addr[3], vf_mac_addr[4], vf_mac_addr[5]); | |
180 | /* | |
181 | * Store away the VF "permananet" MAC address, it will ask | |
182 | * for it later. | |
183 | */ | |
184 | memcpy(adapter->vfinfo[vfn].vf_mac_addresses, vf_mac_addr, 6); | |
185 | } | |
186 | ||
187 | return 0; | |
188 | } | |
189 | ||
190 | inline void ixgbe_vf_reset_msg(struct ixgbe_adapter *adapter, u32 vf) | |
191 | { | |
192 | struct ixgbe_hw *hw = &adapter->hw; | |
193 | u32 reg; | |
194 | u32 reg_offset, vf_shift; | |
195 | ||
196 | vf_shift = vf % 32; | |
197 | reg_offset = vf / 32; | |
198 | ||
199 | /* enable transmit and receive for vf */ | |
200 | reg = IXGBE_READ_REG(hw, IXGBE_VFTE(reg_offset)); | |
201 | reg |= (reg | (1 << vf_shift)); | |
202 | IXGBE_WRITE_REG(hw, IXGBE_VFTE(reg_offset), reg); | |
203 | ||
204 | reg = IXGBE_READ_REG(hw, IXGBE_VFRE(reg_offset)); | |
205 | reg |= (reg | (1 << vf_shift)); | |
206 | IXGBE_WRITE_REG(hw, IXGBE_VFRE(reg_offset), reg); | |
207 | ||
208 | ixgbe_vf_reset_event(adapter, vf); | |
209 | } | |
210 | ||
211 | static int ixgbe_rcv_msg_from_vf(struct ixgbe_adapter *adapter, u32 vf) | |
212 | { | |
213 | u32 mbx_size = IXGBE_VFMAILBOX_SIZE; | |
214 | u32 msgbuf[mbx_size]; | |
215 | struct ixgbe_hw *hw = &adapter->hw; | |
216 | s32 retval; | |
217 | int entries; | |
218 | u16 *hash_list; | |
219 | int add, vid; | |
220 | ||
221 | retval = ixgbe_read_mbx(hw, msgbuf, mbx_size, vf); | |
222 | ||
223 | if (retval) | |
224 | printk(KERN_ERR "Error receiving message from VF\n"); | |
225 | ||
226 | /* this is a message we already processed, do nothing */ | |
227 | if (msgbuf[0] & (IXGBE_VT_MSGTYPE_ACK | IXGBE_VT_MSGTYPE_NACK)) | |
228 | return retval; | |
229 | ||
230 | /* | |
231 | * until the vf completes a virtual function reset it should not be | |
232 | * allowed to start any configuration. | |
233 | */ | |
234 | ||
235 | if (msgbuf[0] == IXGBE_VF_RESET) { | |
236 | unsigned char *vf_mac = adapter->vfinfo[vf].vf_mac_addresses; | |
237 | u8 *addr = (u8 *)(&msgbuf[1]); | |
238 | DPRINTK(PROBE, INFO, "VF Reset msg received from vf %d\n", vf); | |
239 | adapter->vfinfo[vf].clear_to_send = false; | |
240 | ixgbe_vf_reset_msg(adapter, vf); | |
241 | adapter->vfinfo[vf].clear_to_send = true; | |
242 | ||
243 | /* reply to reset with ack and vf mac address */ | |
244 | msgbuf[0] = IXGBE_VF_RESET | IXGBE_VT_MSGTYPE_ACK; | |
245 | memcpy(addr, vf_mac, IXGBE_ETH_LENGTH_OF_ADDRESS); | |
246 | /* | |
247 | * Piggyback the multicast filter type so VF can compute the | |
248 | * correct vectors | |
249 | */ | |
250 | msgbuf[3] = hw->mac.mc_filter_type; | |
251 | ixgbe_write_mbx(hw, msgbuf, IXGBE_VF_PERMADDR_MSG_LEN, vf); | |
252 | ||
253 | return retval; | |
254 | } | |
255 | ||
256 | if (!adapter->vfinfo[vf].clear_to_send) { | |
257 | msgbuf[0] |= IXGBE_VT_MSGTYPE_NACK; | |
258 | ixgbe_write_mbx(hw, msgbuf, 1, vf); | |
259 | return retval; | |
260 | } | |
261 | ||
262 | switch ((msgbuf[0] & 0xFFFF)) { | |
263 | case IXGBE_VF_SET_MAC_ADDR: | |
264 | { | |
265 | u8 *new_mac = ((u8 *)(&msgbuf[1])); | |
266 | if (is_valid_ether_addr(new_mac)) | |
267 | ixgbe_set_vf_mac(adapter, vf, new_mac); | |
268 | else | |
269 | retval = -1; | |
270 | } | |
271 | break; | |
272 | case IXGBE_VF_SET_MULTICAST: | |
273 | entries = (msgbuf[0] & IXGBE_VT_MSGINFO_MASK) | |
274 | >> IXGBE_VT_MSGINFO_SHIFT; | |
275 | hash_list = (u16 *)&msgbuf[1]; | |
276 | retval = ixgbe_set_vf_multicasts(adapter, entries, | |
277 | hash_list, vf); | |
278 | break; | |
279 | case IXGBE_VF_SET_LPE: | |
280 | WARN_ON((msgbuf[0] & 0xFFFF) == IXGBE_VF_SET_LPE); | |
281 | break; | |
282 | case IXGBE_VF_SET_VLAN: | |
283 | add = (msgbuf[0] & IXGBE_VT_MSGINFO_MASK) | |
284 | >> IXGBE_VT_MSGINFO_SHIFT; | |
285 | vid = (msgbuf[1] & IXGBE_VLVF_VLANID_MASK); | |
286 | retval = ixgbe_set_vf_vlan(adapter, add, vid, vf); | |
287 | break; | |
288 | default: | |
289 | DPRINTK(DRV, ERR, "Unhandled Msg %8.8x\n", msgbuf[0]); | |
290 | retval = IXGBE_ERR_MBX; | |
291 | break; | |
292 | } | |
293 | ||
294 | /* notify the VF of the results of what it sent us */ | |
295 | if (retval) | |
296 | msgbuf[0] |= IXGBE_VT_MSGTYPE_NACK; | |
297 | else | |
298 | msgbuf[0] |= IXGBE_VT_MSGTYPE_ACK; | |
299 | ||
300 | msgbuf[0] |= IXGBE_VT_MSGTYPE_CTS; | |
301 | ||
302 | ixgbe_write_mbx(hw, msgbuf, 1, vf); | |
303 | ||
304 | return retval; | |
305 | } | |
306 | ||
307 | static void ixgbe_rcv_ack_from_vf(struct ixgbe_adapter *adapter, u32 vf) | |
308 | { | |
309 | struct ixgbe_hw *hw = &adapter->hw; | |
310 | u32 msg = IXGBE_VT_MSGTYPE_NACK; | |
311 | ||
312 | /* if device isn't clear to send it shouldn't be reading either */ | |
313 | if (!adapter->vfinfo[vf].clear_to_send) | |
314 | ixgbe_write_mbx(hw, &msg, 1, vf); | |
315 | } | |
316 | ||
317 | void ixgbe_msg_task(struct ixgbe_adapter *adapter) | |
318 | { | |
319 | struct ixgbe_hw *hw = &adapter->hw; | |
320 | u32 vf; | |
321 | ||
322 | for (vf = 0; vf < adapter->num_vfs; vf++) { | |
323 | /* process any reset requests */ | |
324 | if (!ixgbe_check_for_rst(hw, vf)) | |
325 | ixgbe_vf_reset_event(adapter, vf); | |
326 | ||
327 | /* process any messages pending */ | |
328 | if (!ixgbe_check_for_msg(hw, vf)) | |
329 | ixgbe_rcv_msg_from_vf(adapter, vf); | |
330 | ||
331 | /* process any acks */ | |
332 | if (!ixgbe_check_for_ack(hw, vf)) | |
333 | ixgbe_rcv_ack_from_vf(adapter, vf); | |
334 | } | |
335 | } | |
336 |