⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 rtl_8139too.c

📁 最新rtlinux内核源码
💻 C
📖 第 1 页 / 共 3 页
字号:
          private_data.cur_rx = 0;        private_data.cur_tx = 0;        private_data.dirty_tx = 0;         for (i = 0; i < NUM_TX_DESC; i++) {                private_data.tx_info[i].skb = NULL;                private_data.tx_info[i].mapping = 0;                private_data.tx_buf[i] = &private_data.tx_bufs[i * TX_BUF_SIZE];        } }static int dev_rtl8139_open (struct pci_dev *dev){        int retval;        long ioaddr;	ioaddr = (long)private_data.mmio_addr;          retval = rtl_request_irq (dev->irq, &rt_rtl8139_interrupt);        if (retval) {                rtl_printf ("rtl_request_irq : EXIT, returning %d\n", retval);                return retval;        } else private_data.must_free_irq = 1;        private_data.tx_bufs = pci_alloc_consistent(private_data.pdev, TX_BUF_TOT_LEN,                                           &private_data.tx_bufs_dma);        private_data.rx_ring = pci_alloc_consistent(private_data.pdev, RX_BUF_TOT_LEN,                                           &private_data.rx_ring_dma);        if (private_data.tx_bufs == NULL || private_data.rx_ring == NULL) {                rtl_free_irq(dev->irq);                 if (private_data.tx_bufs)                        pci_free_consistent(private_data.pdev, TX_BUF_TOT_LEN,                                            private_data.tx_bufs, private_data.tx_bufs_dma);                if (private_data.rx_ring)                        pci_free_consistent(private_data.pdev, RX_BUF_TOT_LEN,                                            private_data.rx_ring, private_data.rx_ring_dma);                 rtl_printf ("EXIT, returning -ENOMEM\n");                return -ENOMEM;         }        private_data.full_duplex = private_data.duplex_lock;        private_data.tx_flag = (TX_FIFO_THRESH << 11) & 0x003f0000;        private_data.twistie = 1;         rt_rtl8139_init_ring (dev);        rt_rtl8139_hw_start (dev);              rtl_printf ("%s: dev_8139_open() ioaddr %#lx IRQ %d"                        " GP Pins %2.2x %s-duplex.\n",                        dev->name, pci_resource_start (private_data.pdev, 1),                        dev->irq, RTL_R8 (MediaStatus),                        private_data.full_duplex ? "full" : "half");         if (private_data.thr_pid < 0)                rtl_printf ( "%s: unable to start kernel thread\n",                        dev->name);         return 0;}/***************************************************************************************/int start_up_device(struct pci_dev *dev){  	u32 pio_start, pio_end, pio_flags, pio_len;    	unsigned long mmio_start, mmio_end, mmio_flags;  	unsigned int mmio_len;  	u8 tmp8;  	int rc=0, i, option, addr_len;  	static int board_idx=0;  	u32 tmp;  	void *ioaddr = NULL;  	char *print_name;   	print_name = dev ? dev->slot_name : "rtl8139";  	pio_start = rt_pci_resource_start (dev, 0);  	pio_end = rt_pci_resource_end (dev, 0);  	pio_flags = rt_pci_resource_flags (dev, 0);  	pio_len = rt_pci_resource_len (dev, 0);   	mmio_start = rt_pci_resource_start (dev, 1);  	mmio_end = rt_pci_resource_end (dev, 1);  	mmio_flags = rt_pci_resource_flags (dev, 1);  	mmio_len = rt_pci_resource_len (dev, 1);  	private_data.mmio_len = mmio_len;  	/* set this immediately, we need to know before  	* we talk to the chip directly */  	if (pio_len == RTL8139B_IO_SIZE) {  		private_data.chipset = CH_8139B;  	}   	/* make sure PCI base addr 0 is PIO */  	if (!(pio_flags & IORESOURCE_IO)) {  		rtl_printf ("region #0 not a PIO resource, aborting\n");  	}   	/* make sure PCI base addr 1 is MMIO */  	if (!(mmio_flags & IORESOURCE_MEM)) {  		rtl_printf ( "region #1 not an MMIO resource, aborting\n");  	}   	/* check for weird/broken PCI region reporting */  	if ((pio_len < RTL_MIN_IO_SIZE) || (mmio_len < RTL_MIN_IO_SIZE)) {  		rtl_printf ( "Invalid PCI region size(s), aborting\n");  	}    	print_name = dev ? dev->slot_name : "rtl8139";  	rc = pci_request_regions (dev, dev->name);     	if (rc)  		goto err_out;  	pci_set_master (dev);   	/* ioremap MMIO region */  	ioaddr = ioremap (mmio_start, mmio_len);  	if (ioaddr == NULL) {  		rtl_printf ("cannot remap MMIO, aborting\n");  		rc = -EIO;  		goto err_out;  	}  	/* Soft reset the chip. */  	RTL_W8 (ChipCmd, (RTL_R8 (ChipCmd) & ChipCmdClear) | CmdReset);   	/* Check that the chip has finished the reset. */  	for (i = 1000; i > 0; i--)  		if ((RTL_R8 (ChipCmd) & CmdReset) == 0)  			break;  		else  			udelay (10);   	/* Bring the chip out of low-power mode. */  	if (private_data.chipset == CH_8139B) {  		RTL_W8 (Config1, RTL_R8 (Config1) & ~(1<<4));  		RTL_W8 (Config4, RTL_R8 (Config4) & ~(1<<2));  	} else {  		/* handle RTL8139A and RTL8139 cases */  		/* XXX from becker driver. is this right?? */  		RTL_W8 (Config1, 0);  	}  	/* make sure chip thinks PIO and MMIO are enabled */  	tmp8 = RTL_R8 (Config1);  	if ((tmp8 & Cfg1_PIO) == 0) {  		rtl_printf ("PIO not enabled, Cfg1=%02X, aborting\n", tmp8);        	rc = -EIO;        	goto err_out;  	}  	if ((tmp8 & Cfg1_MMIO) == 0) {  		rtl_printf ("MMIO not enabled, Cfg1=%02X, aborting\n", tmp8);        	rc = -EIO;        	goto err_out;  	}  	/* identify chip attached to board */	/*      tmp = RTL_R8 (ChipVersion);   */  	tmp = RTL_R32 (TxConfig);  	tmp = ( (tmp&0x7c000000) + ( (tmp&0x00800000)<<2 ) )>>24;  	private_data.drv_flags = board_info[0].hw_flags;  	private_data.pdev = dev;  	private_data.mmio_addr = ioaddr;   	for (i = ARRAY_SIZE (rtl_chip_info) - 1; i >= 0; i--)  		if (tmp == rtl_chip_info[i].version) {        		private_data.chipset = i;        	}  	if(private_data.chipset > (ARRAY_SIZE (rtl_chip_info) - 2))  		private_data.chipset = ARRAY_SIZE (rtl_chip_info) - 2;   	/* Find the connected MII xcvrs.  	Doing this in open() would allow detecting external xcvrs later, but takes too much time. */  	if (private_data.drv_flags & HAS_MII_XCVR) {  		int phy, phy_idx = 0;        	for (phy = 0; phy < 32 && phy_idx < sizeof(private_data.phys); phy++) {        		int mii_status = rt_rtl8139_mdio_read(dev, phy, 1);                	if (mii_status != 0xffff  &&  mii_status != 0x0000) {                       		private_data.phys[phy_idx++] = phy;                       		private_data.advertising = rt_rtl8139_mdio_read(dev, phy, 4);                       		rtl_printf( "%s: MII transceiver %d status 0x%4.4x "                              		"advertising %4.4x.\n",                              		dev->name, phy, mii_status, private_data.advertising);                	}        	}        	if (phy_idx == 0) {                	rtl_printf( "%s: No MII transceivers found!  Assuming SYM "                       		"transceiver.\n",                       		dev->name);                       	private_data.phys[0] = 32;        	}  	} else        	private_data.phys[0] = 32;   	/* Put the chip into low-power mode. */  	RTL_W8_F (Cfg9346, Cfg9346_Unlock);   	tmp = RTL_R8 (Config1) & Config1Clear;  	tmp |= (private_data.chipset == CH_8139B) ? 3 : 1; /* Enable PM/VPD */  	RTL_W8_F (Config1, tmp);   	RTL_W8_F (HltClk, 'H'); /* 'R' would leave the clock running. */   	/* The lower four bits are the media type. */  	option = (board_idx >= MAX_UNITS) ? 0 : media[board_idx];  	private_data.AutoNegoAbility = option&0xF;   	if (option > 0) {        	private_data.full_duplex = (option & 0x210) ? 1 : 0;        	private_data.default_port = option & 0xFF;        	if (private_data.default_port)              		private_data.medialock = 1;  	}  	if (board_idx < MAX_UNITS  &&  full_duplex[board_idx] > 0)        	private_data.full_duplex = full_duplex[board_idx];  	if (private_data.full_duplex) {        	rtl_printf( "%s: Media type forced to Full Duplex.\n", dev->name);        	/* Changing the MII-advertised media because might prevent  re-connection. */        	private_data.duplex_lock = 1;  	}   	if (private_data.default_port) {       		rtl_printf( "%s: Forcing %dMbs %s-duplex operation.\n", dev->name,             		(option & 0x0C ? 100 : 10),             		(option & 0x0A ? "full" : "half"));       			rt_rtl8139_mdio_write(dev, private_data.phys[0], 0,             		((option & 0x20) ? 0x2000 : 0) |     /* 100mbps? */             		((option & 0x10) ? 0x0100 : 0)); /* Full duplex? */  	}  	addr_len = rt_rtl8139_read_eeprom (ioaddr, 0, 8) == 0x8129 ? 8 : 6;  	for (i = 0; i < 3; i++)     		((u16 *) (private_data.dev_addr))[i] =  le16_to_cpu (rt_rtl8139_read_eeprom (ioaddr, i + 7, addr_len));  	rtl_printf( "%s: %s at 0x%lx, "                "%2.2x:%2.2x:%2.2x:%2.2x:%2.2x:%2.2x, "                "IRQ %d\n",                dev->name,                board_info[0].name,                private_data.mmio_addr,                private_data.dev_addr[0], private_data.dev_addr[1],                private_data.dev_addr[2], private_data.dev_addr[3],                private_data.dev_addr[4], private_data.dev_addr[5],                dev->irq);  	dev_rtl8139_open(dev);  	return 0;err_out:  		rtl_printf ("EXIT, returning %d\n", rc);  		return rc;}static void rt_rtl8139_tx_clear (struct rtl8139_private private_data){        int i;         private_data.cur_tx = 0;        private_data.dirty_tx = 0;         /* Dump the unsent Tx packets. */        for (i = 0; i < NUM_TX_DESC; i++) {                struct ring_info *rp = &private_data.tx_info[i];                if (rp->mapping != 0) {                        pci_unmap_single (private_data.pdev, rp->mapping,                                          rp->skb->len, PCI_DMA_TODEVICE);                        rp->mapping = 0;                }                if (rp->skb) {                        dev_kfree_skb (rp->skb);                        rp->skb = NULL;                        private_data.stats.tx_dropped++;                }        }}static int eth_close (struct pci_dev *dev){  void *ioaddr;  rtl_printf("inside eth_close\n");  ioaddr= private_data.mmio_addr;         rtl_printf ("%s: Shutting down ethercard, status was 0x%4.4x.\n", dev->name, RTL_R16 (IntrStatus));         /* Stop the chip's Tx and Rx DMA processes. */        RTL_W8 (ChipCmd, (RTL_R8 (ChipCmd) & ChipCmdClear));         /* Disable interrupts by clearing the interrupt mask. */        RTL_W16 (IntrMask, 0x0000);         /* Update the error counts. */        private_data.stats.rx_missed_errors += RTL_R32 (RxMissed);        RTL_W32 (RxMissed, 0); 	if(private_data.must_free_irq) {        	    rtl_free_irq (dev->irq);	    private_data.must_free_irq = 0;	}         rt_rtl8139_tx_clear(private_data);        pci_free_consistent(private_data.pdev, RX_BUF_TOT_LEN,private_data.rx_ring, private_data.rx_ring_dma);        pci_free_consistent(private_data.pdev, TX_BUF_TOT_LEN,private_data.tx_bufs, private_data.tx_bufs_dma);        private_data.rx_ring = NULL;        private_data.tx_bufs = NULL;         /* Green! Put the chip in low-power mode. */        RTL_W8 (Cfg9346, Cfg9346_Unlock);        RTL_W8 (Config1, 0x03);        RTL_W8 (HltClk, 'H');   /* 'R' would leave the clock running. */         return 0;}static void  eth_remove_one (struct pci_dev *pdev){	long io_addr; 	io_addr = (long)private_data.mmio_addr;         iounmap (private_data.mmio_addr);        pci_release_regions (pdev);  }

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -