2 * Copyright (C) 2015 Michael Brown <mbrown@fensystems.co.uk>.
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.
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.
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
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.
24 FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL );
31 #include <ipxe/netdevice.h>
32 #include <ipxe/ethernet.h>
37 * Intel 10 Gigabit Ethernet virtual function network card driver
41 /******************************************************************************
45 ******************************************************************************
51 * @v intel Intel device
53 static __attribute__ (( unused )) void
54 intelxvf_stats ( struct intel_nic *intel ) {
56 DBGC ( intel, "INTEL %p TX %d (%#x%08x) RX %d (%#x%08x) multi %d\n",
57 intel, readl ( intel->regs + INTELXVF_GPTC ),
58 readl ( intel->regs + INTELXVF_GOTCH ),
59 readl ( intel->regs + INTELXVF_GOTCL ),
60 readl ( intel->regs + INTELXVF_GPRC ),
61 readl ( intel->regs + INTELXVF_GORCH ),
62 readl ( intel->regs + INTELXVF_GORCL ),
63 readl ( intel->regs + INTELXVF_MPRC ) );
66 /******************************************************************************
70 ******************************************************************************
76 * @v intel Intel device
78 static void intelxvf_reset ( struct intel_nic *intel ) {
80 /* Perform a function-level reset */
81 writel ( INTELXVF_CTRL_RST, intel->regs + INTELXVF_CTRL );
84 /******************************************************************************
88 ******************************************************************************
94 * @v netdev Network device
96 static void intelxvf_check_link ( struct net_device *netdev ) {
97 struct intel_nic *intel = netdev->priv;
100 /* Read link status */
101 links = readl ( intel->regs + INTELXVF_LINKS );
102 DBGC ( intel, "INTEL %p link status is %08x\n", intel, links );
104 /* Update network device */
105 if ( links & INTELXVF_LINKS_UP ) {
106 netdev_link_up ( netdev );
108 netdev_link_down ( netdev );
112 /******************************************************************************
116 ******************************************************************************
120 * Send negotiate API version message
122 * @v intel Intel device
123 * @v version Requested version
124 * @ret rc Return status code
126 static int intelxvf_mbox_version ( struct intel_nic *intel,
127 unsigned int version ) {
128 union intelvf_msg msg;
131 /* Send set MTU message */
132 memset ( &msg, 0, sizeof ( msg ) );
133 msg.hdr = INTELXVF_MSG_TYPE_VERSION;
134 msg.version.version = version;
135 if ( ( rc = intelvf_mbox_msg ( intel, &msg ) ) != 0 ) {
136 DBGC ( intel, "INTEL %p negotiate API version failed: %s\n",
137 intel, strerror ( rc ) );
142 if ( ( msg.hdr & INTELVF_MSG_TYPE_MASK ) != INTELXVF_MSG_TYPE_VERSION ){
143 DBGC ( intel, "INTEL %p negotiate API version unexpected "
144 "response:\n", intel );
145 DBGC_HDA ( intel, 0, &msg, sizeof ( msg ) );
149 /* Check that this version is supported */
150 if ( ! ( msg.hdr & INTELVF_MSG_ACK ) ) {
151 DBGC ( intel, "INTEL %p negotiate API version failed\n",
159 /******************************************************************************
161 * Network device interface
163 ******************************************************************************
167 * Open network device
169 * @v netdev Network device
170 * @ret rc Return status code
172 static int intelxvf_open ( struct net_device *netdev ) {
173 struct intel_nic *intel = netdev->priv;
178 /* Reset the function */
179 intelxvf_reset ( intel );
181 /* Notify PF that reset is complete */
182 if ( ( rc = intelvf_mbox_reset ( intel, NULL ) ) != 0 ) {
183 DBGC ( intel, "INTEL %p could not reset: %s\n",
184 intel, strerror ( rc ) );
188 /* Negotiate API version 1.1. If we do not negotiate at least
189 * this version, then the RX datapath will remain disabled if
190 * the PF has jumbo frames enabled.
192 * Ignore failures, since the host may not actually support
195 intelxvf_mbox_version ( intel, INTELXVF_MSG_VERSION_1_1 );
197 /* Set MAC address */
198 if ( ( rc = intelvf_mbox_set_mac ( intel, netdev->ll_addr ) ) != 0 ) {
199 DBGC ( intel, "INTEL %p could not set MAC address: %s\n",
200 intel, strerror ( rc ) );
201 goto err_mbox_set_mac;
205 if ( ( rc = intelvf_mbox_set_mtu ( intel, netdev->max_pkt_len ) ) != 0){
206 DBGC ( intel, "INTEL %p could not set MTU %zd: %s\n",
207 intel, netdev->max_pkt_len, strerror ( rc ) );
208 goto err_mbox_set_mtu;
211 /* Create transmit descriptor ring */
212 if ( ( rc = intel_create_ring ( intel, &intel->tx ) ) != 0 )
215 /* Create receive descriptor ring */
216 if ( ( rc = intel_create_ring ( intel, &intel->rx ) ) != 0 )
219 /* Allocate interrupt vectors */
220 writel ( ( INTELXVF_IVAR_RX0_DEFAULT | INTELXVF_IVAR_RX0_VALID |
221 INTELXVF_IVAR_TX0_DEFAULT | INTELXVF_IVAR_TX0_VALID ),
222 intel->regs + INTELXVF_IVAR );
223 writel ( ( INTELXVF_IVARM_MBOX_DEFAULT | INTELXVF_IVARM_MBOX_VALID ),
224 intel->regs + INTELXVF_IVARM );
226 /* Configure receive buffer sizes and set receive descriptor type */
227 srrctl = readl ( intel->regs + INTELXVF_SRRCTL );
228 srrctl &= ~( INTELXVF_SRRCTL_BSIZE_MASK |
229 INTELXVF_SRRCTL_DESCTYPE_MASK );
230 srrctl |= ( INTELXVF_SRRCTL_BSIZE_DEFAULT |
231 INTELXVF_SRRCTL_DESCTYPE_DEFAULT );
232 writel ( srrctl, intel->regs + INTELXVF_SRRCTL );
234 /* Clear "must-be-zero" bit for direct cache access (DCA). We
235 * leave DCA disabled anyway, but if we do not clear this bit
236 * then the received packets contain garbage data.
238 dca_rxctrl = readl ( intel->regs + INTELXVF_DCA_RXCTRL );
239 dca_rxctrl &= ~INTELXVF_DCA_RXCTRL_MUST_BE_ZERO;
240 writel ( dca_rxctrl, intel->regs + INTELXVF_DCA_RXCTRL );
242 /* Fill receive ring */
243 intel_refill_rx ( intel );
245 /* Update link state */
246 intelxvf_check_link ( netdev );
250 intel_destroy_ring ( intel, &intel->rx );
252 intel_destroy_ring ( intel, &intel->tx );
257 intelxvf_reset ( intel );
262 * Close network device
264 * @v netdev Network device
266 static void intelxvf_close ( struct net_device *netdev ) {
267 struct intel_nic *intel = netdev->priv;
269 /* Destroy receive descriptor ring */
270 intel_destroy_ring ( intel, &intel->rx );
272 /* Discard any unused receive buffers */
273 intel_empty_rx ( intel );
275 /* Destroy transmit descriptor ring */
276 intel_destroy_ring ( intel, &intel->tx );
278 /* Reset the function */
279 intelxvf_reset ( intel );
283 * Poll for completed and received packets
285 * @v netdev Network device
287 static void intelxvf_poll ( struct net_device *netdev ) {
288 struct intel_nic *intel = netdev->priv;
292 /* Check for and acknowledge interrupts */
293 eicr = readl ( intel->regs + INTELXVF_EICR );
297 /* Poll for TX completions, if applicable */
298 if ( eicr & INTELXVF_EIRQ_TX0 )
299 intel_poll_tx ( netdev );
301 /* Poll for RX completions, if applicable */
302 if ( eicr & INTELXVF_EIRQ_RX0 )
303 intel_poll_rx ( netdev );
305 /* Poll for mailbox messages, if applicable */
306 if ( eicr & INTELXVF_EIRQ_MBOX ) {
309 if ( ( rc = intelvf_mbox_poll ( intel ) ) != 0 ) {
310 DBGC ( intel, "INTEL %p mailbox poll failed!\n",
312 netdev_rx_err ( netdev, NULL, rc );
315 /* Update link state */
316 intelxvf_check_link ( netdev );
320 intel_refill_rx ( intel );
324 * Enable or disable interrupts
326 * @v netdev Network device
327 * @v enable Interrupts should be enabled
329 static void intelxvf_irq ( struct net_device *netdev, int enable ) {
330 struct intel_nic *intel = netdev->priv;
333 mask = ( INTELXVF_EIRQ_MBOX | INTELXVF_EIRQ_TX0 | INTELXVF_EIRQ_RX0 );
335 writel ( mask, intel->regs + INTELXVF_EIMS );
337 writel ( mask, intel->regs + INTELXVF_EIMC );
341 /** Network device operations */
342 static struct net_device_operations intelxvf_operations = {
343 .open = intelxvf_open,
344 .close = intelxvf_close,
345 .transmit = intel_transmit,
346 .poll = intelxvf_poll,
350 /******************************************************************************
354 ******************************************************************************
361 * @ret rc Return status code
363 static int intelxvf_probe ( struct pci_device *pci ) {
364 struct net_device *netdev;
365 struct intel_nic *intel;
368 /* Allocate and initialise net device */
369 netdev = alloc_etherdev ( sizeof ( *intel ) );
374 netdev_init ( netdev, &intelxvf_operations );
375 intel = netdev->priv;
376 pci_set_drvdata ( pci, netdev );
377 netdev->dev = &pci->dev;
378 memset ( intel, 0, sizeof ( *intel ) );
379 intel_init_mbox ( &intel->mbox, INTELXVF_MBCTRL, INTELXVF_MBMEM );
380 intel_init_ring ( &intel->tx, INTEL_NUM_TX_DESC, INTELXVF_TD,
381 intel_describe_tx_adv );
382 intel_init_ring ( &intel->rx, INTEL_NUM_RX_DESC, INTELXVF_RD,
385 /* Fix up PCI device */
386 adjust_pci_device ( pci );
389 intel->regs = ioremap ( pci->membase, INTELVF_BAR_SIZE );
390 if ( ! intel->regs ) {
395 /* Reset the function */
396 intelxvf_reset ( intel );
398 /* Send reset message and fetch MAC address */
399 if ( ( rc = intelvf_mbox_reset ( intel, netdev->hw_addr ) ) != 0 ) {
400 DBGC ( intel, "INTEL %p could not reset and fetch MAC: %s\n",
401 intel, strerror ( rc ) );
405 /* Reset the function (since we will not respond to Control
406 * ("ping") mailbox messages until the network device is opened.
408 intelxvf_reset ( intel );
410 /* Register network device */
411 if ( ( rc = register_netdev ( netdev ) ) != 0 )
412 goto err_register_netdev;
414 /* Set initial link state */
415 intelxvf_check_link ( netdev );
419 unregister_netdev ( netdev );
422 intelxvf_reset ( intel );
423 iounmap ( intel->regs );
425 netdev_nullify ( netdev );
426 netdev_put ( netdev );
436 static void intelxvf_remove ( struct pci_device *pci ) {
437 struct net_device *netdev = pci_get_drvdata ( pci );
438 struct intel_nic *intel = netdev->priv;
440 /* Unregister network device */
441 unregister_netdev ( netdev );
444 intelxvf_reset ( intel );
446 /* Free network device */
447 iounmap ( intel->regs );
448 netdev_nullify ( netdev );
449 netdev_put ( netdev );
452 /** PCI device IDs */
453 static struct pci_device_id intelxvf_nics[] = {
454 PCI_ROM ( 0x8086, 0x10ed, "82599-vf", "82599 VF", 0 ),
455 PCI_ROM ( 0x8086, 0x1515, "x540-vf", "X540 VF", 0 ),
456 PCI_ROM ( 0x8086, 0x1565, "x550-vf", "X550 VF", 0 ),
457 PCI_ROM ( 0x8086, 0x15a8, "x552-vf", "X552 VF", 0 ),
461 struct pci_driver intelxvf_driver __pci_driver = {
462 .ids = intelxvf_nics,
463 .id_count = ( sizeof ( intelxvf_nics ) / sizeof ( intelxvf_nics[0] ) ),
464 .probe = intelxvf_probe,
465 .remove = intelxvf_remove,