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
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
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
Name | Description |
---|---|
Macros | |
TCPIP_EMAC_ETH_OPEN_FLAGS | Flags 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_ADDRESS | The PHY address, as configured on the board. By default all the PHYs respond to address 0 |
TCPIP_EMAC_PHY_CONFIG_FLAGS | Flags 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_DELAY | The 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_SIZE | Size 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_BUFFERS | Number 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_DESCRIPTORS | Number 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_FRAGMENTS | MAC 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_BUFFERS | Number of non-dedicated buffers for the MAC initialization Buffers allocated at the MAC driver initialization. |
TCPIP_EMAC_RX_LOW_FILL | Number 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_THRESHOLD | Minumum 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_DESCRIPTORS | Number 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_FILTERS | MAC 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_MTU | Link 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_FRAME | Maximum 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_ENABLE | This 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_WMARK | An 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_WMARK | An 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_BYTES | Pause 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_Deinitialize | MAC driver deinitialization function. |
TCPIP_MAC_Initialize | MAC driver initialization function. |
TCPIP_MAC_ConfigGet | Gets the current MAC driver configuration. |
TCPIP_MAC_LinkCheck | MAC link checking function. |
TCPIP_MAC_Process | MAC periodic processing function. |
TCPIP_MAC_Reinitialize | MAC driver reinitialization function. |
TCPIP_MAC_Status | Provides the current status of the MAC driver module. |
TCPIP_MAC_Tasks | Maintains the MAC driver's state machine. |
Client Control and Status Functions | |
TCPIP_MAC_Close | MAC driver close function. |
TCPIP_MAC_Open | MAC driver open function. |
TCPIP_MAC_EventPendingGet | Returns the currently pending MAC events. |
TCPIP_MAC_ParametersGet | MAC parameter get function. |
TCPIP_MAC_RegisterStatisticsGet | Gets the current MAC hardware statistics registers. |
TCPIP_MAC_StatisticsGet | Gets the current MAC statistics. |
Event Functions | |
TCPIP_MAC_EventAcknowledge | This function acknowledges a previously reported MAC event. |
TCPIP_MAC_EventMaskSet | MAC events report enable/disable function. |
Filter Functions | |
TCPIP_MAC_RxFilterHashTableEntrySet | Sets the current MAC hash table receive filter. |
Data Transfer Functions | |
TCPIP_MAC_PacketRx | A packet is returned if such a pending packet exists. |
TCPIP_MAC_PacketTx | MAC driver transmit function. |
Data Types and Constants | |
TCPIP_MAC_POWER_MODE | Supported MAC power mode state. |
TCPIP_MODULE_MAC_PIC32INT_CONFIG | Data that's passed to the MAC at initialization time as part of the TCPIP_MAC_INIT data structure. |
TCPIP_MAC_ACTION | Network interface action for initialization/deinitialization |
TCPIP_MAC_DATA_SEGMENT | A data segment that's part of a TX/RX packet. |
TCPIP_MAC_EVENT | Defines the possible MAC event types. |
TCPIP_MAC_EventF | MAC event notification handler. |
TCPIP_MAC_HEAP_CallocF | MAC allocation function prototype. |
TCPIP_MAC_HEAP_FreeF | MAC allocation function prototype. |
TCPIP_MAC_HEAP_HANDLE | A handle used for memory allocation functions. |
TCPIP_MAC_HEAP_MallocF | MAC allocation function prototype. |
TCPIP_MAC_MODULE_CTRL | Data structure that's passed to the MAC at the initialization time. |
TCPIP_MAC_PACKET_ACK_FUNC | Prototype of a MAC packet acknowledge function. |
TCPIP_MAC_PACKET_FLAGS | Flags belonging to MAC packet. |
TCPIP_MAC_PACKET_RX_STAT | Status of a received packet. |
TCPIP_MAC_PKT_ACK_RES | List of MAC return codes for a packet acknowledge function. |
TCPIP_MAC_PKT_AckF | MAC packet acknowledge function prototype. |
TCPIP_MAC_PKT_AllocF | MAC packet allocation function prototype. |
TCPIP_MAC_PKT_FreeF | MAC packet free function prototype. |
TCPIP_MAC_PROCESS_FLAGS | List of the MAC processing flags. |
TCPIP_MAC_SEGMENT_FLAGS | Flags belonging to MAC data segment. |
TCPIP_MAC_RX_STATISTICS | MAC receive statistics data gathered at run time. |
TCPIP_MAC_TX_STATISTICS | MAC transmit statistics data gathered at run time. |
TCPIP_MAC_HEAP_CallocFDbg | This is type TCPIP_MAC_HEAP_CallocFDbg. |
TCPIP_MAC_HEAP_FreeFDbg | This is type TCPIP_MAC_HEAP_FreeFDbg. |
TCPIP_MAC_HEAP_MallocFDbg | This is type TCPIP_MAC_HEAP_MallocFDbg. |
TCPIP_MAC_INIT | Contains all the data necessary to initialize the MAC device. |
TCPIP_MAC_PARAMETERS | Data structure that tells the MAC run time parameters. |
TCPIP_MAC_PKT_AllocFDbg | This is type TCPIP_MAC_PKT_AllocFDbg. |
TCPIP_MAC_PKT_FreeFDbg | This is type TCPIP_MAC_PKT_FreeFDbg. |
TCPIP_MAC_STATISTICS_REG_ENTRY | Describes a MAC hardware statistics register. |
TCPIP_MAC_SYNCH_REQUEST | Defines the possible MAC synchronization request types. |
TCPIP_MAC_SynchReqF | MAC synchronization request function definition. |
TCPIP_MAC_TYPE | List of the MAC types. |
TCPIP_MODULE_MAC_ID | IDs of the MAC module supported by the stack. |
TCPIP_MAC_RX_FILTER_TYPE | Defines the possible MAC RX filter types. |
TCPIP_MAC_LINK_MTU | MTU size correspondig to the MAC types. |
TCPIP_MAC_HANDLE | Handle to a MAC driver. |
TCPIP_MAC_RES | List of return codes from MAC functions. |
TCPIP_MAC_PACKET_RX_STAT_PIC32C | Status of a received packet for PIC32C MAC driver. |
TCPIP_MAC_PACKET | Forward reference to a MAC packet. |
TCPIP_MODULE_GMAC_QUEUE_CONFIG | Configuration Structure for Queues in GMAC. |
TCPIP_MODULE_MAC_PIC32C_CONFIG | Data that's passed to the GMAC at initialization time as part of TCPIP_MAC_INIT data structure. |