Ви не можете вибрати більше 25 тем Теми мають розпочинатися з літери або цифри, можуть містити дефіси (-) і не повинні перевищувати 35 символів.

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