SnpMode->NvRamSize = 0; // No NVRAM with this device\r
SnpMode->NvRamAccessSize = 0; // No NVRAM with this device\r
\r
- // Update network mode information\r
- SnpMode->ReceiveFilterMask = EFI_SIMPLE_NETWORK_RECEIVE_MULTICAST |\r
- EFI_SIMPLE_NETWORK_RECEIVE_UNICAST |\r
- EFI_SIMPLE_NETWORK_RECEIVE_BROADCAST |\r
- EFI_SIMPLE_NETWORK_RECEIVE_PROMISCUOUS;/* |\r
- EFI_SIMPLE_NETWORK_RECEIVE_PROMISCUOUS_MULTICAST;*/\r
- // Current allowed settings\r
- SnpMode->ReceiveFilterSetting = EFI_SIMPLE_NETWORK_RECEIVE_MULTICAST |\r
- EFI_SIMPLE_NETWORK_RECEIVE_UNICAST |\r
- EFI_SIMPLE_NETWORK_RECEIVE_BROADCAST;\r
+ //\r
+ // Claim that all receive filter settings are supported, though the MULTICAST mode\r
+ // is not completely supported. The LAN9118 Ethernet controller is only able to\r
+ // do a "hash filtering" and not a perfect filtering on multicast addresses. The\r
+ // controller does not filter the multicast addresses directly but a hash value\r
+ // of them. The hash value of a multicast address is derived from its CRC and\r
+ // ranges from 0 to 63 included.\r
+ // We claim that the perfect MULTICAST filtering mode is supported because\r
+ // we do not want the user to switch directly to the PROMISCOUS_MULTICAST mode\r
+ // and thus not being able to take advantage of the hash filtering.\r
+ //\r
+ SnpMode->ReceiveFilterMask = EFI_SIMPLE_NETWORK_RECEIVE_UNICAST |\r
+ EFI_SIMPLE_NETWORK_RECEIVE_MULTICAST |\r
+ EFI_SIMPLE_NETWORK_RECEIVE_BROADCAST |\r
+ EFI_SIMPLE_NETWORK_RECEIVE_PROMISCUOUS |\r
+ EFI_SIMPLE_NETWORK_RECEIVE_PROMISCUOUS_MULTICAST;\r
+\r
+ // We do not intend to receive anything for the time being.\r
+ SnpMode->ReceiveFilterSetting = 0;\r
\r
// LAN9118 has 64bit hash table, can filter 64 MCast MAC Addresses\r
SnpMode->MaxMCastFilterCount = MAX_MCAST_FILTER_CNT;\r
return Status;\r
}\r
\r
- // Enable the receiver and transmitter\r
- Status = StartRx (0, Snp);\r
- if (EFI_ERROR(Status)) {\r
- return Status;\r
- }\r
-\r
+ // Enable the transmitter\r
Status = StartTx (START_TX_MAC | START_TX_CFG, Snp);\r
if (EFI_ERROR(Status)) {\r
return Status;\r
UINT32 Crc;\r
UINT8 HashValue;\r
UINT32 MacCSRValue;\r
+ UINT32 ReceiveFilterSetting;\r
EFI_MAC_ADDRESS *Mac;\r
+ EFI_MAC_ADDRESS ZeroMac;\r
\r
// Check Snp Instance\r
if (Snp == NULL) {\r
MultHashTableHigh = IndirectMACRead32 (INDIRECT_MAC_INDEX_HASHH);\r
}\r
\r
+ //\r
+ // Before to change anything, stop and reset the reception of\r
+ // packets.\r
+ //\r
+ StopRx (STOP_RX_CLEAR, Snp);\r
+\r
//\r
// Write the mask of the selected hash values for the multicast filtering.\r
// The two masks are set to zero if the multicast filtering is not enabled.\r
IndirectMACWrite32 (INDIRECT_MAC_INDEX_HASHL, MultHashTableLow);\r
IndirectMACWrite32 (INDIRECT_MAC_INDEX_HASHH, MultHashTableHigh);\r
\r
+ ReceiveFilterSetting = (Mode->ReceiveFilterSetting | Enable) & (~Disable);\r
+\r
+ //\r
// Read MAC controller\r
- MacCSRValue = IndirectMACRead32 (INDIRECT_MAC_INDEX_CR);\r
+ //\r
+ MacCSRValue = IndirectMACRead32 (INDIRECT_MAC_INDEX_CR);\r
+ MacCSRValue &= ~(MACCR_HPFILT | MACCR_BCAST | MACCR_PRMS | MACCR_MCPAS);\r
\r
- // Set the options for the MAC_CSR\r
- if (Enable & EFI_SIMPLE_NETWORK_RECEIVE_UNICAST) {\r
- StartRx (0, Snp);\r
+ if (ReceiveFilterSetting & EFI_SIMPLE_NETWORK_RECEIVE_UNICAST) {\r
+ Lan9118SetMacAddress (&Mode->CurrentAddress, Snp);\r
DEBUG ((DEBUG_NET, "Allowing Unicast Frame Reception\n"));\r
+ } else {\r
+ //\r
+ // The Unicast packets do not have to be listen to, set the MAC\r
+ // address of the LAN9118 to be the "not configured" all zeroes\r
+ // ethernet MAC address.\r
+ //\r
+ ZeroMem (&ZeroMac, NET_ETHER_ADDR_LEN);\r
+ Lan9118SetMacAddress (&ZeroMac, Snp);\r
}\r
\r
- if (Disable & EFI_SIMPLE_NETWORK_RECEIVE_UNICAST) {\r
- StopRx (0, Snp);\r
- DEBUG ((DEBUG_NET, "Disabling Unicast Frame Reception\n"));\r
- }\r
-\r
- if (Enable & EFI_SIMPLE_NETWORK_RECEIVE_MULTICAST) {\r
+ if (ReceiveFilterSetting & EFI_SIMPLE_NETWORK_RECEIVE_MULTICAST) {\r
MacCSRValue |= MACCR_HPFILT;\r
DEBUG ((DEBUG_NET, "Allowing Multicast Frame Reception\n"));\r
}\r
\r
- if (Disable & EFI_SIMPLE_NETWORK_RECEIVE_MULTICAST) {\r
- MacCSRValue &= ~MACCR_HPFILT;\r
- DEBUG ((DEBUG_NET, "Disabling Multicast Frame Reception\n"));\r
- }\r
-\r
- if (Enable & EFI_SIMPLE_NETWORK_RECEIVE_BROADCAST) {\r
- MacCSRValue &= ~(MACCR_BCAST);\r
- DEBUG ((DEBUG_NET, "Allowing Broadcast Frame Reception\n"));\r
+ if (ReceiveFilterSetting & EFI_SIMPLE_NETWORK_RECEIVE_PROMISCUOUS_MULTICAST) {\r
+ MacCSRValue |= MACCR_MCPAS;\r
+ DEBUG ((DEBUG_NET, "Enabling Promiscuous Multicast Mode\n"));\r
}\r
\r
- if (Disable & EFI_SIMPLE_NETWORK_RECEIVE_BROADCAST) {\r
+ if ((ReceiveFilterSetting & EFI_SIMPLE_NETWORK_RECEIVE_BROADCAST) == 0) {\r
MacCSRValue |= MACCR_BCAST;\r
- DEBUG ((DEBUG_NET, "Disabling Broadcast Frame Reception\n"));\r
+ } else {\r
+ DEBUG ((DEBUG_NET, "Allowing Broadcast Frame Reception\n"));\r
}\r
\r
- if (Enable & EFI_SIMPLE_NETWORK_RECEIVE_PROMISCUOUS) {\r
+ if (ReceiveFilterSetting & EFI_SIMPLE_NETWORK_RECEIVE_PROMISCUOUS) {\r
MacCSRValue |= MACCR_PRMS;\r
DEBUG ((DEBUG_NET, "Enabling Promiscuous Mode\n"));\r
}\r
\r
- if (Disable & EFI_SIMPLE_NETWORK_RECEIVE_PROMISCUOUS) {\r
- MacCSRValue &= ~MACCR_PRMS;\r
- DEBUG ((DEBUG_NET, "Disabling Promiscuous Mode\n"));\r
- }\r
-\r
- if (Enable & EFI_SIMPLE_NETWORK_RECEIVE_PROMISCUOUS_MULTICAST) {\r
- MacCSRValue |= (MACCR_HPFILT | MACCR_PRMS);\r
- DEBUG ((DEBUG_NET, "Enabling Promiscuous Multicast Mode\n"));\r
- }\r
-\r
- if (Disable & EFI_SIMPLE_NETWORK_RECEIVE_PROMISCUOUS_MULTICAST) {\r
- MacCSRValue &= ~(MACCR_HPFILT | MACCR_PRMS);\r
- DEBUG ((DEBUG_NET, "Disabling Promiscuous Multicast Mode\n"));\r
- }\r
-\r
+ //\r
// Write the options to the MAC_CSR\r
+ //\r
IndirectMACWrite32 (INDIRECT_MAC_INDEX_CR, MacCSRValue);\r
gBS->Stall (LAN9118_STALL);\r
\r
+ //\r
+ // If we have to retrieve something, start packet reception.\r
+ //\r
+ Mode->ReceiveFilterSetting = ReceiveFilterSetting;\r
+ if (ReceiveFilterSetting != 0) {\r
+ StartRx (0, Snp);\r
+ }\r
+\r
return EFI_SUCCESS;\r
}\r
\r
}\r
}\r
\r
- // Write address\r
- Lan9118SetMacAddress (New, Snp);\r
+ CopyMem (&Snp->Mode->CurrentAddress, New, NET_ETHER_ADDR_LEN);\r
+\r
+ //\r
+ // If packet reception is currently activated, stop and reset it,\r
+ // set the new ethernet address and restart the packet reception.\r
+ // Otherwise, nothing to do, the MAC address will be updated in\r
+ // SnpReceiveFilters() when the UNICAST packet reception will be\r
+ // activated.\r
+ //\r
+ if (Snp->Mode->ReceiveFilterSetting != 0) {\r
+ StopRx (STOP_RX_CLEAR, Snp);\r
+ Lan9118SetMacAddress (New, Snp);\r
+ StartRx (0, Snp);\r
+ }\r
\r
return EFI_SUCCESS;\r
}\r