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.

myri10ge.c 27KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041
  1. /************************************************* -*- linux-c -*-
  2. * Myricom 10Gb Network Interface Card Software
  3. * Copyright 2009, Myricom, Inc.
  4. *
  5. * This program is free software; you can redistribute it and/or
  6. * modify it under the terms of the GNU General Public License,
  7. * version 2, as published by the Free Software Foundation.
  8. *
  9. * This program is distributed in the hope that it will be useful,
  10. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  11. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  12. * GNU 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
  17. ****************************************************************/
  18. FILE_LICENCE ( GPL2_ONLY );
  19. /*
  20. * Author: Glenn Brown <glenn@myri.com>
  21. */
  22. /*
  23. * General Theory of Operation
  24. *
  25. * This is a minimal Myricom 10 gigabit Ethernet driver for network
  26. * boot.
  27. *
  28. * Initialization
  29. *
  30. * myri10ge_pci_probe() is called by gPXE during initialization.
  31. * Minimal NIC initialization is performed to minimize resources
  32. * consumed when the driver is resident but unused.
  33. *
  34. * Network Boot
  35. *
  36. * myri10ge_net_open() is called by gPXE before attempting to network
  37. * boot from the card. Packet buffers are allocated and the NIC
  38. * interface is initialized.
  39. *
  40. * Transmit
  41. *
  42. * myri10ge_net_transmit() enqueues frames for transmission by writing
  43. * discriptors to the NIC's tx ring. For simplicity and to avoid
  44. * copies, we always have the NIC DMA up the packet. The sent I/O
  45. * buffer is released once the NIC signals myri10ge_interrupt_handler()
  46. * that the send has completed.
  47. *
  48. * Receive
  49. *
  50. * Receives are posted to the NIC's receive ring. The NIC fills a
  51. * DMAable receive_completion ring with completion notifications.
  52. * myri10ge_net_poll() polls for these receive notifications, posts
  53. * replacement receive buffers to the NIC, and passes received frames
  54. * to netdev_rx().
  55. */
  56. /*
  57. * Debugging levels:
  58. * - DBG() is for any errors, i.e. failed alloc_iob(), malloc_dma(),
  59. * TX overflow, corrupted packets, ...
  60. * - DBG2() is for successful events, like packet received,
  61. * packet transmitted, and other general notifications.
  62. * - DBGP() prints the name of each called function on entry
  63. */
  64. #include <stdint.h>
  65. #include <byteswap.h>
  66. #include <errno.h>
  67. #include <gpxe/ethernet.h>
  68. #include <gpxe/if_ether.h>
  69. #include <gpxe/iobuf.h>
  70. #include <gpxe/malloc.h>
  71. #include <gpxe/netdevice.h>
  72. #include <gpxe/pci.h>
  73. #include <gpxe/timer.h>
  74. #include "myri10ge_mcp.h"
  75. /****************************************************************
  76. * Forward declarations
  77. ****************************************************************/
  78. /* PCI driver entry points */
  79. static int myri10ge_pci_probe ( struct pci_device*,
  80. const struct pci_device_id* );
  81. static void myri10ge_pci_remove ( struct pci_device* );
  82. /* Network device operations */
  83. static void myri10ge_net_close ( struct net_device* );
  84. static void myri10ge_net_irq ( struct net_device*, int enable );
  85. static int myri10ge_net_open ( struct net_device* );
  86. static void myri10ge_net_poll ( struct net_device* );
  87. static int myri10ge_net_transmit ( struct net_device*, struct io_buffer* );
  88. /****************************************************************
  89. * Constants
  90. ****************************************************************/
  91. /* Maximum ring indices, used to wrap ring indices. These must be 2**N-1. */
  92. #define MYRI10GE_TRANSMIT_WRAP 1U
  93. #define MYRI10GE_RECEIVE_WRAP 7U
  94. #define MYRI10GE_RECEIVE_COMPLETION_WRAP 31U
  95. /****************************************************************
  96. * Driver internal data types.
  97. ****************************************************************/
  98. /* Structure holding all DMA buffers for a NIC, which we will
  99. allocated as contiguous read/write DMAable memory when the NIC is
  100. initialized. */
  101. struct myri10ge_dma_buffers
  102. {
  103. /* The NIC DMAs receive completion notifications into this ring */
  104. mcp_slot_t receive_completion[1+MYRI10GE_RECEIVE_COMPLETION_WRAP];
  105. /* Interrupt details are DMAd here before interrupting. */
  106. mcp_irq_data_t irq_data; /* 64B */
  107. /* NIC command completion status is DMAd here. */
  108. mcp_cmd_response_t command_response; /* 8B */
  109. };
  110. struct myri10ge_private
  111. {
  112. /* Interrupt support */
  113. uint32 *irq_claim; /* in NIC SRAM */
  114. uint32 *irq_deassert; /* in NIC SRAM */
  115. /* DMA buffers. */
  116. struct myri10ge_dma_buffers *dma;
  117. /*
  118. * Transmit state.
  119. *
  120. * The counts here are uint32 for easy comparison with
  121. * priv->dma->irq_data.send_done_count and with each other.
  122. */
  123. mcp_kreq_ether_send_t *transmit_ring; /* in NIC SRAM */
  124. uint32 transmit_ring_wrap;
  125. uint32 transmits_posted;
  126. uint32 transmits_done;
  127. struct io_buffer *transmit_iob[1 + MYRI10GE_TRANSMIT_WRAP];
  128. /*
  129. * Receive state.
  130. */
  131. mcp_kreq_ether_recv_t *receive_post_ring; /* in NIC SRAM */
  132. unsigned int receive_post_ring_wrap;
  133. unsigned int receives_posted;
  134. unsigned int receives_done;
  135. struct io_buffer *receive_iob[1 + MYRI10GE_RECEIVE_WRAP];
  136. /* Address for writing commands to the firmware.
  137. BEWARE: the value must be written 32 bits at a time. */
  138. mcp_cmd_t *command;
  139. };
  140. /****************************************************************
  141. * Driver internal functions.
  142. ****************************************************************/
  143. /* Print ring status when debugging. Use this only after a printed
  144. value changes. */
  145. #define DBG2_RINGS( priv ) \
  146. DBG2 ( "tx %x/%x rx %x/%x in %s() \n", \
  147. ( priv ) ->transmits_done, ( priv ) -> transmits_posted, \
  148. ( priv ) ->receives_done, ( priv ) -> receives_posted, \
  149. __FUNCTION__ )
  150. /*
  151. * Return a pointer to the driver private data for a network device.
  152. *
  153. * @v netdev Network device created by this driver.
  154. * @ret priv The corresponding driver private data.
  155. */
  156. static inline struct myri10ge_private *myri10ge_priv ( struct net_device *nd )
  157. {
  158. /* Our private data always follows the network device in memory,
  159. since we use alloc_netdev() to allocate the storage. */
  160. return ( struct myri10ge_private * ) ( nd + 1 );
  161. }
  162. /*
  163. * Pass a receive buffer to the NIC to be filled.
  164. *
  165. * @v priv The network device to receive the buffer.
  166. * @v iob The I/O buffer to fill.
  167. *
  168. * Receive buffers are filled in FIFO order.
  169. */
  170. static void myri10ge_post_receive ( struct myri10ge_private *priv,
  171. struct io_buffer *iob )
  172. {
  173. unsigned int receives_posted;
  174. mcp_kreq_ether_recv_t *request;
  175. /* Record the posted I/O buffer, to be passed to netdev_rx() on
  176. receive. */
  177. receives_posted = priv->receives_posted;
  178. priv->receive_iob[receives_posted & MYRI10GE_RECEIVE_WRAP] = iob;
  179. /* Post the receive. */
  180. request = &priv->receive_post_ring[receives_posted
  181. & priv->receive_post_ring_wrap];
  182. request->addr_high = 0;
  183. wmb();
  184. request->addr_low = htonl ( virt_to_bus ( iob->data ) );
  185. priv->receives_posted = ++receives_posted;
  186. }
  187. /*
  188. * Execute a command on the NIC.
  189. *
  190. * @v priv NIC to perform the command.
  191. * @v cmd The command to perform.
  192. * @v data I/O copy buffer for parameters/results
  193. * @ret rc 0 on success, else an error code.
  194. */
  195. static int myri10ge_command ( struct myri10ge_private *priv,
  196. uint32 cmd,
  197. uint32 data[3] )
  198. {
  199. int i;
  200. mcp_cmd_t *command;
  201. uint32 result;
  202. unsigned int slept_ms;
  203. volatile mcp_cmd_response_t *response;
  204. DBGP ( "myri10ge_command ( ,%d, ) \n", cmd );
  205. command = priv->command;
  206. response = &priv->dma->command_response;
  207. /* Mark the command as incomplete. */
  208. response->result = 0xFFFFFFFF;
  209. /* Pass the command to the NIC. */
  210. command->cmd = htonl ( cmd );
  211. command->data0 = htonl ( data[0] );
  212. command->data1 = htonl ( data[1] );
  213. command->data2 = htonl ( data[2] );
  214. command->response_addr.high = 0;
  215. command->response_addr.low
  216. = htonl ( virt_to_bus ( &priv->dma->command_response ) );
  217. for ( i=0; i<36; i+=4 )
  218. * ( uint32 * ) &command->pad[i] = 0;
  219. wmb();
  220. * ( uint32 * ) &command->pad[36] = 0;
  221. /* Wait up to 2 seconds for a response. */
  222. for ( slept_ms=0; slept_ms<2000; slept_ms++ ) {
  223. result = response->result;
  224. if ( result == 0 ) {
  225. data[0] = ntohl ( response->data );
  226. return 0;
  227. } else if ( result != 0xFFFFFFFF ) {
  228. DBG ( "cmd%d:0x%x\n",
  229. cmd,
  230. ntohl ( response->result ) );
  231. return -EIO;
  232. }
  233. udelay ( 1000 );
  234. rmb();
  235. }
  236. DBG ( "cmd%d:timed out\n", cmd );
  237. return -ETIMEDOUT;
  238. }
  239. /*
  240. * Handle any pending interrupt.
  241. *
  242. * @v netdev Device being polled for interrupts.
  243. *
  244. * This is called periodically to let the driver check for interrupts.
  245. */
  246. static void myri10ge_interrupt_handler ( struct net_device *netdev )
  247. {
  248. struct myri10ge_private *priv;
  249. mcp_irq_data_t *irq_data;
  250. uint8 valid;
  251. priv = myri10ge_priv ( netdev );
  252. irq_data = &priv->dma->irq_data;
  253. /* Return if there was no interrupt. */
  254. rmb();
  255. valid = irq_data->valid;
  256. if ( !valid )
  257. return;
  258. DBG2 ( "irq " );
  259. /* Tell the NIC to deassert the interrupt and clear
  260. irq_data->valid.*/
  261. *priv->irq_deassert = 0; /* any value is OK. */
  262. mb();
  263. /* Handle any new receives. */
  264. if ( valid & 1 ) {
  265. /* Pass the receive interrupt token back to the NIC. */
  266. DBG2 ( "rx " );
  267. *priv->irq_claim = htonl ( 3 );
  268. wmb();
  269. }
  270. /* Handle any sent packet by freeing its I/O buffer, now that
  271. we know it has been DMAd. */
  272. if ( valid & 2 ) {
  273. unsigned int nic_done_count;
  274. DBG2 ( "snt " );
  275. nic_done_count = ntohl ( priv->dma->irq_data.send_done_count );
  276. while ( priv->transmits_done != nic_done_count ) {
  277. struct io_buffer *iob;
  278. iob = priv->transmit_iob [priv->transmits_done
  279. & MYRI10GE_TRANSMIT_WRAP];
  280. DBG2 ( "%p ", iob );
  281. netdev_tx_complete ( netdev, iob );
  282. ++priv->transmits_done;
  283. }
  284. }
  285. /* Record any statistics update. */
  286. if ( irq_data->stats_updated ) {
  287. /* Update the link status. */
  288. DBG2 ( "stats " );
  289. if ( ntohl ( irq_data->link_up ) == MXGEFW_LINK_UP )
  290. netdev_link_up ( netdev );
  291. else
  292. netdev_link_down ( netdev );
  293. /* Ignore all error counters from the NIC. */
  294. }
  295. /* Wait for the interrupt to be deasserted, as indicated by
  296. irq_data->valid, which is set by the NIC after the deassert. */
  297. DBG2 ( "wait " );
  298. do {
  299. mb();
  300. } while ( irq_data->valid );
  301. /* Claim the interrupt to enable future interrupt generation. */
  302. DBG2 ( "claim\n" );
  303. * ( priv->irq_claim + 1 ) = htonl ( 3 );
  304. mb();
  305. }
  306. /* Constants for reading the STRING_SPECS via the Myricom
  307. Vendor Specific PCI configuration space capability. */
  308. #define VS_ADDR ( vs + 0x18 )
  309. #define VS_DATA ( vs + 0x14 )
  310. #define VS_MODE ( vs + 0x10 )
  311. #define VS_MODE_READ32 0x3
  312. #define VS_MODE_LOCATE 0x8
  313. #define VS_LOCATE_STRING_SPECS 0x3
  314. /*
  315. * Read MAC address from its 'string specs' via the vendor-specific
  316. * capability. (This capability allows NIC SRAM and ROM to be read
  317. * before it is mapped.)
  318. *
  319. * @v pci The device.
  320. * @v mac Buffer to store the MAC address.
  321. * @ret rc Returns 0 on success, else an error code.
  322. */
  323. static int mac_address_from_string_specs ( struct pci_device *pci,
  324. uint8 mac[ETH_ALEN] )
  325. {
  326. char string_specs[256];
  327. char *ptr, *limit;
  328. char *to = string_specs;
  329. uint32 addr;
  330. uint32 len;
  331. unsigned int vs;
  332. int mac_set = 0;
  333. /* Find the "vendor specific" capability. */
  334. vs = pci_find_capability ( pci, 9 );
  335. if ( vs == 0 ) {
  336. DBG ( "no VS\n" );
  337. return -ENOTSUP;
  338. }
  339. /* Locate the String specs in LANai SRAM. */
  340. pci_write_config_byte ( pci, VS_MODE, VS_MODE_LOCATE );
  341. pci_write_config_dword ( pci, VS_ADDR, VS_LOCATE_STRING_SPECS );
  342. pci_read_config_dword ( pci, VS_ADDR, &addr );
  343. pci_read_config_dword ( pci, VS_DATA, &len );
  344. DBG2 ( "ss@%x,%x\n", addr, len );
  345. /* Copy in the string specs. Use 32-bit reads for performance. */
  346. if ( len > sizeof ( string_specs ) || ( len & 3 ) ) {
  347. DBG ( "SS too big\n" );
  348. return -ENOTSUP;
  349. }
  350. pci_write_config_byte ( pci, VS_MODE, VS_MODE_READ32 );
  351. while ( len >= 4 ) {
  352. uint32 tmp;
  353. pci_write_config_byte ( pci, VS_ADDR, addr );
  354. pci_read_config_dword ( pci, VS_DATA, &tmp );
  355. tmp = ntohl ( tmp );
  356. memcpy ( to, &tmp, 4 );
  357. to += 4;
  358. addr += 4;
  359. len -= 4;
  360. }
  361. pci_write_config_byte ( pci, VS_MODE, 0 );
  362. /* Parse the string specs. */
  363. DBG2 ( "STRING_SPECS:\n" );
  364. ptr = string_specs;
  365. limit = string_specs + sizeof ( string_specs );
  366. while ( *ptr != '\0' && ptr < limit ) {
  367. DBG2 ( "%s\n", ptr );
  368. if ( memcmp ( ptr, "MAC=", 4 ) == 0 ) {
  369. unsigned int i;
  370. ptr += 4;
  371. for ( i=0; i<6; i++ ) {
  372. if ( ( ptr + 2 ) > limit ) {
  373. DBG ( "bad MAC addr\n" );
  374. return -ENOTSUP;
  375. }
  376. mac[i] = strtoul ( ptr, &ptr, 16 );
  377. ptr += 1;
  378. }
  379. mac_set = 1;
  380. }
  381. else
  382. while ( ptr < limit && *ptr++ );
  383. }
  384. /* Verify we parsed all we need. */
  385. if ( !mac_set ) {
  386. DBG ( "no MAC addr\n" );
  387. return -ENOTSUP;
  388. }
  389. DBG2 ( "MAC %02x:%02x:%02x:%02x:%02x:%02x\n",
  390. mac[0], mac[1], mac[2], mac[3], mac[4], mac[5] );
  391. return 0;
  392. }
  393. /****************************************************************
  394. * gPXE PCI Device Driver API functions
  395. ****************************************************************/
  396. /*
  397. * Initialize the PCI device.
  398. *
  399. * @v pci The device's associated pci_device structure.
  400. * @v id The PCI device + vendor id.
  401. * @ret rc Returns zero if successfully initialized.
  402. *
  403. * This function is called very early on, while gPXE is initializing.
  404. * This is a gPXE PCI Device Driver API function.
  405. */
  406. static int myri10ge_pci_probe ( struct pci_device *pci,
  407. const struct pci_device_id *id __unused )
  408. {
  409. static struct net_device_operations myri10ge_operations = {
  410. .open = myri10ge_net_open,
  411. .close = myri10ge_net_close,
  412. .transmit = myri10ge_net_transmit,
  413. .poll = myri10ge_net_poll,
  414. .irq = myri10ge_net_irq
  415. };
  416. const char *dbg;
  417. int rc;
  418. struct net_device *netdev;
  419. struct myri10ge_private *priv;
  420. DBGP ( "myri10ge_pci_probe: " );
  421. netdev = alloc_etherdev ( sizeof ( *priv ) );
  422. if ( !netdev ) {
  423. rc = -ENOMEM;
  424. dbg = "alloc_etherdev";
  425. goto abort_with_nothing;
  426. }
  427. netdev_init ( netdev, &myri10ge_operations );
  428. priv = myri10ge_priv ( netdev );
  429. pci_set_drvdata ( pci, netdev );
  430. netdev->dev = &pci->dev;
  431. /* Make sure interrupts are disabled. */
  432. myri10ge_net_irq ( netdev, 0 );
  433. /* Read the NIC HW address. */
  434. rc = mac_address_from_string_specs ( pci, netdev->hw_addr );
  435. if ( rc ) {
  436. dbg = "mac_from_ss";
  437. goto abort_with_netdev_init;
  438. }
  439. DBGP ( "mac " );
  440. /* Enable bus master, etc. */
  441. adjust_pci_device ( pci );
  442. DBGP ( "pci " );
  443. /* Register the initialized network device. */
  444. rc = register_netdev ( netdev );
  445. if ( rc ) {
  446. dbg = "register_netdev";
  447. goto abort_with_netdev_init;
  448. }
  449. DBGP ( "done\n" );
  450. return 0;
  451. abort_with_netdev_init:
  452. netdev_nullify ( netdev );
  453. netdev_put ( netdev );
  454. abort_with_nothing:
  455. DBG ( "%s:%s\n", dbg, strerror ( rc ) );
  456. return rc;
  457. }
  458. /*
  459. * Remove a device from the PCI device list.
  460. *
  461. * @v pci PCI device to remove.
  462. *
  463. * This is a PCI Device Driver API function.
  464. */
  465. static void myri10ge_pci_remove ( struct pci_device *pci )
  466. {
  467. struct net_device *netdev;
  468. DBGP ( "myri10ge_pci_remove\n" );
  469. netdev = pci_get_drvdata ( pci );
  470. unregister_netdev ( netdev );
  471. netdev_nullify ( netdev );
  472. netdev_put ( netdev );
  473. }
  474. /****************************************************************
  475. * gPXE Network Device Driver Operations
  476. ****************************************************************/
  477. /*
  478. * Close a network device.
  479. *
  480. * @v netdev Device to close.
  481. *
  482. * This is a gPXE Network Device Driver API function.
  483. */
  484. static void myri10ge_net_close ( struct net_device *netdev )
  485. {
  486. struct myri10ge_private *priv;
  487. uint32 data[3];
  488. DBGP ( "myri10ge_net_close\n" );
  489. priv = myri10ge_priv ( netdev );
  490. /* disable interrupts */
  491. myri10ge_net_irq ( netdev, 0 );
  492. /* Reset the NIC interface, so we won't get any more events from
  493. the NIC. */
  494. myri10ge_command ( priv, MXGEFW_CMD_RESET, data );
  495. /* Free receive buffers that were never filled. */
  496. while ( priv->receives_done != priv->receives_posted ) {
  497. free_iob ( priv->receive_iob[priv->receives_done
  498. & MYRI10GE_RECEIVE_WRAP] );
  499. ++priv->receives_done;
  500. }
  501. /* Release DMAable memory. */
  502. free_dma ( priv->dma, sizeof ( *priv->dma ) );
  503. /* Erase all state from the open. */
  504. memset ( priv, 0, sizeof ( *priv ) );
  505. DBG2_RINGS ( priv );
  506. }
  507. /*
  508. * Enable or disable IRQ masking.
  509. *
  510. * @v netdev Device to control.
  511. * @v enable Zero to mask off IRQ, non-zero to enable IRQ.
  512. *
  513. * This is a gPXE Network Driver API function.
  514. */
  515. static void myri10ge_net_irq ( struct net_device *netdev, int enable )
  516. {
  517. struct pci_device *pci_dev;
  518. uint16 val;
  519. DBGP ( "myri10ge_net_irq\n" );
  520. pci_dev = ( struct pci_device * ) netdev->dev;
  521. /* Adjust the Interrupt Disable bit in the Command register of the
  522. PCI Device. */
  523. pci_read_config_word ( pci_dev, PCI_COMMAND, &val );
  524. if ( enable )
  525. val &= ~PCI_COMMAND_INTX_DISABLE;
  526. else
  527. val |= PCI_COMMAND_INTX_DISABLE;
  528. pci_write_config_word ( pci_dev, PCI_COMMAND, val );
  529. }
  530. /*
  531. * Opens a network device.
  532. *
  533. * @v netdev Device to be opened.
  534. * @ret rc Non-zero if failed to open.
  535. *
  536. * This enables tx and rx on the device.
  537. * This is a gPXE Network Device Driver API function.
  538. */
  539. static int myri10ge_net_open ( struct net_device *netdev )
  540. {
  541. const char *dbg; /* printed upon error return */
  542. int rc;
  543. struct io_buffer *iob;
  544. struct myri10ge_private *priv;
  545. uint32 data[3];
  546. struct pci_device *pci_dev;
  547. void *membase;
  548. DBGP ( "myri10ge_net_open\n" );
  549. priv = myri10ge_priv ( netdev );
  550. pci_dev = ( struct pci_device * ) netdev->dev;
  551. membase = phys_to_virt ( pci_dev->membase );
  552. /* Compute address for passing commands to the firmware. */
  553. priv->command = membase + MXGEFW_ETH_CMD;
  554. /* Ensure interrupts are disabled. */
  555. myri10ge_net_irq ( netdev, 0 );
  556. /* Allocate cleared DMAable buffers. */
  557. priv->dma = malloc_dma ( sizeof ( *priv->dma ) , 128 );
  558. if ( !priv->dma ) {
  559. rc = -ENOMEM;
  560. dbg = "DMA";
  561. goto abort_with_nothing;
  562. }
  563. memset ( priv->dma, 0, sizeof ( *priv->dma ) );
  564. /* Simplify following code. */
  565. #define TRY( prefix, base, suffix ) do { \
  566. rc = myri10ge_command ( priv, \
  567. MXGEFW_ \
  568. ## prefix \
  569. ## base \
  570. ## suffix, \
  571. data ); \
  572. if ( rc ) { \
  573. dbg = #base; \
  574. goto abort_with_dma; \
  575. } \
  576. } while ( 0 )
  577. /* Send a reset command to the card to see if it is alive,
  578. and to reset its queue state. */
  579. TRY ( CMD_, RESET , );
  580. /* Set the interrupt queue size. */
  581. data[0] = ( sizeof ( priv->dma->receive_completion )
  582. | MXGEFW_CMD_SET_INTRQ_SIZE_FLAG_NO_STRICT_SIZE_CHECK );
  583. TRY ( CMD_SET_ , INTRQ_SIZE , );
  584. /* Set the interrupt queue DMA address. */
  585. data[0] = virt_to_bus ( &priv->dma->receive_completion );
  586. data[1] = 0;
  587. TRY ( CMD_SET_, INTRQ_DMA, );
  588. /* Get the NIC interrupt claim address. */
  589. TRY ( CMD_GET_, IRQ_ACK, _OFFSET );
  590. priv->irq_claim = membase + data[0];
  591. /* Get the NIC interrupt assert address. */
  592. TRY ( CMD_GET_, IRQ_DEASSERT, _OFFSET );
  593. priv->irq_deassert = membase + data[0];
  594. /* Disable interrupt coalescing, which is inappropriate for the
  595. minimal buffering we provide. */
  596. TRY ( CMD_GET_, INTR_COAL, _DELAY_OFFSET );
  597. * ( ( uint32 * ) ( membase + data[0] ) ) = 0;
  598. /* Set the NIC mac address. */
  599. data[0] = ( netdev->ll_addr[0] << 24
  600. | netdev->ll_addr[1] << 16
  601. | netdev->ll_addr[2] << 8
  602. | netdev->ll_addr[3] );
  603. data[1] = ( ( netdev->ll_addr[4] << 8 )
  604. | netdev->ll_addr[5] );
  605. TRY ( SET_ , MAC_ADDRESS , );
  606. /* Enable multicast receives, because some gPXE clients don't work
  607. without multicast. . */
  608. TRY ( ENABLE_ , ALLMULTI , );
  609. /* Disable Ethernet flow control, so the NIC cannot deadlock the
  610. network under any circumstances. */
  611. TRY ( DISABLE_ , FLOW , _CONTROL );
  612. /* Compute transmit ring sizes. */
  613. data[0] = 0; /* slice 0 */
  614. TRY ( CMD_GET_, SEND_RING, _SIZE );
  615. priv->transmit_ring_wrap
  616. = data[0] / sizeof ( mcp_kreq_ether_send_t ) - 1;
  617. if ( priv->transmit_ring_wrap
  618. & ( priv->transmit_ring_wrap + 1 ) ) {
  619. rc = -EPROTO;
  620. dbg = "TX_RING";
  621. goto abort_with_dma;
  622. }
  623. /* Compute receive ring sizes. */
  624. data[0] = 0; /* slice 0 */
  625. TRY ( CMD_GET_ , RX_RING , _SIZE );
  626. priv->receive_post_ring_wrap = data[0] / sizeof ( mcp_dma_addr_t ) - 1;
  627. if ( priv->receive_post_ring_wrap
  628. & ( priv->receive_post_ring_wrap + 1 ) ) {
  629. rc = -EPROTO;
  630. dbg = "RX_RING";
  631. goto abort_with_dma;
  632. }
  633. /* Get NIC transmit ring address. */
  634. data[0] = 0; /* slice 0. */
  635. TRY ( CMD_GET_, SEND, _OFFSET );
  636. priv->transmit_ring = membase + data[0];
  637. /* Get the NIC receive ring address. */
  638. data[0] = 0; /* slice 0. */
  639. TRY ( CMD_GET_, SMALL_RX, _OFFSET );
  640. priv->receive_post_ring = membase + data[0];
  641. /* Set the Nic MTU. */
  642. data[0] = ETH_FRAME_LEN;
  643. TRY ( CMD_SET_, MTU, );
  644. /* Tell the NIC our buffer sizes. ( We use only small buffers, so we
  645. set both buffer sizes to the same value, which will force all
  646. received frames to use small buffers. ) */
  647. data[0] = MXGEFW_PAD + ETH_FRAME_LEN;
  648. TRY ( CMD_SET_, SMALL_BUFFER, _SIZE );
  649. data[0] = MXGEFW_PAD + ETH_FRAME_LEN;
  650. TRY ( CMD_SET_, BIG_BUFFER, _SIZE );
  651. /* Tell firmware where to DMA IRQ data */
  652. data[0] = virt_to_bus ( &priv->dma->irq_data );
  653. data[1] = 0;
  654. data[2] = sizeof ( priv->dma->irq_data );
  655. TRY ( CMD_SET_, STATS_DMA_V2, );
  656. /* Post receives. */
  657. while ( priv->receives_posted <= MYRI10GE_RECEIVE_WRAP ) {
  658. /* Reserve 2 extra bytes at the start of packets, since
  659. the firmware always skips the first 2 bytes of the buffer
  660. so TCP headers will be aligned. */
  661. iob = alloc_iob ( MXGEFW_PAD + ETH_FRAME_LEN );
  662. if ( !iob ) {
  663. rc = -ENOMEM;
  664. dbg = "alloc_iob";
  665. goto abort_with_receives_posted;
  666. }
  667. iob_reserve ( iob, MXGEFW_PAD );
  668. myri10ge_post_receive ( priv, iob );
  669. }
  670. /* Bring up the link. */
  671. TRY ( CMD_, ETHERNET_UP, );
  672. DBG2_RINGS ( priv );
  673. return 0;
  674. abort_with_receives_posted:
  675. while ( priv->receives_posted-- )
  676. free_iob ( priv->receive_iob[priv->receives_posted] );
  677. abort_with_dma:
  678. /* Because the link is not up, we don't have to reset the NIC here. */
  679. free_dma ( priv->dma, sizeof ( *priv->dma ) );
  680. abort_with_nothing:
  681. /* Erase all signs of the failed open. */
  682. memset ( priv, 0, sizeof ( *priv ) );
  683. DBG ( "%s: %s\n", dbg, strerror ( rc ) );
  684. return ( rc );
  685. }
  686. /*
  687. * This function allows a driver to process events during operation.
  688. *
  689. * @v netdev Device being polled.
  690. *
  691. * This is called periodically by gPXE to let the driver check the status of
  692. * transmitted packets and to allow the driver to check for received packets.
  693. * This is a gPXE Network Device Driver API function.
  694. */
  695. static void myri10ge_net_poll ( struct net_device *netdev )
  696. {
  697. struct io_buffer *iob;
  698. struct io_buffer *replacement;
  699. struct myri10ge_dma_buffers *dma;
  700. struct myri10ge_private *priv;
  701. unsigned int length;
  702. unsigned int orig_receives_posted;
  703. DBGP ( "myri10ge_net_poll\n" );
  704. priv = myri10ge_priv ( netdev );
  705. dma = priv->dma;
  706. /* Process any pending interrupt. */
  707. myri10ge_interrupt_handler ( netdev );
  708. /* Pass up received frames, but limit ourselves to receives posted
  709. before this function was called, so we cannot livelock if
  710. receives are arriving faster than we process them. */
  711. orig_receives_posted = priv->receives_posted;
  712. while ( priv->receives_done != orig_receives_posted ) {
  713. /* Stop if there is no pending receive. */
  714. length = ntohs ( dma->receive_completion
  715. [priv->receives_done
  716. & MYRI10GE_RECEIVE_COMPLETION_WRAP]
  717. .length );
  718. if ( length == 0 )
  719. break;
  720. /* Allocate a replacement buffer. If none is available,
  721. stop passing up packets until a buffer is available.
  722. Reserve 2 extra bytes at the start of packets, since
  723. the firmware always skips the first 2 bytes of the buffer
  724. so TCP headers will be aligned. */
  725. replacement = alloc_iob ( MXGEFW_PAD + ETH_FRAME_LEN );
  726. if ( !replacement ) {
  727. DBG ( "NO RX BUF\n" );
  728. break;
  729. }
  730. iob_reserve ( replacement, MXGEFW_PAD );
  731. /* Pass up the received frame. */
  732. iob = priv->receive_iob[priv->receives_done
  733. & MYRI10GE_RECEIVE_WRAP];
  734. iob_put ( iob, length );
  735. netdev_rx ( netdev, iob );
  736. /* We have consumed the packet, so clear the receive
  737. notification. */
  738. dma->receive_completion [priv->receives_done
  739. & MYRI10GE_RECEIVE_COMPLETION_WRAP]
  740. .length = 0;
  741. wmb();
  742. /* Replace the passed-up I/O buffer. */
  743. myri10ge_post_receive ( priv, replacement );
  744. ++priv->receives_done;
  745. DBG2_RINGS ( priv );
  746. }
  747. }
  748. /*
  749. * This transmits a packet.
  750. *
  751. * @v netdev Device to transmit from.
  752. * @v iobuf Data to transmit.
  753. * @ret rc Non-zero if failed to transmit.
  754. *
  755. * This is a gPXE Network Driver API function.
  756. */
  757. static int myri10ge_net_transmit ( struct net_device *netdev,
  758. struct io_buffer *iobuf )
  759. {
  760. mcp_kreq_ether_send_t *kreq;
  761. size_t len;
  762. struct myri10ge_private *priv;
  763. uint32 transmits_posted;
  764. DBGP ( "myri10ge_net_transmit\n" );
  765. priv = myri10ge_priv ( netdev );
  766. /* Confirm space in the send ring. */
  767. transmits_posted = priv->transmits_posted;
  768. if ( transmits_posted - priv->transmits_done
  769. > MYRI10GE_TRANSMIT_WRAP ) {
  770. DBG ( "TX ring full\n" );
  771. return -ENOBUFS;
  772. }
  773. DBG2 ( "TX %p+%d ", iobuf->data, iob_len ( iobuf ) );
  774. DBG2_HD ( iobuf->data, 14 );
  775. /* Record the packet being transmitted, so we can later report
  776. send completion. */
  777. priv->transmit_iob[transmits_posted & MYRI10GE_TRANSMIT_WRAP] = iobuf;
  778. /* Copy and pad undersized frames, because the NIC does not pad,
  779. and we would rather copy small frames than do a gather. */
  780. len = iob_len ( iobuf );
  781. if ( len < ETH_ZLEN ) {
  782. iob_pad ( iobuf, ETH_ZLEN );
  783. len = ETH_ZLEN;
  784. }
  785. /* Enqueue the packet by writing a descriptor to the NIC.
  786. This is a bit tricky because the HW requires 32-bit writes,
  787. but the structure has smaller fields. */
  788. kreq = &priv->transmit_ring[transmits_posted
  789. & priv->transmit_ring_wrap];
  790. kreq->addr_high = 0;
  791. kreq->addr_low = htonl ( virt_to_bus ( iobuf->data ) );
  792. ( ( uint32 * ) kreq ) [2] = htonl (
  793. 0x0000 << 16 /* pseudo_header_offset */
  794. | ( len & 0xFFFF ) /* length */
  795. );
  796. wmb();
  797. ( ( uint32 * ) kreq ) [3] = htonl (
  798. 0x00 << 24 /* pad */
  799. | 0x01 << 16 /* rdma_count */
  800. | 0x00 << 8 /* cksum_offset */
  801. | ( MXGEFW_FLAGS_SMALL
  802. | MXGEFW_FLAGS_FIRST
  803. | MXGEFW_FLAGS_NO_TSO ) /* flags */
  804. );
  805. wmb();
  806. /* Mark the slot as consumed and return. */
  807. priv->transmits_posted = ++transmits_posted;
  808. DBG2_RINGS ( priv );
  809. return 0;
  810. }
  811. static struct pci_device_id myri10ge_nics[] = {
  812. /* Each of these macros must be a single line to satisfy a script. */
  813. PCI_ROM ( 0x14c1, 0x0008, "myri10ge", "Myricom 10Gb Ethernet Adapter", 0 ) ,
  814. };
  815. struct pci_driver myri10ge_driver __pci_driver = {
  816. .ids = myri10ge_nics,
  817. .id_count = ( sizeof ( myri10ge_nics ) / sizeof ( myri10ge_nics[0] ) ) ,
  818. .probe = myri10ge_pci_probe,
  819. .remove = myri10ge_pci_remove
  820. };
  821. /*
  822. * Local variables:
  823. * c-basic-offset: 8
  824. * c-indent-level: 8
  825. * tab-width: 8
  826. * End:
  827. */