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.

intelx.c 13KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484
  1. /*
  2. * Copyright (C) 2013 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 <stdint.h>
  25. #include <string.h>
  26. #include <unistd.h>
  27. #include <errno.h>
  28. #include <byteswap.h>
  29. #include <ipxe/netdevice.h>
  30. #include <ipxe/ethernet.h>
  31. #include <ipxe/if_ether.h>
  32. #include <ipxe/iobuf.h>
  33. #include <ipxe/malloc.h>
  34. #include <ipxe/pci.h>
  35. #include "intelx.h"
  36. /** @file
  37. *
  38. * Intel 10 Gigabit Ethernet network card driver
  39. *
  40. */
  41. /******************************************************************************
  42. *
  43. * MAC address
  44. *
  45. ******************************************************************************
  46. */
  47. /**
  48. * Try to fetch initial MAC address
  49. *
  50. * @v intel Intel device
  51. * @v ral0 RAL0 register address
  52. * @v hw_addr Hardware address to fill in
  53. * @ret rc Return status code
  54. */
  55. static int intelx_try_fetch_mac ( struct intel_nic *intel, unsigned int ral0,
  56. uint8_t *hw_addr ) {
  57. union intel_receive_address mac;
  58. /* Read current address from RAL0/RAH0 */
  59. mac.reg.low = cpu_to_le32 ( readl ( intel->regs + ral0 ) );
  60. mac.reg.high = cpu_to_le32 ( readl ( intel->regs + ral0 +
  61. ( INTELX_RAH0 - INTELX_RAL0 ) ) );
  62. /* Use current address if valid */
  63. if ( is_valid_ether_addr ( mac.raw ) ) {
  64. DBGC ( intel, "INTEL %p has autoloaded MAC address %s at "
  65. "%#05x\n", intel, eth_ntoa ( mac.raw ), ral0 );
  66. memcpy ( hw_addr, mac.raw, ETH_ALEN );
  67. return 0;
  68. }
  69. return -ENOENT;
  70. }
  71. /**
  72. * Fetch initial MAC address
  73. *
  74. * @v intel Intel device
  75. * @v hw_addr Hardware address to fill in
  76. * @ret rc Return status code
  77. */
  78. static int intelx_fetch_mac ( struct intel_nic *intel, uint8_t *hw_addr ) {
  79. int rc;
  80. /* Try to fetch address from INTELX_RAL0 */
  81. if ( ( rc = intelx_try_fetch_mac ( intel, INTELX_RAL0,
  82. hw_addr ) ) == 0 ) {
  83. return 0;
  84. }
  85. /* Try to fetch address from INTELX_RAL0_ALT */
  86. if ( ( rc = intelx_try_fetch_mac ( intel, INTELX_RAL0_ALT,
  87. hw_addr ) ) == 0 ) {
  88. return 0;
  89. }
  90. DBGC ( intel, "INTEL %p has no MAC address to use\n", intel );
  91. return -ENOENT;
  92. }
  93. /******************************************************************************
  94. *
  95. * Device reset
  96. *
  97. ******************************************************************************
  98. */
  99. /**
  100. * Reset hardware
  101. *
  102. * @v intel Intel device
  103. * @ret rc Return status code
  104. */
  105. static int intelx_reset ( struct intel_nic *intel ) {
  106. uint32_t ctrl;
  107. /* Perform a global software reset */
  108. ctrl = readl ( intel->regs + INTELX_CTRL );
  109. writel ( ( ctrl | INTELX_CTRL_RST | INTELX_CTRL_LRST ),
  110. intel->regs + INTELX_CTRL );
  111. mdelay ( INTELX_RESET_DELAY_MS );
  112. DBGC ( intel, "INTEL %p reset (ctrl %08x)\n", intel, ctrl );
  113. return 0;
  114. }
  115. /******************************************************************************
  116. *
  117. * Link state
  118. *
  119. ******************************************************************************
  120. */
  121. /**
  122. * Check link state
  123. *
  124. * @v netdev Network device
  125. */
  126. static void intelx_check_link ( struct net_device *netdev ) {
  127. struct intel_nic *intel = netdev->priv;
  128. uint32_t links;
  129. /* Read link status */
  130. links = readl ( intel->regs + INTELX_LINKS );
  131. DBGC ( intel, "INTEL %p link status is %08x\n", intel, links );
  132. /* Update network device */
  133. if ( links & INTELX_LINKS_UP ) {
  134. netdev_link_up ( netdev );
  135. } else {
  136. netdev_link_down ( netdev );
  137. }
  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 intelx_open ( struct net_device *netdev ) {
  152. struct intel_nic *intel = netdev->priv;
  153. union intel_receive_address mac;
  154. uint32_t ral0;
  155. uint32_t rah0;
  156. uint32_t dmatxctl;
  157. uint32_t fctrl;
  158. uint32_t srrctl;
  159. uint32_t hlreg0;
  160. uint32_t maxfrs;
  161. uint32_t rdrxctl;
  162. uint32_t rxctrl;
  163. uint32_t dca_rxctrl;
  164. int rc;
  165. /* Create transmit descriptor ring */
  166. if ( ( rc = intel_create_ring ( intel, &intel->tx ) ) != 0 )
  167. goto err_create_tx;
  168. /* Create receive descriptor ring */
  169. if ( ( rc = intel_create_ring ( intel, &intel->rx ) ) != 0 )
  170. goto err_create_rx;
  171. /* Program MAC address */
  172. memset ( &mac, 0, sizeof ( mac ) );
  173. memcpy ( mac.raw, netdev->ll_addr, sizeof ( mac.raw ) );
  174. ral0 = le32_to_cpu ( mac.reg.low );
  175. rah0 = ( le32_to_cpu ( mac.reg.high ) | INTELX_RAH0_AV );
  176. writel ( ral0, intel->regs + INTELX_RAL0 );
  177. writel ( rah0, intel->regs + INTELX_RAH0 );
  178. writel ( ral0, intel->regs + INTELX_RAL0_ALT );
  179. writel ( rah0, intel->regs + INTELX_RAH0_ALT );
  180. /* Allocate interrupt vectors */
  181. writel ( ( INTELX_IVAR_RX0_DEFAULT | INTELX_IVAR_RX0_VALID |
  182. INTELX_IVAR_TX0_DEFAULT | INTELX_IVAR_TX0_VALID ),
  183. intel->regs + INTELX_IVAR );
  184. /* Enable transmitter */
  185. dmatxctl = readl ( intel->regs + INTELX_DMATXCTL );
  186. dmatxctl |= INTELX_DMATXCTL_TE;
  187. writel ( dmatxctl, intel->regs + INTELX_DMATXCTL );
  188. /* Configure receive filter */
  189. fctrl = readl ( intel->regs + INTELX_FCTRL );
  190. fctrl |= ( INTELX_FCTRL_BAM | INTELX_FCTRL_UPE | INTELX_FCTRL_MPE );
  191. writel ( fctrl, intel->regs + INTELX_FCTRL );
  192. /* Configure receive buffer sizes */
  193. srrctl = readl ( intel->regs + INTELX_SRRCTL );
  194. srrctl &= ~INTELX_SRRCTL_BSIZE_MASK;
  195. srrctl |= INTELX_SRRCTL_BSIZE_DEFAULT;
  196. writel ( srrctl, intel->regs + INTELX_SRRCTL );
  197. /* Configure jumbo frames. Required to allow the extra 4-byte
  198. * headroom for VLANs, since we don't use the hardware's
  199. * native VLAN offload.
  200. */
  201. hlreg0 = readl ( intel->regs + INTELX_HLREG0 );
  202. hlreg0 |= INTELX_HLREG0_JUMBOEN;
  203. writel ( hlreg0, intel->regs + INTELX_HLREG0 );
  204. /* Configure frame size */
  205. maxfrs = readl ( intel->regs + INTELX_MAXFRS );
  206. maxfrs &= ~INTELX_MAXFRS_MFS_MASK;
  207. maxfrs |= INTELX_MAXFRS_MFS_DEFAULT;
  208. writel ( maxfrs, intel->regs + INTELX_MAXFRS );
  209. /* Configure receive DMA */
  210. rdrxctl = readl ( intel->regs + INTELX_RDRXCTL );
  211. rdrxctl |= INTELX_RDRXCTL_SECRC;
  212. writel ( rdrxctl, intel->regs + INTELX_RDRXCTL );
  213. /* Clear "must-be-zero" bit for direct cache access (DCA). We
  214. * leave DCA disabled anyway, but if we do not clear this bit
  215. * then the received packets contain garbage data.
  216. */
  217. dca_rxctrl = readl ( intel->regs + INTELX_DCA_RXCTRL );
  218. dca_rxctrl &= ~INTELX_DCA_RXCTRL_MUST_BE_ZERO;
  219. writel ( dca_rxctrl, intel->regs + INTELX_DCA_RXCTRL );
  220. /* Enable receiver */
  221. rxctrl = readl ( intel->regs + INTELX_RXCTRL );
  222. rxctrl |= INTELX_RXCTRL_RXEN;
  223. writel ( rxctrl, intel->regs + INTELX_RXCTRL );
  224. /* Fill receive ring */
  225. intel_refill_rx ( intel );
  226. /* Update link state */
  227. intelx_check_link ( netdev );
  228. return 0;
  229. intel_destroy_ring ( intel, &intel->rx );
  230. err_create_rx:
  231. intel_destroy_ring ( intel, &intel->tx );
  232. err_create_tx:
  233. return rc;
  234. }
  235. /**
  236. * Close network device
  237. *
  238. * @v netdev Network device
  239. */
  240. static void intelx_close ( struct net_device *netdev ) {
  241. struct intel_nic *intel = netdev->priv;
  242. uint32_t rxctrl;
  243. uint32_t dmatxctl;
  244. /* Disable receiver */
  245. rxctrl = readl ( intel->regs + INTELX_RXCTRL );
  246. rxctrl &= ~INTELX_RXCTRL_RXEN;
  247. writel ( rxctrl, intel->regs + INTELX_RXCTRL );
  248. /* Disable transmitter */
  249. dmatxctl = readl ( intel->regs + INTELX_DMATXCTL );
  250. dmatxctl &= ~INTELX_DMATXCTL_TE;
  251. writel ( dmatxctl, intel->regs + INTELX_DMATXCTL );
  252. /* Destroy receive descriptor ring */
  253. intel_destroy_ring ( intel, &intel->rx );
  254. /* Discard any unused receive buffers */
  255. intel_empty_rx ( intel );
  256. /* Destroy transmit descriptor ring */
  257. intel_destroy_ring ( intel, &intel->tx );
  258. /* Reset the NIC, to flush the transmit and receive FIFOs */
  259. intelx_reset ( intel );
  260. }
  261. /**
  262. * Poll for completed and received packets
  263. *
  264. * @v netdev Network device
  265. */
  266. static void intelx_poll ( struct net_device *netdev ) {
  267. struct intel_nic *intel = netdev->priv;
  268. uint32_t eicr;
  269. /* Check for and acknowledge interrupts */
  270. eicr = readl ( intel->regs + INTELX_EICR );
  271. if ( ! eicr )
  272. return;
  273. /* Poll for TX completions, if applicable */
  274. if ( eicr & INTELX_EIRQ_TX0 )
  275. intel_poll_tx ( netdev );
  276. /* Poll for RX completions, if applicable */
  277. if ( eicr & ( INTELX_EIRQ_RX0 | INTELX_EIRQ_RXO ) )
  278. intel_poll_rx ( netdev );
  279. /* Report receive overruns */
  280. if ( eicr & INTELX_EIRQ_RXO )
  281. netdev_rx_err ( netdev, NULL, -ENOBUFS );
  282. /* Check link state, if applicable */
  283. if ( eicr & INTELX_EIRQ_LSC )
  284. intelx_check_link ( netdev );
  285. /* Refill RX ring */
  286. intel_refill_rx ( intel );
  287. }
  288. /**
  289. * Enable or disable interrupts
  290. *
  291. * @v netdev Network device
  292. * @v enable Interrupts should be enabled
  293. */
  294. static void intelx_irq ( struct net_device *netdev, int enable ) {
  295. struct intel_nic *intel = netdev->priv;
  296. uint32_t mask;
  297. mask = ( INTELX_EIRQ_LSC | INTELX_EIRQ_RXO | INTELX_EIRQ_TX0 |
  298. INTELX_EIRQ_RX0 );
  299. if ( enable ) {
  300. writel ( mask, intel->regs + INTELX_EIMS );
  301. } else {
  302. writel ( mask, intel->regs + INTELX_EIMC );
  303. }
  304. }
  305. /** Network device operations */
  306. static struct net_device_operations intelx_operations = {
  307. .open = intelx_open,
  308. .close = intelx_close,
  309. .transmit = intel_transmit,
  310. .poll = intelx_poll,
  311. .irq = intelx_irq,
  312. };
  313. /******************************************************************************
  314. *
  315. * PCI interface
  316. *
  317. ******************************************************************************
  318. */
  319. /**
  320. * Probe PCI device
  321. *
  322. * @v pci PCI device
  323. * @ret rc Return status code
  324. */
  325. static int intelx_probe ( struct pci_device *pci ) {
  326. struct net_device *netdev;
  327. struct intel_nic *intel;
  328. int rc;
  329. /* Allocate and initialise net device */
  330. netdev = alloc_etherdev ( sizeof ( *intel ) );
  331. if ( ! netdev ) {
  332. rc = -ENOMEM;
  333. goto err_alloc;
  334. }
  335. netdev_init ( netdev, &intelx_operations );
  336. intel = netdev->priv;
  337. pci_set_drvdata ( pci, netdev );
  338. netdev->dev = &pci->dev;
  339. memset ( intel, 0, sizeof ( *intel ) );
  340. intel->port = PCI_FUNC ( pci->busdevfn );
  341. intel_init_ring ( &intel->tx, INTEL_NUM_TX_DESC, INTELX_TD,
  342. intel_describe_tx );
  343. intel_init_ring ( &intel->rx, INTEL_NUM_RX_DESC, INTELX_RD,
  344. intel_describe_rx );
  345. /* Fix up PCI device */
  346. adjust_pci_device ( pci );
  347. /* Map registers */
  348. intel->regs = ioremap ( pci->membase, INTEL_BAR_SIZE );
  349. if ( ! intel->regs ) {
  350. rc = -ENODEV;
  351. goto err_ioremap;
  352. }
  353. /* Reset the NIC */
  354. if ( ( rc = intelx_reset ( intel ) ) != 0 )
  355. goto err_reset;
  356. /* Fetch MAC address */
  357. if ( ( rc = intelx_fetch_mac ( intel, netdev->hw_addr ) ) != 0 )
  358. goto err_fetch_mac;
  359. /* Register network device */
  360. if ( ( rc = register_netdev ( netdev ) ) != 0 )
  361. goto err_register_netdev;
  362. /* Set initial link state */
  363. intelx_check_link ( netdev );
  364. return 0;
  365. unregister_netdev ( netdev );
  366. err_register_netdev:
  367. err_fetch_mac:
  368. intelx_reset ( intel );
  369. err_reset:
  370. iounmap ( intel->regs );
  371. err_ioremap:
  372. netdev_nullify ( netdev );
  373. netdev_put ( netdev );
  374. err_alloc:
  375. return rc;
  376. }
  377. /**
  378. * Remove PCI device
  379. *
  380. * @v pci PCI device
  381. */
  382. static void intelx_remove ( struct pci_device *pci ) {
  383. struct net_device *netdev = pci_get_drvdata ( pci );
  384. struct intel_nic *intel = netdev->priv;
  385. /* Unregister network device */
  386. unregister_netdev ( netdev );
  387. /* Reset the NIC */
  388. intelx_reset ( intel );
  389. /* Free network device */
  390. iounmap ( intel->regs );
  391. netdev_nullify ( netdev );
  392. netdev_put ( netdev );
  393. }
  394. /** PCI device IDs */
  395. static struct pci_device_id intelx_nics[] = {
  396. PCI_ROM ( 0x8086, 0x10f7, "82599-kx4", "82599 (KX/KX4)", 0 ),
  397. PCI_ROM ( 0x8086, 0x10f8, "82599-combo-backplane", "82599 (combined backplane; KR/KX4/KX)", 0 ),
  398. PCI_ROM ( 0x8086, 0x10f9, "82599-cx4", "82599 (CX4)", 0 ),
  399. PCI_ROM ( 0x8086, 0x10fb, "82599-sfp", "82599 (SFI/SFP+)", 0 ),
  400. PCI_ROM ( 0x8086, 0x10fc, "82599-xaui", "82599 (XAUI/BX4)", 0 ),
  401. PCI_ROM ( 0x8086, 0x1528, "x540t", "X540-AT2/X540-BT2", 0 ),
  402. PCI_ROM ( 0x8086, 0x154d, "82599-sfp-sf2", "82599 (SFI/SFP+)", 0 ),
  403. PCI_ROM ( 0x8086, 0x1557, "82599en-sfp", "82599 (Single Port SFI Only)", 0 ),
  404. PCI_ROM ( 0x8086, 0x1560, "x540t1", "X540-AT2/X540-BT2 (with single port NVM)", 0 ),
  405. };
  406. /** PCI driver */
  407. struct pci_driver intelx_driver __pci_driver = {
  408. .ids = intelx_nics,
  409. .id_count = ( sizeof ( intelx_nics ) / sizeof ( intelx_nics[0] ) ),
  410. .probe = intelx_probe,
  411. .remove = intelx_remove,
  412. };