#define REALTEK_VENDER_ID 0x10EC #define REALTEK_DEVICE_ID 0x8139 //#define REALTEK_VENDER_ID 0x10b5 //#define REALTEK_DEVICE_ID 0x9050 //#define VENDOR_ID 0x10b5 //#define DEVICE_ID 0x9050 #include #include #include #include #include int print_pci(struct pci_dev *pdev); struct rtl8139_private { struct pci_dev *pci_dev; /* PCI device */ void *mmio_addr; /* memory mapped I/O addr */ unsigned long regs_len; /* length of I/O or MMI/O region */ }; static struct pci_dev* probe_for_realtek8139(void) { struct pci_dev *pdev = NULL; /* Ensure we are not working on a non-PCI system */ //if(!pci_present( )) { // printk("<1>pci not present\n"); // return pdev; //} //else // printk("<1>pci device is present\n"); /* Look for RealTek 8139 NIC */ pdev = pci_find_device(REALTEK_VENDER_ID, REALTEK_DEVICE_ID, NULL); if(pdev) { printk("Found PCI device with vendorid = %x deviceid = %x\n", REALTEK_VENDER_ID, REALTEK_DEVICE_ID); /* device found, enable it */ if(pci_enable_device(pdev)) { printk("Could not enable the device\n"); return NULL; } else printk("Device enabled\n"); } else { printk("device not found\n"); return pdev; } return pdev; } #define DRIVER "rtl8139" static struct net_device *rtl8139_dev; static int rtl8139_init(struct pci_dev *pdev, struct net_device **dev_out) { struct net_device *dev; struct rtl8139_private *tp; /* * alloc_etherdev allocates memory for dev and dev->priv. * dev->priv shall have sizeof(struct rtl8139_private) memory * allocated. */ dev = alloc_etherdev(sizeof(struct rtl8139_private)); if(!dev) { printk("Could not allocate etherdev\n"); return -1; } tp = dev->priv; tp->pci_dev = pdev; *dev_out = dev; return 0; } static int rtl8139_open(struct net_device *dev) { printk("rtl8139_open is called\n"); return 0; } static int rtl8139_stop(struct net_device *dev) { printk("rtl8139_open is called\n"); return 0; } static int rtl8139_start_xmit(struct sk_buff *skb, struct net_device *dev) { printk("rtl8139_start_xmit is called\n"); return 0; } static struct net_device_stats* rtl8139_get_stats(struct net_device *dev) { printk("rtl8139_get_stats is called\n"); return 0; } int init_module(void) { struct pci_dev *pdev; unsigned long mmio_start, mmio_end, mmio_len, mmio_flags; void *ioaddr; struct rtl8139_private *tp; int i, err = 0; pdev = probe_for_realtek8139( ); if(!pdev) return 0; print_pci(pdev); if(rtl8139_init(pdev, &rtl8139_dev)) { printk("Could not initialize device\n"); return 0; } tp = rtl8139_dev->priv; // rtl8139 private information printk("Reading the PCI BAR registers \n"); // get PCI memory mapped I/O space base address from BAR1 mmio_start = pci_resource_start(pdev, 1); mmio_end = pci_resource_end(pdev, 1); mmio_len = pci_resource_len(pdev, 1); mmio_flags = pci_resource_flags(pdev, 1); printk("Checking the PCI BAR registers for Memory mapped flag \n"); // make sure above region is MMI/O if(!(mmio_flags & IORESOURCE_MEM)) { printk("region not MMI/O region\n"); goto cleanup1; } else printk("region is Memory mapped region\n"); printk("Calling pci_request_region \n"); // get PCI memory space if(pci_request_regions(pdev, DRIVER)) { printk("Could not get PCI region\n"); goto cleanup1; } printk("Calling pci_set_master\n"); pci_set_master(pdev); printk("Calling ioremap\n"); // ioremap MMI/O region ioaddr = ioremap(mmio_start, mmio_len); if(!ioaddr) { printk("Could not ioremap\n"); goto cleanup2; } printk("Assigning ioaddress and length \n"); rtl8139_dev->base_addr = (long)ioaddr; tp->mmio_addr = ioaddr; tp->regs_len = mmio_len; // UPDATE NET_DEVICE printk("Assigning hardware address \n"); for(i = 0; i < 6; i++) { // Hardware Address rtl8139_dev->dev_addr[i] = readb(rtl8139_dev->base_addr+i); rtl8139_dev->broadcast[i] = 0xff; } rtl8139_dev->hard_header_len = 14; printk("Assigning function address \n"); memcpy(rtl8139_dev->name, DRIVER, sizeof(DRIVER)); // Device Name rtl8139_dev->irq = pdev->irq; // Interrupt Number rtl8139_dev->open = rtl8139_open; rtl8139_dev->stop = rtl8139_stop; rtl8139_dev->hard_start_xmit = rtl8139_start_xmit; rtl8139_dev->get_stats = rtl8139_get_stats; printk("Calling register_netdev \n"); // register the device if(register_netdev(rtl8139_dev)) { printk("Could not register netdevice\n"); goto cleanup0; } cleanup0: unregister_netdev(rtl8139_dev); err = 1; cleanup2: iounmap(tp->mmio_addr); err = 1; cleanup1: pci_release_regions(tp->pci_dev); err = 1; return err; } void cleanup_module(void) { struct rtl8139_private *tp; tp = rtl8139_dev->priv; iounmap(tp->mmio_addr); pci_release_regions(tp->pci_dev); unregister_netdev(rtl8139_dev); pci_disable_device(tp->pci_dev); return; } // Should be called after pci_find_device and pci_enable_device have been called int print_pci(struct pci_dev *dev) { int i; int start, end, length, resflags; for (i = 0; i < 6; i++) { start = pci_resource_start (dev, i); if (!start) continue; end = pci_resource_end (dev, i); length = pci_resource_len (dev, i); resflags = pci_resource_flags (dev, i); if (resflags & IORESOURCE_IO) { printk("----------------------------------------------------------------\n"); printk("Base %d Starting Address = %x End Address = %x Length = %d\n",i, start, end, length); printk ("This Port is I/O mapped. "); if (resflags & IORESOURCE_PREFETCH) printk ("It is Prefetchable."); else printk ("It is NON Prefetchable."); if (resflags & IORESOURCE_READONLY) printk ("This is read only.\n"); else printk ("This is readable and writable.\n"); if (check_region (start, length) < 0) printk ("Base %d starting Address = %x End Address = %x Length = %d resource is not available \n", i, start, end, length); //else if (request_region (start, length, DRIVER_NAME) < 0) // printk ("The Resource is not allocated for BAR %d\n", i); // else // printk ("The Resource is allocated for BAR %d\n", i); } else { if (resflags & IORESOURCE_MEM) { printk ("Base %d Starting Address = %x End Address = %x Length = %d\n",i, start, end, length); printk ("This Port is Memory mapped. "); if (resflags & IORESOURCE_PREFETCH) printk ("It is Prefetchable. "); else printk ("It is NON Prefetchable. "); if (resflags & IORESOURCE_READONLY) printk ("It is read only.\n"); else printk ("This is readable and writable.\n"); if (check_mem_region (start, length) < 0) printk ("Base %d starting Address = %x End Address = %x Length = %d resource is not available \n", i, start, end, length); else { //if (request_mem_region (start, length, DRIVER_NAME) < 0) // printk("The Resource is not allocated for BAR %d\n", i); //else // printk ("The Resource is allocated for BAR %d\n", i); } } } } return 0; }