|
|
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.