Вы не можете выбрать более 25 тем Темы должны начинаться с буквы или цифры, могут содержать дефисы(-) и должны содержать не более 35 символов.

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670
  1. /*
  2. * Copyright (C) 2012 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. FILE_LICENCE ( GPL2_OR_LATER );
  20. #include <stdint.h>
  21. #include <string.h>
  22. #include <unistd.h>
  23. #include <errno.h>
  24. #include <byteswap.h>
  25. #include <ipxe/netdevice.h>
  26. #include <ipxe/ethernet.h>
  27. #include <ipxe/if_ether.h>
  28. #include <ipxe/iobuf.h>
  29. #include <ipxe/malloc.h>
  30. #include <ipxe/pci.h>
  31. #include <ipxe/mii.h>
  32. #include "myson.h"
  33. /** @file
  34. *
  35. * Myson Technology network card driver
  36. *
  37. */
  38. /******************************************************************************
  39. *
  40. * Device reset
  41. *
  42. ******************************************************************************
  43. */
  44. /**
  45. * Reset controller chip
  46. *
  47. * @v myson Myson device
  48. * @ret rc Return status code
  49. */
  50. static int myson_soft_reset ( struct myson_nic *myson ) {
  51. uint32_t bcr;
  52. unsigned int i;
  53. /* Initiate reset */
  54. bcr = readl ( myson->regs + MYSON_BCR );
  55. writel ( ( bcr | MYSON_BCR_SWR ), myson->regs + MYSON_BCR );
  56. /* Wait for reset to complete */
  57. for ( i = 0 ; i < MYSON_RESET_MAX_WAIT_MS ; i++ ) {
  58. /* If reset is not complete, delay 1ms and retry */
  59. if ( readl ( myson->regs + MYSON_BCR ) & MYSON_BCR_SWR ) {
  60. mdelay ( 1 );
  61. continue;
  62. }
  63. /* Apply a sensible default bus configuration */
  64. bcr = readl ( myson->regs + MYSON_BCR );
  65. bcr &= ~MYSON_BCR_PBL_MASK;
  66. bcr |= ( MYSON_BCR_RLE | MYSON_BCR_RME | MYSON_BCR_WIE |
  67. MYSON_BCR_PBL_DEFAULT );
  68. writel ( bcr, myson->regs + MYSON_BCR );
  69. DBGC ( myson, "MYSON %p using configuration %08x\n",
  70. myson, bcr );
  71. return 0;
  72. }
  73. DBGC ( myson, "MYSON %p timed out waiting for reset\n", myson );
  74. return -ETIMEDOUT;
  75. }
  76. /**
  77. * Reload configuration from EEPROM
  78. *
  79. * @v myson Myson device
  80. * @ret rc Return status code
  81. */
  82. static int myson_reload_config ( struct myson_nic *myson ) {
  83. unsigned int i;
  84. /* Initiate reload */
  85. writel ( MYSON_ROM_AUTOLD, myson->regs + MYSON_ROM_MII );
  86. /* Wait for reload to complete */
  87. for ( i = 0 ; i < MYSON_AUTOLD_MAX_WAIT_MS ; i++ ) {
  88. /* If reload is not complete, delay 1ms and retry */
  89. if ( readl ( myson->regs + MYSON_ROM_MII ) & MYSON_ROM_AUTOLD ){
  90. mdelay ( 1 );
  91. continue;
  92. }
  93. return 0;
  94. }
  95. DBGC ( myson, "MYSON %p timed out waiting for configuration "
  96. "reload\n", myson );
  97. return -ETIMEDOUT;
  98. }
  99. /**
  100. * Reset hardware
  101. *
  102. * @v myson Myson device
  103. * @ret rc Return status code
  104. */
  105. static int myson_reset ( struct myson_nic *myson ) {
  106. int rc;
  107. /* Disable all interrupts */
  108. writel ( 0, myson->regs + MYSON_IMR );
  109. /* Perform soft reset */
  110. if ( ( rc = myson_soft_reset ( myson ) ) != 0 )
  111. return rc;
  112. /* Reload configuration from EEPROM */
  113. if ( ( rc = myson_reload_config ( myson ) ) != 0 )
  114. return rc;
  115. return 0;
  116. }
  117. /******************************************************************************
  118. *
  119. * Network device interface
  120. *
  121. ******************************************************************************
  122. */
  123. /**
  124. * Create descriptor ring
  125. *
  126. * @v myson Myson device
  127. * @v ring Descriptor ring
  128. * @ret rc Return status code
  129. */
  130. static int myson_create_ring ( struct myson_nic *myson,
  131. struct myson_ring *ring ) {
  132. size_t len = ( ring->count * sizeof ( ring->desc[0] ) );
  133. struct myson_descriptor *desc;
  134. struct myson_descriptor *next;
  135. physaddr_t address;
  136. unsigned int i;
  137. int rc;
  138. /* Allocate descriptor ring */
  139. ring->desc = malloc_dma ( len, MYSON_RING_ALIGN );
  140. if ( ! ring->desc ) {
  141. rc = -ENOMEM;
  142. goto err_alloc;
  143. }
  144. address = virt_to_bus ( ring->desc );
  145. /* Check address is usable by card */
  146. if ( ! myson_address_ok ( address + len ) ) {
  147. DBGC ( myson, "MYSON %p cannot support 64-bit ring address\n",
  148. myson );
  149. rc = -ENOTSUP;
  150. goto err_64bit;
  151. }
  152. /* Initialise descriptor ring */
  153. memset ( ring->desc, 0, len );
  154. for ( i = 0 ; i < ring->count ; i++ ) {
  155. desc = &ring->desc[i];
  156. next = &ring->desc[ ( i + 1 ) % ring->count ];
  157. desc->next = cpu_to_le32 ( virt_to_bus ( next ) );
  158. }
  159. /* Program ring address */
  160. writel ( address, myson->regs + ring->reg );
  161. DBGC ( myson, "MYSON %p ring %02x is at [%08llx,%08llx)\n",
  162. myson, ring->reg, ( ( unsigned long long ) address ),
  163. ( ( unsigned long long ) address + len ) );
  164. return 0;
  165. err_64bit:
  166. free_dma ( ring->desc, len );
  167. ring->desc = NULL;
  168. err_alloc:
  169. return rc;
  170. }
  171. /**
  172. * Destroy descriptor ring
  173. *
  174. * @v myson Myson device
  175. * @v ring Descriptor ring
  176. */
  177. static void myson_destroy_ring ( struct myson_nic *myson,
  178. struct myson_ring *ring ) {
  179. size_t len = ( ring->count * sizeof ( ring->desc[0] ) );
  180. /* Clear ring address */
  181. writel ( 0, myson->regs + ring->reg );
  182. /* Free descriptor ring */
  183. free_dma ( ring->desc, len );
  184. ring->desc = NULL;
  185. ring->prod = 0;
  186. ring->cons = 0;
  187. }
  188. /**
  189. * Refill receive descriptor ring
  190. *
  191. * @v netdev Network device
  192. */
  193. static void myson_refill_rx ( struct net_device *netdev ) {
  194. struct myson_nic *myson = netdev->priv;
  195. struct myson_descriptor *rx;
  196. struct io_buffer *iobuf;
  197. unsigned int rx_idx;
  198. physaddr_t address;
  199. while ( ( myson->rx.prod - myson->rx.cons ) < MYSON_NUM_RX_DESC ) {
  200. /* Allocate I/O buffer */
  201. iobuf = alloc_iob ( MYSON_RX_MAX_LEN );
  202. if ( ! iobuf ) {
  203. /* Wait for next refill */
  204. return;
  205. }
  206. /* Check address is usable by card */
  207. address = virt_to_bus ( iobuf->data );
  208. if ( ! myson_address_ok ( address ) ) {
  209. DBGC ( myson, "MYSON %p cannot support 64-bit RX "
  210. "buffer address\n", myson );
  211. netdev_rx_err ( netdev, iobuf, -ENOTSUP );
  212. return;
  213. }
  214. /* Get next receive descriptor */
  215. rx_idx = ( myson->rx.prod++ % MYSON_NUM_RX_DESC );
  216. rx = &myson->rx.desc[rx_idx];
  217. /* Populate receive descriptor */
  218. rx->address = cpu_to_le32 ( address );
  219. rx->control =
  220. cpu_to_le32 ( MYSON_RX_CTRL_RBS ( MYSON_RX_MAX_LEN ) );
  221. wmb();
  222. rx->status = cpu_to_le32 ( MYSON_RX_STAT_OWN );
  223. wmb();
  224. /* Record I/O buffer */
  225. assert ( myson->rx_iobuf[rx_idx] == NULL );
  226. myson->rx_iobuf[rx_idx] = iobuf;
  227. /* Notify card that there are descriptors available */
  228. writel ( 0, myson->regs + MYSON_RXPDR );
  229. DBGC2 ( myson, "MYSON %p RX %d is [%llx,%llx)\n", myson,
  230. rx_idx, ( ( unsigned long long ) address ),
  231. ( ( unsigned long long ) address + MYSON_RX_MAX_LEN ) );
  232. }
  233. }
  234. /**
  235. * Open network device
  236. *
  237. * @v netdev Network device
  238. * @ret rc Return status code
  239. */
  240. static int myson_open ( struct net_device *netdev ) {
  241. struct myson_nic *myson = netdev->priv;
  242. union myson_physical_address mac;
  243. int rc;
  244. /* Set MAC address */
  245. memset ( &mac, 0, sizeof ( mac ) );
  246. memcpy ( mac.raw, netdev->ll_addr, ETH_ALEN );
  247. writel ( le32_to_cpu ( mac.reg.low ), myson->regs + MYSON_PAR0 );
  248. writel ( le32_to_cpu ( mac.reg.high ), myson->regs + MYSON_PAR4 );
  249. /* Create transmit descriptor ring */
  250. if ( ( rc = myson_create_ring ( myson, &myson->tx ) ) != 0 )
  251. goto err_create_tx;
  252. /* Create receive descriptor ring */
  253. if ( ( rc = myson_create_ring ( myson, &myson->rx ) ) != 0 )
  254. goto err_create_rx;
  255. /* Configure transmitter and receiver */
  256. writel ( ( MYSON_TCR_TE | MYSON_RCR_PROM | MYSON_RCR_AB | MYSON_RCR_AM |
  257. MYSON_RCR_ARP | MYSON_RCR_ALP | MYSON_RCR_RE ),
  258. myson->regs + MYSON_TCR_RCR );
  259. /* Fill receive ring */
  260. myson_refill_rx ( netdev );
  261. return 0;
  262. myson_destroy_ring ( myson, &myson->rx );
  263. err_create_rx:
  264. myson_destroy_ring ( myson, &myson->tx );
  265. err_create_tx:
  266. return rc;
  267. }
  268. /**
  269. * Wait for transmit and receive to become idle
  270. *
  271. * @v myson Myson device
  272. * @ret rc Return status code
  273. */
  274. static int myson_wait_idle ( struct myson_nic *myson ) {
  275. uint32_t tcr_rcr;
  276. unsigned int i;
  277. /* Wait for both transmit and receive to be idle */
  278. for ( i = 0 ; i < MYSON_IDLE_MAX_WAIT_MS ; i++ ) {
  279. /* If either process is running, delay 1ms and retry */
  280. tcr_rcr = readl ( myson->regs + MYSON_TCR_RCR );
  281. if ( tcr_rcr & ( MYSON_TCR_TXS | MYSON_RCR_RXS ) ) {
  282. mdelay ( 1 );
  283. continue;
  284. }
  285. return 0;
  286. }
  287. DBGC ( myson, "MYSON %p timed out waiting for idle state (status "
  288. "%08x)\n", myson, tcr_rcr );
  289. return -ETIMEDOUT;
  290. }
  291. /**
  292. * Close network device
  293. *
  294. * @v netdev Network device
  295. */
  296. static void myson_close ( struct net_device *netdev ) {
  297. struct myson_nic *myson = netdev->priv;
  298. unsigned int i;
  299. /* Disable receiver and transmitter */
  300. writel ( 0, myson->regs + MYSON_TCR_RCR );
  301. /* Allow time for receiver and transmitter to become idle */
  302. myson_wait_idle ( myson );
  303. /* Destroy receive descriptor ring */
  304. myson_destroy_ring ( myson, &myson->rx );
  305. /* Discard any unused receive buffers */
  306. for ( i = 0 ; i < MYSON_NUM_RX_DESC ; i++ ) {
  307. if ( myson->rx_iobuf[i] )
  308. free_iob ( myson->rx_iobuf[i] );
  309. myson->rx_iobuf[i] = NULL;
  310. }
  311. /* Destroy transmit descriptor ring */
  312. myson_destroy_ring ( myson, &myson->tx );
  313. }
  314. /**
  315. * Transmit packet
  316. *
  317. * @v netdev Network device
  318. * @v iobuf I/O buffer
  319. * @ret rc Return status code
  320. */
  321. static int myson_transmit ( struct net_device *netdev,
  322. struct io_buffer *iobuf ) {
  323. struct myson_nic *myson = netdev->priv;
  324. struct myson_descriptor *tx;
  325. unsigned int tx_idx;
  326. physaddr_t address;
  327. /* Check address is usable by card */
  328. address = virt_to_bus ( iobuf->data );
  329. if ( ! myson_address_ok ( address ) ) {
  330. DBGC ( myson, "MYSON %p cannot support 64-bit TX buffer "
  331. "address\n", myson );
  332. return -ENOTSUP;
  333. }
  334. /* Get next transmit descriptor */
  335. if ( ( myson->tx.prod - myson->tx.cons ) >= MYSON_NUM_TX_DESC ) {
  336. DBGC ( myson, "MYSON %p out of transmit descriptors\n",
  337. myson );
  338. return -ENOBUFS;
  339. }
  340. tx_idx = ( myson->tx.prod++ % MYSON_NUM_TX_DESC );
  341. tx = &myson->tx.desc[tx_idx];
  342. /* Populate transmit descriptor */
  343. tx->address = cpu_to_le32 ( address );
  344. tx->control = cpu_to_le32 ( MYSON_TX_CTRL_IC | MYSON_TX_CTRL_LD |
  345. MYSON_TX_CTRL_FD | MYSON_TX_CTRL_CRC |
  346. MYSON_TX_CTRL_PAD | MYSON_TX_CTRL_RTLC |
  347. MYSON_TX_CTRL_PKTS ( iob_len ( iobuf ) ) |
  348. MYSON_TX_CTRL_TBS ( iob_len ( iobuf ) ) );
  349. wmb();
  350. tx->status = cpu_to_le32 ( MYSON_TX_STAT_OWN );
  351. wmb();
  352. /* Notify card that there are packets ready to transmit */
  353. writel ( 0, myson->regs + MYSON_TXPDR );
  354. DBGC2 ( myson, "MYSON %p TX %d is [%llx,%llx)\n", myson, tx_idx,
  355. ( ( unsigned long long ) address ),
  356. ( ( unsigned long long ) address + iob_len ( iobuf ) ) );
  357. return 0;
  358. }
  359. /**
  360. * Poll for completed packets
  361. *
  362. * @v netdev Network device
  363. */
  364. static void myson_poll_tx ( struct net_device *netdev ) {
  365. struct myson_nic *myson = netdev->priv;
  366. struct myson_descriptor *tx;
  367. unsigned int tx_idx;
  368. /* Check for completed packets */
  369. while ( myson->tx.cons != myson->tx.prod ) {
  370. /* Get next transmit descriptor */
  371. tx_idx = ( myson->tx.cons % MYSON_NUM_TX_DESC );
  372. tx = &myson->tx.desc[tx_idx];
  373. /* Stop if descriptor is still in use */
  374. if ( tx->status & cpu_to_le32 ( MYSON_TX_STAT_OWN ) )
  375. return;
  376. /* Complete TX descriptor */
  377. if ( tx->status & cpu_to_le32 ( MYSON_TX_STAT_ABORT |
  378. MYSON_TX_STAT_CSL ) ) {
  379. DBGC ( myson, "MYSON %p TX %d completion error "
  380. "(%08x)\n", myson, tx_idx,
  381. le32_to_cpu ( tx->status ) );
  382. netdev_tx_complete_next_err ( netdev, -EIO );
  383. } else {
  384. DBGC2 ( myson, "MYSON %p TX %d complete\n",
  385. myson, tx_idx );
  386. netdev_tx_complete_next ( netdev );
  387. }
  388. myson->tx.cons++;
  389. }
  390. }
  391. /**
  392. * Poll for received packets
  393. *
  394. * @v netdev Network device
  395. */
  396. static void myson_poll_rx ( struct net_device *netdev ) {
  397. struct myson_nic *myson = netdev->priv;
  398. struct myson_descriptor *rx;
  399. struct io_buffer *iobuf;
  400. unsigned int rx_idx;
  401. size_t len;
  402. /* Check for received packets */
  403. while ( myson->rx.cons != myson->rx.prod ) {
  404. /* Get next receive descriptor */
  405. rx_idx = ( myson->rx.cons % MYSON_NUM_RX_DESC );
  406. rx = &myson->rx.desc[rx_idx];
  407. /* Stop if descriptor is still in use */
  408. if ( rx->status & MYSON_RX_STAT_OWN )
  409. return;
  410. /* Populate I/O buffer */
  411. iobuf = myson->rx_iobuf[rx_idx];
  412. myson->rx_iobuf[rx_idx] = NULL;
  413. len = MYSON_RX_STAT_FLNG ( le32_to_cpu ( rx->status ) );
  414. iob_put ( iobuf, len - 4 /* strip CRC */ );
  415. /* Hand off to network stack */
  416. if ( rx->status & cpu_to_le32 ( MYSON_RX_STAT_ES ) ) {
  417. DBGC ( myson, "MYSON %p RX %d error (length %zd, "
  418. "status %08x)\n", myson, rx_idx, len,
  419. le32_to_cpu ( rx->status ) );
  420. netdev_rx_err ( netdev, iobuf, -EIO );
  421. } else {
  422. DBGC2 ( myson, "MYSON %p RX %d complete (length "
  423. "%zd)\n", myson, rx_idx, len );
  424. netdev_rx ( netdev, iobuf );
  425. }
  426. myson->rx.cons++;
  427. }
  428. }
  429. /**
  430. * Poll for completed and received packets
  431. *
  432. * @v netdev Network device
  433. */
  434. static void myson_poll ( struct net_device *netdev ) {
  435. struct myson_nic *myson = netdev->priv;
  436. uint32_t isr;
  437. unsigned int i;
  438. /* Polling the ISR seems to really upset this card; it ends up
  439. * getting no useful PCI transfers done and, for some reason,
  440. * flooding the network with invalid packets. Work around
  441. * this by introducing deliberate delays between ISR reads.
  442. */
  443. for ( i = 0 ; i < MYSON_ISR_IODELAY_COUNT ; i++ )
  444. iodelay();
  445. /* Check for and acknowledge interrupts */
  446. isr = readl ( myson->regs + MYSON_ISR );
  447. if ( ! isr )
  448. return;
  449. writel ( isr, myson->regs + MYSON_ISR );
  450. /* Poll for TX completions, if applicable */
  451. if ( isr & MYSON_IRQ_TI )
  452. myson_poll_tx ( netdev );
  453. /* Poll for RX completionsm, if applicable */
  454. if ( isr & MYSON_IRQ_RI )
  455. myson_poll_rx ( netdev );
  456. /* Refill RX ring */
  457. myson_refill_rx ( netdev );
  458. }
  459. /**
  460. * Enable or disable interrupts
  461. *
  462. * @v netdev Network device
  463. * @v enable Interrupts should be enabled
  464. */
  465. static void myson_irq ( struct net_device *netdev, int enable ) {
  466. struct myson_nic *myson = netdev->priv;
  467. uint32_t imr;
  468. imr = ( enable ? ( MYSON_IRQ_TI | MYSON_IRQ_RI ) : 0 );
  469. writel ( imr, myson->regs + MYSON_IMR );
  470. }
  471. /** Myson network device operations */
  472. static struct net_device_operations myson_operations = {
  473. .open = myson_open,
  474. .close = myson_close,
  475. .transmit = myson_transmit,
  476. .poll = myson_poll,
  477. .irq = myson_irq,
  478. };
  479. /******************************************************************************
  480. *
  481. * PCI interface
  482. *
  483. ******************************************************************************
  484. */
  485. /**
  486. * Probe PCI device
  487. *
  488. * @v pci PCI device
  489. * @ret rc Return status code
  490. */
  491. static int myson_probe ( struct pci_device *pci ) {
  492. struct net_device *netdev;
  493. struct myson_nic *myson;
  494. union myson_physical_address mac;
  495. int rc;
  496. /* Allocate and initialise net device */
  497. netdev = alloc_etherdev ( sizeof ( *myson ) );
  498. if ( ! netdev ) {
  499. rc = -ENOMEM;
  500. goto err_alloc;
  501. }
  502. netdev_init ( netdev, &myson_operations );
  503. myson = netdev->priv;
  504. pci_set_drvdata ( pci, netdev );
  505. netdev->dev = &pci->dev;
  506. memset ( myson, 0, sizeof ( *myson ) );
  507. myson_init_ring ( &myson->tx, MYSON_NUM_TX_DESC, MYSON_TXLBA );
  508. myson_init_ring ( &myson->rx, MYSON_NUM_RX_DESC, MYSON_RXLBA );
  509. /* Fix up PCI device */
  510. adjust_pci_device ( pci );
  511. /* Map registers */
  512. myson->regs = ioremap ( pci->membase, MYSON_BAR_SIZE );
  513. /* Reset the NIC */
  514. if ( ( rc = myson_reset ( myson ) ) != 0 )
  515. goto err_reset;
  516. /* Read MAC address */
  517. mac.reg.low = cpu_to_le32 ( readl ( myson->regs + MYSON_PAR0 ) );
  518. mac.reg.high = cpu_to_le32 ( readl ( myson->regs + MYSON_PAR4 ) );
  519. memcpy ( netdev->hw_addr, mac.raw, ETH_ALEN );
  520. /* Register network device */
  521. if ( ( rc = register_netdev ( netdev ) ) != 0 )
  522. goto err_register_netdev;
  523. /* Mark as link up; we don't yet handle link state */
  524. netdev_link_up ( netdev );
  525. return 0;
  526. unregister_netdev ( netdev );
  527. err_register_netdev:
  528. myson_reset ( myson );
  529. err_reset:
  530. iounmap ( myson->regs );
  531. netdev_nullify ( netdev );
  532. netdev_put ( netdev );
  533. err_alloc:
  534. return rc;
  535. }
  536. /**
  537. * Remove PCI device
  538. *
  539. * @v pci PCI device
  540. */
  541. static void myson_remove ( struct pci_device *pci ) {
  542. struct net_device *netdev = pci_get_drvdata ( pci );
  543. struct myson_nic *myson = netdev->priv;
  544. /* Unregister network device */
  545. unregister_netdev ( netdev );
  546. /* Reset card */
  547. myson_reset ( myson );
  548. /* Free network device */
  549. iounmap ( myson->regs );
  550. netdev_nullify ( netdev );
  551. netdev_put ( netdev );
  552. }
  553. /** Myson PCI device IDs */
  554. static struct pci_device_id myson_nics[] = {
  555. PCI_ROM ( 0x1516, 0x0800, "mtd800", "MTD-8xx", 0 ),
  556. PCI_ROM ( 0x1516, 0x0803, "mtd803", "Surecom EP-320X-S", 0 ),
  557. PCI_ROM ( 0x1516, 0x0891, "mtd891", "MTD-8xx", 0 ),
  558. };
  559. /** Myson PCI driver */
  560. struct pci_driver myson_driver __pci_driver = {
  561. .ids = myson_nics,
  562. .id_count = ( sizeof ( myson_nics ) / sizeof ( myson_nics[0] ) ),
  563. .probe = myson_probe,
  564. .remove = myson_remove,
  565. };