You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

intelxvf.c 14KB

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