X-Git-Url: http://bbs.cooldavid.org/git/?p=jme.git;a=blobdiff_plain;f=jme.c;h=4da81a3602dc21d72b8b81c4de5c34488394f16d;hp=04565c9e37bb04329c6f387b58567411fb8ece41;hb=94c5ea022639d374c91194d3c7551755646b28c8;hpb=cd0ff491e3c0fdb01fb189987c4d822b1113cc53 diff --git a/jme.c b/jme.c index 04565c9..4da81a3 100644 --- a/jme.c +++ b/jme.c @@ -21,7 +21,6 @@ * */ -#include #include #include #include @@ -38,6 +37,7 @@ #include #include #include +#include #include "jme.h" static int force_pseudohp = -1; @@ -106,115 +106,6 @@ jme_mdio_write(struct net_device *netdev, return; } -static void -jme_spi_start(struct pci_dev *pdev, struct jme_spi_op *spiop) -{ - spiop->sr |= SPI_EN; - pci_write_config_byte(pdev, PCI_SPI, spiop->sr); - ndelay(spiop->halfclk << 2); - if (spiop->mode & SPI_MODE_CPOL) { - spiop->sr |= SPI_SCLK; - pci_write_config_byte(pdev, PCI_SPI, spiop->sr); - ndelay(spiop->halfclk << 2); - } - spiop->sr &= ~SPI_CS; - pci_write_config_byte(pdev, PCI_SPI, spiop->sr); - ndelay(spiop->halfclk); -} - -static void -jme_spi_write(struct pci_dev *pdev, struct jme_spi_op *spiop, u8 byte) -{ - int bit; - - for (bit = 0 ; bit < 8 ; ++bit) { - if (byte & 0x80) - spiop->sr |= SPI_MOSI; - else - spiop->sr &= ~SPI_MOSI; - pci_write_config_byte(pdev, PCI_SPI, spiop->sr); - - byte <<= 1; - ndelay(spiop->halfclk); - spiop->sr ^= SPI_SCLK; - pci_write_config_byte(pdev, PCI_SPI, spiop->sr); - - ndelay(spiop->halfclk); - spiop->sr ^= SPI_SCLK; - pci_write_config_byte(pdev, PCI_SPI, spiop->sr); - } -} - -static void -jme_spi_read(struct pci_dev *pdev, struct jme_spi_op *spiop, u8 *byte) -{ - int bit; - u8 b; - - spiop->sr &= ~SPI_MOSI; - for (bit = 0 ; bit < 8 ; ++bit) { - *byte <<= 1; - ndelay(spiop->halfclk); - spiop->sr ^= SPI_SCLK; - pci_write_config_byte(pdev, PCI_SPI, spiop->sr); - - ndelay(spiop->halfclk); - pci_read_config_byte(pdev, PCI_SPI, &b); - *byte |= !!(b & SPI_MISO); - spiop->sr ^= SPI_SCLK; - pci_write_config_byte(pdev, PCI_SPI, spiop->sr); - } -} - -static void -jme_spi_stop(struct pci_dev *pdev, struct jme_spi_op *spiop) -{ - spiop->sr &= ~SPI_EN; - spiop->sr |= SPI_CS; - pci_write_config_byte(pdev, PCI_SPI, spiop->sr); -} - -/** - * jme_spi_io - SPI Access helper function. - * @jme: Adapter informations - * @spiop: SPI operation. - * - * We have a SPI SW Access register in PCI configuration space, - * which directly connect to flash controller with SPI interface. - * This function is used to communicate with it in SPI protocol. - */ -static int -jme_spi_op(struct jme_adapter *jme, struct jme_spi_op *spiop) -{ - int i; - - /* - * Only support 8 bits for now - */ - if (spiop->bitn != 8) - return -EINVAL; - - /* - * Only support half-duplex for now - */ - if (spiop->mode & SPI_MODE_DUP) - return -EINVAL; - - spiop->halfclk = HALF_US / spiop->spd; - spiop->sr = SPI_CS; - jme_spi_start(jme->pdev, spiop); - - for (i = 0 ; i < spiop->wn ; ++i) - jme_spi_write(jme->pdev, spiop, spiop->kwbuf[i]); - - for (i = 0 ; i < spiop->rn ; ++i) - jme_spi_read(jme->pdev, spiop, spiop->krbuf + i); - - jme_spi_stop(jme->pdev, spiop); - - return 0; -} - static inline void jme_reset_phy_processor(struct jme_adapter *jme) { @@ -299,7 +190,7 @@ jme_reset_mac_processor(struct jme_adapter *jme) else gpreg0 = GPREG0_DEFAULT; jwrite32(jme, JME_GPREG0, gpreg0); - jwrite32(jme, JME_GPREG1, 0); + jwrite32(jme, JME_GPREG1, GPREG1_DEFAULT); } static inline void @@ -459,13 +350,13 @@ jme_linkstat_from_phy(struct jme_adapter *jme) } static inline void -jme_set_gmii(struct jme_adapter *jme) +jme_set_phyfifoa(struct jme_adapter *jme) { jme_mdio_write(jme->dev, jme->mii_if.phy_id, 27, 0x0004); } static inline void -jme_set_rgmii(struct jme_adapter *jme) +jme_set_phyfifob(struct jme_adapter *jme) { jme_mdio_write(jme->dev, jme->mii_if.phy_id, 27, 0x0000); } @@ -474,7 +365,7 @@ static int jme_check_link(struct net_device *netdev, int testonly) { struct jme_adapter *jme = netdev_priv(netdev); - u32 phylink, ghc, cnt = JME_SPDRSV_TIMEOUT, bmcr; + u32 phylink, ghc, cnt = JME_SPDRSV_TIMEOUT, bmcr, gpreg1; char linkmsg[64]; int rc = 0; @@ -538,45 +429,32 @@ jme_check_link(struct net_device *netdev, int testonly) jme->phylink = phylink; - ghc = jme->reg_ghc & ~(GHC_SPEED_10M | - GHC_SPEED_100M | - GHC_SPEED_1000M | - GHC_DPX); + ghc = jme->reg_ghc & ~(GHC_SPEED | GHC_DPX | + GHC_TO_CLK_PCIE | GHC_TXMAC_CLK_PCIE | + GHC_TO_CLK_GPHY | GHC_TXMAC_CLK_GPHY); switch (phylink & PHY_LINK_SPEED_MASK) { case PHY_LINK_SPEED_10M: - ghc |= GHC_SPEED_10M; + ghc |= GHC_SPEED_10M | + GHC_TO_CLK_PCIE | GHC_TXMAC_CLK_PCIE; strcat(linkmsg, "10 Mbps, "); - if (jme->rev == 0x11) - jme_set_gmii(jme); break; case PHY_LINK_SPEED_100M: - ghc |= GHC_SPEED_100M; + ghc |= GHC_SPEED_100M | + GHC_TO_CLK_PCIE | GHC_TXMAC_CLK_PCIE; strcat(linkmsg, "100 Mbps, "); - if (jme->rev == 0x11) - jme_set_rgmii(jme); break; case PHY_LINK_SPEED_1000M: - ghc |= GHC_SPEED_1000M; + ghc |= GHC_SPEED_1000M | + GHC_TO_CLK_GPHY | GHC_TXMAC_CLK_GPHY; strcat(linkmsg, "1000 Mbps, "); - if (jme->rev == 0x11) - jme_set_gmii(jme); break; default: break; } - ghc |= (phylink & PHY_LINK_DUPLEX) ? GHC_DPX : 0; - - strcat(linkmsg, (phylink & PHY_LINK_DUPLEX) ? - "Full-Duplex, " : - "Half-Duplex, "); - - if (phylink & PHY_LINK_MDI_STAT) - strcat(linkmsg, "MDI-X"); - else - strcat(linkmsg, "MDI"); if (phylink & PHY_LINK_DUPLEX) { jwrite32(jme, JME_TXMCS, TXMCS_DEFAULT); + ghc |= GHC_DPX; } else { jwrite32(jme, JME_TXMCS, TXMCS_DEFAULT | TXMCS_BACKOFF | @@ -588,9 +466,37 @@ jme_check_link(struct net_device *netdev, int testonly) ((8 << TXTRHD_TXRL_SHIFT) & TXTRHD_TXRL)); } - jme->reg_ghc = ghc; + gpreg1 = GPREG1_DEFAULT; + if (is_buggy250(jme->pdev->device, jme->chiprev)) { + if (!(phylink & PHY_LINK_DUPLEX)) + gpreg1 |= GPREG1_HALFMODEPATCH; + switch (phylink & PHY_LINK_SPEED_MASK) { + case PHY_LINK_SPEED_10M: + jme_set_phyfifoa(jme); + gpreg1 |= GPREG1_RSSPATCH; + break; + case PHY_LINK_SPEED_100M: + jme_set_phyfifob(jme); + gpreg1 |= GPREG1_RSSPATCH; + break; + case PHY_LINK_SPEED_1000M: + jme_set_phyfifoa(jme); + break; + default: + break; + } + } + + jwrite32(jme, JME_GPREG1, gpreg1); jwrite32(jme, JME_GHC, ghc); + jme->reg_ghc = ghc; + strcat(linkmsg, (phylink & PHY_LINK_DUPLEX) ? + "Full-Duplex, " : + "Half-Duplex, "); + strcat(linkmsg, (phylink & PHY_LINK_MDI_STAT) ? + "MDI-X" : + "MDI"); msg_link(jme, "Link is up at %s.\n", linkmsg); netif_carrier_on(netdev); } else { @@ -1006,26 +912,25 @@ jme_alloc_and_feed_skb(struct jme_adapter *jme, int idx) skb_put(skb, framesize); skb->protocol = eth_type_trans(skb, jme->dev); - if (jme_rxsum_ok(jme, rxdesc->descwb.flags)) + if (jme_rxsum_ok(jme, le16_to_cpu(rxdesc->descwb.flags))) skb->ip_summed = CHECKSUM_UNNECESSARY; else skb->ip_summed = CHECKSUM_NONE; - if (rxdesc->descwb.flags & RXWBFLAG_TAGON) { + if (rxdesc->descwb.flags & cpu_to_le16(RXWBFLAG_TAGON)) { if (jme->vlgrp) { jme->jme_vlan_rx(skb, jme->vlgrp, - le32_to_cpu(rxdesc->descwb.vlan)); + le16_to_cpu(rxdesc->descwb.vlan)); NET_STAT(jme).rx_bytes += 4; } } else { jme->jme_rx(skb); } - if ((le16_to_cpu(rxdesc->descwb.flags) & RXWBFLAG_DEST) == - RXWBFLAG_DEST_MUL) + if ((rxdesc->descwb.flags & cpu_to_le16(RXWBFLAG_DEST)) == + cpu_to_le16(RXWBFLAG_DEST_MUL)) ++(NET_STAT(jme).multicast); - jme->dev->last_rx = jiffies; NET_STAT(jme).rx_bytes += framesize; ++(NET_STAT(jme).rx_packets); } @@ -1055,7 +960,7 @@ jme_process_receive(struct jme_adapter *jme, int limit) rxdesc = rxring->desc; rxdesc += i; - if ((rxdesc->descwb.flags & RXWBFLAG_OWN) || + if ((rxdesc->descwb.flags & cpu_to_le16(RXWBFLAG_OWN)) || !(rxdesc->descwb.desccnt & RXWBDCNT_WBCPL)) goto out; @@ -1257,7 +1162,7 @@ jme_link_change_tasklet(unsigned long arg) while (!atomic_dec_and_test(&jme->link_changing)) { atomic_inc(&jme->link_changing); msg_intr(jme, "Get link change lock failed.\n"); - while(atomic_read(&jme->link_changing) != 1) + while (atomic_read(&jme->link_changing) != 1) msg_intr(jme, "Waiting link change lock.\n"); } @@ -1344,7 +1249,6 @@ static int jme_poll(JME_NAPI_HOLDER(holder), JME_NAPI_WEIGHT(budget)) { struct jme_adapter *jme = jme_napi_priv(holder); - struct net_device *netdev = jme->dev; int rest; rest = jme_process_receive(jme, JME_NAPI_WEIGHT_VAL(budget)); @@ -1557,7 +1461,7 @@ jme_intr(int irq, void *dev_id) /* * Check if it's really an interrupt for us */ - if (unlikely(intrstat == 0)) + if (unlikely((intrstat & INTR_ENABLE) == 0)) return IRQ_NONE; /* @@ -1687,6 +1591,7 @@ err_out: return rc; } +#ifdef CONFIG_PM static void jme_set_100m_half(struct jme_adapter *jme) { @@ -1719,6 +1624,7 @@ jme_wait_link(struct jme_adapter *jme) phylink = jme_linkstat_from_phy(jme); } } +#endif static inline void jme_phy_off(struct jme_adapter *jme) @@ -1855,10 +1761,9 @@ jme_expand_header(struct jme_adapter *jme, struct sk_buff *skb) } static int -jme_tx_tso(struct sk_buff *skb, - u16 *mss, u8 *flags) +jme_tx_tso(struct sk_buff *skb, __le16 *mss, u8 *flags) { - *mss = skb_shinfo(skb)->gso_size << TXDESC_MSS_SHIFT; + *mss = cpu_to_le16(skb_shinfo(skb)->gso_size << TXDESC_MSS_SHIFT); if (*mss) { *flags |= TXFLAG_LSEN; @@ -1918,16 +1823,16 @@ jme_tx_csum(struct jme_adapter *jme, struct sk_buff *skb, u8 *flags) } static inline void -jme_tx_vlan(struct sk_buff *skb, u16 *vlan, u8 *flags) +jme_tx_vlan(struct sk_buff *skb, __le16 *vlan, u8 *flags) { if (vlan_tx_tag_present(skb)) { *flags |= TXFLAG_TAGON; - *vlan = vlan_tx_tag_get(skb); + *vlan = cpu_to_le16(vlan_tx_tag_get(skb)); } } static int -jme_fill_first_tx_desc(struct jme_adapter *jme, struct sk_buff *skb, int idx) +jme_fill_tx_desc(struct jme_adapter *jme, struct sk_buff *skb, int idx) { struct jme_ring *txring = jme->txring; struct txdesc *txdesc; @@ -1957,6 +1862,7 @@ jme_fill_first_tx_desc(struct jme_adapter *jme, struct sk_buff *skb, int idx) if (jme_tx_tso(skb, &txdesc->desc1.mss, &flags)) jme_tx_csum(jme, skb, &flags); jme_tx_vlan(skb, &txdesc->desc1.vlan, &flags); + jme_map_tx_skb(jme, skb, idx); txdesc->desc1.flags = flags; /* * Set tx buffer info after telling NIC to send @@ -2026,8 +1932,7 @@ jme_start_xmit(struct sk_buff *skb, struct net_device *netdev) return NETDEV_TX_BUSY; } - jme_map_tx_skb(jme, skb, idx); - jme_fill_first_tx_desc(jme, skb, idx); + jme_fill_tx_desc(jme, skb, idx); jwrite32(jme, JME_TXCS, jme->reg_txcs | TXCS_SELECT_QUEUE0 | @@ -2146,48 +2051,6 @@ jme_change_mtu(struct net_device *netdev, int new_mtu) return 0; } -static int -jme_ioctl(struct net_device *netdev, struct ifreq *ifr, int cmd) -{ - struct jme_adapter *jme = netdev_priv(netdev); - struct jme_spi_op spiop; - int rc; - - switch (cmd) { - case JMESPIIOCTL: - if (!capable(CAP_NET_ADMIN)) - return -EPERM; - - copy_from_user(&spiop, ifr->ifr_data, - sizeof(struct jme_spi_op)); - spiop.kwbuf = kmalloc(spiop.wn, GFP_KERNEL); - if (!spiop.kwbuf) { - rc = -ENOMEM; - goto out; - } - spiop.krbuf = kmalloc(spiop.rn, GFP_KERNEL); - if (!spiop.krbuf) { - rc = -ENOMEM; - goto out_free1; - } - copy_from_user(spiop.kwbuf, spiop.uwbuf, spiop.wn); - rc = jme_spi_op(jme, &spiop); - if (rc) - goto out_free; - copy_to_user(spiop.urbuf, spiop.krbuf, spiop.rn); -out_free: - kfree(spiop.krbuf); -out_free1: - kfree(spiop.kwbuf); -out: - return rc; - default: - break; - } - - return -EOPNOTSUPP; -} - static void jme_tx_timeout(struct net_device *netdev) { @@ -2726,11 +2589,13 @@ static const struct ethtool_ops jme_ethtool_ops = { static int jme_pci_dma64(struct pci_dev *pdev) { - if (!pci_set_dma_mask(pdev, DMA_64BIT_MASK)) + if (pdev->device == PCI_DEVICE_ID_JMICRON_JMC250 && + !pci_set_dma_mask(pdev, DMA_64BIT_MASK)) if (!pci_set_consistent_dma_mask(pdev, DMA_64BIT_MASK)) return 1; - if (!pci_set_dma_mask(pdev, DMA_40BIT_MASK)) + if (pdev->device == PCI_DEVICE_ID_JMICRON_JMC250 && + !pci_set_dma_mask(pdev, DMA_40BIT_MASK)) if (!pci_set_consistent_dma_mask(pdev, DMA_40BIT_MASK)) return 1; @@ -2758,8 +2623,20 @@ jme_check_hw_ver(struct jme_adapter *jme) chipmode = jread32(jme, JME_CHIPMODE); jme->fpgaver = (chipmode & CM_FPGAVER_MASK) >> CM_FPGAVER_SHIFT; - jme->chipver = (chipmode & CM_CHIPVER_MASK) >> CM_CHIPVER_SHIFT; -} + jme->chiprev = (chipmode & CM_CHIPREV_MASK) >> CM_CHIPREV_SHIFT; +} + +static const struct net_device_ops jme_netdev_ops = { + .ndo_open = jme_open, + .ndo_stop = jme_close, + .ndo_validate_addr = eth_validate_addr, + .ndo_start_xmit = jme_start_xmit, + .ndo_set_mac_address = jme_set_macaddr, + .ndo_set_multicast_list = jme_set_multi, + .ndo_change_mtu = jme_change_mtu, + .ndo_tx_timeout = jme_tx_timeout, + .ndo_vlan_rx_register = jme_vlan_rx_register, +}; static int __devinit jme_init_one(struct pci_dev *pdev, @@ -2810,18 +2687,9 @@ jme_init_one(struct pci_dev *pdev, rc = -ENOMEM; goto err_out_release_regions; } - netdev->open = jme_open; - netdev->stop = jme_close; - netdev->hard_start_xmit = jme_start_xmit; - netdev->set_mac_address = jme_set_macaddr; - netdev->set_multicast_list = jme_set_multi; - netdev->change_mtu = jme_change_mtu; - netdev->do_ioctl = jme_ioctl; + netdev->netdev_ops = &jme_netdev_ops; netdev->ethtool_ops = &jme_ethtool_ops; - netdev->tx_timeout = jme_tx_timeout; netdev->watchdog_timeo = TX_TIMEOUT; - netdev->vlan_rx_register = jme_vlan_rx_register; - NETDEV_GET_STATS(netdev, &jme_get_stats); netdev->features = NETIF_F_HW_CSUM | NETIF_F_SG | NETIF_F_TSO | @@ -2964,7 +2832,7 @@ jme_init_one(struct pci_dev *pdev, jme->mii_if.mdio_write = jme_mdio_write; jme_clear_pm(jme); - jme_set_gmii(jme); + jme_set_phyfifoa(jme); pci_read_config_byte(pdev, PCI_REVISION_ID, &jme->rev); if (!jme->fpgaver) jme_phy_init(jme); @@ -2997,18 +2865,14 @@ jme_init_one(struct pci_dev *pdev, goto err_out_free_shadow; } - msg_probe(jme, - "JMC250 gigabit%s ver:%u rev:%1x.%1x " - "macaddr:%02x:%02x:%02x:%02x:%02x:%02x\n", + msg_probe(jme, "%s%s ver:%x rev:%x macaddr:%pM\n", + (jme->pdev->device == PCI_DEVICE_ID_JMICRON_JMC250) ? + "JMC250 Gigabit Ethernet" : + (jme->pdev->device == PCI_DEVICE_ID_JMICRON_JMC260) ? + "JMC260 Fast Ethernet" : "Unknown", (jme->fpgaver != 0) ? " (FPGA)" : "", - (jme->fpgaver != 0) ? jme->fpgaver : jme->chipver, - jme->rev & 0xf, (jme->rev >> 4) & 0xf, - netdev->dev_addr[0], - netdev->dev_addr[1], - netdev->dev_addr[2], - netdev->dev_addr[3], - netdev->dev_addr[4], - netdev->dev_addr[5]); + (jme->fpgaver != 0) ? jme->fpgaver : jme->chiprev, + jme->rev, netdev->dev_addr); return 0; @@ -3049,6 +2913,7 @@ jme_remove_one(struct pci_dev *pdev) } +#ifdef CONFIG_PM static int jme_suspend(struct pci_dev *pdev, pm_message_t state) { @@ -3128,6 +2993,7 @@ jme_resume(struct pci_dev *pdev) return 0; } +#endif static struct pci_device_id jme_pci_tbl[] = { { PCI_VDEVICE(JMICRON, PCI_DEVICE_ID_JMICRON_JMC250) }, @@ -3149,7 +3015,7 @@ static struct pci_driver jme_driver = { static int __init jme_init_module(void) { - printk(KERN_INFO PFX "JMicron JMC250 gigabit ethernet " + printk(KERN_INFO PFX "JMicron JMC2XX ethernet " "driver version %s\n", DRV_VERSION); return pci_register_driver(&jme_driver); }