X-Git-Url: http://pilppa.org/gitweb/gitweb.cgi?a=blobdiff_plain;f=drivers%2Fnet%2Fipg.c;h=9752902f2d9a51bde550411b9ecac88ff32d1057;hb=0da1b995aee447656c0eb77e4e32468e37f868a3;hp=59898ce54dcf3170a7579d28aa12c0d4bce35bee;hpb=e3d18658d4f28e4783e1bb1c41e9134c9e5db0a9;p=linux-2.6-omap-h63xx.git diff --git a/drivers/net/ipg.c b/drivers/net/ipg.c index 59898ce54dc..9752902f2d9 100644 --- a/drivers/net/ipg.c +++ b/drivers/net/ipg.c @@ -55,6 +55,26 @@ MODULE_DESCRIPTION("IC Plus IP1000 Gigabit Ethernet Adapter Linux Driver " DrvVer); MODULE_LICENSE("GPL"); +//variable record -- index by leading revision/length +//Revision/Length(=N*4), Address1, Data1, Address2, Data2,...,AddressN,DataN +static unsigned short DefaultPhyParam[] = { + // 11/12/03 IP1000A v1-3 rev=0x40 + /*-------------------------------------------------------------------------- + (0x4000|(15*4)), 31, 0x0001, 27, 0x01e0, 31, 0x0002, 22, 0x85bd, 24, 0xfff2, + 27, 0x0c10, 28, 0x0c10, 29, 0x2c10, 31, 0x0003, 23, 0x92f6, + 31, 0x0000, 23, 0x003d, 30, 0x00de, 20, 0x20e7, 9, 0x0700, + --------------------------------------------------------------------------*/ + // 12/17/03 IP1000A v1-4 rev=0x40 + (0x4000 | (07 * 4)), 31, 0x0001, 27, 0x01e0, 31, 0x0002, 27, 0xeb8e, 31, + 0x0000, + 30, 0x005e, 9, 0x0700, + // 01/09/04 IP1000A v1-5 rev=0x41 + (0x4100 | (07 * 4)), 31, 0x0001, 27, 0x01e0, 31, 0x0002, 27, 0xeb8e, 31, + 0x0000, + 30, 0x005e, 9, 0x0700, + 0x0000 +}; + static const char *ipg_brand_name[] = { "IC PLUS IP1000 1000/100/10 based NIC", "Sundance Technology ST2021 based NIC", @@ -754,7 +774,7 @@ static int init_rfdlist(struct net_device *dev) if (sp->RxBuff[i]) { pci_unmap_single(sp->pdev, - le64_to_cpu(rxfd->frag_info & ~IPG_RFI_FRAGLEN), + le64_to_cpu(rxfd->frag_info) & ~IPG_RFI_FRAGLEN, sp->rx_buf_sz, PCI_DMA_FROMDEVICE); IPG_DEV_KFREE_SKB(sp->RxBuff[i]); sp->RxBuff[i] = NULL; @@ -837,21 +857,14 @@ static void init_tfdlist(struct net_device *dev) static void ipg_nic_txfree(struct net_device *dev) { struct ipg_nic_private *sp = netdev_priv(dev); - void __iomem *ioaddr = sp->ioaddr; - unsigned int curr; - u64 txd_map; - unsigned int released, pending; - - txd_map = (u64)sp->txd_map; - curr = ipg_r32(TFD_LIST_PTR_0) - - do_div(txd_map, sizeof(struct ipg_tx)) - 1; + unsigned int released, pending, dirty; IPG_DEBUG_MSG("_nic_txfree\n"); pending = sp->tx_current - sp->tx_dirty; + dirty = sp->tx_dirty % IPG_TFDLIST_LENGTH; for (released = 0; released < pending; released++) { - unsigned int dirty = sp->tx_dirty % IPG_TFDLIST_LENGTH; struct sk_buff *skb = sp->TxBuff[dirty]; struct ipg_tx *txfd = sp->txd + dirty; @@ -862,22 +875,20 @@ static void ipg_nic_txfree(struct net_device *dev) * If the TFDDone bit is set, free the associated * buffer. */ - if (dirty == curr) - break; - - /* Setup TFDDONE for compatible issue. */ - txfd->tfc |= cpu_to_le64(IPG_TFC_TFDDONE); + if (!(txfd->tfc & cpu_to_le64(IPG_TFC_TFDDONE))) + break; /* Free the transmit buffer. */ if (skb) { pci_unmap_single(sp->pdev, - le64_to_cpu(txfd->frag_info & ~IPG_TFI_FRAGLEN), + le64_to_cpu(txfd->frag_info) & ~IPG_TFI_FRAGLEN, skb->len, PCI_DMA_TODEVICE); IPG_DEV_KFREE_SKB(skb); sp->TxBuff[dirty] = NULL; } + dirty = (dirty + 1) % IPG_TFDLIST_LENGTH; } sp->tx_dirty += released; @@ -990,7 +1001,7 @@ static void ipg_nic_txcleanup(struct net_device *dev) } /* Provides statistical information about the IPG NIC. */ -struct net_device_stats *ipg_nic_get_stats(struct net_device *dev) +static struct net_device_stats *ipg_nic_get_stats(struct net_device *dev) { struct ipg_nic_private *sp = netdev_priv(dev); void __iomem *ioaddr = sp->ioaddr; @@ -1413,10 +1424,10 @@ static int ipg_nic_rx(struct net_device *dev) framelen = IPG_RXFRAG_SIZE; } - if ((IPG_DROP_ON_RX_ETH_ERRORS && (le64_to_cpu(rxfd->rfs & + if ((IPG_DROP_ON_RX_ETH_ERRORS && (le64_to_cpu(rxfd->rfs) & (IPG_RFS_RXFIFOOVERRUN | IPG_RFS_RXRUNTFRAME | IPG_RFS_RXALIGNMENTERROR | IPG_RFS_RXFCSERROR | - IPG_RFS_RXOVERSIZEDFRAME | IPG_RFS_RXLENGTHERROR))))) { + IPG_RFS_RXOVERSIZEDFRAME | IPG_RFS_RXLENGTHERROR)))) { IPG_DEBUG_MSG("Rx error, RFS = %16.16lx\n", (unsigned long int) rxfd->rfs); @@ -1425,27 +1436,27 @@ static int ipg_nic_rx(struct net_device *dev) sp->stats.rx_errors++; /* Increment detailed receive error statistics. */ - if (le64_to_cpu(rxfd->rfs & IPG_RFS_RXFIFOOVERRUN)) { + if (le64_to_cpu(rxfd->rfs) & IPG_RFS_RXFIFOOVERRUN) { IPG_DEBUG_MSG("RX FIFO overrun occured.\n"); sp->stats.rx_fifo_errors++; } - if (le64_to_cpu(rxfd->rfs & IPG_RFS_RXRUNTFRAME)) { + if (le64_to_cpu(rxfd->rfs) & IPG_RFS_RXRUNTFRAME) { IPG_DEBUG_MSG("RX runt occured.\n"); sp->stats.rx_length_errors++; } - if (le64_to_cpu(rxfd->rfs & IPG_RFS_RXOVERSIZEDFRAME)) ; + if (le64_to_cpu(rxfd->rfs) & IPG_RFS_RXOVERSIZEDFRAME) ; /* Do nothing, error count handled by a IPG * statistic register. */ - if (le64_to_cpu(rxfd->rfs & IPG_RFS_RXALIGNMENTERROR)) { + if (le64_to_cpu(rxfd->rfs) & IPG_RFS_RXALIGNMENTERROR) { IPG_DEBUG_MSG("RX alignment error occured.\n"); sp->stats.rx_frame_errors++; } - if (le64_to_cpu(rxfd->rfs & IPG_RFS_RXFCSERROR)) ; + if (le64_to_cpu(rxfd->rfs) & IPG_RFS_RXFCSERROR) ; /* Do nothing, error count handled by a IPG * statistic register. */ @@ -1455,10 +1466,10 @@ static int ipg_nic_rx(struct net_device *dev) * not pass it to higher layer processes. */ if (skb) { - u64 info = rxfd->frag_info; + __le64 info = rxfd->frag_info; pci_unmap_single(sp->pdev, - le64_to_cpu(info & ~IPG_RFI_FRAGLEN), + le64_to_cpu(info) & ~IPG_RFI_FRAGLEN, sp->rx_buf_sz, PCI_DMA_FROMDEVICE); IPG_DEV_KFREE_SKB(skb); @@ -1532,9 +1543,9 @@ static int ipg_nic_rx(struct net_device *dev) if (!i) sp->EmptyRFDListCount++; #endif - while ((le64_to_cpu(rxfd->rfs & IPG_RFS_RFDDONE)) && - !((le64_to_cpu(rxfd->rfs & IPG_RFS_FRAMESTART)) && - (le64_to_cpu(rxfd->rfs & IPG_RFS_FRAMEEND)))) { + while ((le64_to_cpu(rxfd->rfs) & IPG_RFS_RFDDONE) && + !((le64_to_cpu(rxfd->rfs) & IPG_RFS_FRAMESTART) && + (le64_to_cpu(rxfd->rfs) & IPG_RFS_FRAMEEND))) { unsigned int entry = curr++ % IPG_RFDLIST_LENGTH; rxfd = sp->rxd + entry; @@ -1552,7 +1563,7 @@ static int ipg_nic_rx(struct net_device *dev) */ if (sp->RxBuff[entry]) { pci_unmap_single(sp->pdev, - le64_to_cpu(rxfd->frag_info & ~IPG_RFI_FRAGLEN), + le64_to_cpu(rxfd->frag_info) & ~IPG_RFI_FRAGLEN, sp->rx_buf_sz, PCI_DMA_FROMDEVICE); IPG_DEV_KFREE_SKB(sp->RxBuff[entry]); } @@ -1610,6 +1621,8 @@ static irqreturn_t ipg_interrupt_handler(int irq, void *dev_inst) #ifdef JUMBO_FRAME ipg_nic_rxrestore(dev); #endif + spin_lock(&sp->lock); + /* Get interrupt source information, and acknowledge * some (i.e. TxDMAComplete, RxDMAComplete, RxEarly, * IntRequested, MacControlFrame, LinkEvent) interrupts @@ -1627,9 +1640,7 @@ static irqreturn_t ipg_interrupt_handler(int irq, void *dev_inst) handled = 1; if (unlikely(!netif_running(dev))) - goto out; - - spin_lock(&sp->lock); + goto out_unlock; /* If RFDListEnd interrupt, restore all used RFDs. */ if (status & IPG_IS_RFD_LIST_END) { @@ -1713,9 +1724,9 @@ out_enable: ipg_w16(IPG_IE_TX_DMA_COMPLETE | IPG_IE_RX_DMA_COMPLETE | IPG_IE_HOST_ERROR | IPG_IE_INT_REQUESTED | IPG_IE_TX_COMPLETE | IPG_IE_LINK_EVENT | IPG_IE_UPDATE_STATS, INT_ENABLE); - +out_unlock: spin_unlock(&sp->lock); -out: + return IRQ_RETVAL(handled); } @@ -1730,7 +1741,7 @@ static void ipg_rx_clear(struct ipg_nic_private *sp) IPG_DEV_KFREE_SKB(sp->RxBuff[i]); sp->RxBuff[i] = NULL; pci_unmap_single(sp->pdev, - le64_to_cpu(rxfd->frag_info & ~IPG_RFI_FRAGLEN), + le64_to_cpu(rxfd->frag_info) & ~IPG_RFI_FRAGLEN, sp->rx_buf_sz, PCI_DMA_FROMDEVICE); } } @@ -1745,7 +1756,7 @@ static void ipg_tx_clear(struct ipg_nic_private *sp) struct ipg_tx *txfd = sp->txd + i; pci_unmap_single(sp->pdev, - le64_to_cpu(txfd->frag_info & ~IPG_TFI_FRAGLEN), + le64_to_cpu(txfd->frag_info) & ~IPG_TFI_FRAGLEN, sp->TxBuff[i]->len, PCI_DMA_TODEVICE); IPG_DEV_KFREE_SKB(sp->TxBuff[i]);