1 // 2 // Copyright (c) 2010-2018 Antmicro 3 // Copyright (c) 2011-2015 Realtime Embedded 4 // 5 // This file is licensed under the MIT License. 6 // Full license text is available in 'licenses/MIT.txt'. 7 // 8 using System; 9 using Antmicro.Renode.Core.Structure; 10 using Antmicro.Renode.Logging; 11 using Antmicro.Renode.Peripherals.Network; 12 using System.Collections.Generic; 13 using Antmicro.Renode.Network; 14 using Antmicro.Renode.Core; 15 using Antmicro.Renode.Utilities; 16 17 namespace Antmicro.Renode.Peripherals.USBDeprecated 18 { 19 public class SMSC9500 : IUSBPeripheral, IMACInterface 20 { 21 public event Action <uint> SendInterrupt 22 { 23 add {} 24 remove {} 25 } 26 public event Action <uint> SendPacket 27 { 28 add {} 29 remove {} 30 } 31 SMSC9500()32 public SMSC9500() 33 { 34 MAC = EmulationManager.Instance.CurrentEmulation.MACRepository.GenerateUniqueMAC(); 35 for(int i=0; i<NumberOfEndpoints; i++) 36 { 37 dataToggleBit[i] = false; 38 } 39 endpointDescriptor = new EndpointUSBDescriptor[NumberOfEndpoints]; 40 for(int i=0; i<NumberOfEndpoints; i++) 41 { 42 endpointDescriptor[i] = new EndpointUSBDescriptor(); 43 } 44 fillEndpointsDescriptors(endpointDescriptor); 45 interfaceDescriptor[0].EndpointDescriptor = endpointDescriptor; 46 configurationDescriptor.InterfaceDescriptor = interfaceDescriptor; 47 48 rxPacketQueue = new Queue<EthernetFrame>(); 49 } 50 GetData()51 public byte[] GetData() 52 { 53 return null; 54 } 55 56 uint addr; 57 GetAddress()58 public uint GetAddress() 59 { 60 return addr; 61 } 62 GetSpeed()63 public USBDeviceSpeed GetSpeed() 64 { 65 return USBDeviceSpeed.High; 66 } 67 #region IUSBDevice implementation ProcessClassGet(USBPacket packet, USBSetupPacket setupPacket)68 public byte[] ProcessClassGet(USBPacket packet, USBSetupPacket setupPacket) 69 { 70 throw new System.NotImplementedException(); 71 } 72 73 bool linkUp = false; 74 WriteInterrupt(USBPacket packet)75 public byte[] WriteInterrupt(USBPacket packet) 76 { 77 if(linkUp == false) 78 { 79 linkUp = true; 80 packet.data = new byte[4]; 81 packet.data[0] = 0x00; 82 packet.data[1] = 0x80; 83 packet.data[2] = 0x00; 84 packet.data[3] = 0x00; 85 return packet.data; 86 } 87 else 88 return null; 89 } 90 GetTransferStatus()91 public byte GetTransferStatus() 92 { 93 return 0; 94 } 95 96 byte[] controlPacket; 97 GetDataControl(USBPacket packet)98 public byte[] GetDataControl(USBPacket packet) 99 { 100 return controlPacket; 101 } 102 GetDescriptor(USBPacket packet, USBSetupPacket setupPacket)103 public byte[] GetDescriptor(USBPacket packet, USBSetupPacket setupPacket) 104 { 105 DescriptorType type; 106 type = (DescriptorType)((setupPacket.value & 0xff00) >> 8); 107 uint index = (uint)(setupPacket.value & 0xff); 108 switch(type) 109 { 110 case DescriptorType.Device: 111 controlPacket = new byte[deviceDescriptor.ToArray().Length]; 112 deviceDescriptor.ToArray().CopyTo(controlPacket, 0); 113 return deviceDescriptor.ToArray(); 114 case DescriptorType.Configuration: 115 controlPacket = new byte[configurationDescriptor.ToArray().Length]; 116 configurationDescriptor.ToArray().CopyTo(controlPacket, 0); 117 return configurationDescriptor.ToArray(); 118 case DescriptorType.DeviceQualifier: 119 controlPacket = new byte[deviceQualifierDescriptor.ToArray().Length]; 120 deviceQualifierDescriptor.ToArray().CopyTo(controlPacket, 0); 121 return deviceQualifierDescriptor.ToArray(); 122 case DescriptorType.InterfacePower: 123 throw new NotImplementedException("Interface Power Descriptor is not yet implemented. Please contact AntMicro for further support."); 124 case DescriptorType.OtherSpeedConfiguration: 125 controlPacket = new byte[otherConfigurationDescriptor.ToArray().Length]; 126 otherConfigurationDescriptor.ToArray().CopyTo(controlPacket, 0); 127 return otherConfigurationDescriptor.ToArray(); 128 case DescriptorType.String: 129 if(index == 0) 130 { 131 stringDescriptor = new StringUSBDescriptor(1); 132 stringDescriptor.LangId[0] = EnglishLangId; 133 } 134 else 135 { 136 if(index < stringValues.Count) 137 { 138 stringDescriptor = new StringUSBDescriptor(stringValues[setupPacket.index][index]); 139 } 140 else 141 { 142 stringDescriptor = new StringUSBDescriptor(""); 143 } 144 145 } 146 controlPacket = new byte[stringDescriptor.ToArray().Length]; 147 stringDescriptor.ToArray().CopyTo(controlPacket, 0); 148 return stringDescriptor.ToArray(); 149 default: 150 return null; 151 } 152 } 153 WriteDataControl(USBPacket packet)154 public void WriteDataControl(USBPacket packet) 155 { 156 } 157 ProcessClassSet(USBPacket packet, USBSetupPacket setupPacket)158 public void ProcessClassSet(USBPacket packet, USBSetupPacket setupPacket) 159 { 160 throw new System.NotImplementedException(); 161 } 162 SetDataToggle(byte endpointNumber)163 public void SetDataToggle(byte endpointNumber) 164 { 165 dataToggleBit[endpointNumber] = true; 166 } 167 Reset()168 public void Reset() 169 { 170 linkUp = false; 171 } 172 CleanDataToggle(byte endpointNumber)173 public void CleanDataToggle(byte endpointNumber) 174 { 175 dataToggleBit[endpointNumber] = false; 176 } 177 ToggleDataToggle(byte endpointNumber)178 public void ToggleDataToggle(byte endpointNumber) 179 { 180 dataToggleBit[endpointNumber] = !dataToggleBit[endpointNumber]; 181 } 182 GetDataToggle(byte endpointNumber)183 public bool GetDataToggle(byte endpointNumber) 184 { 185 return dataToggleBit[endpointNumber]; 186 } 187 ClearFeature(USBPacket packet, USBSetupPacket setupPacket)188 public void ClearFeature(USBPacket packet, USBSetupPacket setupPacket) 189 { 190 throw new System.NotImplementedException(); 191 } 192 GetConfiguration()193 public byte[] GetConfiguration() 194 { 195 throw new System.NotImplementedException(); 196 } 197 GetInterface(USBPacket packet, USBSetupPacket setupPacket)198 public byte[] GetInterface(USBPacket packet, USBSetupPacket setupPacket) 199 { 200 throw new System.NotImplementedException(); 201 } 202 GetStatus(USBPacket packet, USBSetupPacket setupPacket)203 public byte[] GetStatus(USBPacket packet, USBSetupPacket setupPacket) 204 { 205 var arr = new byte[2]; 206 MessageRecipient recipient = (MessageRecipient)(setupPacket.requestType & 0x3); 207 switch(recipient) 208 { 209 case MessageRecipient.Device: 210 arr[0] = (byte)(((configurationDescriptor.RemoteWakeup ? 1 : 0) << 1) | (configurationDescriptor.SelfPowered ? 1 : 0)); 211 break; 212 case MessageRecipient.Endpoint: 213 //TODO: endpoint halt status 214 goto default; 215 default: 216 arr[0] = 0; 217 break; 218 } 219 controlPacket = new byte[arr.Length]; 220 arr.CopyTo(controlPacket, 0); 221 return arr; 222 } 223 SetAddress(uint address)224 public void SetAddress(uint address) 225 { 226 //this.address = address; 227 addr = address; 228 this.Log(LogLevel.Info, "Device addres set to 0x{0:X}", address); 229 } 230 SetConfiguration(USBPacket packet, USBSetupPacket setupPacket)231 public void SetConfiguration(USBPacket packet, USBSetupPacket setupPacket) 232 { 233 234 } 235 SetDescriptor(USBPacket packet, USBSetupPacket setupPacket)236 public void SetDescriptor(USBPacket packet, USBSetupPacket setupPacket) 237 { 238 throw new System.NotImplementedException(); 239 } 240 SetFeature(USBPacket packet, USBSetupPacket setupPacket)241 public void SetFeature(USBPacket packet, USBSetupPacket setupPacket) 242 { 243 244 } 245 SetInterface(USBPacket packet, USBSetupPacket setupPacket)246 public void SetInterface(USBPacket packet, USBSetupPacket setupPacket) 247 { 248 249 } 250 SyncFrame(uint endpointId)251 public void SyncFrame(uint endpointId) 252 { 253 throw new System.NotImplementedException(); 254 } CalculateChecksumTX(byte[] data)255 private ushort CalculateChecksumTX(byte[] data) 256 { 257 ulong sum = 0; 258 int size = data.Length; 259 uint i = 0; 260 ushort addVal; 261 while(size > 1) 262 { 263 addVal = (ushort)((data[i] << 8) | data[i + 1]); 264 sum += addVal; 265 i += 2; 266 size -= 2; 267 } 268 if(size != 0) //if odd length 269 sum += (ushort)((data[i] << 8) | 0x00); 270 271 272 while((sum >>16) != 0) 273 { 274 sum = (sum >> 16) + (sum & 0xffff); 275 } 276 return (ushort)((~sum) + 1); 277 } WriteDataBulk(USBPacket packet)278 public void WriteDataBulk(USBPacket packet) 279 { 280 if(packet.data == null) 281 return; 282 283 byte[] packetToSend; 284 if(packet.data[5] != 64) 285 { 286 packetToSend = new byte[packet.data.Length - 8]; 287 Array.Copy(packet.data, 8, packetToSend, 0, packetToSend.Length); 288 } 289 else 290 { 291 packetToSend = new byte[packet.data.Length - 12]; 292 Array.Copy(packet.data, 12, packetToSend, 0, packetToSend.Length); 293 294 if((packetToSend[14] & 0xF0) == 0x40) //IP packet 295 { 296 ushort cksum; 297 IPHeaderLength = (ushort)((packetToSend[14] & 0x0F) * 4); 298 if(packetToSend[23] == 0x06) // TCP packet 299 { 300 301 IPpacket tcpPacket = new IPpacket(IPHeaderLength, IPpacket.PacketType.TCP); 302 tcpPacket.ReadFromBuffer(packetToSend); 303 cksum = tcpPacket.GetChecksum(); 304 cksum -= 1; 305 packetToSend[MACHeaderLegth + IPHeaderLength + 16] = (byte)((cksum >> 8) & 0xFF); 306 packetToSend[MACHeaderLegth + IPHeaderLength + 17] = (byte)((cksum) & 0xFF); 307 } 308 else if(packetToSend[23] == 0x11) // UDP packet 309 { 310 IPpacket udpPacket = new IPpacket(IPHeaderLength, IPpacket.PacketType.UDP); 311 udpPacket.ReadFromBuffer(packetToSend); 312 cksum = udpPacket.GetChecksum(); 313 cksum -= 1; 314 packetToSend[MACHeaderLegth + IPHeaderLength + 6] = (byte)((cksum >> 8) & 0xFF); 315 packetToSend[MACHeaderLegth + IPHeaderLength + 7] = (byte)((cksum) & 0xFF); 316 } 317 } 318 319 } 320 321 if(Misc.TryCreateFrameOrLogWarning(this, packetToSend, out var frame, addCrc: true)) 322 { 323 FrameReady?.Invoke(frame); 324 } 325 } 326 CalculateChecksumRX(byte[] data)327 private ushort CalculateChecksumRX(byte[] data) 328 { 329 ulong sum = 0; 330 ulong part = 0; 331 int size = data.Length; 332 uint i = 0; 333 while(size > 1) 334 { 335 part = (ulong)((data[i + 1] * 256) + data[i]); 336 sum += ((part & 0xFFFFu) + (part >> 16)); 337 i += 2; 338 size -= 2; 339 } 340 if(size != 0) //if odd length 341 sum += (ushort)(data[size - 1]); 342 343 return (ushort)sum; 344 } 345 346 private readonly Queue<EthernetFrame> rxPacketQueue; 347 GetDataBulk(USBPacket packet)348 public byte[] GetDataBulk(USBPacket packet) 349 { 350 lock(sync) 351 { 352 if(packet.bytesToTransfer > 0) 353 if(rxPacketQueue.Count > 0) 354 { 355 356 EthernetFrame receivedFrame = rxPacketQueue.Dequeue(); 357 358 //byte frameBytes []= rxFifo.Dequeue(); 359 var size = receivedFrame.Bytes.Length; 360 uint packetSize; 361 // var packetSize = Math.Max(64, size & ~1); //64 is the minimal length 362 packetSize = (uint)size; 363 packetSize += 6; 364 365 366 packetSize += 6; 367 368 if(packetSize > 1514 + 12) 369 { 370 //Maybe we should react to overruns. Now we just drop. 371 return null; 372 } 373 374 byte[] currentBuffer = new byte[(uint)packetSize]; 375 currentBuffer[2] = (byte)((packetSize - 6) & 0xff); 376 currentBuffer[3] = (byte)((packetSize - 6) >> 8); 377 var frameBytes = receivedFrame.Bytes; 378 ushort cksum = 0; 379 380 byte[] tmp = new byte[(uint)frameBytes.Length - 14]; 381 Array.Copy(frameBytes, 14, tmp, 0, tmp.Length); 382 cksum = CalculateChecksumRX(tmp); 383 if((frameBytes[14] & 0xF0) == 0x40) //IP packet 384 { 385 386 if(frameBytes[23] == 0x06) // TCP packet 387 { 388 389 uint sa = (uint)((frameBytes[MACHeaderLegth + 12 + 3] << 24) | (frameBytes[MACHeaderLegth + 12 + 2] << 16) | (frameBytes[MACHeaderLegth + 12 + 1] << 8) | (frameBytes[MACHeaderLegth + 12 + 0] << 0)); 390 uint da = (uint)((frameBytes[MACHeaderLegth + 16 + 3] << 24) | (frameBytes[MACHeaderLegth + 16 + 2] << 16) | (frameBytes[MACHeaderLegth + 16 + 1] << 8) | (frameBytes[MACHeaderLegth + 16 + 0] << 0)); 391 ushort protocol = frameBytes[MACHeaderLegth + 9]; 392 ushort IPHeaderLength = (ushort)((frameBytes[14] & 0x0F) * 4); 393 ushort packetLength = (ushort)(System.Net.IPAddress.HostToNetworkOrder((ushort)(frameBytes.Length - (MACHeaderLegth + IPHeaderLength))) >> 16); 394 long s = sa + da + (protocol << 8) + packetLength; 395 s += (s >> 32); 396 s = (s & 0xffff) + (s >> 16); 397 s = (s & 0xffff) + (s >> 16); 398 cksum = (ushort)~s; 399 } 400 } 401 402 if((frameBytes[14] & 0xF0) == 0x40) //IP packet 403 { 404 if(frameBytes[23] == 0x01) // UDP packet 405 { 406 Array.Copy(frameBytes, 14, tmp, 0, tmp.Length); 407 ushort cksumm = CalculateChecksumRX(tmp); 408 frameBytes[36] = (byte)((cksumm >> 8) & 0xFF); 409 frameBytes[37] = (byte)((cksumm) & 0xFF); 410 } 411 } 412 413 for(int i=0; i< size; i++) 414 { 415 currentBuffer[6 + i] = frameBytes[i]; 416 } 417 418 if((frameBytes[14] & 0xF0) == 0x40) //IP packet 419 { 420 if(frameBytes[23] == 0x06) 421 { 422 currentBuffer[packetSize - 1] = (byte)(((cksum) >> 8) & 0xFF); 423 currentBuffer[packetSize - 2] = (byte)((cksum) & 0xFF); 424 } 425 else if(frameBytes[23] == 0x11) 426 { 427 currentBuffer[packetSize - 1] = (byte)(((cksum) >> 8) & 0xFF); 428 currentBuffer[packetSize - 2] = (byte)((cksum) & 0xFF); 429 } 430 } 431 return currentBuffer; 432 } 433 return null; 434 } 435 436 437 } 438 #endregion 439 #region ping hack variables 440 private readonly object sync = new object(); 441 #endregion 442 #region INetworkInterface implementation 443 public event Action<EthernetFrame> FrameReady; 444 ReceiveFrame(EthernetFrame frame)445 public void ReceiveFrame(EthernetFrame frame)//when data is send to us 446 { 447 lock(sync) 448 { 449 if(!frame.DestinationMAC.IsBroadcast && frame.DestinationMAC != MAC) 450 { 451 return; 452 } 453 454 if(!EthernetFrame.CheckCRC(frame.Bytes)) 455 { 456 this.Log(LogLevel.Info, "Invalid CRC, packet discarded"); 457 return; 458 } 459 460 rxPacketQueue.Enqueue(frame); 461 } 462 } 463 #endregion 464 #region device registers 465 // private byte[] macAddress = new byte[] {0,0,0,0,0,0}; 466 #endregion 467 #region USB descriptors 468 469 private ConfigurationUSBDescriptor configurationDescriptor = new ConfigurationUSBDescriptor() { 470 ConfigurationIndex = 3, 471 SelfPowered = true, 472 NumberOfInterfaces = 1, 473 RemoteWakeup = true, 474 MaxPower = 0x01, //2mA 475 ConfigurationValue = 1 476 }; 477 private ConfigurationUSBDescriptor otherConfigurationDescriptor = new ConfigurationUSBDescriptor(); 478 private StringUSBDescriptor stringDescriptor = null; 479 private StandardUSBDescriptor deviceDescriptor = new StandardUSBDescriptor { 480 DeviceClass=0xff,//vendor specific 481 DeviceSubClass = 0xff,//vendor specific 482 USB = 0x0200, 483 DeviceProtocol = 0xff,//vendor specific 484 MaxPacketSize = 64, 485 VendorId = 0x0424, 486 ProductId = 0xec00, 487 Device = 0x0200, 488 ManufacturerIndex = 4, 489 ProductIndex = 1, 490 SerialNumberIndex = 2, 491 NumberOfConfigurations = 1 492 }; 493 private DeviceQualifierUSBDescriptor deviceQualifierDescriptor = new DeviceQualifierUSBDescriptor(); 494 private EndpointUSBDescriptor[] endpointDescriptor; 495 private InterfaceUSBDescriptor[] interfaceDescriptor = new[] {new InterfaceUSBDescriptor 496 { 497 AlternateSetting = 0, 498 InterfaceNumber = 0, 499 NumberOfEndpoints = NumberOfEndpoints, 500 InterfaceClass = 0xff, //vendor specific 501 InterfaceProtocol = 0xff, 502 InterfaceSubClass = 0xff, 503 InterfaceIndex = 0 504 } 505 }; 506 //private uint address; 507 private Dictionary<ushort, string[]> stringValues = new Dictionary<ushort, string[]>() { 508 {EnglishLangId, new string[]{ 509 "", 510 "SMSC914", 511 "0xALLMAN", 512 "Configuration", 513 "AntMicro" 514 }} 515 }; 516 fillEndpointsDescriptors(EndpointUSBDescriptor[] endpointDesc)517 private void fillEndpointsDescriptors(EndpointUSBDescriptor[] endpointDesc) 518 { 519 endpointDesc[0].EndpointNumber = 1; 520 endpointDesc[0].InEnpoint = true; 521 endpointDesc[0].TransferType = EndpointUSBDescriptor.TransferTypeEnum.Bulk; 522 endpointDesc[0].MaxPacketSize = 512; 523 endpointDesc[0].SynchronizationType = EndpointUSBDescriptor.SynchronizationTypeEnum.NoSynchronization; 524 endpointDesc[0].UsageType = EndpointUSBDescriptor.UsageTypeEnum.Data; 525 endpointDesc[0].Interval = 0; 526 527 endpointDesc[1].EndpointNumber = 2; 528 endpointDesc[1].InEnpoint = false; 529 endpointDesc[1].TransferType = EndpointUSBDescriptor.TransferTypeEnum.Bulk; 530 endpointDesc[1].MaxPacketSize = 512; 531 endpointDesc[1].SynchronizationType = EndpointUSBDescriptor.SynchronizationTypeEnum.NoSynchronization; 532 endpointDesc[1].UsageType = EndpointUSBDescriptor.UsageTypeEnum.Data; 533 endpointDesc[1].Interval = 0; 534 535 endpointDesc[2].EndpointNumber = 3; 536 endpointDesc[2].InEnpoint = true; 537 endpointDesc[2].TransferType = EndpointUSBDescriptor.TransferTypeEnum.Interrupt; 538 endpointDesc[2].MaxPacketSize = 16; 539 endpointDesc[2].SynchronizationType = EndpointUSBDescriptor.SynchronizationTypeEnum.NoSynchronization; 540 endpointDesc[2].UsageType = EndpointUSBDescriptor.UsageTypeEnum.Data; 541 endpointDesc[2].Interval = 2; 542 543 } 544 #endregion 545 #region Device enums 546 private enum vendorRequest : byte 547 { 548 WriteRegister = 0xA0, 549 ReadRegister = 0xA1 550 } 551 552 private enum txCommands 553 { 554 FirstSegment = 0x00002000, 555 LastSegment = 0x00001000 556 } 557 558 private enum rxStatus 559 { 560 FrameLength = 0x3FFF0000, 561 ErrorSummary = 0x00008000 562 } 563 564 private enum SCSR 565 { 566 IdRevision = 0x00, 567 InterruptStatus = 0x08, 568 TxConfig = 0x10, 569 HwConfig = 0x14, 570 PmControl = 0x20, 571 AfcConfig = 0x2C, 572 E2PCommand = 0x30, 573 E2PData = 0x34, 574 BurstCapabilities = 0x38, 575 InterruptEndpointControl = 0x68, 576 BulkInDly = 0x6C, 577 MACControl = 0x100, 578 MACAddressHi = 0x104, 579 MACAddressLo = 0x108, 580 MediaIndependentInterfaceAddress = 0x114, 581 MediaIndependentInterfaceData = 0x118, 582 Flow = 0x11C, 583 Vlan1 = 0x120, 584 ConnectionOrientedEthernetControl = 0x130 585 } 586 #endregion 587 #region Device constans 588 private const byte NumberOfEndpoints = 3; 589 private const ushort EnglishLangId = 0x09; 590 #endregion 591 #region Device variables 592 private uint macControlRegister = 0x00; 593 private uint e2pCommand = 0x00; 594 private uint hardwareConfigurationRegister = 0x00; 595 private uint powerMenagementConfigurationRegister = 0x00; 596 private uint miiData = 0x04; 597 private uint miiAddress = 0x04; 598 private bool[] dataToggleBit = new bool[NumberOfEndpoints + 1]; 599 #endregion 600 #region IUSBDevice implementation ProcessVendorGet(USBPacket packet, USBSetupPacket setupPacket)601 public byte[] ProcessVendorGet(USBPacket packet, USBSetupPacket setupPacket) 602 { 603 ushort index = setupPacket.index; 604 byte request = setupPacket.request; 605 ushort value = setupPacket.value; 606 if(request == (byte)vendorRequest.ReadRegister) 607 { 608 switch((SCSR)index) 609 { 610 case SCSR.MACAddressLo: 611 612 break; 613 case SCSR.MACAddressHi: 614 615 break; 616 case SCSR.E2PData: 617 if((e2pCommand & 0x000001FF) >= 0x1 && (e2pCommand & 0x000001FF) <= 0x6) 618 { 619 controlPacket = new byte[1]; 620 controlPacket[0] = MAC.Bytes[(e2pCommand & 0x000001FF) - 1]; 621 return controlPacket; 622 } 623 else 624 { 625 controlPacket = BitConverter.GetBytes((uint)0); 626 return BitConverter.GetBytes((uint)0); 627 } 628 case SCSR.MACControl: 629 controlPacket = BitConverter.GetBytes(macControlRegister); 630 return BitConverter.GetBytes(macControlRegister); 631 case SCSR.E2PCommand: 632 controlPacket = BitConverter.GetBytes(e2pCommand); 633 return BitConverter.GetBytes(e2pCommand); 634 case SCSR.HwConfig: 635 controlPacket = BitConverter.GetBytes(hardwareConfigurationRegister & (~0x00000008)); 636 return (BitConverter.GetBytes(hardwareConfigurationRegister & (~0x00000008))); 637 case SCSR.PmControl: 638 controlPacket = BitConverter.GetBytes(powerMenagementConfigurationRegister & (~0x00000010)); 639 return BitConverter.GetBytes(powerMenagementConfigurationRegister & (~0x00000010)); 640 case SCSR.MediaIndependentInterfaceData: 641 controlPacket = BitConverter.GetBytes(miiData & (~0x8000) | 0x0004 | 0x0100); 642 return BitConverter.GetBytes(miiData & (~0x8000) | 0x0004 | 0x0100); 643 case SCSR.MediaIndependentInterfaceAddress: 644 controlPacket = BitConverter.GetBytes(miiAddress); 645 controlPacket[0] &= ((byte)(0xFEu)); 646 return controlPacket; 647 default: 648 this.Log(LogLevel.Warning, "Unknown register read request (request=0x{0:X}, value=0x{1:X}, index=0x{2:X})", request, value, index); 649 break; 650 } 651 } 652 var arr = new byte[] { 0 }; 653 controlPacket = arr; 654 return arr; 655 } 656 ProcessVendorSet(USBPacket packet, USBSetupPacket setupPacket)657 public void ProcessVendorSet(USBPacket packet, USBSetupPacket setupPacket) 658 { 659 ushort index = setupPacket.index; 660 byte request = setupPacket.request; 661 ushort value = setupPacket.value; 662 if(request == (byte)vendorRequest.WriteRegister) 663 { 664 switch((SCSR)index) 665 { 666 case SCSR.HwConfig: 667 if(packet.data != null) 668 hardwareConfigurationRegister = BitConverter.ToUInt32(packet.data, 0); 669 break; 670 case SCSR.PmControl: 671 if(packet.data != null) 672 powerMenagementConfigurationRegister = BitConverter.ToUInt32(packet.data, 0); 673 break; 674 case SCSR.MACAddressLo: 675 break; 676 case SCSR.MACAddressHi: 677 break; 678 case SCSR.MACControl: 679 if(packet.data != null) 680 macControlRegister = BitConverter.ToUInt32(packet.data, 0); 681 this.Log(LogLevel.Warning, "macControlRegister=0x{0:X}", macControlRegister); 682 break; 683 case SCSR.E2PData: 684 break; 685 case SCSR.E2PCommand: 686 if(packet.data != null) 687 e2pCommand = BitConverter.ToUInt32(packet.data, 0) & (~(0x80000000 | 0x00000400)); 688 break; 689 case SCSR.MediaIndependentInterfaceAddress: 690 if(packet.data != null) 691 miiAddress = BitConverter.ToUInt32(packet.data, 0); 692 break; 693 case SCSR.MediaIndependentInterfaceData: 694 if(packet.data != null) 695 miiData = BitConverter.ToUInt32(packet.data, 0); 696 break; 697 default: 698 this.Log(LogLevel.Warning, "Unknown register write request (request=0x{0:X}, value=0x{1:X}, index=0x{2:X})", request, value, index); 699 break; 700 } 701 } 702 } 703 #endregion 704 #region IMACInterface implementation 705 public MACAddress MAC { get; set; } 706 #endregion 707 708 private ushort IPHeaderLength = 20; 709 private const ushort MACHeaderLegth = 14; 710 711 712 private class IPpacket 713 { IPpacket(ushort IPLength, PacketType type)714 public IPpacket(ushort IPLength, PacketType type) 715 { 716 IPHeaderLength = IPLength; 717 packetType = type; 718 pseudoheader = new PseudoHeader(); 719 } 720 ReadFromBuffer(byte[] buffer)721 public void ReadFromBuffer(byte[] buffer) 722 { 723 pseudoheader.FillFromBuffer( buffer ); 724 725 packet = new byte[buffer.Length - (MACHeaderLegth + IPHeaderLength) ]; 726 Array.Copy(buffer, MACHeaderLegth + IPHeaderLength, packet, 0, ( buffer.Length - (MACHeaderLegth + IPHeaderLength) ) ); 727 if( packetType == PacketType.TCP ) 728 { 729 packet[16] = 0; 730 packet[17] = 0; 731 } 732 else if( packetType == PacketType.UDP ) 733 { 734 packet[6] = 0; 735 packet[7] = 0; 736 } 737 738 } 739 CalculateChecksum(byte [] data)740 private ushort CalculateChecksum(byte [] data) 741 { 742 ulong sum = 0; 743 int size = data.Length; 744 uint i = 0; 745 ushort addVal; 746 while( size > 1 ) 747 { 748 addVal = (ushort)((data[i] << 8) | data[i+1]); 749 sum += addVal; 750 i+=2; 751 size -= 2; 752 } 753 if( size != 0) //if odd length 754 sum += (ushort)((data[i] << 8) | 0x00); 755 756 757 while ( (sum >>16) != 0 ) 758 { 759 sum = (sum >> 16) + (sum & 0xffff); 760 } 761 return (ushort)( (~sum) + 1 ); 762 } 763 GetChecksum()764 public ushort GetChecksum() 765 { 766 ushort cksum; 767 768 checksumCalculationBase = new byte[packet.Length + pseudoheader.Length]; 769 770 Array.Copy(pseudoheader.ToArray(),0,checksumCalculationBase,0,pseudoheader.Length); 771 Array.Copy(packet,0,checksumCalculationBase,pseudoheader.Length,packet.Length); 772 773 cksum = CalculateChecksum(checksumCalculationBase); 774 return (ushort)(cksum); 775 776 } 777 778 private class PseudoHeader 779 { FillFromBuffer(byte[] buffer)780 public void FillFromBuffer(byte[] buffer) 781 { 782 sourceAddress = new byte[4]; 783 destinationAddress = new byte[4]; 784 Array.Copy(buffer,MACHeaderLegth+12,sourceAddress,0,4); 785 Array.Copy(buffer,MACHeaderLegth+16,destinationAddress,0,4); 786 protocol = buffer[MACHeaderLegth + 9]; 787 packetLength = (ushort)(System.Net.IPAddress.HostToNetworkOrder((ushort)(buffer.Length - (MACHeaderLegth + IPHeaderLength)))>>16); 788 } 789 ToArray()790 public byte[] ToArray() 791 792 { 793 byte[] arr = new byte[Length]; 794 Array.Copy(sourceAddress,0,arr,0,4); 795 Array.Copy(destinationAddress,0,arr,4,4); 796 arr[8] = zeros; 797 arr[9] = protocol; 798 Array.Copy(BitConverter.GetBytes(packetLength),0,arr,10,2); 799 return arr; 800 } 801 802 private byte[] sourceAddress; 803 private byte[] destinationAddress; 804 private readonly byte zeros = 0x00; 805 private byte protocol; 806 private ushort packetLength; 807 808 public readonly ushort Length = 12; 809 810 } 811 812 public enum PacketType 813 { 814 TCP = 1, 815 UDP = 2 816 } 817 818 private PacketType packetType; 819 private static ushort IPHeaderLength; 820 private const ushort MACHeaderLegth = 14; 821 822 private PseudoHeader pseudoheader; 823 private byte[] packet; 824 private byte[] checksumCalculationBase; 825 826 } 827 } 828 } 829 830