|
|
1.1 ! root 1: /*++ ! 2: ! 3: Copyright (c) 1990-1992 Microsoft Corporation ! 4: ! 5: Module Name: ! 6: ! 7: loopback.c ! 8: ! 9: Abstract: ! 10: ! 11: The routines here indicate packets on the loopback queue and are ! 12: responsible for inserting and removing packets from the loopback ! 13: queue and the send finishing queue. ! 14: ! 15: Author: ! 16: ! 17: Anthony V. Ercolano (Tonye) 12-Sept-1990 ! 18: ! 19: Environment: ! 20: ! 21: Operates at dpc level - or the equivalent. ! 22: ! 23: Revision History: ! 24: ! 25: ! 26: --*/ ! 27: ! 28: #include <ndis.h> ! 29: #include <efilter.h> ! 30: ! 31: #include <sonichrd.h> ! 32: #include <sonicsft.h> ! 33: ! 34: ! 35: extern ! 36: VOID ! 37: SonicProcessLoopback( ! 38: IN PSONIC_ADAPTER Adapter ! 39: ) ! 40: ! 41: /*++ ! 42: ! 43: Routine Description: ! 44: ! 45: This routine is responsible for indicating *one* packet on ! 46: the loopback queue either completing it or moving on to the ! 47: finish send queue. ! 48: ! 49: NOTE : This routine is called with the lock held! ! 50: ! 51: Arguments: ! 52: ! 53: Adapter - The adapter whose loopback queue we are processing. ! 54: ! 55: Return Value: ! 56: ! 57: None. ! 58: ! 59: --*/ ! 60: ! 61: { ! 62: ! 63: // ! 64: // Packet at the head of the loopback list. ! 65: // ! 66: PNDIS_PACKET PacketToMove; ! 67: ! 68: // ! 69: // The reserved portion of the above packet. ! 70: // ! 71: PSONIC_PACKET_RESERVED Reserved; ! 72: ! 73: // ! 74: // The first buffer in the ndis packet to be loopbacked. ! 75: // ! 76: PNDIS_BUFFER FirstBuffer; ! 77: ! 78: // ! 79: // The total amount of user data in the packet to be ! 80: // loopbacked. ! 81: // ! 82: UINT TotalPacketLength; ! 83: ! 84: // ! 85: // The address of the first buffer in the packet. ! 86: // ! 87: ! 88: PVOID BufferAddress; ! 89: ! 90: // ! 91: // The address of the data to be indicated ! 92: // to the transport. ! 93: // ! 94: PVOID DataAddress; ! 95: ! 96: // ! 97: // Eventually the length of the data to be indicated ! 98: // to the transport. ! 99: // ! 100: UINT BufferLength; ! 101: ! 102: // ! 103: // Open that submitted the packet ! 104: // ! 105: PSONIC_OPEN Open; ! 106: ! 107: ASSERT(Adapter->FirstLoopBack != NULL); ! 108: ! 109: PacketToMove = Adapter->FirstLoopBack; ! 110: ! 111: Reserved = PSONIC_RESERVED_FROM_PACKET(PacketToMove); ! 112: ! 113: if (Reserved->Next == NULL) { ! 114: ! 115: Adapter->LastLoopBack = NULL; ! 116: ! 117: } ! 118: ! 119: Adapter->FirstLoopBack = Reserved->Next; ! 120: ! 121: Open = PSONIC_OPEN_FROM_BINDING_HANDLE(Reserved->MacBindingHandle); ! 122: ! 123: Adapter->CurrentLoopbackPacket = PacketToMove; ! 124: ! 125: NdisReleaseSpinLock(&Adapter->Lock); ! 126: ! 127: // ! 128: // See if we need to copy the data from the packet ! 129: // into the loopback buffer. ! 130: // ! 131: // We need to copy to the local loopback buffer if ! 132: // the first buffer of the packet is less than the ! 133: // minimum loopback size AND the first buffer isn't ! 134: // the total packet. ! 135: // ! 136: ! 137: NdisQueryPacket( ! 138: PacketToMove, ! 139: NULL, ! 140: NULL, ! 141: &FirstBuffer, ! 142: &TotalPacketLength ! 143: ); ! 144: ! 145: NdisQueryBuffer( ! 146: FirstBuffer, ! 147: &BufferAddress, ! 148: &BufferLength ! 149: ); ! 150: ! 151: // ! 152: // Indicate the packet to every open binding ! 153: // that could want it. Since loopback indications ! 154: // are seralized, we store the packet here ! 155: // and use a NULL handle to indicate that it ! 156: // is for a loopback packet. ! 157: // ! 158: ! 159: if (BufferLength < 14) { ! 160: ! 161: // ! 162: // Must have at least the destination address ! 163: // ! 164: ! 165: if (BufferLength >= ETH_LENGTH_OF_ADDRESS) { ! 166: ! 167: // ! 168: // Runt packet ! 169: // ! 170: ! 171: EthFilterIndicateReceive( ! 172: Adapter->FilterDB, ! 173: (NDIS_HANDLE)NULL, ! 174: ((PCHAR)BufferAddress), ! 175: BufferAddress, // header ! 176: BufferLength, // header size ! 177: NULL, // lookahead ! 178: 0, // lookahead size ! 179: 0 // packet size ! 180: ); ! 181: ! 182: } ! 183: ! 184: } else { ! 185: ! 186: // ! 187: // Copy the data if the first buffer does not hold ! 188: // the header plus the loopback amount required. ! 189: // ! 190: // NOTE: We could copy less if all the bindings had ! 191: // a shorted lookahead length set. ! 192: // ! 193: ! 194: if ((BufferLength < SONIC_LOOPBACK_MAXIMUM+14) && ! 195: (BufferLength != TotalPacketLength)) { ! 196: ! 197: SonicCopyFromPacketToBuffer( ! 198: PacketToMove, ! 199: 14, ! 200: SONIC_LOOPBACK_MAXIMUM, ! 201: Adapter->Loopback, ! 202: &BufferLength ! 203: ); ! 204: ! 205: DataAddress = Adapter->Loopback; ! 206: ! 207: } else { ! 208: ! 209: DataAddress = (PUCHAR)BufferAddress + 14; ! 210: BufferLength -= 14; ! 211: ! 212: } ! 213: ! 214: EthFilterIndicateReceive( ! 215: Adapter->FilterDB, ! 216: (NDIS_HANDLE)NULL, ! 217: ((PCHAR)BufferAddress), ! 218: BufferAddress, // header ! 219: 14, // header size ! 220: DataAddress, // lookahead ! 221: BufferLength, // lookahead size ! 222: TotalPacketLength - 14 // packet size ! 223: ); ! 224: ! 225: } ! 226: ! 227: // ! 228: // Remove the packet from the loopback queue and ! 229: // either indicate that it is finished or put ! 230: // it on the finishing up queue for the real transmits. ! 231: // ! 232: ! 233: NdisCompleteSend( ! 234: Open->NdisBindingContext, ! 235: PacketToMove, ! 236: ((Reserved->SuccessfulTransmit)? ! 237: (NDIS_STATUS_SUCCESS):(NDIS_STATUS_FAILURE)) ! 238: ); ! 239: ! 240: NdisAcquireSpinLock(&Adapter->Lock); ! 241: ! 242: #ifdef CHECK_DUP_SENDS ! 243: { ! 244: VOID SonicRemovePacketFromList(PSONIC_ADAPTER, PNDIS_PACKET); ! 245: SonicRemovePacketFromList(Adapter, PacketToMove); ! 246: } ! 247: #endif ! 248: ! 249: // ! 250: // We can decrement the reference count on the open ! 251: // since it is no longer being "referenced" by the ! 252: // packet on the loopback queue. ! 253: // ! 254: ! 255: Open->References--; ! 256: ! 257: // ! 258: // If there is nothing else on the loopback queue ! 259: // then indicate that reception is "done". ! 260: // ! 261: ! 262: if (!Adapter->FirstLoopBack) { ! 263: ! 264: // ! 265: // Indicate to every open binding that "receives" ! 266: // are complete. ! 267: // ! 268: ! 269: NdisReleaseSpinLock(&Adapter->Lock); ! 270: ! 271: EthFilterIndicateReceiveComplete(Adapter->FilterDB); ! 272: ! 273: NdisAcquireSpinLock(&Adapter->Lock); ! 274: ! 275: } ! 276: ! 277: } ! 278: #ifdef CHECK_FINISH_TRANS ! 279: VOID ! 280: SonicShowFinishTrans( ! 281: IN PSONIC_ADAPTER Adapter, ! 282: IN UINT CheckLocation, ! 283: IN PVOID PacketPointer ! 284: ) ! 285: { ! 286: PNDIS_PACKET CurPointer; ! 287: PSONIC_PACKET_RESERVED Reserved; ! 288: ! 289: DbgPrint("SONIC: at %d for %lx: %lx to %lx\n", CheckLocation, PacketPointer, ! 290: Adapter->FirstFinishTransmit, Adapter->LastFinishTransmit); ! 291: ! 292: CurPointer = Adapter->FirstFinishTransmit; ! 293: ! 294: while (CurPointer) { ! 295: ! 296: Reserved = PSONIC_RESERVED_FROM_PACKET(CurPointer); ! 297: DbgPrint("%lx: %lx ->\n", CurPointer, Reserved->Next); ! 298: ! 299: CurPointer = Reserved->Next; ! 300: ! 301: } ! 302: } ! 303: VOID ! 304: SonicCheckFinishTrans( ! 305: IN PSONIC_ADAPTER Adapter, ! 306: IN UINT CheckLocation, ! 307: IN PVOID PacketPointer ! 308: ) ! 309: { ! 310: PNDIS_PACKET CurPointer, PrevPointer; ! 311: PSONIC_PACKET_RESERVED Reserved; ! 312: BOOLEAN BadQueue = FALSE; ! 313: ! 314: CurPointer = Adapter->FirstFinishTransmit; ! 315: PrevPointer = (PNDIS_PACKET)NULL; ! 316: ! 317: ! 318: while (CurPointer) { ! 319: ! 320: Reserved = PSONIC_RESERVED_FROM_PACKET(CurPointer); ! 321: ! 322: PrevPointer = CurPointer; ! 323: CurPointer = Reserved->Next; ! 324: ! 325: } ! 326: ! 327: if (Adapter->LastFinishTransmit != PrevPointer) { ! 328: ! 329: BadQueue = TRUE; ! 330: ! 331: } ! 332: ! 333: if (BadQueue) { ! 334: ! 335: SonicShowFinishTrans(Adapter, CheckLocation, PacketPointer); ! 336: ! 337: } ! 338: } ! 339: #endif // CHECK_FINISH_TRANS ! 340: ! 341: extern ! 342: VOID ! 343: SonicPutPacketOnLoopBack( ! 344: IN PSONIC_ADAPTER Adapter, ! 345: IN PNDIS_PACKET Packet, ! 346: IN BOOLEAN SuccessfulTransmit ! 347: ) ! 348: ! 349: /*++ ! 350: ! 351: Routine Description: ! 352: ! 353: Put the packet on the adapter wide loop back list. ! 354: ! 355: NOTE: This routine assumes that the lock is held. ! 356: ! 357: Arguments: ! 358: ! 359: Adapter - The adapter that contains the loop back list. ! 360: ! 361: Packet - The packet to be put on loop back. ! 362: ! 363: SuccessfulTransmit - This value should be placed in the ! 364: reserved section. ! 365: ! 366: NOTE: If ReadyToComplete == TRUE then the packets completion status ! 367: field will also be set TRUE. ! 368: ! 369: Return Value: ! 370: ! 371: None. ! 372: ! 373: --*/ ! 374: ! 375: { ! 376: ! 377: PSONIC_PACKET_RESERVED Reserved = PSONIC_RESERVED_FROM_PACKET(Packet); ! 378: ! 379: if (!Adapter->FirstLoopBack) { ! 380: ! 381: Adapter->FirstLoopBack = Packet; ! 382: ! 383: } else { ! 384: ! 385: PSONIC_RESERVED_FROM_PACKET(Adapter->LastLoopBack)->Next = Packet; ! 386: ! 387: } ! 388: ! 389: Reserved->SuccessfulTransmit = SuccessfulTransmit; ! 390: ! 391: Reserved->Next = NULL; ! 392: Adapter->LastLoopBack = Packet; ! 393: ! 394: } ! 395:
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.