La transmisión de datos en la capa de enlace de la pila de protocolos Linux - recepción de datos

  

datos de proceso de la recepción de los datos de la tarjeta a fin de comprender que reciben. Es necesario discutir el proceso específico de la DMA. DMA transfiere los datos se pueden dividir en los siguientes pasos: en primer lugar: el envío de un comando a la DMA CPU, tales como el modo DMA, la dirección de memoria, el número de palabras de transmisión, entonces el programa original y la CPU ejecuta el control DMA dispositivos de E /S y la memoria principal. entre los datos de cambio. Después de recibir los datos, la solicitud de DMA se envía a la CPU, para obtener el control del bus para transferencia de datos, la tarjeta principal dirección de memoria modificación, comprobar y modificar el valor de contador de palabras es cero, cero no es continuar para transmitir, cero Ruoyi , a continuación, enviar una solicitud de interrupción a la CPU .. Es decir, cuando la tarjeta recibe un paquete, se colocará en la corriente gt skb- y; datos en. Una vez más, cuando un paquete. DMA modificará la dirección de memoria principal en la tarjeta, a skb- > siguiente, en el cual los datos. Es decir, un skb- > Causa de datos almacenados en un paquete de datos. Pues bien, ahora se puede ver en los implementos de código específico. Cuando los datos de la red a la red, lo ponen en la tarjeta de memoria DMA, y luego informan al DMA interrumpir la CPU, el vector de interrupción de la CPU para encontrar las rutinas de manejo de interrupción, sino que hemos e100_intr ya registrado () según el procedimiento. e100_intr estática irqreturn_t (int IRQ, void * dev_id, pt_regs struct * regs) {struct net_device * netdev = dev_id; struct nic * nic = netdev_priv (netdev); u8 stat_ack = readb (&NIC- > csr- > SCB .stat_ack); DPRINTK (INTR, DEBUG, " stat_ack = 0x% 02X \\ n ", stat_ack), si (stat_ack == stat_ack_not_ours | |  /* No es nuestra interrupción * /stat_ack == stat_ack_not_present) /* * Hardware se expulsa /retorno IRQ_NONE; /* Ack de interrupción (s) * ///envía un ACK de interrupción. CPU envía un ACK al dispositivo. Esto representa la interrupción ha sido procesado writeb (stat_ack, &NIC-> csr- > scb.stat_ack); /* Llegamos a recibir ningún Recursos (RNR); reiniciar RU después de la limpieza * /if (stat_ack &stat_ack_rnr) NIC- > ru_running = 0; //deshabilitar interrupciones e100_disable_irq (nic); //planificación de la CPU se pone en marcha para este dispositivo. A su vez se ejecuta gt netdev- y; pollnetif_rx_schedule (netdev); IRQ_HANDLED regreso; después} netif_rx_schedule (netdev), la CPU comienza a programar el dispositivo, el dispositivo de sondeo si hay datos a procesar. Llamada después de la transfección, netdev- > función de consulta, a saber: e100_poll () static int e100_poll (struct net_device * netdev, presupuesto int *) {struct nic * nic = netdev_priv (netdev); unsigned int work_to_do = min (netdev- > cuota , * presupuesto); unsigned int work_done = 0; int tx_cleaned; //comienzan nic, el procesamiento e100_rx_clean (nic de los datos de DMA, &work_done, work_to_do); tx_cleaned = e100_tx_clean (NIC); /* Si no hay Tx y Rx trabajos de limpieza se llevó a cabo, salga del modo de votación * /if ((tx_cleaned &&.! (work_done == 0)) | |  ! Netif_running (netdev)) {netif_rx_complete (netdev); e100_enable_irq (NIC); return 0;} * Presupuesto - = work_done; netdev- > cuotas - = work_done; return 1;} seguimiento en e100_rx_clean (): inline void e100_rx_clean (struct nic * nic, unsigned int * work_done, unsigned int work_to_do) {struct rx * rx; /* Indica recién llegado paquetes * ///a través de los datos en el anillo de DMA, llame e100_rx_indicate () de procesamiento para (rx = NIC- > rx_to_clean; RX- > skb; rx = NIC- > rx_to_clean = RX- > siguiente) {if (e100_rx_indicate (nic, rx, work_done, work_to_do)) break; /* No más de limpiar * /} /* Alloc nuevos SKBS para rellenar lista * /for (rx = NIC- > rx_to_use;! RX- > skb; rx = NIC- > rx_to_use = RX- > siguiente) {if (poco probable (e100_rx_alloc_skb (nic, rx ))) romper; /* Mejor suerte la próxima vez (ver watchdog) * /} e100_start_receiver (nic);} aquí, pasa por los datos de la DMA anillo, es decir, desde NIC- > a partir de datos rx_to_clean hasta que todos los datos procesado en la función de procesamiento: e100_rx_indicate () estática inline int e100_rx_indicate (struct nic * nic, struct rx * rx, unsigned int * work_done, unsigned int work_to_do) {sk_buff struct * skb = RX- > skb;. //rfd hecho aquí parte de la información recibida que incluye, pero no es una transmisión de datos válidos sobre el rfd enlace struct * RFD = (struct rfd *) skb- > datos; rfd_status u16, actual_size; si (poco probable (work_done &&* work_done > = work_to_do)) RETURN -EAGAIN; //síncrono pci_dma_sync_single_for_cpu tampón DMA (NIC- > PDEV, RX- > dma_addr, sizeof (struct rfd), PCI_DMA_FROMDEVICE); //estado de recepción adquirido rfd_status = le16_to_cpu (rfd- > status); DPRINTK (RX_STATUS, DEBUG, " estado = 0x% 04X \\ n " , rfd_status); /* Si los datos no está listo, no hay nada que indique * ///no recibieron por completo, vuelve

Copyright © Conocimiento de Windows All Rights Reserved