1 /*
2 * Copyright (C) 2015 Michael Brown <mbrown@fensystems.co.uk>.
3 *
4 * This program is free software; you can redistribute it and/or
5 * modify it under the terms of the GNU General Public License as
6 * published by the Free Software Foundation; either version 2 of the
7 * License, or (at your option) any later version.
8 *
9 * This program is distributed in the hope that it will be useful, but
10 * WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12 * General Public License for more details.
13 *
14 * You should have received a copy of the GNU General Public License
15 * along with this program; if not, write to the Free Software
16 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
17 * 02110-1301, USA.
18 *
19 * You can also choose to distribute this program under the terms of
20 * the Unmodified Binary Distribution Licence (as given in the file
21 * COPYING.UBDL), provided that you have satisfied its requirements.
22 */
23
24 FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL );
25
26 #include <string.h>
27 #include <unistd.h>
28 #include <errno.h>
29 #include <ipxe/io.h>
30 #include <ipxe/pci.h>
31 #include <ipxe/netdevice.h>
32 #include <ipxe/ethernet.h>
33 #include "intelx.h"
34 #include "intelxvf.h"
35
36 /** @file
37 *
38 * Intel 10 Gigabit Ethernet virtual function network card driver
39 *
40 */
41
42 /******************************************************************************
43 *
44 * Diagnostics
45 *
46 ******************************************************************************
47 */
48
49 /**
50 * Dump statistics
51 *
52 * @v intel Intel device
53 */
54 static __attribute__ (( unused )) void
intelxvf_stats(struct intel_nic * intel)55 intelxvf_stats ( struct intel_nic *intel ) {
56
57 DBGC ( intel, "INTEL %p TX %d (%#x%08x) RX %d (%#x%08x) multi %d\n",
58 intel, readl ( intel->regs + INTELXVF_GPTC ),
59 readl ( intel->regs + INTELXVF_GOTCH ),
60 readl ( intel->regs + INTELXVF_GOTCL ),
61 readl ( intel->regs + INTELXVF_GPRC ),
62 readl ( intel->regs + INTELXVF_GORCH ),
63 readl ( intel->regs + INTELXVF_GORCL ),
64 readl ( intel->regs + INTELXVF_MPRC ) );
65 }
66
67 /******************************************************************************
68 *
69 * Device reset
70 *
71 ******************************************************************************
72 */
73
74 /**
75 * Reset hardware
76 *
77 * @v intel Intel device
78 */
intelxvf_reset(struct intel_nic * intel)79 static void intelxvf_reset ( struct intel_nic *intel ) {
80
81 /* Perform a function-level reset */
82 writel ( INTELXVF_CTRL_RST, intel->regs + INTELXVF_CTRL );
83 }
84
85 /******************************************************************************
86 *
87 * Link state
88 *
89 ******************************************************************************
90 */
91
92 /**
93 * Check link state
94 *
95 * @v netdev Network device
96 */
intelxvf_check_link(struct net_device * netdev)97 static void intelxvf_check_link ( struct net_device *netdev ) {
98 struct intel_nic *intel = netdev->priv;
99 uint32_t links;
100
101 /* Read link status */
102 links = readl ( intel->regs + INTELXVF_LINKS );
103 DBGC ( intel, "INTEL %p link status is %08x\n", intel, links );
104
105 /* Update network device */
106 if ( links & INTELXVF_LINKS_UP ) {
107 netdev_link_up ( netdev );
108 } else {
109 netdev_link_down ( netdev );
110 }
111 }
112
113 /******************************************************************************
114 *
115 * Mailbox messages
116 *
117 ******************************************************************************
118 */
119
120 /**
121 * Send negotiate API version message
122 *
123 * @v intel Intel device
124 * @v version Requested version
125 * @ret rc Return status code
126 */
intelxvf_mbox_version(struct intel_nic * intel,unsigned int version)127 static int intelxvf_mbox_version ( struct intel_nic *intel,
128 unsigned int version ) {
129 union intelvf_msg msg;
130 int rc;
131
132 /* Send set MTU message */
133 memset ( &msg, 0, sizeof ( msg ) );
134 msg.hdr = INTELXVF_MSG_TYPE_VERSION;
135 msg.version.version = version;
136 if ( ( rc = intelvf_mbox_msg ( intel, &msg ) ) != 0 ) {
137 DBGC ( intel, "INTEL %p negotiate API version failed: %s\n",
138 intel, strerror ( rc ) );
139 return rc;
140 }
141
142 /* Check response */
143 if ( ( msg.hdr & INTELVF_MSG_TYPE_MASK ) != INTELXVF_MSG_TYPE_VERSION ){
144 DBGC ( intel, "INTEL %p negotiate API version unexpected "
145 "response:\n", intel );
146 DBGC_HDA ( intel, 0, &msg, sizeof ( msg ) );
147 return -EPROTO;
148 }
149
150 /* Check that this version is supported */
151 if ( ! ( msg.hdr & INTELVF_MSG_ACK ) ) {
152 DBGC ( intel, "INTEL %p negotiate API version failed\n",
153 intel );
154 return -EPERM;
155 }
156
157 return 0;
158 }
159
160 /**
161 * Get queue configuration
162 *
163 * @v intel Intel device
164 * @v vlan_thing VLAN hand-waving thing to fill in
165 * @ret rc Return status code
166 */
intelxvf_mbox_queues(struct intel_nic * intel,int * vlan_thing)167 static int intelxvf_mbox_queues ( struct intel_nic *intel, int *vlan_thing ) {
168 union intelvf_msg msg;
169 int rc;
170
171 /* Send queue configuration message */
172 memset ( &msg, 0, sizeof ( msg ) );
173 msg.hdr = INTELVF_MSG_TYPE_GET_QUEUES;
174 if ( ( rc = intelvf_mbox_msg ( intel, &msg ) ) != 0 ) {
175 DBGC ( intel, "INTEL %p get queue configuration failed: %s\n",
176 intel, strerror ( rc ) );
177 return rc;
178 }
179
180 /* Check response */
181 if ( ( msg.hdr & INTELVF_MSG_TYPE_MASK ) !=INTELVF_MSG_TYPE_GET_QUEUES){
182 DBGC ( intel, "INTEL %p get queue configuration unexpected "
183 "response:\n", intel );
184 DBGC_HDA ( intel, 0, &msg, sizeof ( msg ) );
185 return -EPROTO;
186 }
187
188 /* Check that we were allowed to get the queue configuration */
189 if ( ! ( msg.hdr & INTELVF_MSG_ACK ) ) {
190 DBGC ( intel, "INTEL %p get queue configuration refused\n",
191 intel );
192 return -EPERM;
193 }
194
195 /* Extract VLAN hand-waving thing */
196 *vlan_thing = msg.queues.vlan_thing;
197
198 return 0;
199 }
200
201 /******************************************************************************
202 *
203 * Network device interface
204 *
205 ******************************************************************************
206 */
207
208 /**
209 * Open network device
210 *
211 * @v netdev Network device
212 * @ret rc Return status code
213 */
intelxvf_open(struct net_device * netdev)214 static int intelxvf_open ( struct net_device *netdev ) {
215 struct intel_nic *intel = netdev->priv;
216 uint32_t rxdctl;
217 uint32_t srrctl;
218 uint32_t dca_rxctrl;
219 unsigned int i;
220 int vlan_thing;
221 int rc;
222
223 /* Reset the function */
224 intelxvf_reset ( intel );
225
226 /* Notify PF that reset is complete */
227 if ( ( rc = intelvf_mbox_reset ( intel, NULL ) ) != 0 ) {
228 DBGC ( intel, "INTEL %p could not reset: %s\n",
229 intel, strerror ( rc ) );
230 goto err_mbox_reset;
231 }
232
233 /* Negotiate API version 1.1. If we do not negotiate at least
234 * this version, then the RX datapath will remain disabled if
235 * the PF has jumbo frames enabled.
236 *
237 * Ignore failures, since the host may not actually support
238 * v1.1.
239 */
240 intelxvf_mbox_version ( intel, INTELXVF_MSG_VERSION_1_1 );
241
242 /* Set MAC address */
243 if ( ( rc = intelvf_mbox_set_mac ( intel, netdev->ll_addr ) ) != 0 ) {
244 DBGC ( intel, "INTEL %p could not set MAC address: %s\n",
245 intel, strerror ( rc ) );
246 goto err_mbox_set_mac;
247 }
248
249 /* Set MTU */
250 if ( ( rc = intelvf_mbox_set_mtu ( intel, netdev->max_pkt_len ) ) != 0){
251 DBGC ( intel, "INTEL %p could not set MTU %zd: %s\n",
252 intel, netdev->max_pkt_len, strerror ( rc ) );
253 goto err_mbox_set_mtu;
254 }
255
256 /* Reset all descriptor rings */
257 for ( i = 0 ; i < INTELXVF_NUM_RINGS ; i++ ) {
258 intel_reset_ring ( intel, INTELXVF_TD ( i ) );
259 intel_reset_ring ( intel, INTELXVF_RD ( i ) );
260 }
261
262 /* Reset packet split receive type register */
263 writel ( 0, intel->regs + INTELXVF_PSRTYPE );
264
265 /* Get queue configuration. Ignore failures, since the host
266 * may not support this message.
267 */
268 vlan_thing = 0;
269 intelxvf_mbox_queues ( intel, &vlan_thing );
270 if ( vlan_thing ) {
271 DBGC ( intel, "INTEL %p stripping VLAN tags (thing=%d)\n",
272 intel, vlan_thing );
273 rxdctl = readl ( intel->regs + INTELXVF_RD(0) + INTEL_xDCTL );
274 rxdctl |= INTELX_RXDCTL_VME;
275 writel ( rxdctl, intel->regs + INTELXVF_RD(0) + INTEL_xDCTL );
276 }
277
278 /* Create transmit descriptor ring */
279 if ( ( rc = intel_create_ring ( intel, &intel->tx ) ) != 0 )
280 goto err_create_tx;
281
282 /* Create receive descriptor ring */
283 if ( ( rc = intel_create_ring ( intel, &intel->rx ) ) != 0 )
284 goto err_create_rx;
285
286 /* Allocate interrupt vectors */
287 writel ( ( INTELXVF_IVAR_RX0_DEFAULT | INTELXVF_IVAR_RX0_VALID |
288 INTELXVF_IVAR_TX0_DEFAULT | INTELXVF_IVAR_TX0_VALID ),
289 intel->regs + INTELXVF_IVAR );
290 writel ( ( INTELXVF_IVARM_MBOX_DEFAULT | INTELXVF_IVARM_MBOX_VALID ),
291 intel->regs + INTELXVF_IVARM );
292
293 /* Configure receive buffer sizes and set receive descriptor type */
294 srrctl = readl ( intel->regs + INTELXVF_SRRCTL );
295 srrctl &= ~( INTELXVF_SRRCTL_BSIZE_MASK |
296 INTELXVF_SRRCTL_BHDRSIZE_MASK |
297 INTELXVF_SRRCTL_DESCTYPE_MASK );
298 srrctl |= ( INTELXVF_SRRCTL_BSIZE_DEFAULT |
299 INTELXVF_SRRCTL_BHDRSIZE_DEFAULT |
300 INTELXVF_SRRCTL_DESCTYPE_DEFAULT |
301 INTELXVF_SRRCTL_DROP_EN );
302 writel ( srrctl, intel->regs + INTELXVF_SRRCTL );
303
304 /* Clear "must-be-zero" bit for direct cache access (DCA). We
305 * leave DCA disabled anyway, but if we do not clear this bit
306 * then the received packets contain garbage data.
307 */
308 dca_rxctrl = readl ( intel->regs + INTELXVF_DCA_RXCTRL );
309 dca_rxctrl &= ~INTELXVF_DCA_RXCTRL_MUST_BE_ZERO;
310 writel ( dca_rxctrl, intel->regs + INTELXVF_DCA_RXCTRL );
311
312 /* Fill receive ring */
313 intel_refill_rx ( intel );
314
315 /* Update link state */
316 intelxvf_check_link ( netdev );
317
318 return 0;
319
320 intel_destroy_ring ( intel, &intel->rx );
321 err_create_rx:
322 intel_destroy_ring ( intel, &intel->tx );
323 err_create_tx:
324 err_mbox_set_mtu:
325 err_mbox_set_mac:
326 err_mbox_reset:
327 intelxvf_reset ( intel );
328 return rc;
329 }
330
331 /**
332 * Close network device
333 *
334 * @v netdev Network device
335 */
intelxvf_close(struct net_device * netdev)336 static void intelxvf_close ( struct net_device *netdev ) {
337 struct intel_nic *intel = netdev->priv;
338
339 /* Destroy receive descriptor ring */
340 intel_destroy_ring ( intel, &intel->rx );
341
342 /* Discard any unused receive buffers */
343 intel_empty_rx ( intel );
344
345 /* Destroy transmit descriptor ring */
346 intel_destroy_ring ( intel, &intel->tx );
347
348 /* Reset the function */
349 intelxvf_reset ( intel );
350 }
351
352 /**
353 * Poll for completed and received packets
354 *
355 * @v netdev Network device
356 */
intelxvf_poll(struct net_device * netdev)357 static void intelxvf_poll ( struct net_device *netdev ) {
358 struct intel_nic *intel = netdev->priv;
359 uint32_t eicr;
360 int rc;
361
362 /* Check for and acknowledge interrupts */
363 eicr = readl ( intel->regs + INTELXVF_EICR );
364 if ( ! eicr )
365 return;
366
367 /* Poll for TX completions, if applicable */
368 if ( eicr & INTELXVF_EIRQ_TX0 )
369 intel_poll_tx ( netdev );
370
371 /* Poll for RX completions, if applicable */
372 if ( eicr & INTELXVF_EIRQ_RX0 )
373 intel_poll_rx ( netdev );
374
375 /* Poll for mailbox messages, if applicable */
376 if ( eicr & INTELXVF_EIRQ_MBOX ) {
377
378 /* Poll mailbox */
379 if ( ( rc = intelvf_mbox_poll ( intel ) ) != 0 ) {
380 DBGC ( intel, "INTEL %p mailbox poll failed!\n",
381 intel );
382 netdev_rx_err ( netdev, NULL, rc );
383 }
384
385 /* Update link state */
386 intelxvf_check_link ( netdev );
387 }
388
389 /* Refill RX ring */
390 intel_refill_rx ( intel );
391 }
392
393 /**
394 * Enable or disable interrupts
395 *
396 * @v netdev Network device
397 * @v enable Interrupts should be enabled
398 */
intelxvf_irq(struct net_device * netdev,int enable)399 static void intelxvf_irq ( struct net_device *netdev, int enable ) {
400 struct intel_nic *intel = netdev->priv;
401 uint32_t mask;
402
403 mask = ( INTELXVF_EIRQ_MBOX | INTELXVF_EIRQ_TX0 | INTELXVF_EIRQ_RX0 );
404 if ( enable ) {
405 writel ( mask, intel->regs + INTELXVF_EIMS );
406 } else {
407 writel ( mask, intel->regs + INTELXVF_EIMC );
408 }
409 }
410
411 /** Network device operations */
412 static struct net_device_operations intelxvf_operations = {
413 .open = intelxvf_open,
414 .close = intelxvf_close,
415 .transmit = intel_transmit,
416 .poll = intelxvf_poll,
417 .irq = intelxvf_irq,
418 };
419
420 /******************************************************************************
421 *
422 * PCI interface
423 *
424 ******************************************************************************
425 */
426
427 /**
428 * Probe PCI device
429 *
430 * @v pci PCI device
431 * @ret rc Return status code
432 */
intelxvf_probe(struct pci_device * pci)433 static int intelxvf_probe ( struct pci_device *pci ) {
434 struct net_device *netdev;
435 struct intel_nic *intel;
436 int rc;
437
438 /* Allocate and initialise net device */
439 netdev = alloc_etherdev ( sizeof ( *intel ) );
440 if ( ! netdev ) {
441 rc = -ENOMEM;
442 goto err_alloc;
443 }
444 netdev_init ( netdev, &intelxvf_operations );
445 intel = netdev->priv;
446 pci_set_drvdata ( pci, netdev );
447 netdev->dev = &pci->dev;
448 memset ( intel, 0, sizeof ( *intel ) );
449 intel_init_mbox ( &intel->mbox, INTELXVF_MBCTRL, INTELXVF_MBMEM );
450 intel_init_ring ( &intel->tx, INTEL_NUM_TX_DESC, INTELXVF_TD(0),
451 intel_describe_tx_adv );
452 intel_init_ring ( &intel->rx, INTEL_NUM_RX_DESC, INTELXVF_RD(0),
453 intel_describe_rx );
454
455 /* Fix up PCI device */
456 adjust_pci_device ( pci );
457
458 /* Map registers */
459 intel->regs = ioremap ( pci->membase, INTELVF_BAR_SIZE );
460 if ( ! intel->regs ) {
461 rc = -ENODEV;
462 goto err_ioremap;
463 }
464
465 /* Reset the function */
466 intelxvf_reset ( intel );
467
468 /* Send reset message and fetch MAC address */
469 if ( ( rc = intelvf_mbox_reset ( intel, netdev->hw_addr ) ) != 0 ) {
470 DBGC ( intel, "INTEL %p could not reset and fetch MAC: %s\n",
471 intel, strerror ( rc ) );
472 goto err_mbox_reset;
473 }
474
475 /* Reset the function (since we will not respond to Control
476 * ("ping") mailbox messages until the network device is opened.
477 */
478 intelxvf_reset ( intel );
479
480 /* Register network device */
481 if ( ( rc = register_netdev ( netdev ) ) != 0 )
482 goto err_register_netdev;
483
484 /* Set initial link state */
485 intelxvf_check_link ( netdev );
486
487 return 0;
488
489 unregister_netdev ( netdev );
490 err_register_netdev:
491 err_mbox_reset:
492 intelxvf_reset ( intel );
493 iounmap ( intel->regs );
494 err_ioremap:
495 netdev_nullify ( netdev );
496 netdev_put ( netdev );
497 err_alloc:
498 return rc;
499 }
500
501 /**
502 * Remove PCI device
503 *
504 * @v pci PCI device
505 */
intelxvf_remove(struct pci_device * pci)506 static void intelxvf_remove ( struct pci_device *pci ) {
507 struct net_device *netdev = pci_get_drvdata ( pci );
508 struct intel_nic *intel = netdev->priv;
509
510 /* Unregister network device */
511 unregister_netdev ( netdev );
512
513 /* Reset the NIC */
514 intelxvf_reset ( intel );
515
516 /* Free network device */
517 iounmap ( intel->regs );
518 netdev_nullify ( netdev );
519 netdev_put ( netdev );
520 }
521
522 /** PCI device IDs */
523 static struct pci_device_id intelxvf_nics[] = {
524 PCI_ROM ( 0x8086, 0x10ed, "82599-vf", "82599 VF", 0 ),
525 PCI_ROM ( 0x8086, 0x1515, "x540-vf", "X540 VF", 0 ),
526 PCI_ROM ( 0x8086, 0x1565, "x550-vf", "X550 VF", 0 ),
527 PCI_ROM ( 0x8086, 0x15a8, "x552-vf", "X552 VF", 0 ),
528 };
529
530 /** PCI driver */
531 struct pci_driver intelxvf_driver __pci_driver = {
532 .ids = intelxvf_nics,
533 .id_count = ( sizeof ( intelxvf_nics ) / sizeof ( intelxvf_nics[0] ) ),
534 .probe = intelxvf_probe,
535 .remove = intelxvf_remove,
536 };
537