Red de conocimiento informático - Conocimiento informático - ¿Cómo escribir un controlador de tarjeta de red?

¿Cómo escribir un controlador de tarjeta de red?

Los métodos y pasos de implementación son los siguientes:

1. Si el dispositivo de red (incluido el dispositivo inalámbrico) tiene especificación PCI, primero registre el dispositivo PCI (pci_register_driver) con el kernel. y luego use la estructura de datos pci_driver. La función de sonda a la que apunta el puntero de función de sonda inicializa el dispositivo PCI y también registra e inicializa el dispositivo de red.

Declarado como dispositivo PCI: static?struct?pci_driver?tg3_driver?=?{

.name?=?DRV_MODULE_NAME,

.id_table?=?tg3_pci_tbl ,?//La serie de tarjetas de red, proveedor_id, dispositivo_id admitidos por este controlador

.probe?=?tg3_init_one,?//Función de devolución de llamada para inicializar el dispositivo de red

.remove? =? __devexit_p(tg3_remove_one),?//Función de devolución de llamada para cerrar sesión en el equipo de red

.suspend?=?tg3_suspend,?//Función de suspensión del dispositivo

.resume?=?tg3_resume ?/ /Función de recuperación del dispositivo

};

Función de sonda del dispositivo PCI, inicialización del dispositivo de red: static?int?__devinit?tg3_init_one(struct?pci_ dev?*pdev, const? struct?pci_device_id?*ent)

{

//Inicializa el dispositivo, hace que las E/S y la memoria estén disponibles y activa el dispositivo

pci_enable_device( pdev);

/Espacio de memoria de la aplicación

pci_request_regions(pdev,?DRV_MODULE_NAME);

pci_set_master(pdev);

// establecer atributo DMA

pci_set_dma _mask(pdev, ?

tg3reg_len?=?pci_resource_len(pdev,?0);

/ Asignar y configurar dispositivos de red

dev?alloc_etherdev(sizeof(*tp));

/Especificado como módulo de dispositivo del kernel

SET_MODULE_OWNER(dev);

// Inicializando estructura privada Cada valor de miembro de

tp?=?dev->priv;

tp->pdev?=?pdev;

tp->dev ?= ?dev;

(sin firmar?long)?ioremap(tg3reg_base,?tg3reg_len);

dev->irq?=?pdev->irq;

/Asignación de función de devolución de llamada de dispositivo de red

dev->open?=?tg3_open;

dev->stop?=?tg3_close;

dev-> get_stats? =?tg3_get_stats;

dev->set_multicast_list?=?tg3_set_rx_mode;

dev->set_mac_address?=?tg3_set_mac_addr;

dev->do_ioctl? =? tg3_ioctl;

dev->tx_timeout?=?tg3_tx_timeout;

dev->hard_start_xmit=?tg3_start_xmit;

// Dirección MAC de la tarjeta de red Asignar dev->addr

tg3_get_device_address(tp);/ Register_network_device

register_

netdev(dev);

//Coloque la dirección del puntero del dispositivo de red en el puntero del dispositivo PCI

pci_set_drvdata(pdev,?dev);

}

Abra el dispositivo de red: /*?

void(*handler)(int?irq,?void?*dev_id,?struct?pt_regs?*regs),?

irqflags largos sin firmar,?

const char * devname,?

void?*dev_id);?

irq es la interrupción de hardware Se solicitará el número de serie. En las plataformas Intel, el rango es de 0 a 15.

Handler es una función de manejo de interrupciones registrada en el sistema.

Esta es una función de devolución de llamada. Cuando ocurre una interrupción, el sistema la llamará. Los parámetros entrantes incluyen el número de interrupción de hardware, la identificación del dispositivo y el valor del registro.

dev_id es el parámetro dev_id pasado al sistema bajo request_irq.

irqflags son algunos atributos del manejo de interrupciones. Los más importantes son ?SA_INTERRUPT y ?

Indican si el controlador de interrupciones es un controlador rápido (SA_INTERRUPT está configurado) o un controlador lento (SA_INTERRUPT no está configurado).

¿Rápido? El controlador enmascara todas las interrupciones cuando se le llama. Los manejadores lentos no enmascaran las interrupciones.

También hay un atributo SA_SHIRQ, que se puede configurar para ejecutar múltiples dispositivos para disfrutar de las interrupciones. Cuando **** consume la interrupción, se utilizará dev_id. Por lo general, se establece en la estructura del dispositivo en sí o en NULL. Un controlador de interrupciones puede usar dev_id para encontrar el dispositivo que controla la interrupción, o rq2dev_map para encontrar el dispositivo correspondiente a la interrupción.

*/

static?int?tg3_open(struct?net_device?*dev)

{

/Asignar una interrupción

request_irq(dev->irq,?tg3_interrupción,?SA_SHIRQ,?dev->nombre,?dev);