#include <stdint.h>#include <byteswap.h>#include <errno.h>#include <gpxe/ethernet.h>#include <gpxe/if_ether.h>#include <gpxe/iobuf.h>#include <gpxe/malloc.h>#include <gpxe/netdevice.h>#include <gpxe/pci.h>#include <gpxe/timer.h>#include "myri10ge_mcp.h"Go to the source code of this file.
| #define MYRI10GE_TRANSMIT_WRAP 1U |
Definition at line 107 of file myri10ge.c.
Referenced by myri10ge_interrupt_handler(), and myri10ge_net_transmit().
| #define MYRI10GE_RECEIVE_WRAP 7U |
Definition at line 108 of file myri10ge.c.
Referenced by myri10ge_net_close(), myri10ge_net_open(), myri10ge_net_poll(), and myri10ge_post_receive().
| #define MYRI10GE_RECEIVE_COMPLETION_WRAP 31U |
| #define DBG2_RINGS | ( | priv | ) |
Value:
DBG2 ( "tx %x/%x rx %x/%x in %s() \n", \ ( priv ) ->transmits_done, ( priv ) -> transmits_posted, \ ( priv ) ->receives_done, ( priv ) -> receives_posted, \ __FUNCTION__ )
Definition at line 181 of file myri10ge.c.
Referenced by myri10ge_net_close(), myri10ge_net_open(), myri10ge_net_poll(), and myri10ge_net_transmit().
| #define VS_ADDR ( vs + 0x18 ) |
| #define VS_DATA ( vs + 0x14 ) |
| #define VS_MODE ( vs + 0x10 ) |
| #define VS_MODE_READ32 0x3 |
| #define VS_MODE_LOCATE 0x8 |
| #define VS_LOCATE_STRING_SPECS 0x3 |
| #define TRY | ( | prefix, | |||
| base, | |||||
| suffix | ) |
Value:
do { \ rc = myri10ge_command ( priv, \ MXGEFW_ \ ## prefix \ ## base \ ## suffix, \ data ); \ if ( rc ) { \ dbg = #base; \ goto abort_with_dma; \ } \ } while ( 0 )
Referenced by myri10ge_net_open().
| FILE_LICENCE | ( | GPL2_ONLY | ) |
| static int myri10ge_pci_probe | ( | struct pci_device * | , | |
| const struct pci_device_id * | ||||
| ) | [static] |
| static void myri10ge_pci_remove | ( | struct pci_device * | pci | ) | [static] |
Definition at line 576 of file myri10ge.c.
References DBGP, netdev, netdev_nullify(), netdev_put(), pci_get_drvdata(), and unregister_netdev().
00577 { 00578 struct net_device *netdev; 00579 00580 DBGP ( "myri10ge_pci_remove\n" ); 00581 netdev = pci_get_drvdata ( pci ); 00582 00583 unregister_netdev ( netdev ); 00584 netdev_nullify ( netdev ); 00585 netdev_put ( netdev ); 00586 }
| static void myri10ge_net_close | ( | struct net_device * | netdev | ) | [static] |
Definition at line 599 of file myri10ge.c.
References DBG2_RINGS, DBGP, myri10ge_private::dma, free_dma(), free_iob(), memset(), MXGEFW_CMD_RESET, myri10ge_command(), myri10ge_net_irq(), myri10ge_priv(), MYRI10GE_RECEIVE_WRAP, priv, myri10ge_private::receive_iob, myri10ge_private::receives_done, and myri10ge_private::receives_posted.
Referenced by myri10ge_pci_probe().
00600 { 00601 struct myri10ge_private *priv; 00602 uint32 data[3]; 00603 00604 DBGP ( "myri10ge_net_close\n" ); 00605 priv = myri10ge_priv ( netdev ); 00606 00607 /* disable interrupts */ 00608 00609 myri10ge_net_irq ( netdev, 0 ); 00610 00611 /* Reset the NIC interface, so we won't get any more events from 00612 the NIC. */ 00613 00614 myri10ge_command ( priv, MXGEFW_CMD_RESET, data ); 00615 00616 /* Free receive buffers that were never filled. */ 00617 00618 while ( priv->receives_done != priv->receives_posted ) { 00619 free_iob ( priv->receive_iob[priv->receives_done 00620 & MYRI10GE_RECEIVE_WRAP] ); 00621 ++priv->receives_done; 00622 } 00623 00624 /* Release DMAable memory. */ 00625 00626 free_dma ( priv->dma, sizeof ( *priv->dma ) ); 00627 00628 /* Erase all state from the open. */ 00629 00630 memset ( priv, 0, sizeof ( *priv ) ); 00631 00632 DBG2_RINGS ( priv ); 00633 }
| static void myri10ge_net_irq | ( | struct net_device * | netdev, | |
| int | enable | |||
| ) | [static] |
Definition at line 643 of file myri10ge.c.
References DBGP, net_device::dev, PCI_COMMAND, PCI_COMMAND_INTX_DISABLE, pci_read_config_word(), and pci_write_config_word().
Referenced by myri10ge_net_close(), myri10ge_net_open(), and myri10ge_pci_probe().
00644 { 00645 struct pci_device *pci_dev; 00646 uint16 val; 00647 00648 DBGP ( "myri10ge_net_irq\n" ); 00649 pci_dev = ( struct pci_device * ) netdev->dev; 00650 00651 /* Adjust the Interrupt Disable bit in the Command register of the 00652 PCI Device. */ 00653 00654 pci_read_config_word ( pci_dev, PCI_COMMAND, &val ); 00655 if ( enable ) 00656 val &= ~PCI_COMMAND_INTX_DISABLE; 00657 else 00658 val |= PCI_COMMAND_INTX_DISABLE; 00659 pci_write_config_word ( pci_dev, PCI_COMMAND, val ); 00660 }
| static int myri10ge_net_open | ( | struct net_device * | netdev | ) | [static] |
Definition at line 671 of file myri10ge.c.
References alloc_iob(), myri10ge_private::command, DBG, DBG2_RINGS, DBGP, net_device::dev, myri10ge_private::dma, ENOMEM, EPROTO, ETH_FRAME_LEN, free_dma(), free_iob(), iob_reserve, myri10ge_private::irq_claim, myri10ge_dma_buffers::irq_data, myri10ge_private::irq_deassert, net_device::ll_addr, malloc_dma(), pci_device::membase, memset(), MXGEFW_CMD_SET_INTRQ_SIZE_FLAG_NO_STRICT_SIZE_CHECK, MXGEFW_ETH_CMD, MXGEFW_PAD, myri10ge_net_irq(), myri10ge_post_receive(), myri10ge_priv(), MYRI10GE_RECEIVE_WRAP, phys_to_virt(), priv, myri10ge_dma_buffers::receive_completion, myri10ge_private::receive_iob, myri10ge_private::receive_post_ring, myri10ge_private::receive_post_ring_wrap, myri10ge_private::receives_posted, RESET, RX_RING, strerror(), myri10ge_private::transmit_ring, myri10ge_private::transmit_ring_wrap, TRY, and virt_to_bus().
Referenced by myri10ge_pci_probe().
00672 { 00673 const char *dbg; /* printed upon error return */ 00674 int rc; 00675 struct io_buffer *iob; 00676 struct myri10ge_private *priv; 00677 uint32 data[3]; 00678 struct pci_device *pci_dev; 00679 void *membase; 00680 00681 DBGP ( "myri10ge_net_open\n" ); 00682 priv = myri10ge_priv ( netdev ); 00683 pci_dev = ( struct pci_device * ) netdev->dev; 00684 membase = phys_to_virt ( pci_dev->membase ); 00685 00686 /* Compute address for passing commands to the firmware. */ 00687 00688 priv->command = membase + MXGEFW_ETH_CMD; 00689 00690 /* Ensure interrupts are disabled. */ 00691 00692 myri10ge_net_irq ( netdev, 0 ); 00693 00694 /* Allocate cleared DMAable buffers. */ 00695 00696 priv->dma = malloc_dma ( sizeof ( *priv->dma ) , 128 ); 00697 if ( !priv->dma ) { 00698 rc = -ENOMEM; 00699 dbg = "DMA"; 00700 goto abort_with_nothing; 00701 } 00702 memset ( priv->dma, 0, sizeof ( *priv->dma ) ); 00703 00704 /* Simplify following code. */ 00705 00706 #define TRY( prefix, base, suffix ) do { \ 00707 rc = myri10ge_command ( priv, \ 00708 MXGEFW_ \ 00709 ## prefix \ 00710 ## base \ 00711 ## suffix, \ 00712 data ); \ 00713 if ( rc ) { \ 00714 dbg = #base; \ 00715 goto abort_with_dma; \ 00716 } \ 00717 } while ( 0 ) 00718 00719 /* Send a reset command to the card to see if it is alive, 00720 and to reset its queue state. */ 00721 00722 TRY ( CMD_, RESET , ); 00723 00724 /* Set the interrupt queue size. */ 00725 00726 data[0] = ( sizeof ( priv->dma->receive_completion ) 00727 | MXGEFW_CMD_SET_INTRQ_SIZE_FLAG_NO_STRICT_SIZE_CHECK ); 00728 TRY ( CMD_SET_ , INTRQ_SIZE , ); 00729 00730 /* Set the interrupt queue DMA address. */ 00731 00732 data[0] = virt_to_bus ( &priv->dma->receive_completion ); 00733 data[1] = 0; 00734 TRY ( CMD_SET_, INTRQ_DMA, ); 00735 00736 /* Get the NIC interrupt claim address. */ 00737 00738 TRY ( CMD_GET_, IRQ_ACK, _OFFSET ); 00739 priv->irq_claim = membase + data[0]; 00740 00741 /* Get the NIC interrupt assert address. */ 00742 00743 TRY ( CMD_GET_, IRQ_DEASSERT, _OFFSET ); 00744 priv->irq_deassert = membase + data[0]; 00745 00746 /* Disable interrupt coalescing, which is inappropriate for the 00747 minimal buffering we provide. */ 00748 00749 TRY ( CMD_GET_, INTR_COAL, _DELAY_OFFSET ); 00750 * ( ( uint32 * ) ( membase + data[0] ) ) = 0; 00751 00752 /* Set the NIC mac address. */ 00753 00754 data[0] = ( netdev->ll_addr[0] << 24 00755 | netdev->ll_addr[1] << 16 00756 | netdev->ll_addr[2] << 8 00757 | netdev->ll_addr[3] ); 00758 data[1] = ( ( netdev->ll_addr[4] << 8 ) 00759 | netdev->ll_addr[5] ); 00760 TRY ( SET_ , MAC_ADDRESS , ); 00761 00762 /* Enable multicast receives, because some gPXE clients don't work 00763 without multicast. . */ 00764 00765 TRY ( ENABLE_ , ALLMULTI , ); 00766 00767 /* Disable Ethernet flow control, so the NIC cannot deadlock the 00768 network under any circumstances. */ 00769 00770 TRY ( DISABLE_ , FLOW , _CONTROL ); 00771 00772 /* Compute transmit ring sizes. */ 00773 00774 data[0] = 0; /* slice 0 */ 00775 TRY ( CMD_GET_, SEND_RING, _SIZE ); 00776 priv->transmit_ring_wrap 00777 = data[0] / sizeof ( mcp_kreq_ether_send_t ) - 1; 00778 if ( priv->transmit_ring_wrap 00779 & ( priv->transmit_ring_wrap + 1 ) ) { 00780 rc = -EPROTO; 00781 dbg = "TX_RING"; 00782 goto abort_with_dma; 00783 } 00784 00785 /* Compute receive ring sizes. */ 00786 00787 data[0] = 0; /* slice 0 */ 00788 TRY ( CMD_GET_ , RX_RING , _SIZE ); 00789 priv->receive_post_ring_wrap = data[0] / sizeof ( mcp_dma_addr_t ) - 1; 00790 if ( priv->receive_post_ring_wrap 00791 & ( priv->receive_post_ring_wrap + 1 ) ) { 00792 rc = -EPROTO; 00793 dbg = "RX_RING"; 00794 goto abort_with_dma; 00795 } 00796 00797 /* Get NIC transmit ring address. */ 00798 00799 data[0] = 0; /* slice 0. */ 00800 TRY ( CMD_GET_, SEND, _OFFSET ); 00801 priv->transmit_ring = membase + data[0]; 00802 00803 /* Get the NIC receive ring address. */ 00804 00805 data[0] = 0; /* slice 0. */ 00806 TRY ( CMD_GET_, SMALL_RX, _OFFSET ); 00807 priv->receive_post_ring = membase + data[0]; 00808 00809 /* Set the Nic MTU. */ 00810 00811 data[0] = ETH_FRAME_LEN; 00812 TRY ( CMD_SET_, MTU, ); 00813 00814 /* Tell the NIC our buffer sizes. ( We use only small buffers, so we 00815 set both buffer sizes to the same value, which will force all 00816 received frames to use small buffers. ) */ 00817 00818 data[0] = MXGEFW_PAD + ETH_FRAME_LEN; 00819 TRY ( CMD_SET_, SMALL_BUFFER, _SIZE ); 00820 data[0] = MXGEFW_PAD + ETH_FRAME_LEN; 00821 TRY ( CMD_SET_, BIG_BUFFER, _SIZE ); 00822 00823 /* Tell firmware where to DMA IRQ data */ 00824 00825 data[0] = virt_to_bus ( &priv->dma->irq_data ); 00826 data[1] = 0; 00827 data[2] = sizeof ( priv->dma->irq_data ); 00828 TRY ( CMD_SET_, STATS_DMA_V2, ); 00829 00830 /* Post receives. */ 00831 00832 while ( priv->receives_posted <= MYRI10GE_RECEIVE_WRAP ) { 00833 00834 /* Reserve 2 extra bytes at the start of packets, since 00835 the firmware always skips the first 2 bytes of the buffer 00836 so TCP headers will be aligned. */ 00837 00838 iob = alloc_iob ( MXGEFW_PAD + ETH_FRAME_LEN ); 00839 if ( !iob ) { 00840 rc = -ENOMEM; 00841 dbg = "alloc_iob"; 00842 goto abort_with_receives_posted; 00843 } 00844 iob_reserve ( iob, MXGEFW_PAD ); 00845 myri10ge_post_receive ( priv, iob ); 00846 } 00847 00848 /* Bring up the link. */ 00849 00850 TRY ( CMD_, ETHERNET_UP, ); 00851 00852 DBG2_RINGS ( priv ); 00853 return 0; 00854 00855 abort_with_receives_posted: 00856 while ( priv->receives_posted-- ) 00857 free_iob ( priv->receive_iob[priv->receives_posted] ); 00858 abort_with_dma: 00859 /* Because the link is not up, we don't have to reset the NIC here. */ 00860 free_dma ( priv->dma, sizeof ( *priv->dma ) ); 00861 abort_with_nothing: 00862 /* Erase all signs of the failed open. */ 00863 memset ( priv, 0, sizeof ( *priv ) ); 00864 DBG ( "%s: %s\n", dbg, strerror ( rc ) ); 00865 return ( rc ); 00866 }
| static void myri10ge_net_poll | ( | struct net_device * | netdev | ) | [static] |
Definition at line 877 of file myri10ge.c.
References alloc_iob(), DBG, DBG2_RINGS, DBGP, myri10ge_private::dma, ETH_FRAME_LEN, iob_put, iob_reserve, mcp_slot::length, MXGEFW_PAD, myri10ge_interrupt_handler(), myri10ge_post_receive(), myri10ge_priv(), MYRI10GE_RECEIVE_COMPLETION_WRAP, MYRI10GE_RECEIVE_WRAP, netdev_rx(), ntohs, priv, myri10ge_dma_buffers::receive_completion, myri10ge_private::receive_iob, myri10ge_private::receives_done, myri10ge_private::receives_posted, and wmb.
Referenced by myri10ge_pci_probe().
00878 { 00879 struct io_buffer *iob; 00880 struct io_buffer *replacement; 00881 struct myri10ge_dma_buffers *dma; 00882 struct myri10ge_private *priv; 00883 unsigned int length; 00884 unsigned int orig_receives_posted; 00885 00886 DBGP ( "myri10ge_net_poll\n" ); 00887 priv = myri10ge_priv ( netdev ); 00888 dma = priv->dma; 00889 00890 /* Process any pending interrupt. */ 00891 00892 myri10ge_interrupt_handler ( netdev ); 00893 00894 /* Pass up received frames, but limit ourselves to receives posted 00895 before this function was called, so we cannot livelock if 00896 receives are arriving faster than we process them. */ 00897 00898 orig_receives_posted = priv->receives_posted; 00899 while ( priv->receives_done != orig_receives_posted ) { 00900 00901 /* Stop if there is no pending receive. */ 00902 00903 length = ntohs ( dma->receive_completion 00904 [priv->receives_done 00905 & MYRI10GE_RECEIVE_COMPLETION_WRAP] 00906 .length ); 00907 if ( length == 0 ) 00908 break; 00909 00910 /* Allocate a replacement buffer. If none is available, 00911 stop passing up packets until a buffer is available. 00912 00913 Reserve 2 extra bytes at the start of packets, since 00914 the firmware always skips the first 2 bytes of the buffer 00915 so TCP headers will be aligned. */ 00916 00917 replacement = alloc_iob ( MXGEFW_PAD + ETH_FRAME_LEN ); 00918 if ( !replacement ) { 00919 DBG ( "NO RX BUF\n" ); 00920 break; 00921 } 00922 iob_reserve ( replacement, MXGEFW_PAD ); 00923 00924 /* Pass up the received frame. */ 00925 00926 iob = priv->receive_iob[priv->receives_done 00927 & MYRI10GE_RECEIVE_WRAP]; 00928 iob_put ( iob, length ); 00929 netdev_rx ( netdev, iob ); 00930 00931 /* We have consumed the packet, so clear the receive 00932 notification. */ 00933 00934 dma->receive_completion [priv->receives_done 00935 & MYRI10GE_RECEIVE_COMPLETION_WRAP] 00936 .length = 0; 00937 wmb(); 00938 00939 /* Replace the passed-up I/O buffer. */ 00940 00941 myri10ge_post_receive ( priv, replacement ); 00942 ++priv->receives_done; 00943 DBG2_RINGS ( priv ); 00944 } 00945 }
| static int myri10ge_net_transmit | ( | struct net_device * | netdev, | |
| struct io_buffer * | iobuf | |||
| ) | [static] |
Definition at line 956 of file myri10ge.c.
References mcp_kreq_ether_send::addr_high, mcp_kreq_ether_send::addr_low, io_buffer::data, DBG, DBG2, DBG2_HD, DBG2_RINGS, DBGP, ENOBUFS, ETH_ZLEN, htonl, iob_len(), iob_pad(), MXGEFW_FLAGS_FIRST, MXGEFW_FLAGS_NO_TSO, MXGEFW_FLAGS_SMALL, myri10ge_priv(), MYRI10GE_TRANSMIT_WRAP, priv, myri10ge_private::transmit_iob, myri10ge_private::transmit_ring, myri10ge_private::transmit_ring_wrap, myri10ge_private::transmits_done, myri10ge_private::transmits_posted, virt_to_bus(), and wmb.
Referenced by myri10ge_pci_probe().
00958 { 00959 mcp_kreq_ether_send_t *kreq; 00960 size_t len; 00961 struct myri10ge_private *priv; 00962 uint32 transmits_posted; 00963 00964 DBGP ( "myri10ge_net_transmit\n" ); 00965 priv = myri10ge_priv ( netdev ); 00966 00967 /* Confirm space in the send ring. */ 00968 00969 transmits_posted = priv->transmits_posted; 00970 if ( transmits_posted - priv->transmits_done 00971 > MYRI10GE_TRANSMIT_WRAP ) { 00972 DBG ( "TX ring full\n" ); 00973 return -ENOBUFS; 00974 } 00975 00976 DBG2 ( "TX %p+%d ", iobuf->data, iob_len ( iobuf ) ); 00977 DBG2_HD ( iobuf->data, 14 ); 00978 00979 /* Record the packet being transmitted, so we can later report 00980 send completion. */ 00981 00982 priv->transmit_iob[transmits_posted & MYRI10GE_TRANSMIT_WRAP] = iobuf; 00983 00984 /* Copy and pad undersized frames, because the NIC does not pad, 00985 and we would rather copy small frames than do a gather. */ 00986 00987 len = iob_len ( iobuf ); 00988 if ( len < ETH_ZLEN ) { 00989 iob_pad ( iobuf, ETH_ZLEN ); 00990 len = ETH_ZLEN; 00991 } 00992 00993 /* Enqueue the packet by writing a descriptor to the NIC. 00994 This is a bit tricky because the HW requires 32-bit writes, 00995 but the structure has smaller fields. */ 00996 00997 kreq = &priv->transmit_ring[transmits_posted 00998 & priv->transmit_ring_wrap]; 00999 kreq->addr_high = 0; 01000 kreq->addr_low = htonl ( virt_to_bus ( iobuf->data ) ); 01001 ( ( uint32 * ) kreq ) [2] = htonl ( 01002 0x0000 << 16 /* pseudo_header_offset */ 01003 | ( len & 0xFFFF ) /* length */ 01004 ); 01005 wmb(); 01006 ( ( uint32 * ) kreq ) [3] = htonl ( 01007 0x00 << 24 /* pad */ 01008 | 0x01 << 16 /* rdma_count */ 01009 | 0x00 << 8 /* cksum_offset */ 01010 | ( MXGEFW_FLAGS_SMALL 01011 | MXGEFW_FLAGS_FIRST 01012 | MXGEFW_FLAGS_NO_TSO ) /* flags */ 01013 ); 01014 wmb(); 01015 01016 /* Mark the slot as consumed and return. */ 01017 01018 priv->transmits_posted = ++transmits_posted; 01019 DBG2_RINGS ( priv ); 01020 return 0; 01021 }
| static struct myri10ge_private* myri10ge_priv | ( | struct net_device * | nd | ) | [static, read] |
Definition at line 193 of file myri10ge.c.
Referenced by myri10ge_interrupt_handler(), myri10ge_net_close(), myri10ge_net_open(), myri10ge_net_poll(), myri10ge_net_transmit(), and myri10ge_pci_probe().
00194 { 00195 /* Our private data always follows the network device in memory, 00196 since we use alloc_netdev() to allocate the storage. */ 00197 00198 return ( struct myri10ge_private * ) ( nd + 1 ); 00199 }
| static void myri10ge_post_receive | ( | struct myri10ge_private * | priv, | |
| struct io_buffer * | iob | |||
| ) | [static] |
Definition at line 209 of file myri10ge.c.
References mcp_kreq_ether_recv::addr_high, mcp_kreq_ether_recv::addr_low, io_buffer::data, htonl, MYRI10GE_RECEIVE_WRAP, myri10ge_private::receive_iob, myri10ge_private::receive_post_ring, myri10ge_private::receive_post_ring_wrap, myri10ge_private::receives_posted, virt_to_bus(), and wmb.
Referenced by myri10ge_net_open(), and myri10ge_net_poll().
00211 { 00212 unsigned int receives_posted; 00213 mcp_kreq_ether_recv_t *request; 00214 00215 /* Record the posted I/O buffer, to be passed to netdev_rx() on 00216 receive. */ 00217 00218 receives_posted = priv->receives_posted; 00219 priv->receive_iob[receives_posted & MYRI10GE_RECEIVE_WRAP] = iob; 00220 00221 /* Post the receive. */ 00222 00223 request = &priv->receive_post_ring[receives_posted 00224 & priv->receive_post_ring_wrap]; 00225 request->addr_high = 0; 00226 wmb(); 00227 request->addr_low = htonl ( virt_to_bus ( iob->data ) ); 00228 priv->receives_posted = ++receives_posted; 00229 }
| static int myri10ge_command | ( | struct myri10ge_private * | priv, | |
| uint32 | cmd, | |||
| uint32 | data[3] | |||
| ) | [static] |
Definition at line 239 of file myri10ge.c.
References mcp_cmd::cmd, myri10ge_private::command, myri10ge_dma_buffers::command_response, mcp_cmd_response::data, mcp_cmd::data0, mcp_cmd::data1, mcp_cmd::data2, DBG, DBGP, myri10ge_private::dma, EIO, ETIMEDOUT, mcp_dma_addr::high, htonl, mcp_dma_addr::low, ntohl, mcp_cmd::pad, mcp_cmd::response_addr, mcp_cmd_response::result, rmb, udelay(), virt_to_bus(), and wmb.
Referenced by myri10ge_net_close().
00242 { 00243 int i; 00244 mcp_cmd_t *command; 00245 uint32 result; 00246 unsigned int slept_ms; 00247 volatile mcp_cmd_response_t *response; 00248 00249 DBGP ( "myri10ge_command ( ,%d, ) \n", cmd ); 00250 command = priv->command; 00251 response = &priv->dma->command_response; 00252 00253 /* Mark the command as incomplete. */ 00254 00255 response->result = 0xFFFFFFFF; 00256 00257 /* Pass the command to the NIC. */ 00258 00259 command->cmd = htonl ( cmd ); 00260 command->data0 = htonl ( data[0] ); 00261 command->data1 = htonl ( data[1] ); 00262 command->data2 = htonl ( data[2] ); 00263 command->response_addr.high = 0; 00264 command->response_addr.low 00265 = htonl ( virt_to_bus ( &priv->dma->command_response ) ); 00266 for ( i=0; i<36; i+=4 ) 00267 * ( uint32 * ) &command->pad[i] = 0; 00268 wmb(); 00269 * ( uint32 * ) &command->pad[36] = 0; 00270 00271 /* Wait up to 2 seconds for a response. */ 00272 00273 for ( slept_ms=0; slept_ms<2000; slept_ms++ ) { 00274 result = response->result; 00275 if ( result == 0 ) { 00276 data[0] = ntohl ( response->data ); 00277 return 0; 00278 } else if ( result != 0xFFFFFFFF ) { 00279 DBG ( "cmd%d:0x%x\n", 00280 cmd, 00281 ntohl ( response->result ) ); 00282 return -EIO; 00283 } 00284 udelay ( 1000 ); 00285 rmb(); 00286 } 00287 DBG ( "cmd%d:timed out\n", cmd ); 00288 return -ETIMEDOUT; 00289 }
| static void myri10ge_interrupt_handler | ( | struct net_device * | netdev | ) | [static] |
Definition at line 298 of file myri10ge.c.
References DBG2, myri10ge_private::dma, htonl, myri10ge_private::irq_claim, myri10ge_dma_buffers::irq_data, myri10ge_private::irq_deassert, mcp_irq_data::link_up, mb(), MXGEFW_LINK_UP, myri10ge_priv(), MYRI10GE_TRANSMIT_WRAP, netdev_link_down(), netdev_link_up(), netdev_tx_complete(), ntohl, priv, rmb, mcp_irq_data::send_done_count, mcp_irq_data::stats_updated, myri10ge_private::transmit_iob, myri10ge_private::transmits_done, mcp_irq_data::valid, and wmb.
Referenced by myri10ge_net_poll().
00299 { 00300 struct myri10ge_private *priv; 00301 mcp_irq_data_t *irq_data; 00302 uint8 valid; 00303 00304 priv = myri10ge_priv ( netdev ); 00305 irq_data = &priv->dma->irq_data; 00306 00307 /* Return if there was no interrupt. */ 00308 00309 rmb(); 00310 valid = irq_data->valid; 00311 if ( !valid ) 00312 return; 00313 DBG2 ( "irq " ); 00314 00315 /* Tell the NIC to deassert the interrupt and clear 00316 irq_data->valid.*/ 00317 00318 *priv->irq_deassert = 0; /* any value is OK. */ 00319 mb(); 00320 00321 /* Handle any new receives. */ 00322 00323 if ( valid & 1 ) { 00324 00325 /* Pass the receive interrupt token back to the NIC. */ 00326 00327 DBG2 ( "rx " ); 00328 *priv->irq_claim = htonl ( 3 ); 00329 wmb(); 00330 } 00331 00332 /* Handle any sent packet by freeing its I/O buffer, now that 00333 we know it has been DMAd. */ 00334 00335 if ( valid & 2 ) { 00336 unsigned int nic_done_count; 00337 00338 DBG2 ( "snt " ); 00339 nic_done_count = ntohl ( priv->dma->irq_data.send_done_count ); 00340 while ( priv->transmits_done != nic_done_count ) { 00341 struct io_buffer *iob; 00342 00343 iob = priv->transmit_iob [priv->transmits_done 00344 & MYRI10GE_TRANSMIT_WRAP]; 00345 DBG2 ( "%p ", iob ); 00346 netdev_tx_complete ( netdev, iob ); 00347 ++priv->transmits_done; 00348 } 00349 } 00350 00351 /* Record any statistics update. */ 00352 00353 if ( irq_data->stats_updated ) { 00354 00355 /* Update the link status. */ 00356 00357 DBG2 ( "stats " ); 00358 if ( ntohl ( irq_data->link_up ) == MXGEFW_LINK_UP ) 00359 netdev_link_up ( netdev ); 00360 else 00361 netdev_link_down ( netdev ); 00362 00363 /* Ignore all error counters from the NIC. */ 00364 } 00365 00366 /* Wait for the interrupt to be deasserted, as indicated by 00367 irq_data->valid, which is set by the NIC after the deassert. */ 00368 00369 DBG2 ( "wait " ); 00370 do { 00371 mb(); 00372 } while ( irq_data->valid ); 00373 00374 /* Claim the interrupt to enable future interrupt generation. */ 00375 00376 DBG2 ( "claim\n" ); 00377 * ( priv->irq_claim + 1 ) = htonl ( 3 ); 00378 mb(); 00379 }
| static int mac_address_from_string_specs | ( | struct pci_device * | pci, | |
| uint8 | mac[ETH_ALEN] | |||
| ) | [static] |
Definition at line 400 of file myri10ge.c.
References DBG, DBG2, ENOTSUP, memcmp(), memcpy, ntohl, pci_find_capability(), pci_read_config_dword(), pci_write_config_byte(), pci_write_config_dword(), strtoul(), VS_ADDR, VS_DATA, VS_LOCATE_STRING_SPECS, VS_MODE, VS_MODE_LOCATE, and VS_MODE_READ32.
Referenced by myri10ge_pci_probe().
00402 { 00403 char string_specs[256]; 00404 char *ptr, *limit; 00405 char *to = string_specs; 00406 uint32 addr; 00407 uint32 len; 00408 unsigned int vs; 00409 int mac_set = 0; 00410 00411 /* Find the "vendor specific" capability. */ 00412 00413 vs = pci_find_capability ( pci, 9 ); 00414 if ( vs == 0 ) { 00415 DBG ( "no VS\n" ); 00416 return -ENOTSUP; 00417 } 00418 00419 /* Locate the String specs in LANai SRAM. */ 00420 00421 pci_write_config_byte ( pci, VS_MODE, VS_MODE_LOCATE ); 00422 pci_write_config_dword ( pci, VS_ADDR, VS_LOCATE_STRING_SPECS ); 00423 pci_read_config_dword ( pci, VS_ADDR, &addr ); 00424 pci_read_config_dword ( pci, VS_DATA, &len ); 00425 DBG2 ( "ss@%x,%x\n", addr, len ); 00426 00427 /* Copy in the string specs. Use 32-bit reads for performance. */ 00428 00429 if ( len > sizeof ( string_specs ) || ( len & 3 ) ) { 00430 DBG ( "SS too big\n" ); 00431 return -ENOTSUP; 00432 } 00433 00434 pci_write_config_byte ( pci, VS_MODE, VS_MODE_READ32 ); 00435 while ( len >= 4 ) { 00436 uint32 tmp; 00437 00438 pci_write_config_byte ( pci, VS_ADDR, addr ); 00439 pci_read_config_dword ( pci, VS_DATA, &tmp ); 00440 tmp = ntohl ( tmp ); 00441 memcpy ( to, &tmp, 4 ); 00442 to += 4; 00443 addr += 4; 00444 len -= 4; 00445 } 00446 pci_write_config_byte ( pci, VS_MODE, 0 ); 00447 00448 /* Parse the string specs. */ 00449 00450 DBG2 ( "STRING_SPECS:\n" ); 00451 ptr = string_specs; 00452 limit = string_specs + sizeof ( string_specs ); 00453 while ( *ptr != '\0' && ptr < limit ) { 00454 DBG2 ( "%s\n", ptr ); 00455 if ( memcmp ( ptr, "MAC=", 4 ) == 0 ) { 00456 unsigned int i; 00457 00458 ptr += 4; 00459 for ( i=0; i<6; i++ ) { 00460 if ( ( ptr + 2 ) > limit ) { 00461 DBG ( "bad MAC addr\n" ); 00462 return -ENOTSUP; 00463 } 00464 mac[i] = strtoul ( ptr, &ptr, 16 ); 00465 ptr += 1; 00466 } 00467 mac_set = 1; 00468 } 00469 else 00470 while ( ptr < limit && *ptr++ ); 00471 } 00472 00473 /* Verify we parsed all we need. */ 00474 00475 if ( !mac_set ) { 00476 DBG ( "no MAC addr\n" ); 00477 return -ENOTSUP; 00478 } 00479 00480 DBG2 ( "MAC %02x:%02x:%02x:%02x:%02x:%02x\n", 00481 mac[0], mac[1], mac[2], mac[3], mac[4], mac[5] ); 00482 00483 return 0; 00484 }
| static int myri10ge_pci_probe | ( | struct pci_device * | pci, | |
| const struct pci_device_id *id | __unused | |||
| ) | [static] |
Definition at line 500 of file myri10ge.c.
References adjust_pci_device(), alloc_etherdev(), DBG, DBGP, pci_device::dev, net_device::dev, ENOMEM, net_device::hw_addr, mac_address_from_string_specs(), myri10ge_net_close(), myri10ge_net_irq(), myri10ge_net_open(), myri10ge_net_poll(), myri10ge_net_transmit(), myri10ge_priv(), netdev, netdev_init(), netdev_nullify(), netdev_put(), net_device_operations::open, pci_set_drvdata(), priv, register_netdev(), and strerror().
00502 { 00503 static struct net_device_operations myri10ge_operations = { 00504 .open = myri10ge_net_open, 00505 .close = myri10ge_net_close, 00506 .transmit = myri10ge_net_transmit, 00507 .poll = myri10ge_net_poll, 00508 .irq = myri10ge_net_irq 00509 }; 00510 00511 const char *dbg; 00512 int rc; 00513 struct net_device *netdev; 00514 struct myri10ge_private *priv; 00515 00516 DBGP ( "myri10ge_pci_probe: " ); 00517 00518 netdev = alloc_etherdev ( sizeof ( *priv ) ); 00519 if ( !netdev ) { 00520 rc = -ENOMEM; 00521 dbg = "alloc_etherdev"; 00522 goto abort_with_nothing; 00523 } 00524 00525 netdev_init ( netdev, &myri10ge_operations ); 00526 priv = myri10ge_priv ( netdev ); 00527 00528 pci_set_drvdata ( pci, netdev ); 00529 netdev->dev = &pci->dev; 00530 00531 /* Make sure interrupts are disabled. */ 00532 00533 myri10ge_net_irq ( netdev, 0 ); 00534 00535 /* Read the NIC HW address. */ 00536 00537 rc = mac_address_from_string_specs ( pci, netdev->hw_addr ); 00538 if ( rc ) { 00539 dbg = "mac_from_ss"; 00540 goto abort_with_netdev_init; 00541 } 00542 DBGP ( "mac " ); 00543 00544 /* Enable bus master, etc. */ 00545 00546 adjust_pci_device ( pci ); 00547 DBGP ( "pci " ); 00548 00549 /* Register the initialized network device. */ 00550 00551 rc = register_netdev ( netdev ); 00552 if ( rc ) { 00553 dbg = "register_netdev"; 00554 goto abort_with_netdev_init; 00555 } 00556 00557 DBGP ( "done\n" ); 00558 00559 return 0; 00560 00561 abort_with_netdev_init: 00562 netdev_nullify ( netdev ); 00563 netdev_put ( netdev ); 00564 abort_with_nothing: 00565 DBG ( "%s:%s\n", dbg, strerror ( rc ) ); 00566 return rc; 00567 }
struct pci_device_id myri10ge_nics[] [static] |
Initial value:
{
PCI_ROM ( 0x14c1, 0x0008, "myri10ge", "Myricom 10Gb Ethernet Adapter", 0 ) ,
}
Definition at line 1023 of file myri10ge.c.
| struct pci_driver myri10ge_driver __pci_driver |
Initial value:
{
.ids = myri10ge_nics,
.id_count = ( sizeof ( myri10ge_nics ) / sizeof ( myri10ge_nics[0] ) ) ,
.probe = myri10ge_pci_probe,
.remove = myri10ge_pci_remove
}
Definition at line 1028 of file myri10ge.c.
1.5.7.1