改写drivers/net/8139too.c(3)

2020-06-23 00:00:00 专区 订阅 付费 交易 评论

static struct net_device_stats *xc_get_stats (struct net_device *dev)
{
struct xc_priv *tp = netdev_priv(dev);
return &tp->stats;
}

static void xc_tx_timeout(struct net_device *dev)
{
struct xc_priv *tp = netdev_priv(dev);
void __iomem *ioaddr = tp->ioaddr;
u8 tmp8;

tmp8= ioread8(ioaddr+ChipCmd);
if (tmp8 & CmdTxEnb)
iowrite8(CmdRxEnb,ioaddr+ChipCmd);/*如果8139任开启写则关闭,只保留读*/

spin_lock_bh(&tp->rx_lock);
/* Disable interrupts by clearing the interrupt mask. */
iowrite16(0x0000,ioaddr+IntrMask);

/* Stop a shared interrupt from scavenging while we are. */
spin_lock_irq(&tp->lock);
tp->cur_tx = 0;
tp->dirty_tx = 0;
spin_unlock_irq(&tp->lock);

if (netif_running(dev))
{/*重新设置8139所有信息*/
xc_hw_start (dev);
netif_wake_queue (dev);
}
spin_unlock_bh(&tp->rx_lock);
}

static int __devinit xc_board(struct pci_dev *pdev,struct net_device **dev_out)
{
struct net_device *dev;
struct xc_priv *tp;
void __iomem *ioaddr;
int rc,dev_on,i;
u32 version;
u8 tmp;
if(pdev == NULL)
return -1;
dev_on = 0;
*dev_out = NULL;
dev = alloc_etherdev(sizeof(*tp));
if(dev == NULL)
return -ENOMEM;
SET_MODULE_OWNER(dev);
SET_NETDEV_DEV(dev, &pdev->dev);
tp = netdev_priv(dev);
tp->pdev = pdev;
rc = pci_enable_device(pdev);
if(rc) goto err_out;
rc = pci_request_regions (pdev, "xc8139too";
if (rc) goto err_out;
dev_on = 1;
pci_set_master (pdev);
ioaddr = pci_iomap(pdev, 1, 0);
if (ioaddr == NULL) {rc = -EIO;goto err_out;}
tp->ioaddr = ioaddr;
dev->base_addr = (long)ioaddr;
iowrite8('R',ioaddr+HltClk);
if (ioread32(ioaddr+TxConfig) == 0xFFFFFFFF) {rc = -EIO;goto err_out;}
version = ioread32(ioaddr+TxConfig) & HW_REVID_MASK;
for(i=0;i<ARRAY_SIZE(rtl_chip_info);++i)
if(version == rtl_chip_info.version)
{tp->chipset = i;goto match;}
tp->chipset = 0;
match:
if(tp->chipset >= CH_8139B)
{
u8 ntmp = tmp = ioread8(ioaddr+Config1);
if((rtl_chip_info[tp->chipset].flags & HasLWake) && (ntmp & LWAKE))
ntmp = ntmp & ~LWAKE;
ntmp = ntmp | Cfg1_PM_Enable;
if(ntmp != tmp)
{
iowrite8(Cfg9346_Unlock,ioaddr+Cfg9346);
iowrite8(ntmp,ioaddr+Config1);
iowrite8(Cfg9346_lock,ioaddr+Cfg9346);
}
if(rtl_chip_info[tp->chipset].flags & HasLWake)
{
tmp = ioread8(ioaddr+Config4);
if(tmp & LWPTN)
{
iowrite8(Cfg9346_Unlock,ioaddr+Cfg9346);
iowrite8(tmp & ~LWPTN,ioaddr+Config4);
iowrite8(Cfg9346_lock,ioaddr+Cfg9346);
}
}
}
else
{
tmp = ioread8(ioaddr+Config1);
tmp = tmp & ~((1 << 1) | (1 << 0));
iowrite8(tmp,ioaddr+Config1);
}
xc_reset(ioaddr);
*dev_out = dev;
return 0;
err_out:
xc_cleanup_dev (dev);
if(dev_on)
pci_disable_device(pdev);
return rc;

}

static int __devinit xc_probe(struct pci_dev *pdev,const struct pci_device_id *ent)
{
struct xc_priv *tp;
struct net_device *dev = NULL;
void __iomem *ioaddr;
int rc,option;
static int index = -1;
if(pdev == NULL || ent == NULL)
return -ENODEV;
++index;
rc = xc_board(pdev,&dev);
if(rc < 0)
return rc;
if(dev == NULL)
return -1;
tp = netdev_priv(dev);
ioaddr = tp->ioaddr;
if(ioaddr == NULL)
return -1;
((u16*)dev->dev_addr)[0] = 0xE000;
((u16*)dev->dev_addr)[1] = 0x964C;
((u16*)dev->dev_addr)[2] = 0x9D16;
if(!dev->addr_len)
{
printk(KERN_INFO "XC:%i:dev->addr_len is set here\n",dev->addr_len);
dev->addr_len = 6;
}
memcpy(dev->perm_addr,dev->dev_addr,dev->addr_len);
/*dev function init*/
dev->open = xc_open;
dev->stop = xc_stop;
dev->hard_start_xmit = xc_tx;
dev->poll = xc_poll;
dev->weight = 64;
dev->get_stats = xc_get_stats;
dev->set_multicast_list = xc_set_multicast_list;
dev->do_ioctl = NULL;
dev->ethtool_ops = &xc_ethtool_ops;
dev->tx_timeout = xc_tx_timeout;
dev->watchdog_timeo = 6*HZ;
dev->features |= NETIF_F_SG | NETIF_F_HW_CSUM | NETIF_F_HIGHDMA;
dev->irq = pdev->irq;

tp = netdev_priv(dev);
ioaddr = tp->ioaddr;
tp->msg_enable = NETIF_MSG_DRV | NETIF_MSG_PROBE | NETIF_MSG_LINK;
spin_lock_init(&tp->lock);
spin_lock_init(&tp->rx_lock);
tp->mii.dev = dev;
tp->mii.mdio_read = mdio_read;
tp->mii.mdio_write = mdio_write;
tp->mii.phy_id_mask = 0x3f;
tp->mii.reg_num_mask = 0x1f;
rc = register_netdev(dev);
if(rc) goto err_out;
pci_set_drvdata (pdev, dev);

printk (KERN_INFO "%s:0x%lx--%2.2x:%2.2x:%2.2x:%2.2x:%2.2x:%2.2x,IRQ %d\n",
dev->name,dev->base_addr,dev->dev_addr[0], dev->dev_addr[1],
dev->dev_addr[2], dev->dev_addr[3],dev->dev_addr[4], dev->dev_addr[5],
dev->irq);
printk (KERN_DEBUG "%s: Identified 8139 chip type '%s'\n",
dev->name, rtl_chip_info[tp->chipset].name);
/*MII define*/
tp->phys[0] = 32;
tp->mii.phy_id = tp->phys[0];

/* The lower four bits are the media type. */
option = (index >= ? 0 : -1;
if (tp->mii.full_duplex) {
printk(KERN_INFO "%s: Media type forced to Full Duplex.\n", dev->name);
/* Changing the MII-advertised media because might prevent
re-connection. */
tp->mii.force_media = 1;
}
if (tp->default_port) {
printk(KERN_INFO " Forcing %dMbps %s-duplex operation.\n",
(option & 0x20 ? 100 : 10),
(option & 0x10 ? "full" : "half");
mdio_write(dev, tp->phys[0], 0,
((option & 0x20) ? 0x2000 : 0) | /* 100Mbps? */
((option & 0x10) ? 0x0100 : 0)); /* Full duplex? */
}
/*MII*/
if (rtl_chip_info[tp->chipset].flags & HasHltClk)
iowrite8('H',ioaddr+HltClk);
return 0;
err_out:
xc_cleanup_dev (dev);
pci_disable_device (pdev);
return rc;
}

static void __devexit xc_remove(struct pci_dev *pdev)
{
struct net_device *dev = pci_get_drvdata(pdev);
unregister_netdev(dev);
xc_cleanup_dev(dev);
pci_disable_device(pdev);
}

struct pci_driver xc_driver =
{
.name = "xc8139too",
.id_table = xc_id,
.probe = xc_probe,
.remove = __devexit_p(xc_remove),
};

static int __init xc_module_init(void)
{
return pci_module_init(&xc_driver);
}
static void __exit xc_module_exit(void)
{
pci_unregister_driver(&xc_driver);
}
module_init(xc_module_init);
module_exit(xc_module_exit);


文章来源CU社区:改写drivers/net/8139too.c


相关文章