Leaked source code of windows server 2003
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

2369 lines
76 KiB

  1. /*++
  2. Copyright (c) 1991 Microsoft Corporation
  3. Module Name:
  4. llcsend.c
  5. Abstract:
  6. The module implements all sending functions and the main
  7. send process. There three different send queues:
  8. - I_Queue
  9. - DirU_Queue
  10. - ExpiditedQueue (for LLC commands)
  11. Each queue has the pointer of a packet building primitive, that
  12. takes an NDIS packet of an queue element.
  13. Contents:
  14. RunSendTaskAndUnlock
  15. BackgroundProcessAndUnlock
  16. BackgroundProcess
  17. LlcNdisSendComplete
  18. GetI_Packet
  19. StartSendProcess
  20. EnableSendProcess
  21. StopSendProcess
  22. DisableSendProcess
  23. BuildDirOrU_Packet
  24. SendLlcFrame
  25. GetLlcCommandPacket
  26. SendNdisPacket
  27. CompleteSendAndLock
  28. RespondTestOrXid
  29. LlcSendU
  30. LlcSendI
  31. QueuePacket
  32. CheckAndDuplicatePacket
  33. BackgroundProcessWithinLock
  34. Author:
  35. Antti Saarenheimo (o-anttis) 23-MAY-1991
  36. Revision History:
  37. --*/
  38. #include <llc.h>
  39. //
  40. // The IEEE XID frame is constant data: (id, support Class II, maxin = 127};
  41. //
  42. LLC_XID_INFORMATION Ieee802Xid = {IEEE_802_XID_ID, LLC_CLASS_II, (127 << 1)};
  43. PMDL pXidMdl = NULL;
  44. //
  45. // Because normally LAN networks are error free, we added this option
  46. // to test the error recovery of DLC protocol. It seems to work now
  47. // quite well (but first we had to fix a fundamental bug in the sending
  48. // of REJ-r0).
  49. //
  50. //
  51. // Enable this to test REJECT states (after a major changes in
  52. // the state machine).
  53. //
  54. //#define LLC_LOSE_I_PACKETS
  55. #ifdef LLC_LOSE_I_PACKETS
  56. #define DBG_ERROR_PERCENT(a) (((a) * 0x8000) / 100)
  57. //
  58. // Pseudo random table to lose packets
  59. //
  60. static USHORT aRandom[1000] = {
  61. 41, 18467, 6334, 26500, 19169, 15724, 11478, 29358, 26962, 24464,
  62. 5705, 28145, 23281, 16827, 9961, 491, 2995, 11942, 4827, 5436,
  63. 32391, 14604, 3902, 153, 292, 12382, 17421, 18716, 19718, 19895,
  64. 5447, 21726, 14771, 11538, 1869, 19912, 25667, 26299, 17035, 9894,
  65. 28703, 23811, 31322, 30333, 17673, 4664, 15141, 7711, 28253, 6868,
  66. 25547, 27644, 32662, 32757, 20037, 12859, 8723, 9741, 27529, 778,
  67. 12316, 3035, 22190, 1842, 288, 30106, 9040, 8942, 19264, 22648,
  68. 27446, 23805, 15890, 6729, 24370, 15350, 15006, 31101, 24393, 3548,
  69. 19629, 12623, 24084, 19954, 18756, 11840, 4966, 7376, 13931, 26308,
  70. 16944, 32439, 24626, 11323, 5537, 21538, 16118, 2082, 22929, 16541,
  71. 4833, 31115, 4639, 29658, 22704, 9930, 13977, 2306, 31673, 22386,
  72. 5021, 28745, 26924, 19072, 6270, 5829, 26777, 15573, 5097, 16512,
  73. 23986, 13290, 9161, 18636, 22355, 24767, 23655, 15574, 4031, 12052,
  74. 27350, 1150, 16941, 21724, 13966, 3430, 31107, 30191, 18007, 11337,
  75. 15457, 12287, 27753, 10383, 14945, 8909, 32209, 9758, 24221, 18588,
  76. 6422, 24946, 27506, 13030, 16413, 29168, 900, 32591, 18762, 1655,
  77. 17410, 6359, 27624, 20537, 21548, 6483, 27595, 4041, 3602, 24350,
  78. 10291, 30836, 9374, 11020, 4596, 24021, 27348, 23199, 19668, 24484,
  79. 8281, 4734, 53, 1999, 26418, 27938, 6900, 3788, 18127, 467,
  80. 3728, 14893, 24648, 22483, 17807, 2421, 14310, 6617, 22813, 9514,
  81. 14309, 7616, 18935, 17451, 20600, 5249, 16519, 31556, 22798, 30303,
  82. 6224, 11008, 5844, 32609, 14989, 32702, 3195, 20485, 3093, 14343,
  83. 30523, 1587, 29314, 9503, 7448, 25200, 13458, 6618, 20580, 19796,
  84. 14798, 15281, 19589, 20798, 28009, 27157, 20472, 23622, 18538, 12292,
  85. 6038, 24179, 18190, 29657, 7958, 6191, 19815, 22888, 19156, 11511,
  86. 16202, 2634, 24272, 20055, 20328, 22646, 26362, 4886, 18875, 28433,
  87. 29869, 20142, 23844, 1416, 21881, 31998, 10322, 18651, 10021, 5699,
  88. 3557, 28476, 27892, 24389, 5075, 10712, 2600, 2510, 21003, 26869,
  89. 17861, 14688, 13401, 9789, 15255, 16423, 5002, 10585, 24182, 10285,
  90. 27088, 31426, 28617, 23757, 9832, 30932, 4169, 2154, 25721, 17189,
  91. 19976, 31329, 2368, 28692, 21425, 10555, 3434, 16549, 7441, 9512,
  92. 30145, 18060, 21718, 3753, 16139, 12423, 16279, 25996, 16687, 12529,
  93. 22549, 17437, 19866, 12949, 193, 23195, 3297, 20416, 28286, 16105,
  94. 24488, 16282, 12455, 25734, 18114, 11701, 31316, 20671, 5786, 12263,
  95. 4313, 24355, 31185, 20053, 912, 10808, 1832, 20945, 4313, 27756,
  96. 28321, 19558, 23646, 27982, 481, 4144, 23196, 20222, 7129, 2161,
  97. 5535, 20450, 11173, 10466, 12044, 21659, 26292, 26439, 17253, 20024,
  98. 26154, 29510, 4745, 20649, 13186, 8313, 4474, 28022, 2168, 14018,
  99. 18787, 9905, 17958, 7391, 10202, 3625, 26477, 4414, 9314, 25824,
  100. 29334, 25874, 24372, 20159, 11833, 28070, 7487, 28297, 7518, 8177,
  101. 17773, 32270, 1763, 2668, 17192, 13985, 3102, 8480, 29213, 7627,
  102. 4802, 4099, 30527, 2625, 1543, 1924, 11023, 29972, 13061, 14181,
  103. 31003, 27432, 17505, 27593, 22725, 13031, 8492, 142, 17222, 31286,
  104. 13064, 7900, 19187, 8360, 22413, 30974, 14270, 29170, 235, 30833,
  105. 19711, 25760, 18896, 4667, 7285, 12550, 140, 13694, 2695, 21624,
  106. 28019, 2125, 26576, 21694, 22658, 26302, 17371, 22466, 4678, 22593,
  107. 23851, 25484, 1018, 28464, 21119, 23152, 2800, 18087, 31060, 1926,
  108. 9010, 4757, 32170, 20315, 9576, 30227, 12043, 22758, 7164, 5109,
  109. 7882, 17086, 29565, 3487, 29577, 14474, 2625, 25627, 5629, 31928,
  110. 25423, 28520, 6902, 14962, 123, 24596, 3737, 13261, 10195, 32525,
  111. 1264, 8260, 6202, 8116, 5030, 20326, 29011, 30771, 6411, 25547,
  112. 21153, 21520, 29790, 14924, 30188, 21763, 4940, 20851, 18662, 13829,
  113. 30900, 17713, 18958, 17578, 8365, 13007, 11477, 1200, 26058, 6439,
  114. 2303, 12760, 19357, 2324, 6477, 5108, 21113, 14887, 19801, 22850,
  115. 14460, 22428, 12993, 27384, 19405, 6540, 31111, 28704, 12835, 32356,
  116. 6072, 29350, 18823, 14485, 20556, 23216, 1626, 9357, 8526, 13357,
  117. 29337, 23271, 23869, 29361, 12896, 13022, 29617, 10112, 12717, 18696,
  118. 11585, 24041, 24423, 24129, 24229, 4565, 6559, 8932, 22296, 29855,
  119. 12053, 16962, 3584, 29734, 6654, 16972, 21457, 14369, 22532, 2963,
  120. 2607, 2483, 911, 11635, 10067, 22848, 4675, 12938, 2223, 22142,
  121. 23754, 6511, 22741, 20175, 21459, 17825, 3221, 17870, 1626, 31934,
  122. 15205, 31783, 23850, 17398, 22279, 22701, 12193, 12734, 1637, 26534,
  123. 5556, 1993, 10176, 25705, 6962, 10548, 15881, 300, 14413, 16641,
  124. 19855, 24855, 13142, 11462, 27611, 30877, 20424, 32678, 1752, 18443,
  125. 28296, 12673, 10040, 9313, 875, 20072, 12818, 610, 1017, 14932,
  126. 28112, 30695, 13169, 23831, 20040, 26488, 28685, 19090, 19497, 2589,
  127. 25990, 15145, 19353, 19314, 18651, 26740, 22044, 11258, 335, 8759,
  128. 11192, 7605, 25264, 12181, 28503, 3829, 23775, 20608, 29292, 5997,
  129. 17549, 29556, 25561, 31627, 6467, 29541, 26129, 31240, 27813, 29174,
  130. 20601, 6077, 20215, 8683, 8213, 23992, 25824, 5601, 23392, 15759,
  131. 2670, 26428, 28027, 4084, 10075, 18786, 15498, 24970, 6287, 23847,
  132. 32604, 503, 21221, 22663, 5706, 2363, 9010, 22171, 27489, 18240,
  133. 12164, 25542, 7619, 20913, 7591, 6704, 31818, 9232, 750, 25205,
  134. 4975, 1539, 303, 11422, 21098, 11247, 13584, 13648, 2971, 17864,
  135. 22913, 11075, 21545, 28712, 17546, 18678, 1769, 15262, 8519, 13985,
  136. 28289, 15944, 2865, 18540, 23245, 25508, 28318, 27870, 9601, 28323,
  137. 21132, 24472, 27152, 25087, 28570, 29763, 29901, 17103, 14423, 3527,
  138. 11600, 26969, 14015, 5565, 28, 21543, 25347, 2088, 2943, 12637,
  139. 22409, 26463, 5049, 4681, 1588, 11342, 608, 32060, 21221, 1758,
  140. 29954, 20888, 14146, 690, 7949, 12843, 21430, 25620, 748, 27067,
  141. 4536, 20783, 18035, 32226, 15185, 7038, 9853, 25629, 11224, 15748,
  142. 19923, 3359, 32257, 24766, 4944, 14955, 23318, 32726, 25411, 21025,
  143. 20355, 31001, 22549, 9496, 18584, 9515, 17964, 23342, 8075, 17913,
  144. 16142, 31196, 21948, 25072, 20426, 14606, 26173, 24429, 32404, 6705,
  145. 20626, 29812, 19375, 30093, 16565, 16036, 14736, 29141, 30814, 5994,
  146. 8256, 6652, 23936, 30838, 20482, 1355, 21015, 1131, 18230, 17841,
  147. 14625, 2011, 32637, 4186, 19690, 1650, 5662, 21634, 10893, 10353,
  148. 21416, 13452, 14008, 7262, 22233, 5454, 16303, 16634, 26303, 14256,
  149. 148, 11124, 12317, 4213, 27109, 24028, 29200, 21080, 21318, 16858,
  150. 24050, 24155, 31361, 15264, 11903, 3676, 29643, 26909, 14902, 3561,
  151. 28489, 24948, 1282, 13653, 30674, 2220, 5402, 6923, 3831, 19369,
  152. 3878, 20259, 19008, 22619, 23971, 30003, 21945, 9781, 26504, 12392,
  153. 32685, 25313, 6698, 5589, 12722, 5938, 19037, 6410, 31461, 6234,
  154. 12508, 9961, 3959, 6493, 1515, 25269, 24937, 28869, 58, 14700,
  155. 13971, 26264, 15117, 16215, 24555, 7815, 18330, 3039, 30212, 29288,
  156. 28082, 1954, 16085, 20710, 24484, 24774, 8380, 29815, 25951, 6541,
  157. 18115, 1679, 17110, 25898, 23073, 788, 23977, 18132, 29956, 28689,
  158. 26113, 10008, 12941, 15790, 1723, 21363, 28, 25184, 24778, 7200,
  159. 5071, 1885, 21974, 1071, 11333, 22867, 26153, 14295, 32168, 20825,
  160. 9676, 15629, 28650, 2598, 3309, 4693, 4686, 30080, 10116, 12249,
  161. };
  162. #endif
  163. VOID
  164. RunSendTaskAndUnlock(
  165. IN PADAPTER_CONTEXT pAdapterContext
  166. )
  167. /*++
  168. Routine Description:
  169. Function is the send engine of the data link driver
  170. and the background task.
  171. It sends the queue objects as far as there is
  172. free NDIS packets in a small packet queue.
  173. The number of NDIS packets are limited because
  174. too deep send queues are bad for the connection based protocols.
  175. This is called from NdisIndicateReceiveComplete,
  176. NdisSendComplete and almost all LLC commands.
  177. Arguments:
  178. pAdapterContext - adapter context
  179. Return Value:
  180. None
  181. --*/
  182. {
  183. ASSUME_IRQL(DISPATCH_LEVEL);
  184. //
  185. // We must serialize the sending. 802.2 protocol
  186. // will simply die if two sequential packets are sent in a wrong
  187. // order. The receiving and DLC level transmit processing can still
  188. // work even if the sending is syncronous in the data link level.
  189. //
  190. if (pAdapterContext->SendProcessIsActive == FALSE) {
  191. pAdapterContext->SendProcessIsActive = TRUE;
  192. while (!IsListEmpty(&pAdapterContext->NextSendTask)
  193. && pAdapterContext->pNdisPacketPool != NULL
  194. && !pAdapterContext->ResetInProgress) {
  195. //
  196. // executed the next send task in the send queue,
  197. // expidited data (if any) is always the first and
  198. // it is executed as far as there is any expidited packets.
  199. // The rest (I, UI, DIR) are executed in a round robin
  200. //
  201. SendNdisPacket(pAdapterContext,
  202. //
  203. // this next generates a pointer to a function which returns a
  204. // packet to send (eg. GetI_Packet)
  205. //
  206. ((PF_GET_PACKET)((PLLC_QUEUE)pAdapterContext->NextSendTask.Flink)->pObject)(pAdapterContext)
  207. );
  208. }
  209. pAdapterContext->SendProcessIsActive = FALSE;
  210. }
  211. RELEASE_SPIN_LOCK(&pAdapterContext->SendSpinLock);
  212. }
  213. VOID
  214. BackgroundProcessAndUnlock(
  215. IN PADAPTER_CONTEXT pAdapterContext
  216. )
  217. /*++
  218. Routine Description:
  219. Function is both the send engine of the data link driver
  220. and the background task.
  221. It executes the queue objects as far as there is
  222. free NDIS packets in a small packet queue.
  223. The number of NDIS packets are limited because
  224. too deep send queues are bad for the connection based protocols.
  225. This is called from NdisIndicateReceiveComplete,
  226. NdisSendComplete and almost all LLC commands.
  227. Arguments:
  228. pAdapterContext - adapter context
  229. Return Value:
  230. None
  231. --*/
  232. {
  233. ASSUME_IRQL(DISPATCH_LEVEL);
  234. //
  235. // Prevent recursive background process calls, we don't need to start
  236. // new loop, if there is already one instance running somewhere
  237. // up in the stack. Still we must do everything again,
  238. // if there was another backgroun process request, because
  239. // it may have been saved before the current position.
  240. //
  241. pAdapterContext->BackgroundProcessRequests++;
  242. if (pAdapterContext->BackgroundProcessRequests == 1) {
  243. //
  244. // repeat this as far as there are new tasks
  245. //
  246. do {
  247. USHORT InitialRequestCount;
  248. InitialRequestCount = pAdapterContext->BackgroundProcessRequests;
  249. //
  250. // This actually completes only link transmit, connect and
  251. // disconnect commands. The connectionless frames
  252. // are completed immediately when NDIS send completes.
  253. // Usually several frames are acknowledged in the same time.
  254. // Thus we create a local command list and execute
  255. // its all completions with a single spin locking.
  256. //
  257. while (!IsListEmpty(&pAdapterContext->QueueCommands)) {
  258. PLLC_PACKET pCommand;
  259. pCommand = LlcRemoveHeadList(&pAdapterContext->QueueCommands);
  260. RELEASE_SPIN_LOCK(&pAdapterContext->SendSpinLock);
  261. pCommand->pBinding->pfCommandComplete(pCommand->pBinding->hClientContext,
  262. pCommand->Data.Completion.hClientHandle,
  263. pCommand
  264. );
  265. ACQUIRE_SPIN_LOCK(&pAdapterContext->SendSpinLock);
  266. }
  267. //
  268. // indicate the queued events
  269. //
  270. while (!IsListEmpty(&pAdapterContext->QueueEvents)) {
  271. PEVENT_PACKET pEvent;
  272. pEvent = LlcRemoveHeadList(&pAdapterContext->QueueEvents);
  273. RELEASE_SPIN_LOCK(&pAdapterContext->SendSpinLock);
  274. pEvent->pBinding->pfEventIndication(pEvent->pBinding->hClientContext,
  275. pEvent->hClientHandle,
  276. pEvent->Event,
  277. pEvent->pEventInformation,
  278. pEvent->SecondaryInfo
  279. );
  280. ACQUIRE_SPIN_LOCK(&pAdapterContext->SendSpinLock);
  281. DEALLOCATE_PACKET_LLC_PKT(pAdapterContext->hPacketPool, pEvent);
  282. }
  283. pAdapterContext->BackgroundProcessRequests -= InitialRequestCount;
  284. } while (pAdapterContext->BackgroundProcessRequests > 0);
  285. }
  286. //
  287. // also execute the send task if the send queue is not empty
  288. //
  289. pAdapterContext->LlcPacketInSendQueue = FALSE;
  290. RunSendTaskAndUnlock(pAdapterContext);
  291. }
  292. //
  293. // Background process entry for those, that don't
  294. // want to play with SendSpinLock.
  295. // We will execute the DPC taks on DPC level (hLockHandle = NULL),
  296. // that's perfectly OK as far as the major send operations by
  297. // LlcSendI and LlcSendU lower the IRQL level while they are sending
  298. // (to allow the DPC processing when we doing a long string io or
  299. // memory move to a slow ISA adapter)
  300. //
  301. VOID
  302. BackgroundProcess(
  303. IN PADAPTER_CONTEXT pAdapterContext
  304. )
  305. {
  306. ACQUIRE_SPIN_LOCK(&pAdapterContext->SendSpinLock);
  307. BackgroundProcessAndUnlock(pAdapterContext);
  308. }
  309. VOID
  310. LlcNdisSendComplete(
  311. IN PADAPTER_CONTEXT pAdapterContext,
  312. IN PNDIS_PACKET pNdisPacket,
  313. IN NDIS_STATUS NdisStatus
  314. )
  315. /*++
  316. Routine Description:
  317. The routine handles NdisCompleteSend indication, it makes send
  318. completed indication to upper protocol drivers if necessary and
  319. executes the background process to find if there is any other
  320. frames in the send queue.
  321. This is usually called below the DPC level.
  322. Arguments:
  323. pAdapterContext - adapter context
  324. Return Value:
  325. None
  326. --*/
  327. {
  328. //
  329. // this function may be called from NDIS wrapper at DPC level or from
  330. // SendNdisPacket() at passive level
  331. //
  332. ASSUME_IRQL(ANY_IRQL);
  333. ACQUIRE_DRIVER_LOCK();
  334. CompleteSendAndLock(pAdapterContext,
  335. (PLLC_NDIS_PACKET)pNdisPacket,
  336. NdisStatus
  337. );
  338. //
  339. // Send command completion should not queue any command
  340. // completions or events. The send queue is the only possiblity.
  341. //
  342. if (!IsListEmpty(&pAdapterContext->NextSendTask)) {
  343. RunSendTaskAndUnlock(pAdapterContext);
  344. } else {
  345. RELEASE_SPIN_LOCK(&pAdapterContext->SendSpinLock);
  346. }
  347. RELEASE_DRIVER_LOCK();
  348. #ifdef NDIS40
  349. REFDEL(&pAdapterContext->AdapterRefCnt, 'dneS');
  350. #endif // NDIS40
  351. }
  352. PLLC_PACKET
  353. GetI_Packet(
  354. IN PADAPTER_CONTEXT pAdapterContext
  355. )
  356. /*++
  357. Routine Description:
  358. Function does:
  359. - selects the current link station in the queue and schedules
  360. (round robin) the queues for the next send
  361. - executes its send procedure
  362. - initializes the data link packet for the I frame
  363. Arguments:
  364. pAdapterContext - adapter context
  365. Return Value:
  366. PLLC_PACKET
  367. --*/
  368. {
  369. PDATA_LINK pLink;
  370. PLLC_PACKET pPacket;
  371. //
  372. // search the link (three LLC queues linked together!)
  373. //
  374. pLink = (((PLLC_QUEUE)pAdapterContext->QueueI.ListHead.Flink)->pObject);
  375. /*
  376. This is probably just wasting of CPU cycles. Remove the comments,
  377. if somebody has troubles because of this. Stop send process will
  378. reschedule the queues in any way.
  379. //
  380. // We have a round robin scheduling for all main queues (U, I
  381. // and expidited) and for all sending links within the I- queue.
  382. // Select the next main task and the next sending link, if
  383. // there is any. (Usually we have only one sending object)
  384. //
  385. ScheduleQueue(&pAdapterContext->NextSendTask);
  386. ScheduleQueue(&pAdapterContext->QueueI.ListHead);
  387. */
  388. //
  389. // A resent packet may still not be completed by NDIS,
  390. // a very, very bad things begin to happen, if we try
  391. // to send packet again before it has been completed
  392. // by NDIS (we may complete the same packet twice).
  393. // The flag indicates, that the send process should be
  394. // restarted.
  395. //
  396. if (((PLLC_PACKET)pLink->SendQueue.ListHead.Flink)->CompletionType & LLC_I_PACKET_PENDING_NDIS) {
  397. ((PLLC_PACKET)pLink->SendQueue.ListHead.Flink)->CompletionType |= LLC_I_PACKET_WAITING_NDIS;
  398. StopSendProcess(pAdapterContext, pLink);
  399. return NULL;
  400. }
  401. //
  402. // move the next element in the send list to the list of unacknowledged packets
  403. //
  404. pPacket = LlcRemoveHeadList(&pLink->SendQueue.ListHead);
  405. LlcInsertTailList(&pLink->SentQueue, pPacket);
  406. if (IsListEmpty(&pLink->SendQueue.ListHead)) {
  407. StopSendProcess(pAdapterContext, pLink);
  408. }
  409. //
  410. // Copy SSAP and DSAP, reset the default stuff.
  411. // Set the POLL bit if this is the last frame of the send window.
  412. //
  413. pPacket->Data.Xmit.LlcHeader.I.Dsap = pLink->Dsap;
  414. pPacket->Data.Xmit.LlcHeader.I.Ssap = pLink->Ssap;
  415. pPacket->Data.Xmit.LlcHeader.I.Ns = pLink->Vs;
  416. pPacket->Data.Xmit.LlcHeader.I.Nr = pLink->Vr;
  417. pPacket->CompletionType = LLC_I_PACKET;
  418. //
  419. // We should actually lock the link, but we cannot do it,
  420. // because it is against the spin lock rules: SendSpinLock has already
  421. // been acquired. But nothing terrible can happen: in the worst case
  422. // pLink->Ir_Ct update is lost and we send an extra ack. All Vs updates
  423. // are done behind SendSpinLock in any way and the timers are
  424. // protected by the timer spin lock.
  425. //
  426. pLink->Vs += 2; // modulo 128 increment for 7 highest bit
  427. // Update VsMax only if this is a new send.
  428. // .... pLink->VsMax = pLink->Vs;
  429. if( pLink->Va <= pLink->VsMax ){
  430. if( pLink->VsMax < pLink->Vs ){
  431. pLink->VsMax = pLink->Vs;
  432. }else if( pLink->Vs < pLink->Va ){
  433. pLink->VsMax = pLink->Vs;
  434. }else{
  435. // Don't change, we are resending.
  436. }
  437. }else{
  438. if( pLink->Va < pLink->Vs ){
  439. // Don't change, wrapping.
  440. }else if( pLink->VsMax < pLink->Vs ){
  441. pLink->VsMax = pLink->Vs;
  442. }else{
  443. // Don't change, we are resending.
  444. }
  445. }
  446. //
  447. // We are now sending the acknowledge, we can stop the ack timer
  448. // if it has been running. T1 timer must be started or reinitialized
  449. // and Ti must be stopped (as always when T1 is started).
  450. //
  451. if (pLink->T2.pNext != NULL) {
  452. StopTimer(&pLink->T2);
  453. }
  454. if (pLink->Ti.pNext != NULL) {
  455. StopTimer(&pLink->Ti);
  456. }
  457. //
  458. // Normally send an I- frame as Command-0 (without the poll bit),
  459. // but Command-Poll when the send window is full.
  460. // BUT! we cannot resend the packets with the poll bit (what?)
  461. //
  462. if (pLink->Vs == (UCHAR)(pLink->Va + pLink->Ww)) {
  463. //
  464. // The send process must be stopped until we have got
  465. // a response for this poll. THE SEND PROCESS MUST BE
  466. // STOPPED BEFORE SendSpinLock IS OPENED. Otherwise
  467. // simultaneous execution could send two polls, corrupt
  468. // the send queues, etc.
  469. //
  470. pLink->Flags |= DLC_SEND_DISABLED;
  471. StopSendProcess(pAdapterContext, pLink);
  472. //
  473. // IBM TR network architecture reference gives some hints how
  474. // to prevent the looping between check and sending states,
  475. // if link can send small S- frames, but not bigger data frames.
  476. // Unfortunately they do not provide any working solution.
  477. // They have described the problem on page 11-22 and in the
  478. // T1 expiration handler of all sending states (different T1
  479. // for sending and poll states in state machine). All Is_Ct stuff
  480. // in the state machine is garbage, because the link sets the
  481. // transmit window to 1 immediately after a failed xmit and enters
  482. // to a check state after every retransmit => T1 timeout happens
  483. // in the current check state, but P_Ct never expires, because
  484. // the other side sends always S acknowledge and link returns
  485. // to open state until the nexting retransmit (which action
  486. // resets the P_Ct counter).
  487. // I added this check to send process and the decrement of
  488. // Is_Ct counter to all SEND_I_POLL actions => The link times out,
  489. // when it cannot send I-frames even if S- exchange works.
  490. //
  491. if (pLink->Vp == pLink->Vs && pLink->Is_Ct == 0) {
  492. //
  493. // The same I- frame has been retransmitted too many times.
  494. // We must shut down this link. This happen now, when
  495. // we give T1 expired indication and and Is_Ct == 0.
  496. //
  497. RunStateMachineCommand(pLink, T1_Expired);
  498. //
  499. // We must (NDIS) complete the last packet now, because
  500. // the data link protocol may have already cancelled it.
  501. //
  502. pPacket->CompletionType &= ~LLC_I_PACKET_PENDING_NDIS;
  503. if (pPacket->CompletionType == LLC_I_PACKET_COMPLETE) {
  504. LlcInsertTailList(&pAdapterContext->QueueCommands, pPacket);
  505. }
  506. //
  507. // We must execute the background process from here,
  508. // because the background process is not called from
  509. // the send task
  510. //
  511. BackgroundProcessAndUnlock(pAdapterContext);
  512. ACQUIRE_SPIN_LOCK(&pAdapterContext->SendSpinLock);
  513. return NULL;
  514. } else {
  515. //
  516. // This is a Command-Poll, set the flag and the current
  517. // time stamp, whenever a new command poll was queued.
  518. //
  519. pLink->LastTimeWhenCmdPollWasSent = (USHORT)AbsoluteTime;
  520. pLink->Flags |= DLC_WAITING_RESPONSE_TO_POLL;
  521. pPacket->Data.Xmit.LlcHeader.I.Nr |= (UCHAR)LLC_I_S_POLL_FINAL;
  522. RunStateMachineCommand(pLink, SEND_I_POLL);
  523. }
  524. } else {
  525. pLink->Ir_Ct = pLink->N3;
  526. if (pLink->T1.pNext == NULL) {
  527. StartTimer(&pLink->T1);
  528. }
  529. }
  530. return pPacket;
  531. }
  532. VOID
  533. StartSendProcess(
  534. IN PADAPTER_CONTEXT pAdapterContext,
  535. IN PDATA_LINK pLink
  536. )
  537. /*++
  538. Routine Description:
  539. The routine starts the send process of a data link station.
  540. It links the data link send queue to the send
  541. queue of all link stations and again that queue
  542. to the main send queue.
  543. THE QUEUES MUST BE SPIN LOCKED WHEN THIS IS CALLED!
  544. Arguments:
  545. pAdapterContext - adapter context
  546. pLink -
  547. Return Value:
  548. None
  549. --*/
  550. {
  551. //
  552. // This procedure can be called when there is nothing to send,
  553. // or when the send process is already running or when
  554. // the link is not in a active state for send.
  555. //
  556. if (pLink->SendQueue.ListEntry.Flink == NULL
  557. && !(pLink->Flags & DLC_SEND_DISABLED)
  558. && !IsListEmpty(&pLink->SendQueue.ListHead)) {
  559. //
  560. // Link the queue to the active I send tasks of all links
  561. //
  562. LlcInsertTailList(&pAdapterContext->QueueI.ListHead,
  563. &pLink->SendQueue.ListEntry
  564. );
  565. //
  566. // Link first the queue of I send tasks to the generic main
  567. // send task queue, if it has not yet been linked
  568. //
  569. if (pAdapterContext->QueueI.ListEntry.Flink == NULL) {
  570. LlcInsertTailList(&pAdapterContext->NextSendTask,
  571. &pAdapterContext->QueueI.ListEntry
  572. );
  573. }
  574. }
  575. }
  576. //
  577. // Procedure is a space saving version of the send process enabling
  578. // for the state machine. It also reset any bits disabling the send.
  579. // CALL THIS ONLY FROM THE STATE MACHINE!!!!
  580. //
  581. VOID
  582. EnableSendProcess(
  583. IN PDATA_LINK pLink
  584. )
  585. {
  586. //
  587. // reset the disabled send state
  588. //
  589. pLink->Flags &= ~DLC_SEND_DISABLED;
  590. pLink->Gen.pAdapterContext->LlcPacketInSendQueue = TRUE;
  591. StartSendProcess(pLink->Gen.pAdapterContext, pLink);
  592. }
  593. VOID
  594. StopSendProcess(
  595. IN PADAPTER_CONTEXT pAdapterContext,
  596. IN PDATA_LINK pLink
  597. )
  598. /*++
  599. Routine Description:
  600. The routine stops the send process of a data link station.
  601. It unlinks the data link send queue from the send
  602. queue of all link stations and again that queue
  603. from the main send queue.
  604. THE QUEUES MUST BE SPIN LOCKED WHEN THIS IS CALLED!
  605. Arguments:
  606. pAdapterContext - adapter context
  607. pLink - data link object
  608. Return Value:
  609. None
  610. --*/
  611. {
  612. //
  613. // Do all this only if the send process is really running.
  614. // The NULL pointer marks a list element as a disconnected,
  615. // A non-empty I- queue of a link may be disconencted from
  616. // the link station send queue of the adapter, if the link is
  617. // not in a sending state. The same thing is true also on
  618. // the next level.
  619. //
  620. if (pLink->SendQueue.ListEntry.Flink != NULL) {
  621. //
  622. // unlink the queue from the active I send tasks of all links
  623. //
  624. LlcRemoveEntryList(&pLink->SendQueue.ListEntry);
  625. pLink->SendQueue.ListEntry.Flink = NULL;
  626. //
  627. // Unlink first the queue of all I send tasks from the
  628. // generic main send task queue, if it is now empty.
  629. //
  630. if (IsListEmpty(&pAdapterContext->QueueI.ListHead)) {
  631. LlcRemoveEntryList(&pAdapterContext->QueueI.ListEntry);
  632. pAdapterContext->QueueI.ListEntry.Flink = NULL;
  633. }
  634. }
  635. }
  636. //
  637. // Procedure is a space saving version of the send process disabling
  638. // for the state machine.
  639. //
  640. VOID
  641. DisableSendProcess(
  642. IN PDATA_LINK pLink
  643. )
  644. {
  645. //
  646. // set the send state variable disabled
  647. //
  648. pLink->Flags |= DLC_SEND_DISABLED;
  649. StopSendProcess(pLink->Gen.pAdapterContext, pLink);
  650. }
  651. PLLC_PACKET
  652. BuildDirOrU_Packet(
  653. IN PADAPTER_CONTEXT pAdapterContext
  654. )
  655. /*++
  656. Routine Description:
  657. Function selects the next packet from the queue of connectionless
  658. frames (U, TEST, XID, DIX and Direct),
  659. initilizes the LLC packet for the send.
  660. Arguments:
  661. pAdapterContext - adapter context
  662. Return Value:
  663. None
  664. --*/
  665. {
  666. PLLC_PACKET pPacket;
  667. //
  668. // Take next element, select the next send queue and
  669. // unlink the current queue, if this was the only packet left.
  670. //
  671. pPacket = LlcRemoveHeadList(&pAdapterContext->QueueDirAndU.ListHead);
  672. /*
  673. This is probably just wasting of CPU cycles. Remove the comments,
  674. if somebody has troubles because of this.
  675. ScheduleQueue(&pAdapterContext->NextSendTask);
  676. */
  677. if (IsListEmpty(&pAdapterContext->QueueDirAndU.ListHead)) {
  678. LlcRemoveEntryList(&pAdapterContext->QueueDirAndU.ListEntry);
  679. pAdapterContext->QueueDirAndU.ListEntry.Flink = NULL;
  680. }
  681. return pPacket;
  682. }
  683. DLC_STATUS
  684. SendLlcFrame(
  685. IN PDATA_LINK pLink,
  686. IN UCHAR LlcCommandId
  687. )
  688. /*++
  689. Routine Description:
  690. Function queues a Type 2 LLC S or U command frame.
  691. The LLC command code includes also the command/response and
  692. poll/final bits. That saves quite a lot space in the state machine,
  693. because this function is called from very many places.
  694. The code execution may also be faster because of this packing.
  695. Arguments:
  696. pLink - current data link station
  697. LlcCommand - Packed LLC command (bit 0 is the Poll-Final bit,
  698. bit 1 is the command/response and higher bits inlcude
  699. the enumerated LLC command code.
  700. Return Value:
  701. DLC_STATUS
  702. --*/
  703. {
  704. PLLC_PACKET pPacket;
  705. PADAPTER_CONTEXT pAdapterContext = pLink->Gen.pAdapterContext;
  706. ASSUME_IRQL(DISPATCH_LEVEL);
  707. pPacket = ALLOCATE_PACKET_LLC_PKT(pAdapterContext->hPacketPool);
  708. if (pPacket == NULL) {
  709. //
  710. // The non paged pool is empty, we must drop this
  711. // frame and hope that the protocol can recover (or disconnect)
  712. //
  713. return DLC_STATUS_NO_MEMORY;
  714. }
  715. pPacket->InformationLength = 0;
  716. pPacket->pBinding = NULL;
  717. //
  718. // Supervisory S commands (RR, RNR, REJ) consists 4 bytes and poll/final
  719. // bit is in a different place. The unnumbered U commands are only 3
  720. // bytes, but FRMR has some special data in the info field, that will be
  721. // added also to the 'extended LLC header'. We must reserve some
  722. // extra space for the FRMR data in the few NDIS packets!!!!!
  723. //
  724. if ((auchLlcCommands[LlcCommandId >> 2] & LLC_S_U_TYPE_MASK) == LLC_S_TYPE) {
  725. //
  726. // Build S frame
  727. //
  728. pPacket->Data.Xmit.LlcHeader.S.Command = auchLlcCommands[LlcCommandId >> 2];
  729. #if(0)
  730. if(pPacket->Data.Xmit.LlcHeader.S.Command == LLC_REJ)
  731. {
  732. DbgPrint("SendLlcFrame: REJ\n");
  733. }
  734. #endif
  735. pPacket->Data.Xmit.pLlcObject = (PLLC_OBJECT)pLink;
  736. pPacket->Data.Xmit.pLanHeader = pLink->auchLanHeader;
  737. pPacket->Data.Xmit.LlcHeader.S.Dsap = pLink->Dsap;
  738. pPacket->Data.Xmit.LlcHeader.S.Ssap = pLink->Ssap;
  739. pPacket->CompletionType = LLC_I_PACKET_UNACKNOWLEDGED;
  740. pPacket->cbLlcHeader = sizeof(LLC_S_HEADER); // 4
  741. pPacket->Data.Xmit.LlcHeader.S.Nr = pLink->Vr | (LlcCommandId & (UCHAR)LLC_I_S_POLL_FINAL);
  742. //
  743. // Second bit is the LLC command flag, set it to the source SAP
  744. //
  745. if (!(LlcCommandId & 2)) {
  746. pPacket->Data.Xmit.LlcHeader.S.Ssap |= LLC_SSAP_RESPONSE;
  747. //
  748. // We must have only one final response in LLC or NDIS
  749. // send queues in any time. Thus we just discard any further
  750. // final responses until the previous one is sent.
  751. // This is a partial solution to the problem, when the
  752. // the Elnkii send queue is totally hung because of overflowing
  753. // packets.
  754. //
  755. if ((LlcCommandId & (UCHAR)LLC_I_S_POLL_FINAL)) {
  756. // >>> SNA bug #9517 (NT bug #12907)
  757. #if(0)
  758. if (pLink->Flags & DLC_FINAL_RESPONSE_PENDING_IN_NDIS) {
  759. DEALLOCATE_PACKET_LLC_PKT(pAdapterContext->hPacketPool, pPacket);
  760. return STATUS_SUCCESS;
  761. }
  762. #endif
  763. // Changed the if statment to ignore the Poll only if the link
  764. // speed is 10MB (the unit of link speed measurement is 100 bps).
  765. //
  766. // Ignoring the Poll kills the DLC performance on 100MB ethernet
  767. // (particularly on MP machines). The other end must time out (T1 timer)
  768. // before it can send more data if we ignore the Poll here.
  769. if ((pLink->Flags & DLC_FINAL_RESPONSE_PENDING_IN_NDIS) &&
  770. pAdapterContext->LinkSpeed <= 100000) {
  771. DEALLOCATE_PACKET_LLC_PKT(pAdapterContext->hPacketPool, pPacket);
  772. return STATUS_SUCCESS;
  773. }
  774. // >>> SNA bug #9517
  775. pLink->Flags |= DLC_FINAL_RESPONSE_PENDING_IN_NDIS;
  776. }
  777. } else if (LlcCommandId & (UCHAR)LLC_I_S_POLL_FINAL) {
  778. //
  779. // This is a Command-Poll, set the flag and the current
  780. // time stamp, whenever a new command poll was queued
  781. //
  782. pLink->LastTimeWhenCmdPollWasSent = (USHORT)AbsoluteTime;
  783. pLink->Flags |= DLC_WAITING_RESPONSE_TO_POLL;
  784. }
  785. //
  786. // The last sent command/response is included in the DLC statistics
  787. //
  788. pLink->LastCmdOrRespSent = pPacket->Data.Xmit.LlcHeader.S.Command;
  789. } else {
  790. pPacket->Data.XmitU.Command = auchLlcCommands[LlcCommandId >> 2];
  791. pPacket->Data.XmitU.Dsap = pLink->Dsap;
  792. pPacket->Data.XmitU.Ssap = pLink->Ssap;
  793. //
  794. // Second bit is the LLC command flag, set it to the source SAP
  795. //
  796. if (!(LlcCommandId & 2)) {
  797. pPacket->Data.XmitU.Ssap |= LLC_SSAP_RESPONSE;
  798. }
  799. //
  800. // Build a U command frame (FRMR has some data!!!)
  801. //
  802. pPacket->cbLlcHeader = sizeof(LLC_U_HEADER); // 3
  803. if (pPacket->Data.XmitU.Command == LLC_FRMR) {
  804. pPacket->cbLlcHeader += sizeof(LLC_FRMR_INFORMATION);
  805. pPacket->Data.Response.Info.Frmr = pLink->DlcStatus.FrmrData;
  806. }
  807. if (LlcCommandId & 1) {
  808. pPacket->Data.XmitU.Command |= LLC_U_POLL_FINAL;
  809. }
  810. //
  811. // U- commands (eg. UA response for DISC) may be sent after
  812. // the link object has been deleted. This invalidates
  813. // the lan header pointer => we must change all U- commands
  814. // to response types. Null object handle prevents the
  815. // the close process to cancel the packet, when the
  816. // station is closed.
  817. //
  818. //
  819. // RLF 05/09/94
  820. //
  821. // If the framing type stored in the link structure is unspecified then
  822. // either this is an AUTO configured binding and we haven't worked out
  823. // the type of framing to use, or this is not an AUTO configured binding.
  824. // In this case, defer to the address translation stored in the binding.
  825. // If the framing type is known, use it
  826. //
  827. if (pLink->FramingType == LLC_SEND_UNSPECIFIED) {
  828. pPacket->Data.XmitU.TranslationType = (UCHAR)pLink->Gen.pLlcBinding->InternalAddressTranslation;
  829. } else {
  830. pPacket->Data.XmitU.TranslationType = (UCHAR)pLink->FramingType;
  831. }
  832. pPacket->CompletionType = LLC_U_COMMAND_RESPONSE;
  833. pPacket->Data.XmitU.pLanHeader = (PUCHAR)ALLOCATE_PACKET_LLC_PKT(pAdapterContext->hPacketPool);
  834. if (pPacket->Data.XmitU.pLanHeader == NULL) {
  835. DEALLOCATE_PACKET_LLC_PKT(pAdapterContext->hPacketPool, pPacket);
  836. return DLC_STATUS_NO_MEMORY;
  837. }
  838. LlcMemCpy(pPacket->Data.XmitU.pLanHeader,
  839. pLink->auchLanHeader,
  840. pLink->cbLanHeaderLength
  841. );
  842. //
  843. // In the AUTO mode in ethernet we duplicate all
  844. // TEST, XID and SABME packets and send them both in
  845. // 802.3 and DIX formats.
  846. //
  847. //
  848. // RLF 05/09/94
  849. //
  850. // Similarly, we duplicate DISC frames (since right now we don't
  851. // keep per-destination frame state information)
  852. //
  853. if (((pPacket->Data.XmitU.Command & ~LLC_U_POLL_FINAL) == LLC_SABME)
  854. // || ((pPacket->Data.XmitU.Command & ~LLC_U_POLL_FINAL) == LLC_DISC)
  855. ) {
  856. CheckAndDuplicatePacket(
  857. #if DBG
  858. pAdapterContext,
  859. #endif
  860. pLink->Gen.pLlcBinding,
  861. pPacket,
  862. &pAdapterContext->QueueExpidited
  863. );
  864. }
  865. //
  866. // The last sent command/response is included in the DLC statistics
  867. //
  868. pLink->LastCmdOrRespSent = pPacket->Data.XmitU.Command;
  869. }
  870. LlcInsertTailList(&pAdapterContext->QueueExpidited.ListHead, pPacket);
  871. //
  872. // The S- frames must be sent immediately before any I- frames,
  873. // because otherwise the sequential frames may have NRs in a
  874. // wrong order => FRMR (that's why we insert the expidited
  875. // queue to the head instead of the tail.
  876. //
  877. pAdapterContext->LlcPacketInSendQueue = TRUE;
  878. if (pAdapterContext->QueueExpidited.ListEntry.Flink == NULL) {
  879. LlcInsertHeadList(&pAdapterContext->NextSendTask,
  880. &pAdapterContext->QueueExpidited.ListEntry
  881. );
  882. }
  883. return STATUS_SUCCESS;
  884. }
  885. PLLC_PACKET
  886. GetLlcCommandPacket(
  887. IN PADAPTER_CONTEXT pAdapterContext
  888. )
  889. /*++
  890. Routine Description:
  891. Function selects the next LLC command from the expidited queue.
  892. Arguments:
  893. pAdapterContext - adapter context
  894. Return Value:
  895. PLLC_PACKET
  896. --*/
  897. {
  898. PLLC_PACKET pPacket;
  899. //
  900. // Unlink the current task, if this was the only one left.
  901. // We will send the expidited packets as far as there is any
  902. //
  903. pPacket = LlcRemoveHeadList(&pAdapterContext->QueueExpidited.ListHead);
  904. if (pPacket->CompletionType == LLC_I_PACKET_UNACKNOWLEDGED) {
  905. pPacket->CompletionType = LLC_I_PACKET;
  906. }
  907. if (IsListEmpty(&pAdapterContext->QueueExpidited.ListHead)) {
  908. LlcRemoveEntryList(&pAdapterContext->QueueExpidited.ListEntry);
  909. pAdapterContext->QueueExpidited.ListEntry.Flink = NULL;
  910. }
  911. return pPacket;
  912. }
  913. VOID
  914. SendNdisPacket(
  915. IN PADAPTER_CONTEXT pAdapterContext,
  916. IN PLLC_PACKET pPacket
  917. )
  918. /*++
  919. Routine Description:
  920. Function builds NDIS packet. LAN and LLC headers can be
  921. given separately to this routine. All NDIS packets
  922. include a fixed MDL descriptor and buffer for the headers.
  923. The actual data is linked after that header.
  924. I would say, that this is a clever algorithm,
  925. in this way we avoid quite well the supid NDIS packet management.
  926. We have just a few (5) NDIS packets for each adapter.
  927. The direct frames includes only the LAN header and MDL pointer are
  928. linked directly to the packet
  929. Steps:
  930. 1. Reset the NDIS packet
  931. 2. Get the frame translation type and initialize the completion
  932. packet.
  933. 3. Build the LAN header into a small buffer in NDIS packet.
  934. 4. Copy optional LLC header behind it
  935. 5. Initialize NDIS packet for the send
  936. 6. Send the packet
  937. 7. if command not pending
  938. - Complete the packet (if there was a non-null request handle)
  939. - Link the NDIS packet back to the send queue.
  940. Arguments:
  941. pAdapterContext - NDIS adapter context
  942. pPacket - generic LLC transmit packet used for all transmit types
  943. Return Value:
  944. NDIS_STATUS (status of NdisSend)
  945. --*/
  946. {
  947. UCHAR LlcOffset;
  948. PLLC_NDIS_PACKET pNdisPacket;
  949. NDIS_STATUS Status = NDIS_STATUS_FAILURE;
  950. ASSUME_IRQL(DISPATCH_LEVEL);
  951. //
  952. // Sometimes we must discard I-frame in GetI_Packet routine and
  953. // return a NULL packet
  954. //
  955. if (pPacket == NULL) {
  956. return;
  957. }
  958. //
  959. // Allocate an NDIS packet from the pool and reset the private NDIS header!
  960. //
  961. pNdisPacket = PopFromList((PLLC_PACKET)pAdapterContext->pNdisPacketPool);
  962. ResetNdisPacket(pNdisPacket);
  963. //
  964. // The internal LAN headers always have the correct address format. Only
  965. // Dir and Type 1 LAN headers need to be swapped, because they are owned
  966. // by users. The internal address swapping is defined by binding basis
  967. // because some transports may want to use DIX\DLC Saps, and others just
  968. // the normal 802.3 DLC
  969. //
  970. if (pPacket->CompletionType == LLC_I_PACKET) {
  971. pNdisPacket->pMdl->Next = pPacket->Data.Xmit.pMdl;
  972. ReferenceObject(pPacket->Data.Xmit.pLlcObject);
  973. //
  974. // Type 2 packets use always the LAN header of the link station
  975. //
  976. LlcMemCpy(pNdisPacket->auchLanHeader,
  977. pPacket->Data.Xmit.pLanHeader,
  978. LlcOffset = pPacket->Data.Xmit.pLlcObject->Link.cbLanHeaderLength
  979. );
  980. //
  981. // Copy the LLC header as it is, the case set its offset
  982. //
  983. LlcMemCpy(&pNdisPacket->auchLanHeader[LlcOffset],
  984. &pPacket->Data.Xmit.LlcHeader,
  985. 4
  986. );
  987. } else {
  988. //
  989. // We must increment the reference counter of an LLC object, when
  990. // we give its pointer to NDIS queue (and increment it, when the
  991. // command is complete)
  992. //-------
  993. // We need two references for each transmit, First caller (DLC module)
  994. // must reference and dereference the object to keep it alive over
  995. // the synchronous code path here we do it second time to keep the
  996. // object alive, when it has pointers queued on NDIS
  997. //
  998. if (pPacket->CompletionType > LLC_MAX_RESPONSE_PACKET) {
  999. pNdisPacket->pMdl->Next = pPacket->Data.Xmit.pMdl;
  1000. ReferenceObject(pPacket->Data.Xmit.pLlcObject);
  1001. } else if (pPacket->CompletionType > LLC_MIN_MDL_PACKET) {
  1002. pNdisPacket->pMdl->Next = pPacket->Data.Xmit.pMdl;
  1003. } else {
  1004. pNdisPacket->pMdl->Next = NULL;
  1005. }
  1006. //
  1007. // LLC_TYPE_1 packets have non-null binding, the internally
  1008. // sent packets (ie. XID and TEST frames) use the current
  1009. // internal default format (tr, ethernet or dix)
  1010. //
  1011. LlcOffset = CopyLanHeader(pPacket->Data.XmitU.TranslationType,
  1012. pPacket->Data.XmitU.pLanHeader,
  1013. pAdapterContext->NodeAddress,
  1014. pNdisPacket->auchLanHeader,
  1015. pAdapterContext->ConfigInfo.SwapAddressBits
  1016. );
  1017. LlcMemCpy(&pNdisPacket->auchLanHeader[LlcOffset],
  1018. &pPacket->Data.XmitU.Dsap,
  1019. pPacket->cbLlcHeader
  1020. );
  1021. }
  1022. pNdisPacket->pCompletionPacket = pPacket;
  1023. MmGetMdlByteCount(pNdisPacket->pMdl) = LlcOffset + pPacket->cbLlcHeader;
  1024. //
  1025. // We must set the lenth field of all 802.2 or DIX DLC Ethernet frames,
  1026. // BUT NOT FOR DIX ethernet types having 2 bytes long 'LLC header'
  1027. //
  1028. if ((pAdapterContext->NdisMedium == NdisMedium802_3) && (pPacket->cbLlcHeader != 2)) {
  1029. UINT InformationLength;
  1030. InformationLength = pPacket->cbLlcHeader + pPacket->InformationLength;
  1031. //
  1032. // The possible offets are 12 and 14 and LLC offsets are 14 and 17
  1033. //
  1034. pNdisPacket->auchLanHeader[(LlcOffset & 0xfe) - 2] = (UCHAR)(InformationLength >> 8);
  1035. pNdisPacket->auchLanHeader[(LlcOffset & 0xfe) - 1] = (UCHAR)InformationLength;
  1036. }
  1037. RELEASE_SPIN_LOCK(&pAdapterContext->SendSpinLock);
  1038. RELEASE_DRIVER_LOCK();
  1039. NdisChainBufferAtFront((PNDIS_PACKET)pNdisPacket, pNdisPacket->pMdl);
  1040. #if LLC_DBG
  1041. if (pNdisPacket->ReferenceCount != 0) {
  1042. DbgBreakPoint();
  1043. }
  1044. pNdisPacket->ReferenceCount++;
  1045. #endif
  1046. #ifdef LLC_LOSE_I_PACKETS
  1047. //
  1048. // This code tests the error recoverability of the LLC protocol.
  1049. // We randomly delete packets to check how the protocol recovers.
  1050. // We use current timer tick, running static and a table of random
  1051. // numbers.
  1052. //
  1053. if (pPacket->CompletionType == LLC_I_PACKET) {
  1054. static UINT i = 0;
  1055. //
  1056. // 2 % is high enough. With 20 percent its takes forever to
  1057. // send the data. We send all discarded packets to Richard =>
  1058. // we can see in the net which one packets were lost.
  1059. //
  1060. i++;
  1061. if (aRandom[(i % 1000)] <= (USHORT)DBG_ERROR_PERCENT(2)) {
  1062. if (pAdapterContext->NdisMedium == NdisMedium802_3) {
  1063. memcpy(pNdisPacket->auchLanHeader,
  1064. "\0FIRTH",
  1065. 6
  1066. );
  1067. } else {
  1068. memcpy(&pNdisPacket->auchLanHeader[2],
  1069. "\0FIRTH",
  1070. 6
  1071. );
  1072. }
  1073. }
  1074. }
  1075. #endif
  1076. #ifdef NDIS40
  1077. REFADD(&pAdapterContext->AdapterRefCnt, 'dneS');
  1078. if (InterlockedCompareExchange(
  1079. &pAdapterContext->BindState,
  1080. BIND_STATE_BOUND,
  1081. BIND_STATE_BOUND) == BIND_STATE_BOUND)
  1082. {
  1083. NdisSend(&Status,
  1084. pAdapterContext->NdisBindingHandle,
  1085. (PNDIS_PACKET)pNdisPacket
  1086. );
  1087. }
  1088. // Above reference is removed by LlcNdisSendComplete handler.
  1089. #endif // NDIS40
  1090. //
  1091. // Ndis may return a synchronous status!
  1092. //
  1093. if (Status != NDIS_STATUS_PENDING) {
  1094. LlcNdisSendComplete(pAdapterContext,
  1095. (PNDIS_PACKET)pNdisPacket,
  1096. Status
  1097. );
  1098. }
  1099. ACQUIRE_DRIVER_LOCK();
  1100. ACQUIRE_SPIN_LOCK(&pAdapterContext->SendSpinLock);
  1101. }
  1102. VOID
  1103. CompleteSendAndLock(
  1104. IN PADAPTER_CONTEXT pAdapterContext,
  1105. IN PLLC_NDIS_PACKET pNdisPacket,
  1106. IN NDIS_STATUS NdisStatus
  1107. )
  1108. /*++
  1109. Routine Description:
  1110. The routines completes the connectionless packets and also the
  1111. I-frames if they have already acknowledged by the other side.
  1112. We will leave the send spinlock locked.
  1113. Arguments:
  1114. pAdapterContext - current adapter context
  1115. pNdisPacket - the NDIS packet used in teh send.
  1116. NdisStatus - the status of the send operation
  1117. Return Value:
  1118. None
  1119. --*/
  1120. {
  1121. PLLC_PACKET pPacket;
  1122. PLLC_OBJECT pLlcObject;
  1123. UCHAR CompletionType;
  1124. ASSUME_IRQL(DISPATCH_LEVEL);
  1125. DLC_TRACE( 'A' );
  1126. //
  1127. // Only the connectionless packets issued by user needs
  1128. // a command completion. I- frames are indicated when they
  1129. // are acknowledged by the remote link station.
  1130. //
  1131. pPacket = pNdisPacket->pCompletionPacket;
  1132. pLlcObject = pPacket->Data.Xmit.pLlcObject;
  1133. if ((CompletionType = pPacket->CompletionType) == LLC_TYPE_1_PACKET) {
  1134. DLC_TRACE( 'j' );
  1135. pPacket->Data.Completion.Status = NdisStatus;
  1136. pPacket->Data.Completion.CompletedCommand = LLC_SEND_COMPLETION;
  1137. pPacket->pBinding->pfCommandComplete(pPacket->pBinding->hClientContext,
  1138. pLlcObject->Gen.hClientHandle,
  1139. pPacket
  1140. );
  1141. }
  1142. //
  1143. // !!! DON'T TOUCH PACKET AFTER THE PREVIOUS PROCEDURE CALL
  1144. // (unless the packet type is different from Type 1)
  1145. //
  1146. ACQUIRE_SPIN_LOCK(&pAdapterContext->SendSpinLock);
  1147. #if LLC_DBG
  1148. pNdisPacket->ReferenceCount--;
  1149. if (pNdisPacket->ReferenceCount != 0) {
  1150. DbgBreakPoint();
  1151. }
  1152. #endif
  1153. PushToList((PLLC_PACKET)pAdapterContext->pNdisPacketPool, (PLLC_PACKET)pNdisPacket);
  1154. //
  1155. // We first complete the internal packets of the data link driver,
  1156. // that has no connection to the link objects.
  1157. //
  1158. if (CompletionType <= LLC_MAX_RESPONSE_PACKET) {
  1159. DLC_TRACE('l');
  1160. //
  1161. // XID and U- command reponses have allocated two packets.
  1162. // TEST reponses have allocated a non paged pool buffer
  1163. // and MDL for the echones frame (it might have been 17 kB)
  1164. //
  1165. switch(CompletionType) {
  1166. case LLC_XID_RESPONSE:
  1167. pAdapterContext->XidTestResponses--;
  1168. #if LLC_DBG
  1169. ((PLLC_PACKET)pPacket->Data.Response.pLanHeader)->pNext = NULL;
  1170. #endif
  1171. DEALLOCATE_PACKET_LLC_PKT(pAdapterContext->hPacketPool, pPacket->Data.Response.pLanHeader);
  1172. break;
  1173. case LLC_U_COMMAND_RESPONSE:
  1174. #if LLC_DBG
  1175. //
  1176. // Break immediately, when we have sent a FRMR packet
  1177. //
  1178. if (pPacket->Data.Xmit.LlcHeader.U.Command == LLC_FRMR) {
  1179. DbgBreakPoint();
  1180. }
  1181. ((PLLC_PACKET)pPacket->Data.Response.pLanHeader)->pNext = NULL;
  1182. #endif
  1183. DEALLOCATE_PACKET_LLC_PKT(pAdapterContext->hPacketPool, pPacket->Data.Response.pLanHeader);
  1184. break;
  1185. case LLC_TEST_RESPONSE:
  1186. pAdapterContext->XidTestResponses--;
  1187. //
  1188. // RLF 03/30/93
  1189. //
  1190. // The TEST response packet may have had 0 information field length,
  1191. // in which case the MDL will be NULL
  1192. //
  1193. if (pPacket->Data.Response.Info.Test.pMdl) {
  1194. IoFreeMdl(pPacket->Data.Response.Info.Test.pMdl);
  1195. }
  1196. FREE_MEMORY_ADAPTER(pPacket->Data.Response.pLanHeader);
  1197. break;
  1198. #if LLC_DBG
  1199. case LLC_DIX_DUPLICATE:
  1200. break;
  1201. default:
  1202. LlcInvalidObjectType();
  1203. break;
  1204. #endif
  1205. }
  1206. DEALLOCATE_PACKET_LLC_PKT(pAdapterContext->hPacketPool, pPacket);
  1207. } else {
  1208. //
  1209. // We use extra status bits to indicate, when I- packet has been both
  1210. // completed by NDIS and acknowledged by the other side of link
  1211. // connection. An I packet can be queued to the completion queue by
  1212. // the second quy (either state machine or SendCompletion handler)
  1213. // only when the first guy has completed its work.
  1214. // An I packet could be acknowledged by the other side before
  1215. // its completion is indicated by NDIS. Dlc Driver deallocates
  1216. // the packet immediately, when Llc driver completes the acknowledged
  1217. // packet => possible data corruption (if packet is reused before
  1218. // NDIS has completed it). This is probably not possible in a
  1219. // single processor NT- system, but very possible in multiprocessor
  1220. // NT or systems without a single level DPC queue (like OS/2 and DOS).
  1221. //
  1222. if (CompletionType != LLC_TYPE_1_PACKET) {
  1223. DLC_TRACE( 'k' );
  1224. //
  1225. // All packets allocated for S-type frames have null
  1226. // binding context. All the rest of packets must
  1227. // be I- completions.
  1228. //
  1229. if (pPacket->pBinding == NULL) {
  1230. //
  1231. // We cannot send a new final response before
  1232. // the previous one has been complete by NDIS.
  1233. //
  1234. if ((pPacket->Data.Xmit.LlcHeader.S.Nr & LLC_I_S_POLL_FINAL)
  1235. && (pPacket->Data.Xmit.LlcHeader.S.Ssap & LLC_SSAP_RESPONSE)) {
  1236. pLlcObject->Link.Flags &= ~DLC_FINAL_RESPONSE_PENDING_IN_NDIS;
  1237. }
  1238. DEALLOCATE_PACKET_LLC_PKT(pAdapterContext->hPacketPool, pPacket);
  1239. } else {
  1240. pPacket->CompletionType &= ~LLC_I_PACKET_PENDING_NDIS;
  1241. //
  1242. // A packet cannot be resent before the previous send
  1243. // has been completed by NDIS. We have simply stopped
  1244. // the send process until the NDIS is completed here.
  1245. //
  1246. if (pPacket->CompletionType & LLC_I_PACKET_WAITING_NDIS) {
  1247. pPacket->CompletionType &= ~LLC_I_PACKET_WAITING_NDIS;
  1248. StartSendProcess(pAdapterContext, (PDATA_LINK)pLlcObject);
  1249. } else if (pPacket->CompletionType == LLC_I_PACKET_COMPLETE) {
  1250. //
  1251. // We don't care at all about the result of the
  1252. // NDIS send operation with the I-frames.
  1253. // If the other side has acknowledged the packet,
  1254. // it is OK. In that case we had to wait the send
  1255. // to complete, because an too early ack and
  1256. // command completion would have invalidated
  1257. // the pointer on NDIS.
  1258. //
  1259. LlcInsertTailList(&pAdapterContext->QueueCommands, pPacket);
  1260. BackgroundProcessWithinLock(pAdapterContext);
  1261. }
  1262. }
  1263. }
  1264. //
  1265. // Pending close commands of LLC object must wait until all its
  1266. // NDIS send commands have been completed.
  1267. // We must also indicate the completed send command.
  1268. // The same must be true, when we are cancelling transmit commands.
  1269. // The system crashes, if we remove a transmit command, that is
  1270. // not yet sent or it is just being sent by NDIS.
  1271. // => Dereference LlcObject when the ndis packet is complete,
  1272. // We must run the background process
  1273. //
  1274. pLlcObject->Gen.ReferenceCount--;
  1275. if (pLlcObject->Gen.ReferenceCount == 0) {
  1276. CompletePendingLlcCommand(pLlcObject);
  1277. BackgroundProcessWithinLock(pAdapterContext);
  1278. }
  1279. DLC_TRACE((UCHAR)pLlcObject->Gen.ReferenceCount);
  1280. }
  1281. }
  1282. VOID
  1283. RespondTestOrXid(
  1284. IN PADAPTER_CONTEXT pAdapterContext,
  1285. IN NDIS_HANDLE MacReceiveContext,
  1286. IN LLC_HEADER LlcHeader,
  1287. IN UINT SourceSap
  1288. )
  1289. /*++
  1290. Routine Description:
  1291. Function builds a response packet for the XID or TEST frame.
  1292. All TEST Commands are echoed directy back as responses.
  1293. 802.2 XID header is the only supported XID command type.
  1294. Arguments:
  1295. pAdapterContext - current adapter context
  1296. MacReceiveContext - For NdisTransferData
  1297. LlcHeader - The received LLC header
  1298. SourceSap - current source SAP
  1299. Return Value:
  1300. None
  1301. --*/
  1302. {
  1303. PLLC_PACKET pPacket = NULL;
  1304. USHORT InfoFieldLength;
  1305. UINT BytesCopied;
  1306. NDIS_STATUS Status;
  1307. PMDL pTestMdl = NULL;
  1308. PUCHAR pBuffer = NULL;
  1309. ASSUME_IRQL(DISPATCH_LEVEL);
  1310. //
  1311. // Respond to a 802.2 XIDs and TESTs, and discard everything else
  1312. // Echo the TEST commands back with the same information field
  1313. // (but that's limited by our buffer capasity).
  1314. //
  1315. if ((LlcHeader.U.Command & ~LLC_U_POLL_FINAL) == LLC_TEST) {
  1316. //
  1317. // Echo the TEST frames back to the sender, but only, we do:
  1318. // 1. Allocate a buffer from the non-paged pool
  1319. // 2. Allocate a MDL for it
  1320. // 3. Transfer the data
  1321. //
  1322. if (pAdapterContext->cbPacketSize < (pAdapterContext->RcvLanHeaderLength + sizeof(LLC_U_HEADER)) ) {
  1323. return;
  1324. }
  1325. InfoFieldLength = (USHORT)(pAdapterContext->cbPacketSize
  1326. - (pAdapterContext->RcvLanHeaderLength
  1327. + sizeof(LLC_U_HEADER)));
  1328. pBuffer = ALLOCATE_ZEROMEMORY_ADAPTER(pAdapterContext->cbPacketSize);
  1329. if (pBuffer == NULL) {
  1330. return;
  1331. }
  1332. //
  1333. // RLF 03/30/93
  1334. //
  1335. // There may be no data in the info field to transfer. In this case
  1336. // don't allocate a MDL
  1337. //
  1338. if (InfoFieldLength) {
  1339. pTestMdl = IoAllocateMdl(pBuffer
  1340. + pAdapterContext->RcvLanHeaderLength
  1341. + sizeof(LLC_U_HEADER),
  1342. InfoFieldLength,
  1343. FALSE,
  1344. FALSE,
  1345. NULL
  1346. );
  1347. if (pTestMdl == NULL) {
  1348. goto ProcedureErrorExit;
  1349. }
  1350. MmBuildMdlForNonPagedPool(pTestMdl);
  1351. //
  1352. // Copy the TEST data from NDIS to our buffer
  1353. //
  1354. ResetNdisPacket(&pAdapterContext->TransferDataPacket);
  1355. RELEASE_DRIVER_LOCK();
  1356. NdisChainBufferAtFront((PNDIS_PACKET)&pAdapterContext->TransferDataPacket, pTestMdl);
  1357. //
  1358. // ADAMBA - Removed pAdapterContext->RcvLanHeaderLength
  1359. // from ByteOffset (the fourth param).
  1360. //
  1361. NdisTransferData(&Status,
  1362. pAdapterContext->NdisBindingHandle,
  1363. MacReceiveContext,
  1364. sizeof(LLC_U_HEADER)
  1365. //
  1366. // RLF 05/09/94
  1367. //
  1368. // if we have received a DIX packet then the data
  1369. // starts 3 bytes from where NDIS thinks the start
  1370. // of non-header data is
  1371. //
  1372. // ASSUME: Only DIX frames have header length of
  1373. // 17 (i.e. on Ethernet)
  1374. //
  1375. // What about FDDI?
  1376. //
  1377. + ((pAdapterContext->RcvLanHeaderLength == 17) ? 3 : 0),
  1378. InfoFieldLength,
  1379. (PNDIS_PACKET)&pAdapterContext->TransferDataPacket,
  1380. &BytesCopied
  1381. );
  1382. ACQUIRE_DRIVER_LOCK();
  1383. //
  1384. // We don't care if the transfer data is still pending,
  1385. // If very, very unlikely, that the received dma would
  1386. // write the data later, than a new transmit command
  1387. // would read the same data. BUT we cannot continue,
  1388. // if transfer data failed.
  1389. //
  1390. if ((Status != STATUS_SUCCESS) && (Status != STATUS_PENDING)) {
  1391. goto ProcedureErrorExit;
  1392. }
  1393. }
  1394. } else if (((LlcHeader.U.Command & ~LLC_U_POLL_FINAL) != LLC_XID)
  1395. || (LlcHeader.auchRawBytes[3] != IEEE_802_XID_ID)) {
  1396. //
  1397. // This was not a IEEE 802.2 XID !!!
  1398. //
  1399. return;
  1400. }
  1401. //
  1402. // We have only a limited number reponse packets available
  1403. // for the XID and TEST responses. Thus we will
  1404. // drop many packets in a broadcast storms created by token-ring
  1405. // source routing bridges, that is
  1406. // actually a good thing. On the other hand we may
  1407. // also loose some packets that should have been reponsed,
  1408. // but who cares (this is a connectionless thing).
  1409. // (This is probably wasted effort, XID and TEST frames are not
  1410. // usually sent with the broadcast bit set).
  1411. //
  1412. ACQUIRE_SPIN_LOCK(&pAdapterContext->SendSpinLock);
  1413. if ((pAdapterContext->XidTestResponses < MAX_XID_TEST_RESPONSES)
  1414. && ((pPacket = (PLLC_PACKET)ALLOCATE_PACKET_LLC_PKT(pAdapterContext->hPacketPool)) != NULL)) {
  1415. if ((LlcHeader.U.Command & ~LLC_U_POLL_FINAL) == LLC_XID) {
  1416. pPacket->Data.Xmit.pLanHeader = (PUCHAR)ALLOCATE_PACKET_LLC_PKT(pAdapterContext->hPacketPool);
  1417. if (pPacket->Data.Xmit.pLanHeader == NULL) {
  1418. DEALLOCATE_PACKET_LLC_PKT(pAdapterContext->hPacketPool, pPacket);
  1419. pPacket = NULL;
  1420. goto LockedErrorExit;
  1421. } else {
  1422. LlcMemCpy(&pPacket->Data.Response.Info,
  1423. &Ieee802Xid,
  1424. sizeof(Ieee802Xid)
  1425. );
  1426. pPacket->InformationLength = 0;
  1427. pPacket->cbLlcHeader = sizeof(Ieee802Xid) + sizeof(LLC_U_HEADER);
  1428. pPacket->CompletionType = LLC_XID_RESPONSE;
  1429. }
  1430. } else {
  1431. pPacket->Data.Xmit.pLanHeader = pBuffer;
  1432. pPacket->cbLlcHeader = sizeof(LLC_U_HEADER);
  1433. pPacket->CompletionType = LLC_TEST_RESPONSE;
  1434. pPacket->Data.Response.Info.Test.pMdl = pTestMdl;
  1435. pPacket->InformationLength = InfoFieldLength;
  1436. }
  1437. pAdapterContext->XidTestResponses++;
  1438. //
  1439. // The packet initialization is the same for XID and TEST
  1440. //
  1441. pPacket->Data.XmitU.Dsap = (UCHAR)(LlcHeader.U.Ssap & ~LLC_SSAP_RESPONSE);
  1442. pPacket->Data.XmitU.Ssap = (UCHAR)(SourceSap | LLC_SSAP_RESPONSE);
  1443. pPacket->Data.XmitU.Command = LlcHeader.U.Command;
  1444. if (pAdapterContext->NdisMedium == NdisMedium802_5) {
  1445. pPacket->Data.Response.TranslationType = LLC_SEND_802_5_TO_802_5;
  1446. } else if (pAdapterContext->NdisMedium == NdisMediumFddi) {
  1447. pPacket->Data.Response.TranslationType = LLC_SEND_FDDI_TO_FDDI;
  1448. } else if (pAdapterContext->RcvLanHeaderLength == 17) {
  1449. pPacket->Data.Response.TranslationType = LLC_SEND_802_3_TO_DIX;
  1450. } else {
  1451. pPacket->Data.Response.TranslationType = LLC_SEND_802_3_TO_802_3;
  1452. }
  1453. LlcBuildAddressFromLanHeader(pAdapterContext->NdisMedium,
  1454. pAdapterContext->pHeadBuf,
  1455. pPacket->Data.Xmit.pLanHeader
  1456. );
  1457. //
  1458. // Connect the packet to the send queues, we can use a subprocedure
  1459. // because this is not on the main code path
  1460. //
  1461. QueuePacket(pAdapterContext, &pAdapterContext->QueueDirAndU, pPacket);
  1462. //
  1463. // Request and send process execution from the receive indication
  1464. //
  1465. pAdapterContext->LlcPacketInSendQueue = TRUE;
  1466. }
  1467. LockedErrorExit:
  1468. RELEASE_SPIN_LOCK(&pAdapterContext->SendSpinLock);
  1469. ProcedureErrorExit:
  1470. if (pPacket == NULL) {
  1471. if (pBuffer) {
  1472. FREE_MEMORY_ADAPTER(pBuffer);
  1473. }
  1474. if (pTestMdl != NULL) {
  1475. IoFreeMdl(pTestMdl);
  1476. }
  1477. }
  1478. }
  1479. //
  1480. // The table maps all SAP send commands to the actual LLC commands
  1481. //
  1482. static struct {
  1483. UCHAR ResponseFlag;
  1484. UCHAR Command;
  1485. } Type1_Commands[LLC_LAST_FRAME_TYPE / 2] = {
  1486. {(UCHAR)-1, (UCHAR)-1},
  1487. {(UCHAR)-1, (UCHAR)-1},
  1488. {(UCHAR)-1, (UCHAR)-1},
  1489. {0, LLC_UI}, // UI command
  1490. {0, LLC_XID | LLC_U_POLL_FINAL}, // XID_COMMAND_POLL
  1491. {0, LLC_XID}, // XID_COMMAND_NOT_POLL
  1492. {LLC_SSAP_RESPONSE, LLC_XID | LLC_U_POLL_FINAL}, // XID_RESPONSE_FINAL
  1493. {LLC_SSAP_RESPONSE, LLC_XID}, // XID_RESPONSE_NOT_FINAL
  1494. {LLC_SSAP_RESPONSE, LLC_TEST | LLC_U_POLL_FINAL}, // TEST_RESPONSE_FINAL
  1495. {LLC_SSAP_RESPONSE, LLC_TEST}, // TEST_RESPONSE_NOT_FINAL
  1496. {(UCHAR)-1, (UCHAR)-1},
  1497. {0, LLC_TEST | LLC_U_POLL_FINAL} // TEST_RESPONSE_FINAL
  1498. };
  1499. VOID
  1500. LlcSendU(
  1501. IN PLLC_OBJECT pStation,
  1502. IN PLLC_PACKET pPacket,
  1503. IN UINT eFrameType,
  1504. IN UINT uDestinationSap
  1505. )
  1506. /*++
  1507. Routine Description:
  1508. Function sends the given network frame. and sets up
  1509. The frame may be a direct frame or Type 1 connectionless
  1510. frame (UI, XID or TEST).
  1511. First we build LLC (or ethernet type) header for the frame
  1512. and then we either send the packet directly or queue it
  1513. on data link.
  1514. Arguments:
  1515. pStation - Link, SAP or Direct station handle
  1516. pPacket - data link packet, also the completion handle for
  1517. the upper protocol.
  1518. eFrameType - the sent frame type
  1519. uDestinationSap - destination sap or dix ethernet type
  1520. Return Value:
  1521. None.
  1522. --*/
  1523. {
  1524. PADAPTER_CONTEXT pAdapterContext = pStation->Gen.pAdapterContext;
  1525. UINT Status;
  1526. ASSUME_IRQL(DISPATCH_LEVEL);
  1527. DLC_TRACE('U');
  1528. pPacket->pBinding = pStation->Gen.pLlcBinding;
  1529. pPacket->Data.Xmit.pLlcObject = pStation;
  1530. pPacket->CompletionType = LLC_TYPE_1_PACKET;
  1531. ACQUIRE_SPIN_LOCK(&pAdapterContext->SendSpinLock);
  1532. //
  1533. // Build LLC header for SAP stations, the direct stations do not have any
  1534. // LLC header
  1535. //
  1536. switch (pStation->Gen.ObjectType) {
  1537. case LLC_SAP_OBJECT:
  1538. pPacket->cbLlcHeader = sizeof(LLC_U_HEADER);
  1539. pPacket->Data.XmitU.TranslationType = (UCHAR)pStation->Gen.pLlcBinding->AddressTranslation;
  1540. pPacket->Data.XmitU.Dsap = (UCHAR)uDestinationSap;
  1541. pPacket->Data.XmitU.Ssap = (UCHAR)pStation->Sap.SourceSap;
  1542. pPacket->Data.XmitU.Ssap |= Type1_Commands[eFrameType >> 1].ResponseFlag;
  1543. pPacket->Data.XmitU.Command = Type1_Commands[eFrameType >> 1].Command;
  1544. //
  1545. // Do the UI- code path ASAP, then check TEST and XID special cases
  1546. //
  1547. if (pPacket->Data.XmitU.Command != LLC_UI) {
  1548. //
  1549. // Data link driver must build the DLC headers if it handles XID
  1550. // frames internally. In this case we use a constant XID info field
  1551. //
  1552. if ((pStation->Sap.OpenOptions & LLC_HANDLE_XID_COMMANDS)
  1553. && ((eFrameType == LLC_XID_COMMAND_POLL)
  1554. || (eFrameType == LLC_XID_COMMAND_NOT_POLL))) {
  1555. pPacket->Data.XmitU.pMdl = pXidMdl;
  1556. }
  1557. //
  1558. // duplicated TEST and XID frame responses are in a separate
  1559. // function since they're off the main code path. The code is also
  1560. // used in more than one place
  1561. //
  1562. Status = CheckAndDuplicatePacket(
  1563. #if DBG
  1564. pAdapterContext,
  1565. #endif
  1566. pStation->Gen.pLlcBinding,
  1567. pPacket,
  1568. &pAdapterContext->QueueDirAndU
  1569. );
  1570. if (Status != DLC_STATUS_SUCCESS) {
  1571. goto ErrorExit;
  1572. }
  1573. }
  1574. break;
  1575. case LLC_DIRECT_OBJECT:
  1576. //
  1577. // We must not send MAC frames to an ethernet network!!!
  1578. // Bit7 and bit6 in FC byte defines the frame type in token ring.
  1579. // 00 => MAC frame (no LLC), 01 => LLC, 10,11 => reserved.
  1580. // We send all other frames to direct except 01 (LLC)
  1581. //
  1582. if (pAdapterContext->NdisMedium != NdisMedium802_5
  1583. && (pPacket->Data.XmitU.pLanHeader[1] & 0xC0) != 0x40) {
  1584. goto ErrorExit;
  1585. }
  1586. pPacket->Data.XmitU.TranslationType = (UCHAR)pStation->Gen.pLlcBinding->AddressTranslation;
  1587. pPacket->cbLlcHeader = 0;
  1588. break;
  1589. case LLC_DIX_OBJECT:
  1590. //
  1591. // Return error if we are sending DIX frames to a token-ring network.
  1592. // The DIX lan header is always in an ethernet format.
  1593. // (But lan headers for LLC and DIR frames are in token-ring
  1594. // format)
  1595. //
  1596. if (pAdapterContext->NdisMedium != NdisMedium802_3) {
  1597. Status = DLC_STATUS_UNAUTHORIZED_MAC;
  1598. goto ErrorExit;
  1599. }
  1600. pPacket->cbLlcHeader = 2;
  1601. pPacket->Data.XmitDix.TranslationType = LLC_SEND_DIX_TO_DIX;
  1602. pPacket->Data.XmitDix.EthernetTypeLowByte = (UCHAR)uDestinationSap;
  1603. pPacket->Data.XmitDix.EthernetTypeHighByte = (UCHAR)(uDestinationSap >> 8);
  1604. break;
  1605. #if LLC_DBG
  1606. default:
  1607. LlcInvalidObjectType();
  1608. break;
  1609. #endif
  1610. }
  1611. //
  1612. // Update the statistics, we may count the transmits as well here because
  1613. // the failed transmissions are not counted. This should be moved to
  1614. // SendComplete and be incremented only if STATUS_SUCCESS and if we counted
  1615. // only the successful transmits. I don't really know which one should be
  1616. // counted
  1617. //
  1618. pStation->Sap.Statistics.FramesTransmitted++;
  1619. LlcInsertTailList(&pAdapterContext->QueueDirAndU.ListHead, pPacket);
  1620. if (pAdapterContext->QueueDirAndU.ListEntry.Flink == NULL) {
  1621. LlcInsertTailList(&pAdapterContext->NextSendTask,
  1622. &pAdapterContext->QueueDirAndU.ListEntry
  1623. );
  1624. }
  1625. RunSendTaskAndUnlock(pAdapterContext);
  1626. return;
  1627. ErrorExit:
  1628. RELEASE_SPIN_LOCK(&pAdapterContext->SendSpinLock);
  1629. pPacket->Data.Completion.Status = Status;
  1630. pPacket->Data.Completion.CompletedCommand = LLC_SEND_COMPLETION;
  1631. pPacket->pBinding->pfCommandComplete(pPacket->pBinding->hClientContext,
  1632. pStation->Gen.hClientHandle,
  1633. pPacket
  1634. );
  1635. }
  1636. VOID
  1637. LlcSendI(
  1638. IN PDATA_LINK pStation,
  1639. IN PLLC_PACKET pPacket
  1640. )
  1641. /*++
  1642. Routine Description:
  1643. The primitive implements a pure connection-oriented LLC Class II send.
  1644. It sends frame to the remote link station and
  1645. indicates the upper protocol when the data has been acknowledged.
  1646. The link station provides all address information and LLC header.
  1647. Function queues the given I packet to the queue and connects the
  1648. I- packet queue to the main send queue, if it has not
  1649. yet been connected.
  1650. Arguments:
  1651. pStation - link, sap or direct station handle
  1652. pPacket - data link packet, it is used also a request handle
  1653. to identify the command completion
  1654. Return Value:
  1655. None.
  1656. --*/
  1657. {
  1658. ASSUME_IRQL(DISPATCH_LEVEL);
  1659. DLC_TRACE('I');
  1660. pPacket->pBinding = pStation->Gen.pLlcBinding;
  1661. pPacket->cbLlcHeader = sizeof(LLC_I_HEADER);
  1662. //
  1663. // We keep the acknowledge bit set, because it identifies that
  1664. // the packet is not yet in the NDIS queue
  1665. //
  1666. pPacket->CompletionType = LLC_I_PACKET_UNACKNOWLEDGED;
  1667. pPacket->Data.Xmit.pLlcObject = (PLLC_OBJECT)pStation;
  1668. pPacket->Data.Xmit.pLanHeader = pStation->auchLanHeader;
  1669. //
  1670. // We check the info field length for I- frames.
  1671. // All Type 1 frames are checked by the data link.
  1672. // Actually it checks also the I-frames, but
  1673. // data links do not care about the physical errors.
  1674. // It would disconnect the link after the too
  1675. // many retries.
  1676. //
  1677. if (pPacket->InformationLength > pStation->MaxIField) {
  1678. pPacket->Data.Completion.Status = DLC_STATUS_INVALID_FRAME_LENGTH;
  1679. pPacket->Data.Completion.CompletedCommand = LLC_SEND_COMPLETION;
  1680. pPacket->pBinding->pfCommandComplete(pPacket->pBinding->hClientContext,
  1681. pStation->Gen.hClientHandle,
  1682. pPacket
  1683. );
  1684. } else {
  1685. PADAPTER_CONTEXT pAdapterContext = pStation->Gen.pAdapterContext;
  1686. //
  1687. // We must do all queue handling inside the send spin lock. We also have
  1688. // to enable the send process and run the background process only when
  1689. // the send queue has been emptied
  1690. //
  1691. ACQUIRE_SPIN_LOCK(&pAdapterContext->SendSpinLock);
  1692. if (!(PrimaryStates[pStation->State] & LLC_LINK_OPENED)) {
  1693. RELEASE_SPIN_LOCK(&pAdapterContext->SendSpinLock);
  1694. //
  1695. // The 802.2 state machine may discard the data send request.
  1696. // It may also only queue the packet, but to keep the send process
  1697. // disabled
  1698. //
  1699. pPacket->Data.Completion.Status = DLC_STATUS_LINK_NOT_TRANSMITTING;
  1700. pPacket->Data.Completion.CompletedCommand = LLC_SEND_COMPLETION;
  1701. pPacket->pBinding->pfCommandComplete(pPacket->pBinding->hClientContext,
  1702. pStation->Gen.hClientHandle,
  1703. pPacket
  1704. );
  1705. } else {
  1706. LlcInsertTailList(&pStation->SendQueue.ListHead, pPacket);
  1707. if (pStation->SendQueue.ListEntry.Flink == NULL) {
  1708. StartSendProcess(pAdapterContext, pStation);
  1709. }
  1710. RunSendTaskAndUnlock(pAdapterContext);
  1711. }
  1712. }
  1713. }
  1714. VOID
  1715. QueuePacket(
  1716. IN PADAPTER_CONTEXT pAdapterContext,
  1717. IN PLLC_QUEUE pQueue,
  1718. IN PLLC_PACKET pPacket
  1719. )
  1720. /*++
  1721. Routine Description:
  1722. The routines queues a packet to a queue and connects the
  1723. queue to the send tack list, if it was not connected.
  1724. This procedure is called from the non-timecritical code paths
  1725. just to save some extra code.
  1726. Arguments:
  1727. pAdapterContext - context of the data link adapter
  1728. pQueue - a special send queue structure
  1729. pPacket - transmit packet
  1730. Return Value:
  1731. None
  1732. --*/
  1733. {
  1734. LlcInsertTailList(&pQueue->ListHead, pPacket);
  1735. if (pQueue->ListEntry.Flink == NULL) {
  1736. LlcInsertTailList(&pAdapterContext->NextSendTask, &pQueue->ListEntry);
  1737. }
  1738. }
  1739. DLC_STATUS
  1740. CheckAndDuplicatePacket(
  1741. #if DBG
  1742. IN PADAPTER_CONTEXT pAdapterContext,
  1743. #endif
  1744. IN PBINDING_CONTEXT pBinding,
  1745. IN PLLC_PACKET pPacket,
  1746. IN PLLC_QUEUE pQueue
  1747. )
  1748. /*++
  1749. Routine Description:
  1750. If determining the ethernet type dynamically, create a duplicate DIX frame
  1751. for a SABME or XID or TEST frame
  1752. Arguments:
  1753. pBindingContext - current data link binding context
  1754. pPacket - transmit packet
  1755. pQueue - a special send queue structure
  1756. Return Value:
  1757. DLC_STATUS
  1758. Success - DLC_STATUS_SUCCESS
  1759. Failure - DLC_STATUS_NO_MEMORY
  1760. --*/
  1761. {
  1762. PLLC_PACKET pNewPacket;
  1763. ASSUME_IRQL(DISPATCH_LEVEL);
  1764. if (pBinding->EthernetType == LLC_ETHERNET_TYPE_AUTO) {
  1765. pNewPacket = ALLOCATE_PACKET_LLC_PKT(pBinding->pAdapterContext->hPacketPool);
  1766. if (pNewPacket == NULL) {
  1767. return DLC_STATUS_NO_MEMORY;
  1768. } else {
  1769. *pNewPacket = *pPacket;
  1770. pNewPacket->pBinding = NULL;
  1771. pNewPacket->CompletionType = LLC_DIX_DUPLICATE;
  1772. //
  1773. // We always send first the 802.3 packet and then the DIX one.
  1774. // The new packet must be sent first, because it has no resources
  1775. // associated with it. Therefore we must change the type of the
  1776. // old packet
  1777. //
  1778. //
  1779. if (pPacket->Data.XmitU.TranslationType == LLC_SEND_802_5_TO_802_3) {
  1780. //
  1781. // token-ring -> dix
  1782. //
  1783. pPacket->Data.XmitU.TranslationType = LLC_SEND_802_5_TO_DIX;
  1784. } else if (pPacket->Data.XmitU.TranslationType == LLC_SEND_802_3_TO_802_3) {
  1785. //
  1786. // ethernet 802.3 -> dix
  1787. //
  1788. pPacket->Data.XmitU.TranslationType = LLC_SEND_802_3_TO_DIX;
  1789. }
  1790. QueuePacket(pBinding->pAdapterContext, pQueue, pNewPacket);
  1791. }
  1792. }
  1793. return DLC_STATUS_SUCCESS;
  1794. }
  1795. VOID
  1796. BackgroundProcessWithinLock(
  1797. IN PADAPTER_CONTEXT pAdapterContext
  1798. )
  1799. {
  1800. ASSUME_IRQL(DISPATCH_LEVEL);
  1801. BackgroundProcessAndUnlock(pAdapterContext);
  1802. ACQUIRE_SPIN_LOCK(&pAdapterContext->SendSpinLock);
  1803. }