]> git.proxmox.com Git - mirror_edk2.git/blobdiff - EmbeddedPkg/Drivers/Lan9118Dxe/Lan9118Dxe.c
EmbeddedPkg/Lan9118Dxe: Remove link check in SNP initialization
[mirror_edk2.git] / EmbeddedPkg / Drivers / Lan9118Dxe / Lan9118Dxe.c
index 507e55f4505f0201166eeb4fc3acf43dfe2036bf..0503dbce1e5536a95dc6b3b2ab8eb81908cce711 100644 (file)
@@ -99,16 +99,25 @@ Lan9118DxeEntry (
   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
@@ -274,7 +283,7 @@ SnpInitialize (
   }\r
 \r
   // Initiate a PHY reset\r
-  Status = PhySoftReset (PHY_RESET_PMT | PHY_RESET_CHECK_LINK, Snp);\r
+  Status = PhySoftReset (PHY_RESET_PMT, Snp);\r
   if (EFI_ERROR (Status)) {\r
     Snp->Mode->State = EfiSimpleNetworkStopped;\r
     DEBUG ((EFI_D_WARN, "Warning: Link not ready after TimeOut. Check ethernet cable\n"));\r
@@ -344,12 +353,7 @@ SnpInitialize (
     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
@@ -399,7 +403,7 @@ SnpReset (
   }\r
 \r
   // Initiate a PHY reset\r
-  Status = PhySoftReset (PHY_RESET_PMT | PHY_RESET_CHECK_LINK, Snp);\r
+  Status = PhySoftReset (PHY_RESET_PMT, Snp);\r
   if (EFI_ERROR (Status)) {\r
     Snp->Mode->State = EfiSimpleNetworkStopped;\r
     return EFI_NOT_STARTED;\r
@@ -553,7 +557,9 @@ SnpReceiveFilters (
   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
@@ -631,6 +637,12 @@ SnpReceiveFilters (
     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
@@ -638,64 +650,62 @@ SnpReceiveFilters (
   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
@@ -769,8 +779,20 @@ SnpStationAddress (
     }\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