1.2.5.1 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.

Library Interface

NameDescription
Macros
TCPIP_EMAC_ETH_OPEN_FLAGSFlags to use for the Ethernet connection A TCPIP_ETH_OPEN_FLAGS value. Set to TCPIP_ETH_OPEN_DEFAULT unless very good reason to use different value
TCPIP_EMAC_PHY_ADDRESSThe PHY address, as configured on the board. By default all the PHYs respond to address 0
TCPIP_EMAC_PHY_CONFIG_FLAGSFlags to configure the MAC ->PHY connection a DRV_ETHPHY_CONFIG_FLAGS This depends on the actual connection (MII/RMII, default/alternate I/O) The DRV_ETHPHY_CFG_AUTO value will use the configuration fuses setting
TCPIP_EMAC_PHY_LINK_INIT_DELAYThe value of the delay for the link initialization, ms This insures that the PHY is ready to transmit after it is reset A usual value is > 500 ms up to 2000 ms. The longer the delay, the less chance that the PHY drops packets when the link is established Adjust to your needs.
TCPIP_EMAC_RX_BUFF_SIZESize of a RX packet buffer. Should be multiple of 16. This is the size of all receive packet buffers processed by the ETHC. The size should be enough to accommodate any network received packet. If the packets are larger, they will have to take multiple RX buffers and the packet manipulation is less efficient. #define TCPIP_EMAC_RX_BUFF_SIZE 512 Together with TCPIP_EMAC_RX_DEDICATED_BUFFERS it has impact on TCPIP_STACK_DRAM_SIZE setting.
TCPIP_EMAC_RX_DEDICATED_BUFFERSNumber of MAC dedicated RX packet buffers. These buffers are always owned by the MAC. Note that the MAC driver allocates these buffers for storing the incoming network packets. The bigger the storage capacity, the higher data throughput can be obtained. Note that these packet buffers are allocated from the private TCP/IP heap that is specified by the TCPIP_STACK_DRAM_SIZE setting.
TCPIP_EMAC_RX_DESCRIPTORSNumber of the RX descriptors to be created. If not using the run time replenish mechanism (see below) it should match the number of dedicated buffers: TCPIP_EMAC_RX_DEDICATED_BUFFERS; Otherwise it should be bigger than the sum of dedicated + non-dedicated buffers: TCPIP_EMAC_RX_DESCRIPTORS > TCPIP_EMAC_RX_DEDICATED_BUFFERS + replenish_buffers
TCPIP_EMAC_RX_FRAGMENTSMAC maximum number of supported RX fragments. Based on the values of TCPIP_EMAC_MAX_FRAME and TCPIP_EMAC_RX_BUFF_SIZE an incoming frame may span multiple RX buffers (fragments). Note that excessive fragmentation leads to performance degradation. The default and recommended value should be 1. #define TCPIP_EMAC_RX_FRAGMENTS 1 Alternatively you can use the calculation of the number of fragments based on the selected RX sizes:
TCPIP_EMAC_RX_INIT_BUFFERSNumber of non-dedicated buffers for the MAC initialization Buffers allocated at the MAC driver initialization.
TCPIP_EMAC_RX_LOW_FILLNumber of RX buffers to allocate when below threshold condition is detected. If 0, the MAC driver will allocate (scheduled buffers - rxThres) If !0, the MAC driver will allocate exactly TCPIP_EMAC_RX_LOW_FILL buffers
TCPIP_EMAC_RX_LOW_THRESHOLDMinumum threshold for the buffer replenish process. Whenever the number of RX scheduled buffers is <= than this threshold the MAC driver will allocate new non-dedicated buffers (meaning that they will be released to the TCP/IP heap once they are processed). Setting this value to 0 disables the buffer replenishing process.
TCPIP_EMAC_TX_DESCRIPTORSNumber of the TX descriptors to be created. Because a TCP packet can span at most 3 buffers, the value should always be >= 4 The amount of memory needed per descriptor is not high (around 24 bytes) so when high MAC TX performance is needed make sure that this number is >= 8.
TCPIP_EMAC_RX_FILTERSMAC RX Filters These filters define the packets that are accepted and rejected by the MAC driver Adjust to your needs The default value allows the processing of unicast, multicast and broadcast packets that have a valid CRC
TCPIP_EMAC_LINK_MTULink Maximum Transmission Unit (MTU) This symbol defines the largest network protocol data unit that can be transmitted over this link in a single frame. It relates to the TCPIP_EMAC_MAX_FRAME value - see above. The default value for an Ethernet link should be 1500. The minimum value for an Eternet link should be 576. If need to change this, make sure that the TCPIP_EMAC_MAX_FRAME >= TCPIP_EMAC_LINK_MTU + 18 where the value 18 represents the Ethernet frame header: 12 bytes - destination + source address 2 bytes - frame type 4 bytes - FCS
TCPIP_EMAC_MAX_FRAMEMaximum MAC supported RX/TX frame size. The default value is 1536 (allows for VLAN tagged frames, although the VLAN tagged frames are discarded on RX). On RX: any incoming ETH frame that's longer than this size will be discarded. On TX: any frame that's longer than this size will be aborted by the MAC. Normally there's no need to touch this value unless you know exactly the maximum size of the frames you want to process on your network.
TCPIP_EMAC_AUTO_FLOW_CONTROL_ENABLEThis symbol enables/disables the auto flow control When in full-duplex mode and the auto flow control is enabled, the MAC will send pause frames whenever the number of pending RX packets reached the full watermark. Once this number drops to the empty watermark, a pause frame with pause value of 0 is transmitted, resuming the normal traffic Use 1 to enable, 0 to disable Default should be enabled
TCPIP_EMAC_FLOW_CONTROL_EMPTY_WMARKAn 8 bit value representing the empty water mark, in number of packets When the auto flow control is active and the number of pending received packets falls reaching this threshold the auto flow control pause frames will stop Always TCPIP_EMAC_FLOW_CONTROL_FULL_WMARK > TCPIP_EMAC_FLOW_CONTROL_EMPTY_WMARK Used only when auto flow control is enabled Default value could be 0: resume normal traffic when there is no pending RX packet
TCPIP_EMAC_FLOW_CONTROL_FULL_WMARKAn 8 bit value representing the full water mark, in number of packets When the number of pending received packets reaches this threshold the auto flow control kicks in A good rule to use for avoiding any packet overflow is to have enough receive room for at least 2 maximum packets, i.e. fullWMMark = (rxScheduledBuffers x rxBuffSize) / TCPIP_EMAC_MAX_FRAME - (2 x TCPIP_EMAC_MAX_FRAME ) / rxBuffSize; Always TCPIP_EMAC_FLOW_CONTROL_FULL_WMARK > TCPIP_EMAC_FLOW_CONTROL_EMPTY_WMARK Used only when auto flow control is enabled Adjust to your own value #define TCPIP_EMAC_FLOW_CONTROL_FULL_WMARK 2 Default value should use the calculation of the watermark based on the selected RX... more
TCPIP_EMAC_FLOW_CONTROL_PAUSE_BYTESPause Time Value for the Auto Flow Control, in bytes This represents the number of bytes to request the pause for when the auto flow control kicks in. It is normally thought of in terms of RX packets: pauseBytes / rxBuffSize = pausePackets Using bytes instead of packets allows better granularity The value should be a multiple of 64 bytes The range is : 64 bytes <= TCPIP_EMAC_FLOW_CONTROL_PAUSE_BYTES <= (4 MB - 64) bytes (0x3fffc0) An usual value is 2 full packets. For example 2 * 1536 bytes Used only when flow control is enabled
Initialization Functions
TCPIP_MAC_DeinitializeMAC driver deinitialization function.
TCPIP_MAC_InitializeMAC driver initialization function.
TCPIP_MAC_ConfigGetGets the current MAC driver configuration.
TCPIP_MAC_LinkCheckMAC link checking function.
TCPIP_MAC_ProcessMAC periodic processing function.
TCPIP_MAC_ReinitializeMAC driver reinitialization function.
TCPIP_MAC_StatusProvides the current status of the MAC driver module.
TCPIP_MAC_TasksMaintains the MAC driver's state machine.
Client Control and Status Functions
TCPIP_MAC_CloseMAC driver close function.
TCPIP_MAC_OpenMAC driver open function.
TCPIP_MAC_EventPendingGetReturns the currently pending MAC events.
TCPIP_MAC_ParametersGetMAC parameter get function.
TCPIP_MAC_RegisterStatisticsGetGets the current MAC hardware statistics registers.
TCPIP_MAC_StatisticsGetGets the current MAC statistics.
Event Functions
TCPIP_MAC_EventAcknowledgeThis function acknowledges a previously reported MAC event.
TCPIP_MAC_EventMaskSetMAC events report enable/disable function.
Filter Functions
TCPIP_MAC_RxFilterHashTableEntrySetSets the current MAC hash table receive filter.
Data Transfer Functions
TCPIP_MAC_PacketRxA packet is returned if such a pending packet exists.
TCPIP_MAC_PacketTxMAC driver transmit function.
Data Types and Constants
TCPIP_MAC_POWER_MODESupported MAC power mode state.
TCPIP_MODULE_MAC_PIC32INT_CONFIGData that's passed to the MAC at initialization time as part of the TCPIP_MAC_INIT data structure.
TCPIP_MAC_ACTIONNetwork interface action for initialization/deinitialization
TCPIP_MAC_DATA_SEGMENTA data segment that's part of a TX/RX packet.
TCPIP_MAC_EVENTDefines the possible MAC event types.
TCPIP_MAC_EventFMAC event notification handler.
TCPIP_MAC_HEAP_CallocFMAC allocation function prototype.
TCPIP_MAC_HEAP_FreeFMAC allocation function prototype.
TCPIP_MAC_HEAP_HANDLEA handle used for memory allocation functions.
TCPIP_MAC_HEAP_MallocFMAC allocation function prototype.
TCPIP_MAC_MODULE_CTRLData structure that's passed to the MAC at the initialization time.
TCPIP_MAC_PACKET_ACK_FUNCPrototype of a MAC packet acknowledge function.
TCPIP_MAC_PACKET_FLAGSFlags belonging to MAC packet.
TCPIP_MAC_PACKET_RX_STATStatus of a received packet.
TCPIP_MAC_PKT_ACK_RESList of MAC return codes for a packet acknowledge function.
TCPIP_MAC_PKT_AckFMAC packet acknowledge function prototype.
TCPIP_MAC_PKT_AllocFMAC packet allocation function prototype.
TCPIP_MAC_PKT_FreeFMAC packet free function prototype.
TCPIP_MAC_PROCESS_FLAGSList of the MAC processing flags.
TCPIP_MAC_SEGMENT_FLAGSFlags belonging to MAC data segment.
TCPIP_MAC_RX_STATISTICSMAC receive statistics data gathered at run time.
TCPIP_MAC_TX_STATISTICSMAC transmit statistics data gathered at run time.
TCPIP_MAC_HEAP_CallocFDbgThis is type TCPIP_MAC_HEAP_CallocFDbg.
TCPIP_MAC_HEAP_FreeFDbgThis is type TCPIP_MAC_HEAP_FreeFDbg.
TCPIP_MAC_HEAP_MallocFDbgThis is type TCPIP_MAC_HEAP_MallocFDbg.
TCPIP_MAC_INITContains all the data necessary to initialize the MAC device.
TCPIP_MAC_PARAMETERSData structure that tells the MAC run time parameters.
TCPIP_MAC_PKT_AllocFDbgThis is type TCPIP_MAC_PKT_AllocFDbg.
TCPIP_MAC_PKT_FreeFDbgThis is type TCPIP_MAC_PKT_FreeFDbg.
TCPIP_MAC_STATISTICS_REG_ENTRYDescribes a MAC hardware statistics register.
TCPIP_MAC_SYNCH_REQUESTDefines the possible MAC synchronization request types.
TCPIP_MAC_SynchReqFMAC synchronization request function definition.
TCPIP_MAC_TYPEList of the MAC types.
TCPIP_MODULE_MAC_IDIDs of the MAC module supported by the stack.
TCPIP_MAC_RX_FILTER_TYPEDefines the possible MAC RX filter types.
TCPIP_MAC_LINK_MTUMTU size correspondig to the MAC types.
TCPIP_MAC_HANDLEHandle to a MAC driver.
TCPIP_MAC_RESList of return codes from MAC functions.
TCPIP_MAC_PACKET_RX_STAT_PIC32CStatus of a received packet for PIC32C MAC driver.
TCPIP_MAC_PACKETForward reference to a MAC packet.
TCPIP_MODULE_GMAC_QUEUE_CONFIGConfiguration Structure for Queues in GMAC.
TCPIP_MODULE_MAC_PIC32C_CONFIGData that's passed to the GMAC at initialization time as part of TCPIP_MAC_INIT data structure.