& Nbsp; in general, when compiling the kernel, there are two methods to choose the device driver: one is to directly compile it into the kernel, and the other is to hook up the module. If the CS8900 NIC driver is mounted as a module, the init_module function is the entry; if it is directly compiled into the kernel, then the cs89x0_probe function
In general, when compiling the kernel, there are two methods to choose the device driver: one is to directly compile it into the kernel, and the other is to hook up the module. If the CS8900 NIC driver is mounted as a module, the init_module function is the entry. if it is directly compiled into the kernel, the cs89x0_probe function is the entry. In this entry function, the NIC driver is initialized. Such as registering virtual addresses, device numbers, interrupt numbers, and initialization of various registers.
Cs89x0_probe function will call the real initialization function cs89x0_probe1. The following describes the important points to be completed in the initialization function:
1. Register a virtual address.
Use the request_region function to register a virtual address. In kenel, the registers we operate on are actually virtual addresses, but each register's virtual address has a unique physical address, because any virtual address in the kernel will be converted to a physical address through MMU. Therefore, after defining the registers to be used in the kernel, you must use the ioremap function to convert the physical addresses of the registers we use into virtual addresses that can be operated in the kernel, then they can be used for specific operations, otherwise everything will be futile.
Ioaddr = (int) ioremap (BASE_ADDR, 16 );
2. fill in the net_device struct.
The members of this struct are all variables related to network devices. There are two important ones: dev_addr and open. In dev_addr, you need to store the MAC address of the host, which is generally read from eeproom and then stored in this variable. of course, you can also manually assign values as needed.
for (i=0; i < ETH_ALEN/2; i++) { unsigned int Addr; Addr = readreg(dev, PP_IA+i*2); dev->dev_addr[i*2] = Addr & 0xFF; dev->dev_addr[i*2+1] = Addr >> 8;}
|
Open is a function pointer, and net_open function must be assigned to it. The net_open function is a function used to register the network device interrupt number. when you input the ifconfig command, the function is called. Set the interrupt number in this function.
writereg(dev, PP_BusCTL, ENABLE_IRQ | MEMORY_ON); request_irq(dev->irq, &net_interrupt, 0, dev->name, dev);
|
3. I/O port interrupt request settings.
The network card cannot and does not need to be interrupted all the time. a reasonable time to trigger the interruption is a necessary condition. According to the pins in the hardware circuit diagram, the corresponding interrupt request registers are GPG1 and EINT9. In the GPG1 register, the EINT9 register function should be activated, and in the EINT9 register, the interrupt should be set to the top hop edge trigger.
writel(readl(S 3C2410_GPGCON) | 0x8, S3C2410_GPGCON); writel(readl(S3C2410_EXTINT1) | 0x40, S3C2410_EXTINT1);
|
Note that the registers of the CS8900 Nic are all 16-bit. Therefore, when selecting the read/write function, you must also select the read/write function of the 16-bit register.
static u16 readword(unsigned long base_addr, int portno){ return inw(base_addr + portno); } static void writeword(unsigned long base_addr, int portno, u16 value){ outw(value, base_addr + portno);}
|
The preceding figure shows the precautions for Linux kernel2.6.25 CS8900 Nic Driver porting. There are a lot of compatible things in the Kernel, removing conflicting parts and adding functions that you need to implement to ensure smooth migration.