wiki:mnc_driver

Version 2 (modified by alain, 7 years ago) (diff)

--

GIET-VM / NIC_MNC Driver

The mnc_driver.c and mnc_driver.h files define the NIC_MNC driver.

This driver supports the vci_master_nic component, that is a Gigabit Ethernet network controller.

This component has a DMA capability, to access the memory mapped RX and TX ethernet packets queues. These queues are implemented by a chained buffers structure, called NIC_CHBUF, and implemented by the nic_chbuf_t structure.

It can exist only one ethernet network controller in the architecture, but to improve the throughput, it supports up to 4 channels (i.e. 4 TX and 4 RX queues), indexed by a key depending on the source IP address for the RX packets, and depending on the destination IP address for the TX packets. All channels use the same source MAC address.

The Ethernet packet length can have any value, between 64 to 1538 bytes. The data transfer unit between software and the NIC is a 4 Kbytes "container", containing an integer number of variable size packets. The max number of packets in a container is 66 packets. The first 34 words of a container are the container header :

word0 NB_WORDS NB_PACKETS
word1 PLEN[0] PLEN[1]
... ....... ........
word33 PLEN[64] PLEN[65]

NB_PACKETS is the actual number of packets in the container, NB_WORDS is the number of useful words in the container, PLEN[i] is the number of bytes for packet[i]. Packets are stored in the (1024 - 34) following words, and are word-aligned.

Each 4 Kbytes container is protected by a SET/RESET synchronisation variable. To access both the container status, and the container itself, the NIC uses two physical addresses, that are packed in a 64 bits "container descriptor".

  • desc[25:0] contain bits[31:6] of the status physical address.
  • desc[51:26] contain bits[31:6] of the buffer physical address.
  • desc[63:52] contain the common 12 physical address extension bits.

To each TX or RX queue is associated a kernel thread that is in charge of moving the infinite stream of containers between the NIC and the RX/TX queue.

The RX/TX queues (and the associated kernel threads) are physically distributed on various clusters, using a round robin policy (modulo the number of clusters).

The actual number of channels is defined by the NB_NIC_CHANNELS parameter in the hard_config.h file, and the SEG_NIC_BASE address must be defined in the hard_config.h file.

The addressable registers map is defined here.

Access Functions

1) void _mnc_init( )

This function allocates memory for the RX_CHBUF and TX_CHBUF implementing the RX and TX queues for all channels. It uses a round-robin policy, to distribute one CHBUF per cluster if the number of clusters is larger than 2 * NB_NIC_CHANNELS. It initialises both the CHBUF descriptors, and the hardware NIC registers.

2) unsigned int _mnc_writable( unsigned int channel, unsigned int length )

This function returns a Boolean indicating if an Ethernet packet of a given length can be stored in the TX queue defined by the channel argument. The internal state of the queue (write pointer) can be modified if required.

  • channel : channel index
  • length : register index
  • return a non-zero value if packet can be written / return zero if queue is full.

3) unsigned int _mnc_readable( unsigned int channel , unsigned int * src_ip , unsigned int * src_port , unsigned int * dst_ip , unsigned int * dst_port , unsigned int * length )

This function returns a Boolean indicating if an Ethernet packet is available in the RX queue defined by the channel argument. It also returns various informations contained in the IP and TCP/UDP headers. The internal state of the queue (read pointer) can be modified if required.

  • channel : channel index
  • src_ip : source IP address (from IP header)
  • src_port : source port index (from TCP/UDP header)
  • src_ip : source IP address (from IP header)
  • src_port : source port index (from TCP/UDP header)
  • length : Ethernet packet length (bytes)
  • return a non-zero value if packet can be read / return zero if queue is empty.

4) void _mnc_write( unsigned int channel , void * buffer , unsigned int length )

This function writes an Ethernet packet in the TX queue defined by the channel argument. It should be called after the _mnc_writable() function.

  • channel : channel index
  • buffer : pointer on buffer containing packet
  • length : Ethernet packet length (bytes)

5) int _mnc_read( unsigned int channel , void * buffer )

This function read an Ethernet packet from the RX queue defined by the channel argument. It should be called after the _mnc_readable() function.

  • channel : channel index
  • buffer : pointer on buffer containing packet

6) void _mnc_set_global_register( unsigned int index , unsigned int value )

This function set a given value in a given NIC global register.

  • index : register index
  • value : value to be written

7) unsigned int _mnc_get_global_register( unsigned int index )

This function returns the value contained in a given NIC global register.

  • index : register index
  • return value

Interrupt Service Routines

8) void _nic_rx_isr( unsigned int irq_type, unsigned int irq_id, unsigned int channel )

This interrupt Service Routine handles IRQs from a NIC_RX channel. WARNING : Not fully implemented yet : no IRQ acknowledge...

9) void _nic_tx_isr( unsigned int irq_type, unsigned int irq_id, unsigned int channel )

This interrupt Service Routine handles IRQs from a NIC_TX channel. WARNING : Not fully implemented yet : no IRQ acknowledge...