1.2.5.2 MAC Driver Module

In the seven-layer OSI model of computer networking, media access control (MAC) data communication protocol is a sub-layer of the data link_layer, which itself is layer_2. The MAC sub-layer provides addressing and channel access control mechanisms that make it possible for several terminals or network nodes to communicate within a multiple access network that incorporates a shared medium (e.g., Ethernet). The hardware that implements the MAC is referred to as a medium access controller.

The MAC sub-layer acts as an interface between the logical link control (LLC) sub-layer and the network's physical_layer. The MAC_layer emulates a full-duplex logical communication channel in a multi-point network. This channel may provide unicast, multicast or broadcast communication service.

Abstraction Model

TCPIP MAC mac_abstraction

How the Library WorksThe MAC layer_(together with the Logical Link Control – LLC) is intended to have the functionality described in the OSI model for the Data Link Layer.

There are two important functions to be performed in the MAC layer_as part of the Data Link Layer:

Data Encapsulation (Transmit and Receive)

  • Framing (frame boundary detection, frame synchronization)

  • Addressing (control of the source and destination addresses)

  • Error detection (detection of transmission errors occurring in the physical medium)

Media Access Management

  • Medium allocation (collision avoidance)

  • Contention resolution (collision handling)

Beside this, the receive packet filtering is another important functionality that is usually integrated in the MAC_layer.

The functionality previously presented is handled by the hardware itself as an intrinsic part of the data exchange that’s performed with the PHY.

From the software point of view the MAC driver exposes an API that’s focused on efficient data transfer routines. Control of the driver and access to the transferred data is given by using regular driver client access functions.

Please note that the MAC model described here corresponds to a virtual MAC driver that the TCP/IP stack uses. All the implementations of the physical MAC drivers (Ethernet, Wi-Fi, etc.) must adhere and implement this API required by the virtual MAC API. This is how the TCP/IP stack achieves virtualization of the operation over multiple network interfaces. The TCP/IP stack makes no assumption about the specifics of an actual implementation and expects all MACs to behave identically

Core Functionality

TCPIP MAC mac_flow

The MAC driver is used internally by the TCP/IP Stack Manager and its API is not normally exposed outside the stack. There is little need to interface directly with the MAC from the application level. The TCP/IP Stack provides all the data interface functions to the application by exposing the_socket_API (TCP and UDP) and also low level IPv4 and IPv6 API. However, the functionality of the MAC driver is important for having a thorough understanding of how the TCP/IP Stack works or for integrating the MPLAB Harmony MAC driver into a third-party TCP/IP Stack.

The MAC driver needs to be initialized by a call to TCPIP_MAC_Initialize() with both stack and module specific initialization data. The stack initialization data contains absolutely necessary data for the MAC driver to operate (memory allocation functions, packet allocation functions, event notification functions, etc.) Note that the module initialization data could be different from one MAC module to another and, if missing, normally the MAC driver should use some default values specified in the tcpip_mac_config.h file.

Once the initialization process succeeds, a MAC client handle is obtained by using TCPIP_MAC_Open.

Other parameters can be set, like the active events and receive filters by calling TCPIP_MAC_EventMaskSet, TCPIP_MAC_RxFilterHashTableEntrySet, etc.

By default the MAC driver operates in interrupts and the events are reported to the TCP/IP stack by using the event notification function that’s passed in at the MAC driver initialization. However, by using the TCPIP_MAC_EventPendingGet function, it is possible to use the MAC driver in a polling manner.

To send a packet, a MAC driver client has to obtain a TCPIP_MAC_PACKET data structure, either statically or dynamically. Note that the Harmony TCP/IP Stack uses dynamic packet allocation and has a packet allocation module that the Stack Manager calls for this purpose. The packet has to be properly formatted with all the required fields before being passed to the MAC driver for transmission. The MAC driver will perform a minimum sanity check and will try to transmit the packet over the network. Once the corresponding interrupt signals to the driver that the packet was (successfully/non-successfully) transmitted the MAC driver will call the packet acknowledge function. This will indicate to the owner of the packet (the module that created/allocated the packet) that the packet is no longer in use and it can be reused, discarded, etc.

The receive process is configured as part of the MAC driver initialization procedure. Usually the MAC driver needs some buffers for storing the received network traffic. How exactly this is done is driver specific and not part of this specification. The Harmony Ethernet MAC driver, for example, allocates multiple receive buffers at initialization and uses those for the whole duration of the driver life. Other implementations may choose to free the receive buffers once they are processed and allocate new ones, as needed.

The receive process is initiated by the hardware indicating through an interrupt that a packet is pending. This will trigger a notification event to the MAC client (the TCP/IP stack) and the actual packet receive function can be called. Alternatively the MAC client can call the TCPIP_MAC_EventPendingGet function which can be used in a polling manner.

To actually receive the packet the TCP/IP stack should call the TCPIP_MAC_PacketRx function. This function, besides returning a pointer to the newly received packet will provide additional info about the packet status. Also, some MAC drivers have the possibility to mark the packet being received as being unicast, multicast or broadcast.

Once a packet is obtained, the stack has to dispatch it accordingly, based on the info contained within the packet (ARP, IPv4, IPv6, etc.). Note that in the Harmony TCP/IP stack it’s the Stack Manager that performs the receiving and dispatching function of the packets. The recipient of the packet will be called to process the incoming packet and may forward the packet for further processing (TCP, UDP, ICMP). Note that during all this processing time this packet can no longer be used by the MAC driver for storing newly receive data. Therefore once the final recipient of the received packet has processed the data it has to call the packet acknowledge function, so that the packet can be returned to its owner, the MAC driver in this case. If the MAC driver reuses the packet (as the Harmony Ethernet MAC driver does) or simply discards it is driver implementation specific.

Once the data transfer of packets over the network is no longer needed the TCPIP_MAC_Close function can be called and also TCPIP_MAC_Deinitialize. This is part of the normal procedure that the Harmony stack uses for shutting down and restarting a network interface dynamically.

For detailed information about the MAC layer_requirements and functionality, please consult the IEEE 802.3 specifications.