Nelze vybrat více než 25 témat Téma musí začínat písmenem nebo číslem, může obsahovat pomlčky („-“) a může být dlouhé až 35 znaků.

intelxvf.c 14KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523
  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. int vlan_thing;
  193. int rc;
  194. /* Reset the function */
  195. intelxvf_reset ( intel );
  196. /* Notify PF that reset is complete */
  197. if ( ( rc = intelvf_mbox_reset ( intel, NULL ) ) != 0 ) {
  198. DBGC ( intel, "INTEL %p could not reset: %s\n",
  199. intel, strerror ( rc ) );
  200. goto err_mbox_reset;
  201. }
  202. /* Negotiate API version 1.1. If we do not negotiate at least
  203. * this version, then the RX datapath will remain disabled if
  204. * the PF has jumbo frames enabled.
  205. *
  206. * Ignore failures, since the host may not actually support
  207. * v1.1.
  208. */
  209. intelxvf_mbox_version ( intel, INTELXVF_MSG_VERSION_1_1 );
  210. /* Set MAC address */
  211. if ( ( rc = intelvf_mbox_set_mac ( intel, netdev->ll_addr ) ) != 0 ) {
  212. DBGC ( intel, "INTEL %p could not set MAC address: %s\n",
  213. intel, strerror ( rc ) );
  214. goto err_mbox_set_mac;
  215. }
  216. /* Set MTU */
  217. if ( ( rc = intelvf_mbox_set_mtu ( intel, netdev->max_pkt_len ) ) != 0){
  218. DBGC ( intel, "INTEL %p could not set MTU %zd: %s\n",
  219. intel, netdev->max_pkt_len, strerror ( rc ) );
  220. goto err_mbox_set_mtu;
  221. }
  222. /* Get queue configuration. Ignore failures, since the host
  223. * may not support this message.
  224. */
  225. vlan_thing = 0;
  226. intelxvf_mbox_queues ( intel, &vlan_thing );
  227. if ( vlan_thing ) {
  228. DBGC ( intel, "INTEL %p stripping VLAN tags (thing=%d)\n",
  229. intel, vlan_thing );
  230. rxdctl = readl ( intel->regs + INTELXVF_RD + INTEL_xDCTL );
  231. rxdctl |= INTELX_RXDCTL_VME;
  232. writel ( rxdctl, intel->regs + INTELXVF_RD + INTEL_xDCTL );
  233. }
  234. /* Create transmit descriptor ring */
  235. if ( ( rc = intel_create_ring ( intel, &intel->tx ) ) != 0 )
  236. goto err_create_tx;
  237. /* Create receive descriptor ring */
  238. if ( ( rc = intel_create_ring ( intel, &intel->rx ) ) != 0 )
  239. goto err_create_rx;
  240. /* Allocate interrupt vectors */
  241. writel ( ( INTELXVF_IVAR_RX0_DEFAULT | INTELXVF_IVAR_RX0_VALID |
  242. INTELXVF_IVAR_TX0_DEFAULT | INTELXVF_IVAR_TX0_VALID ),
  243. intel->regs + INTELXVF_IVAR );
  244. writel ( ( INTELXVF_IVARM_MBOX_DEFAULT | INTELXVF_IVARM_MBOX_VALID ),
  245. intel->regs + INTELXVF_IVARM );
  246. /* Configure receive buffer sizes and set receive descriptor type */
  247. srrctl = readl ( intel->regs + INTELXVF_SRRCTL );
  248. srrctl &= ~( INTELXVF_SRRCTL_BSIZE_MASK |
  249. INTELXVF_SRRCTL_DESCTYPE_MASK );
  250. srrctl |= ( INTELXVF_SRRCTL_BSIZE_DEFAULT |
  251. INTELXVF_SRRCTL_DESCTYPE_DEFAULT );
  252. writel ( srrctl, intel->regs + INTELXVF_SRRCTL );
  253. /* Clear "must-be-zero" bit for direct cache access (DCA). We
  254. * leave DCA disabled anyway, but if we do not clear this bit
  255. * then the received packets contain garbage data.
  256. */
  257. dca_rxctrl = readl ( intel->regs + INTELXVF_DCA_RXCTRL );
  258. dca_rxctrl &= ~INTELXVF_DCA_RXCTRL_MUST_BE_ZERO;
  259. writel ( dca_rxctrl, intel->regs + INTELXVF_DCA_RXCTRL );
  260. /* Fill receive ring */
  261. intel_refill_rx ( intel );
  262. /* Update link state */
  263. intelxvf_check_link ( netdev );
  264. return 0;
  265. intel_destroy_ring ( intel, &intel->rx );
  266. err_create_rx:
  267. intel_destroy_ring ( intel, &intel->tx );
  268. err_create_tx:
  269. err_mbox_set_mtu:
  270. err_mbox_set_mac:
  271. err_mbox_reset:
  272. intelxvf_reset ( intel );
  273. return rc;
  274. }
  275. /**
  276. * Close network device
  277. *
  278. * @v netdev Network device
  279. */
  280. static void intelxvf_close ( struct net_device *netdev ) {
  281. struct intel_nic *intel = netdev->priv;
  282. /* Destroy receive descriptor ring */
  283. intel_destroy_ring ( intel, &intel->rx );
  284. /* Discard any unused receive buffers */
  285. intel_empty_rx ( intel );
  286. /* Destroy transmit descriptor ring */
  287. intel_destroy_ring ( intel, &intel->tx );
  288. /* Reset the function */
  289. intelxvf_reset ( intel );
  290. }
  291. /**
  292. * Poll for completed and received packets
  293. *
  294. * @v netdev Network device
  295. */
  296. static void intelxvf_poll ( struct net_device *netdev ) {
  297. struct intel_nic *intel = netdev->priv;
  298. uint32_t eicr;
  299. int rc;
  300. /* Check for and acknowledge interrupts */
  301. eicr = readl ( intel->regs + INTELXVF_EICR );
  302. if ( ! eicr )
  303. return;
  304. /* Poll for TX completions, if applicable */
  305. if ( eicr & INTELXVF_EIRQ_TX0 )
  306. intel_poll_tx ( netdev );
  307. /* Poll for RX completions, if applicable */
  308. if ( eicr & INTELXVF_EIRQ_RX0 )
  309. intel_poll_rx ( netdev );
  310. /* Poll for mailbox messages, if applicable */
  311. if ( eicr & INTELXVF_EIRQ_MBOX ) {
  312. /* Poll mailbox */
  313. if ( ( rc = intelvf_mbox_poll ( intel ) ) != 0 ) {
  314. DBGC ( intel, "INTEL %p mailbox poll failed!\n",
  315. intel );
  316. netdev_rx_err ( netdev, NULL, rc );
  317. }
  318. /* Update link state */
  319. intelxvf_check_link ( netdev );
  320. }
  321. /* Refill RX ring */
  322. intel_refill_rx ( intel );
  323. }
  324. /**
  325. * Enable or disable interrupts
  326. *
  327. * @v netdev Network device
  328. * @v enable Interrupts should be enabled
  329. */
  330. static void intelxvf_irq ( struct net_device *netdev, int enable ) {
  331. struct intel_nic *intel = netdev->priv;
  332. uint32_t mask;
  333. mask = ( INTELXVF_EIRQ_MBOX | INTELXVF_EIRQ_TX0 | INTELXVF_EIRQ_RX0 );
  334. if ( enable ) {
  335. writel ( mask, intel->regs + INTELXVF_EIMS );
  336. } else {
  337. writel ( mask, intel->regs + INTELXVF_EIMC );
  338. }
  339. }
  340. /** Network device operations */
  341. static struct net_device_operations intelxvf_operations = {
  342. .open = intelxvf_open,
  343. .close = intelxvf_close,
  344. .transmit = intel_transmit,
  345. .poll = intelxvf_poll,
  346. .irq = intelxvf_irq,
  347. };
  348. /******************************************************************************
  349. *
  350. * PCI interface
  351. *
  352. ******************************************************************************
  353. */
  354. /**
  355. * Probe PCI device
  356. *
  357. * @v pci PCI device
  358. * @ret rc Return status code
  359. */
  360. static int intelxvf_probe ( struct pci_device *pci ) {
  361. struct net_device *netdev;
  362. struct intel_nic *intel;
  363. int rc;
  364. /* Allocate and initialise net device */
  365. netdev = alloc_etherdev ( sizeof ( *intel ) );
  366. if ( ! netdev ) {
  367. rc = -ENOMEM;
  368. goto err_alloc;
  369. }
  370. netdev_init ( netdev, &intelxvf_operations );
  371. intel = netdev->priv;
  372. pci_set_drvdata ( pci, netdev );
  373. netdev->dev = &pci->dev;
  374. memset ( intel, 0, sizeof ( *intel ) );
  375. intel_init_mbox ( &intel->mbox, INTELXVF_MBCTRL, INTELXVF_MBMEM );
  376. intel_init_ring ( &intel->tx, INTEL_NUM_TX_DESC, INTELXVF_TD,
  377. intel_describe_tx_adv );
  378. intel_init_ring ( &intel->rx, INTEL_NUM_RX_DESC, INTELXVF_RD,
  379. intel_describe_rx );
  380. /* Fix up PCI device */
  381. adjust_pci_device ( pci );
  382. /* Map registers */
  383. intel->regs = ioremap ( pci->membase, INTELVF_BAR_SIZE );
  384. if ( ! intel->regs ) {
  385. rc = -ENODEV;
  386. goto err_ioremap;
  387. }
  388. /* Reset the function */
  389. intelxvf_reset ( intel );
  390. /* Send reset message and fetch MAC address */
  391. if ( ( rc = intelvf_mbox_reset ( intel, netdev->hw_addr ) ) != 0 ) {
  392. DBGC ( intel, "INTEL %p could not reset and fetch MAC: %s\n",
  393. intel, strerror ( rc ) );
  394. goto err_mbox_reset;
  395. }
  396. /* Reset the function (since we will not respond to Control
  397. * ("ping") mailbox messages until the network device is opened.
  398. */
  399. intelxvf_reset ( intel );
  400. /* Register network device */
  401. if ( ( rc = register_netdev ( netdev ) ) != 0 )
  402. goto err_register_netdev;
  403. /* Set initial link state */
  404. intelxvf_check_link ( netdev );
  405. return 0;
  406. unregister_netdev ( netdev );
  407. err_register_netdev:
  408. err_mbox_reset:
  409. intelxvf_reset ( intel );
  410. iounmap ( intel->regs );
  411. err_ioremap:
  412. netdev_nullify ( netdev );
  413. netdev_put ( netdev );
  414. err_alloc:
  415. return rc;
  416. }
  417. /**
  418. * Remove PCI device
  419. *
  420. * @v pci PCI device
  421. */
  422. static void intelxvf_remove ( struct pci_device *pci ) {
  423. struct net_device *netdev = pci_get_drvdata ( pci );
  424. struct intel_nic *intel = netdev->priv;
  425. /* Unregister network device */
  426. unregister_netdev ( netdev );
  427. /* Reset the NIC */
  428. intelxvf_reset ( intel );
  429. /* Free network device */
  430. iounmap ( intel->regs );
  431. netdev_nullify ( netdev );
  432. netdev_put ( netdev );
  433. }
  434. /** PCI device IDs */
  435. static struct pci_device_id intelxvf_nics[] = {
  436. PCI_ROM ( 0x8086, 0x10ed, "82599-vf", "82599 VF", 0 ),
  437. PCI_ROM ( 0x8086, 0x1515, "x540-vf", "X540 VF", 0 ),
  438. PCI_ROM ( 0x8086, 0x1565, "x550-vf", "X550 VF", 0 ),
  439. PCI_ROM ( 0x8086, 0x15a8, "x552-vf", "X552 VF", 0 ),
  440. };
  441. /** PCI driver */
  442. struct pci_driver intelxvf_driver __pci_driver = {
  443. .ids = intelxvf_nics,
  444. .id_count = ( sizeof ( intelxvf_nics ) / sizeof ( intelxvf_nics[0] ) ),
  445. .probe = intelxvf_probe,
  446. .remove = intelxvf_remove,
  447. };