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.

1420 lines
43 KiB

  1. /*----------------------------------------------------------------------
  2. nic.c - routines for protocol access to NIC card via upper edge NDIS
  3. routines.
  4. Change History:
  5. 1-18-99 - avoid sending empty HDLC packet(ACK only) up stack.
  6. 4-10-98 - Allow for NDIS40 dynamic bind capability if available.
  7. 11-14-97 - Created a thread to retry opening NIC's req by NT5.0. DCS
  8. Copyright 1996-98 Comtrol Corporation. All rights reserved.
  9. |--------------------------------------------------------------------*/
  10. #include "precomp.h"
  11. #define DbgNicSet(n) {sz_modid[3] = nic->RefIndex + '0';}
  12. #define Trace1(s,p1) GTrace1(D_Nic, sz_modid, s, p1)
  13. #define TraceStr(s) GTrace(D_Nic, sz_modid, s)
  14. #define TraceErr(s) GTrace(D_Error, sz_modid_err, s)
  15. static char *sz_modid = {"Nic#"};
  16. static char *sz_modid_err = {"Error,Nic"};
  17. #ifdef NT50
  18. #define DO_AUTO_CONFIG 1
  19. #endif
  20. //---- local functions
  21. static PSERIAL_DEVICE_EXTENSION need_mac_autoassign(void);
  22. int NicOpenAdapter(Nic *nic, IN PUNICODE_STRING NicName);
  23. NDIS_STATUS NicWaitForCompletion(Nic *nic);
  24. #ifdef OLD_BINDING_GATHER
  25. NTSTATUS PacketReadRegistry(
  26. IN PWSTR *MacDriverName,
  27. IN PWSTR *PacketDriverName,
  28. IN PUNICODE_STRING RegistryPath,
  29. IN int style); // 0=nt4.0 location, 1=nt5.0 location
  30. NTSTATUS PacketQueryRegistryRoutine(
  31. IN PWSTR ValueName,
  32. IN ULONG ValueType,
  33. IN PVOID ValueData,
  34. IN ULONG ValueLength,
  35. IN PVOID Context,
  36. IN PVOID EntryContext);
  37. #endif
  38. VOID PacketRequestComplete(
  39. IN NDIS_HANDLE ProtocolBindingContext,
  40. IN PNDIS_REQUEST NdisRequest,
  41. IN NDIS_STATUS Status);
  42. VOID PacketSendComplete(
  43. IN NDIS_HANDLE ProtocolBindingContext,
  44. IN PNDIS_PACKET pPacket,
  45. IN NDIS_STATUS Status);
  46. NDIS_STATUS PacketReceiveIndicate (
  47. IN NDIS_HANDLE ProtocolBindingContext,
  48. IN NDIS_HANDLE MacReceiveContext,
  49. IN PVOID HeaderBuffer,
  50. IN UINT HeaderBufferSize,
  51. IN PVOID LookAheadBuffer,
  52. IN UINT LookAheadBufferSize,
  53. IN UINT PacketSize);
  54. VOID PacketTransferDataComplete (
  55. IN NDIS_HANDLE ProtocolBindingContext,
  56. IN PNDIS_PACKET pPacket,
  57. IN NDIS_STATUS Status,
  58. IN UINT BytesTransfered);
  59. VOID PacketOpenAdapterComplete(
  60. IN NDIS_HANDLE ProtocolBindingContext,
  61. IN NDIS_STATUS Status,
  62. IN NDIS_STATUS OpenErrorStatus);
  63. VOID PacketCloseAdapterComplete(
  64. IN NDIS_HANDLE ProtocolBindingContext,
  65. IN NDIS_STATUS Status);
  66. VOID PacketResetComplete(
  67. IN NDIS_HANDLE ProtocolBindingContext,
  68. IN NDIS_STATUS Status);
  69. VOID PacketReceiveComplete(IN NDIS_HANDLE ProtocolBindingContext);
  70. VOID PacketStatus(
  71. IN NDIS_HANDLE ProtocolBindingContext,
  72. IN NDIS_STATUS Status,
  73. IN PVOID StatusBuffer,
  74. IN UINT StatusBufferSize);
  75. VOID PacketStatusComplete(IN NDIS_HANDLE ProtocolBindingContext);
  76. #ifdef TRY_DYNAMIC_BINDING
  77. void PacketBind(
  78. OUT PNDIS_STATUS Status,
  79. IN NDIS_HANDLE BindContext,
  80. IN PNDIS_STRING DeviceName,
  81. IN PVOID SystemSpecific1,
  82. IN PVOID SystemSpecific2);
  83. VOID PacketUnBind(
  84. OUT PNDIS_STATUS Status,
  85. IN NDIS_HANDLE ProtocolBindingContext,
  86. IN NDIS_HANDLE UnbindContext);
  87. #endif
  88. VOID GotOurPkt(Nic *nic);
  89. void eth_rx_async(Nic *nic);
  90. void eth_rx_admin(Nic *nic, BYTE *rx, BYTE *pkt_hdr, int len, int server);
  91. Hdlc *find_hdlc_handle(BYTE *rx);
  92. static int nic_handle_to_index(Nic *nic);
  93. BYTE broadcast_addr[6] = {0xff,0xff,0xff,0xff,0xff,0xff};
  94. BYTE mac_zero_addr[6] = {0,0,0,0,0,0};
  95. BYTE mac_bogus_addr[6] = {0,0xc0,0x4e,0,0,0};
  96. /*----------------------------------------------------------------------
  97. ProtocolOpen -
  98. |----------------------------------------------------------------------*/
  99. int ProtocolOpen(void)
  100. {
  101. NTSTATUS Status = STATUS_SUCCESS;
  102. NDIS_PROTOCOL_CHARACTERISTICS ProtocolChar;
  103. NDIS_STRING ProtoName = NDIS_STRING_CONST("VSLinka");
  104. int i;
  105. MyKdPrint(D_Init,("Proto Open\n"))
  106. if (Driver.NdisProtocolHandle == NULL)
  107. {
  108. MyKdPrint(D_Init,("P1\n"))
  109. RtlZeroMemory(&ProtocolChar,sizeof(NDIS_PROTOCOL_CHARACTERISTICS));
  110. ProtocolChar.MajorNdisVersion = 4;
  111. ProtocolChar.MinorNdisVersion = 0;
  112. ProtocolChar.Reserved = 0;
  113. ProtocolChar.OpenAdapterCompleteHandler = PacketOpenAdapterComplete;
  114. ProtocolChar.CloseAdapterCompleteHandler = PacketCloseAdapterComplete;
  115. ProtocolChar.SendCompleteHandler = PacketSendComplete;
  116. ProtocolChar.TransferDataCompleteHandler = PacketTransferDataComplete;
  117. ProtocolChar.ResetCompleteHandler = PacketResetComplete;
  118. ProtocolChar.RequestCompleteHandler = PacketRequestComplete;
  119. ProtocolChar.ReceiveHandler = PacketReceiveIndicate;
  120. ProtocolChar.ReceiveCompleteHandler = PacketReceiveComplete;
  121. ProtocolChar.StatusHandler = PacketStatus;
  122. ProtocolChar.StatusCompleteHandler = PacketStatusComplete;
  123. ProtocolChar.Name = ProtoName;
  124. // version 4.0 NDIS parts:
  125. ProtocolChar.ReceivePacketHandler = NULL;
  126. #ifdef TRY_DYNAMIC_BINDING
  127. ProtocolChar.BindAdapterHandler = PacketBind;
  128. ProtocolChar.UnbindAdapterHandler = PacketUnBind;
  129. #endif
  130. //ProtocolChar.TranslateHandler = NULL;
  131. ProtocolChar.UnloadHandler = NULL;
  132. Driver.ndis_version = 4;
  133. #ifdef TRY_DYNAMIC_BINDING
  134. // don't do this yet(not fully debugged)
  135. NdisRegisterProtocol(
  136. &Status,
  137. &Driver.NdisProtocolHandle,
  138. &ProtocolChar,
  139. sizeof(NDIS_PROTOCOL_CHARACTERISTICS));
  140. if (Status != NDIS_STATUS_SUCCESS)
  141. #endif
  142. {
  143. MyKdPrint(D_Init,("No NDIS40\n"))
  144. // try NDIS30
  145. ProtocolChar.MajorNdisVersion = 3;
  146. ProtocolChar.BindAdapterHandler = NULL;
  147. ProtocolChar.UnbindAdapterHandler = NULL;
  148. NdisRegisterProtocol(
  149. &Status,
  150. &Driver.NdisProtocolHandle,
  151. &ProtocolChar,
  152. sizeof(NDIS_PROTOCOL_CHARACTERISTICS));
  153. if (Status != NDIS_STATUS_SUCCESS)
  154. {
  155. MyKdPrint(D_Init,("No NDIS30\n"))
  156. return 1; // error
  157. }
  158. Driver.ndis_version = 3;
  159. }
  160. }
  161. MyKdPrint(D_Init,("NDIS V%d\n",Driver.ndis_version))
  162. return 0; // ok
  163. }
  164. /*----------------------------------------------------------------------
  165. NicOpen - Setup all our stuff for our own protocol, so we can
  166. talk ethernet. Setup our callbacks to upper edge NDIS routines,
  167. grab registry entries which tell us who we are and what NIC cards
  168. we are bound to. Take care of all init stuff associated with using
  169. the NIC card.
  170. |----------------------------------------------------------------------*/
  171. int NicOpen(Nic *nic, IN PUNICODE_STRING NicName)
  172. {
  173. NTSTATUS Status = STATUS_SUCCESS;
  174. //NDIS_HANDLE NdisProtocolHandle;
  175. int i;
  176. NDIS_STATUS ErrorStatus;
  177. PNDIS_BUFFER NdisBuffer;
  178. //MyKdPrint(D_Init,("Nic Open\n"))
  179. DbgNicSet(nic);
  180. TraceStr("NicOpen");
  181. //----- This event is used in case any of the NDIS requests pend;
  182. KeInitializeEvent(&nic->CompletionEvent,
  183. NotificationEvent, FALSE);
  184. Status = NicOpenAdapter(nic, NicName);
  185. if (Status)
  186. {
  187. MyKdPrint(D_Init,("Nic Fail Open\n"))
  188. NicClose(nic);
  189. return Status;
  190. }
  191. MyKdPrint(D_Init,("Nic Open OK\n"))
  192. #ifdef COMMENT_OUT
  193. Nic->MacInfo.DestinationOffset = 0;
  194. Nic->MacInfo.SourceOffset = 6;
  195. Nic->MacInfo.SourceRouting = FALSE;
  196. Nic->MacInfo.AddressLength = 6;
  197. Nic->MacInfo.MaxHeaderLength = 14;
  198. Nic->MacInfo.MediumType = NdisMedium802_3;
  199. #endif
  200. // NDIS packets consist of one or more buffer descriptors which point
  201. // to the actual data. We send or receive single packets made up of
  202. // 1 or more buffers. A MDL is used as a buffer descriptor under NT.
  203. //--------- Allocate a packet pool for our tx packets
  204. NdisAllocatePacketPool(&Status, &nic->TxPacketPoolTemp, 1,
  205. sizeof(PVOID));
  206. // sizeof(PACKET_RESERVED));
  207. if (Status != NDIS_STATUS_SUCCESS)
  208. {
  209. NicClose(nic);
  210. return 4;
  211. }
  212. //--------- Allocate a buffer pool for our tx packets
  213. // we will only use 1 buffer per packet.
  214. NdisAllocateBufferPool(&Status, &nic->TxBufferPoolTemp, 1);
  215. if (Status != NDIS_STATUS_SUCCESS)
  216. {
  217. NicClose(nic);
  218. return 5;
  219. }
  220. //-------- create tx data buffer area
  221. nic->TxBufTemp = our_locked_alloc( MAX_PKT_SIZE,"ncTX");
  222. if (nic->TxBufTemp == NULL)
  223. {
  224. NicClose(nic);
  225. return 16;
  226. }
  227. //-------- form our tx queue packets so they link to our tx buffer area
  228. {
  229. // Get a packet from the pool
  230. NdisAllocatePacket(&Status, &nic->TxPacketsTemp, nic->TxPacketPoolTemp);
  231. if (Status != NDIS_STATUS_SUCCESS)
  232. {
  233. NicClose(nic);
  234. return 8;
  235. }
  236. nic->TxPacketsTemp->ProtocolReserved[0] = 0; // mark with our index
  237. nic->TxPacketsTemp->ProtocolReserved[1] = 0; // free for use
  238. // get a buffer for the temp output packet
  239. NdisAllocateBuffer(&Status, &NdisBuffer, nic->TxBufferPoolTemp,
  240. &nic->TxBufTemp[0], 1520);
  241. if (Status != NDIS_STATUS_SUCCESS)
  242. {
  243. NicClose(nic);
  244. return 9;
  245. }
  246. // we use only one data buffer per packet
  247. NdisChainBufferAtFront(nic->TxPacketsTemp, NdisBuffer);
  248. }
  249. //---------- Allocate a packet pool for our rx packets
  250. NdisAllocatePacketPool(&Status, &nic->RxPacketPool, MAX_RX_PACKETS,
  251. sizeof(PVOID));
  252. // sizeof(PACKET_RESERVED));
  253. if (Status != NDIS_STATUS_SUCCESS)
  254. {
  255. NicClose(nic);
  256. return 6;
  257. }
  258. //--------- Allocate a buffer pool for our rx packets
  259. // we will only use 1 buffer per packet.
  260. NdisAllocateBufferPool(&Status, &nic->RxBufferPool, MAX_RX_PACKETS);
  261. if (Status != NDIS_STATUS_SUCCESS)
  262. {
  263. NicClose(nic);
  264. return 7;
  265. }
  266. //-------- create rx data buffer area, add in space at front
  267. // of packets to put our private data
  268. nic->RxBuf = our_locked_alloc(
  269. (MAX_PKT_SIZE+HDR_SIZE) * MAX_RX_PACKETS,"ncRX");
  270. //------- form our rx queue packets so they link to our rx buffer area
  271. for (i=0; i<MAX_RX_PACKETS; i++)
  272. {
  273. // Get a packet from the pool
  274. NdisAllocatePacket(&Status, &nic->RxPackets[i], nic->RxPacketPool);
  275. if (Status != NDIS_STATUS_SUCCESS)
  276. {
  277. NicClose(nic);
  278. return 10;
  279. }
  280. nic->RxPackets[i]->ProtocolReserved[0] = i; // mark with our index
  281. nic->RxPackets[i]->ProtocolReserved[1] = 0; // free for use
  282. //--- link the buffer to our actual buffer space, leaving 20 bytes
  283. // at start of buffer for our private data(length, index, etc)
  284. NdisAllocateBuffer(&Status, &NdisBuffer, nic->RxBufferPool,
  285. &nic->RxBuf[((MAX_PKT_SIZE+HDR_SIZE) * i)+HDR_SIZE], MAX_PKT_SIZE);
  286. if (Status != NDIS_STATUS_SUCCESS)
  287. {
  288. NicClose(nic);
  289. return 11;
  290. }
  291. // we use only one data buffer per packet
  292. NdisChainBufferAtFront(nic->RxPackets[i], NdisBuffer);
  293. }
  294. strcpy(nic->NicName, UToC1(NicName));
  295. Trace1("Done Open NicName %s", nic->NicName);
  296. nic->Open = 1;
  297. return 0; // ok
  298. }
  299. /*----------------------------------------------------------------------
  300. NicOpenAdapter -
  301. |----------------------------------------------------------------------*/
  302. int NicOpenAdapter(Nic *nic, IN PUNICODE_STRING NicName)
  303. {
  304. UINT Medium;
  305. NDIS_MEDIUM MediumArray=NdisMedium802_3;
  306. NTSTATUS Status = STATUS_SUCCESS;
  307. NDIS_STATUS ErrorStatus;
  308. ULONG RBuf;
  309. DbgNicSet(nic);
  310. NdisOpenAdapter(
  311. &Status, // return status
  312. &ErrorStatus,
  313. &nic->NICHandle, // return handle value
  314. &Medium,
  315. &MediumArray,
  316. 1,
  317. Driver.NdisProtocolHandle, // pass in our protocol handle
  318. (NDIS_HANDLE) nic, // our handle passed to protocol callback routines
  319. NicName, // name of nic-card to open
  320. 0,
  321. NULL);
  322. if (Status == NDIS_STATUS_SUCCESS)
  323. PacketOpenAdapterComplete(nic, Status, NDIS_STATUS_SUCCESS);
  324. else if (Status == NDIS_STATUS_PENDING)
  325. {
  326. TraceErr("NicOpen Pended");
  327. Status = NicWaitForCompletion(nic); // wait for completion
  328. }
  329. if (Status != NDIS_STATUS_SUCCESS)
  330. {
  331. GTrace2(D_Nic, sz_modid, "NicOpen fail:%xH Err:%xH", Status, ErrorStatus);
  332. TraceStr(UToC1(NicName));
  333. nic->NICHandle = NULL;
  334. NicClose(nic);
  335. return 3;
  336. }
  337. GTrace1(D_Nic, sz_modid, "Try NicOpened:%s", nic->NicName);
  338. //----- get the local NIC card identifier address
  339. Status = NicGetNICInfo(nic, OID_802_3_CURRENT_ADDRESS,
  340. (PVOID)nic->address, 6);
  341. //----- set the rx filter
  342. RBuf = NDIS_PACKET_TYPE_DIRECTED;
  343. Status = NicSetNICInfo(nic, OID_GEN_CURRENT_PACKET_FILTER,
  344. (PVOID)&RBuf, sizeof(ULONG));
  345. return 0; // ok
  346. }
  347. /*----------------------------------------------------------------------
  348. NicClose - Shut down our NIC access. Deallocate any NIC resources.
  349. |----------------------------------------------------------------------*/
  350. int NicClose(Nic *nic)
  351. {
  352. NTSTATUS Status;
  353. DbgNicSet(nic);
  354. TraceStr("NicClose");
  355. nic->Open = 0;
  356. nic->NicName[0] = 0;
  357. if (nic->NICHandle != NULL)
  358. {
  359. NdisCloseAdapter(&Status, nic->NICHandle);
  360. if (Status == NDIS_STATUS_PENDING)
  361. {
  362. Status = NicWaitForCompletion(nic); // wait for completion
  363. }
  364. nic->NICHandle = NULL;
  365. }
  366. if (nic->TxPacketPoolTemp != NULL)
  367. NdisFreePacketPool(nic->TxPacketPoolTemp);
  368. nic->TxPacketPoolTemp = NULL;
  369. if (nic->TxBufferPoolTemp != NULL)
  370. NdisFreeBufferPool(nic->TxBufferPoolTemp);
  371. nic->TxBufferPoolTemp = NULL;
  372. if (nic->TxBufTemp != NULL)
  373. our_free(nic->TxBufTemp, "ncTX");
  374. nic->TxBufTemp = NULL;
  375. if (nic->RxPacketPool != NULL)
  376. NdisFreePacketPool(nic->RxPacketPool);
  377. nic->RxPacketPool = NULL;
  378. if (nic->RxBufferPool != NULL)
  379. NdisFreeBufferPool(nic->RxBufferPool);
  380. nic->RxBufferPool = NULL;
  381. if (nic->RxBuf != NULL)
  382. our_free(nic->RxBuf,"ncRX");
  383. nic->RxBuf = NULL;
  384. MyKdPrint(D_Nic,("Nic Close End\n"))
  385. return 0;
  386. }
  387. /*----------------------------------------------------------------------
  388. NicProtocolClose - Deregister our protocol.
  389. |----------------------------------------------------------------------*/
  390. int NicProtocolClose(void)
  391. {
  392. NTSTATUS Status;
  393. MyKdPrint(D_Nic,("Nic Proto Close\n"))
  394. if (Driver.NdisProtocolHandle != NULL)
  395. NdisDeregisterProtocol(&Status, Driver.NdisProtocolHandle);
  396. Driver.NdisProtocolHandle = NULL;
  397. return 0;
  398. }
  399. /*----------------------------------------------------------------------
  400. PacketRequestComplete - If a call is made to NdisRequest() to get
  401. information about the NIC card(OID), then it may return PENDING and
  402. this routine would then be called by NDIS to finalize the call.
  403. |----------------------------------------------------------------------*/
  404. VOID PacketRequestComplete(
  405. IN NDIS_HANDLE ProtocolBindingContext,
  406. IN PNDIS_REQUEST NdisRequest,
  407. IN NDIS_STATUS Status)
  408. {
  409. Nic *nic = (Nic *)ProtocolBindingContext;
  410. MyKdPrint(D_Nic,("PacketReqComp\n"))
  411. //MyDeb(NULL, 0xffff, "PktRqComp\n");
  412. nic->PendingStatus = Status;
  413. KeSetEvent(&nic->CompletionEvent, 0L, FALSE);
  414. return;
  415. }
  416. /*----------------------------------------------------------------------
  417. PacketSendComplete - Callback routine if NdisSend() returns PENDING.
  418. |----------------------------------------------------------------------*/
  419. VOID PacketSendComplete(
  420. IN NDIS_HANDLE ProtocolBindingContext,
  421. IN PNDIS_PACKET pPacket,
  422. IN NDIS_STATUS Status)
  423. {
  424. Nic *nic = (Nic *)ProtocolBindingContext;
  425. #if DBG
  426. if (nic == NULL)
  427. {
  428. MyKdPrint(D_Error, ("**** NicP Err1"))
  429. return;
  430. }
  431. DbgNicSet(nic);
  432. //nic->PendingStatus = Status;
  433. if (Status == STATUS_SUCCESS)
  434. {TraceStr("PcktSendComplete");}
  435. else
  436. {TraceErr("PcktSendComplete Error!");}
  437. #endif
  438. pPacket->ProtocolReserved[1] = 0; // free for use
  439. //--- not using this
  440. //KeSetEvent(&nic->CompletionEvent, 0L, FALSE);
  441. return;
  442. }
  443. /*----------------------------------------------------------------------
  444. NicWaitForCompletion - Utility routine to wait for async. routine
  445. to complete.
  446. |----------------------------------------------------------------------*/
  447. NDIS_STATUS NicWaitForCompletion(Nic *nic)
  448. {
  449. MyKdPrint(D_Nic,("WaitOnComp\n"))
  450. // The completion routine will set PendingStatus.
  451. KeWaitForSingleObject(
  452. &nic->CompletionEvent,
  453. Executive,
  454. KernelMode,
  455. TRUE,
  456. (PLARGE_INTEGER)NULL);
  457. KeResetEvent(&nic->CompletionEvent);
  458. MyKdPrint(D_Nic,("WaitOnCompEnd\n"))
  459. return nic->PendingStatus;
  460. }
  461. /*----------------------------------------------------------------------
  462. PacketReceiveIndicate - When a packet comes in, this routine is called
  463. to let us(protocol) know about it. We may peek at the data and
  464. optionally arrange for NDIS to transfer the complete packet data to
  465. one of our packets.
  466. LookAheadBufferSize is guarenteed to be as big as the
  467. OID_GEN_CURRENT_LOOKAHEAD value or packet size, whichever is smaller.
  468. If (PacketSize != LookAheadBufferSize) then a NdisTransferData() is
  469. required. Otherwise the complete packet is available in the
  470. lookahead buffer.
  471. !!!!Check the OID_GEN_somethin or other, there is a bit which indicates
  472. if we can copy out of lookahead buffer.
  473. The header len is typically 14 bytes in length for ethernet.
  474. |----------------------------------------------------------------------*/
  475. NDIS_STATUS PacketReceiveIndicate (
  476. IN NDIS_HANDLE ProtocolBindingContext,
  477. IN NDIS_HANDLE MacReceiveContext,
  478. IN PVOID HeaderBuffer,
  479. IN UINT HeaderBufferSize,
  480. IN PVOID LookAheadBuffer,
  481. IN UINT LookAheadBufferSize,
  482. IN UINT PacketSize)
  483. {
  484. NDIS_STATUS Status;
  485. UINT BytesTransfered;
  486. WORD LenOrId;
  487. // int stat;
  488. //static char tmparr[60];
  489. Nic *nic = (Nic *)ProtocolBindingContext;
  490. #if DBG
  491. if (nic == NULL)
  492. {
  493. MyKdPrint(D_Error, ("Eth15b\n"))
  494. }
  495. if (!nic->Open)
  496. {
  497. MyKdPrint(D_Error, ("Eth15a\n"))
  498. return 1;
  499. }
  500. #endif
  501. DbgNicSet(nic);
  502. TraceStr("pkt_rec_ind");
  503. if (HeaderBufferSize != 14)
  504. {
  505. TraceErr("Header Size!");
  506. ++nic->pkt_rcvd_not_ours;
  507. return NDIS_STATUS_NOT_ACCEPTED;
  508. }
  509. LenOrId = *(PWORD)(((PBYTE)HeaderBuffer)+12);
  510. if (LenOrId != 0xfe11)
  511. {
  512. // this not our packet
  513. ++nic->pkt_rcvd_not_ours;
  514. return NDIS_STATUS_NOT_ACCEPTED;
  515. }
  516. if (LookAheadBufferSize > 1)
  517. {
  518. //------ lets check for our product id header
  519. LenOrId = *(PBYTE)(((PBYTE)HeaderBuffer)+14);
  520. // serial concentrator product line
  521. if (LenOrId != ASYNC_PRODUCT_HEADER_ID)
  522. {
  523. if (LenOrId != 0xff)
  524. {
  525. TraceStr("nic,not async");
  526. // this not our packet
  527. ++nic->pkt_rcvd_not_ours;
  528. return NDIS_STATUS_NOT_ACCEPTED;
  529. }
  530. }
  531. }
  532. #ifdef BREAK_NIC_STUFF
  533. if (nic->RxPackets[0]->ProtocolReserved[1] & 1) // marked as pending
  534. {
  535. // our one rx buffer is in use! (should never happen)
  536. MyKdPrint(D_Error, ("****** RxBuf in use!"))
  537. //TraceErr("Rx Buf In Use!");
  538. return NDIS_STATUS_NOT_ACCEPTED;
  539. }
  540. nic->RxPackets[0]->ProtocolReserved[1] |= 1; // marked as pending
  541. #endif
  542. memcpy(nic->RxBuf, (BYTE *)HeaderBuffer, 14); // copy the eth. header
  543. if (LookAheadBufferSize == PacketSize)
  544. {
  545. TraceStr("nic,got complete");
  546. ++nic->RxNonPendingMoves;
  547. // we can just copy complete packet out of lookahead buffer
  548. // store the 14 byte header data at start of buffer
  549. memcpy(&nic->RxBuf[HDR_SIZE], (BYTE *)LookAheadBuffer, PacketSize);
  550. HDR_PKTLEN(nic->RxBuf) = PacketSize; // save the pkt size here
  551. ++nic->pkt_rcvd_ours;
  552. GotOurPkt(nic);
  553. }
  554. else // LookAhead not complete buffer, pending, do transfer
  555. {
  556. ++nic->RxPendingMoves;
  557. //MyDeb(NULL, 0xffff, "PktRecInd, Pend\n");
  558. // Call the Mac to transfer the packet
  559. NdisTransferData(&Status, nic->NICHandle, MacReceiveContext,
  560. 0, PacketSize, nic->RxPackets[0], &BytesTransfered);
  561. if (Status == NDIS_STATUS_SUCCESS)
  562. {
  563. TraceStr("nic,got trsfer complete");
  564. HDR_PKTLEN(nic->RxBuf) = PacketSize;
  565. //------ lets check for our product id header
  566. if ((nic->RxBuf[HDR_SIZE] != ASYNC_PRODUCT_HEADER_ID) &&
  567. (nic->RxBuf[HDR_SIZE] != 0xff) )
  568. {
  569. nic->RxPackets[0]->ProtocolReserved[1] = 0; // marked as not use
  570. TraceStr("nic,not async");
  571. // this not our packet
  572. ++nic->pkt_rcvd_not_ours;
  573. return NDIS_STATUS_NOT_ACCEPTED;
  574. }
  575. ++nic->pkt_rcvd_ours;
  576. GotOurPkt(nic);
  577. }
  578. else if (Status == NDIS_STATUS_PENDING)
  579. {
  580. TraceStr("nic,got pending");
  581. // ndis will call PacketTransferDataComplete.
  582. }
  583. else // an error occurred(adapter maybe getting reset)
  584. {
  585. MyKdPrint(D_Error, ("nic, Err1D"))
  586. nic->RxPackets[0]->ProtocolReserved[1] = 0; // marked as not use
  587. //MyDeb(NULL, 0xffff, "PktRecInd, PendError\n");
  588. }
  589. }
  590. return NDIS_STATUS_SUCCESS;
  591. }
  592. /*----------------------------------------------------------------------
  593. GotOurPkt - Its our packet(0x11fe for id at [12,13],
  594. and ASYNC(VS1000) or ff as [14],
  595. index byte we don't care about[16],
  596. rx = ptr to rx_pkt[16].
  597. [12,13] WORD 11fe(comtrol-pci-id, used as ethertype)
  598. [14] Product(55H=async, 15H=isdn, FFH=all)
  599. [15] Index Field(Server assigned box index)
  600. [16] Packet Class, 1=ADMIN, 0x55=VS1000 packet
  601. [17] word len for admin packet
  602. [17] hdlc control field for vs1000 packet
  603. |----------------------------------------------------------------------*/
  604. VOID GotOurPkt(Nic *nic)
  605. {
  606. // [HDR_SIZE] is after 14 byte header, so contains [14] data
  607. // [14]=55H or FFH, [15]=Index, not used [16]=1(ADMIN),55H=ASYNC_MESSAGE
  608. switch(nic->RxBuf[HDR_SIZE+2])
  609. {
  610. case ADMIN_FRAME: // ADMIN function, special setup admin functions
  611. TraceStr("admin");
  612. eth_rx_admin(nic,
  613. nic->RxBuf+(HDR_SIZE+3), // ptr to admin data
  614. nic->RxBuf, // ptr to ethernet header data
  615. HDR_PKTLEN(nic->RxBuf), // we embed length at [12] 0x11fe
  616. 1); // server flag
  617. break;
  618. case ASYNC_FRAME: // async frame(normal iframe/control hdlc packets)
  619. TraceStr("iframe");
  620. eth_rx_async(nic);
  621. break;
  622. default:
  623. TraceStr("badf");
  624. Tprintf("D: %x %x %x %x",
  625. nic->RxBuf[HDR_SIZE],
  626. nic->RxBuf[HDR_SIZE+1],
  627. nic->RxBuf[HDR_SIZE+2],
  628. nic->RxBuf[HDR_SIZE+3]);
  629. break;
  630. }
  631. nic->RxPackets[0]->ProtocolReserved[1] = 0; // mark as not use
  632. }
  633. /*----------------------------------------------------------------
  634. eth_rx_async - We receive from layer1, validate using the
  635. hdlc validation call, and ship rx-pkt up to the next upper layer.
  636. |-----------------------------------------------------------------*/
  637. void eth_rx_async(Nic *nic)
  638. {
  639. int i;
  640. Hdlc *hd;
  641. //WORD hd_index;
  642. WORD id;
  643. BYTE *rx;
  644. PSERIAL_DEVICE_EXTENSION ext;
  645. rx = nic->RxBuf;
  646. #ifdef USE_INDEX_FIELD
  647. id = rx[HDR_SIZE];
  648. #endif
  649. // find the HDLC level with the reply address
  650. //hd_index = 0xffff; // save index to hdlc handle in header area
  651. hd = NULL;
  652. i = 0;
  653. ext = Driver.board_ext;
  654. while (ext != NULL)
  655. {
  656. #ifdef USE_INDEX_FIELD
  657. if (id == ext->pm->unique_id)
  658. #else
  659. if (mac_match(&rx[6], ext->hd->dest_addr))
  660. #endif
  661. {
  662. hd = ext->hd;
  663. break;
  664. }
  665. ++i;
  666. ext = ext->board_ext; // next one
  667. }
  668. if (hd == NULL)
  669. {
  670. TraceErr("no Mac Match!");
  671. return;
  672. }
  673. if (!hd->nic || !hd->nic->Open)
  674. {
  675. TraceErr("notOpen!");
  676. return;
  677. }
  678. // 55 0 55 control snd_index ack_index
  679. rx += (HDR_SIZE+3); // skip over header
  680. i = hdlc_validate_rx_pkt(hd, rx); // validate the packet
  681. if (i == 0)
  682. {
  683. TraceStr("nic, pass upper");
  684. if (hd->upper_layer_proc != NULL)
  685. {
  686. if (*(rx+3) != 0) // not an empty packet(HDLC ACK packets, t1 timeout)
  687. {
  688. (*hd->upper_layer_proc)(hd->context,
  689. EV_L2_RX_PACKET,
  690. (DWORD) (rx+3) );
  691. }
  692. ++(hd->frames_rcvd);
  693. }
  694. }
  695. else
  696. {
  697. switch (i)
  698. {
  699. case ERR_GET_EMPTY : // 1 // empty
  700. TraceErr("Empty!");
  701. break;
  702. case ERR_GET_BAD_INDEX : // 2 // error, packet out of sequence
  703. TraceErr("LanIdx!");
  704. break;
  705. case ERR_GET_BADHDR : // 3 // error, not our packet
  706. // TraceErr("LanHdr!");
  707. break;
  708. case ERR_CONTROL_PACKET :
  709. break;
  710. default: TraceErr("LanErr!"); break;
  711. }
  712. } // else hdlc, error or control, not iframe
  713. }
  714. /*----------------------------------------------------------------------------
  715. | eth_rx_admin - PortMan handles admin functions, validate and pass on as
  716. event messages. rx is ptr to admin data, [17][18]=len, [19]=sub-admin-header
  717. |----------------------------------------------------------------------------*/
  718. void eth_rx_admin(Nic *nic, BYTE *rx, BYTE *pkt_hdr, int len, int server)
  719. {
  720. Hdlc *hd;
  721. rx += 2;
  722. TraceStr("AdminPkt");
  723. if (mac_match(pkt_hdr, broadcast_addr)) // its a broadcast
  724. {
  725. if ((*rx == 2) && (!server)) // Product ID request, Broadcast by server
  726. {
  727. // ok, we will reply
  728. }
  729. else if ((*rx == 3) && (server)) // Product ID reply, reply by concentrator.
  730. {
  731. // might be box waking up, or responding to server request.
  732. // shouldn't see it broadcast, but ISDN box currently broadcasts
  733. // on power-up.
  734. }
  735. else
  736. {
  737. TraceErr("bad b-admin!");
  738. }
  739. TraceErr("broadcast admin!");
  740. return;
  741. }
  742. switch(*rx)
  743. {
  744. #ifdef COMMENT_OUT
  745. case 2: // Product ID request, Broadcast or sent by server
  746. TraceStr("idreq");
  747. if (!server) // we are not a server, we are box
  748. eth_id_req(&pkt_hdr[6]);
  749. break;
  750. #endif
  751. case 1: // boot loader query
  752. if (!server) // we are a server
  753. break;
  754. if ((hd = find_hdlc_handle(&pkt_hdr[6])) != NULL)
  755. {
  756. PortMan *pm = (PortMan *) hd->context;
  757. if (pm->state != ST_SENDCODE)
  758. {
  759. #if 0
  760. // not functional at this point.
  761. // port manager is not uploading code, so it must be debug pkt
  762. // let port.c code handle boot-loader ADMIN reply.
  763. debug_device_reply(pm,
  764. rx+1,
  765. pkt_hdr);
  766. #endif
  767. }
  768. else
  769. {
  770. TraceStr("load_reply");
  771. // tell upper layer(port-manager) about ID reply
  772. // port-manager does code loading.
  773. if (hd->upper_layer_proc != NULL)
  774. (*hd->upper_layer_proc)(hd->context,
  775. EV_L2_BOOT_REPLY,
  776. (DWORD) (rx+1));
  777. }
  778. }
  779. #ifdef COMMENT_OUT
  780. #endif
  781. break;
  782. case 3: // Product ID reply, reply by concentrator.
  783. TraceStr("id_reply");
  784. if (!server) // we are a server
  785. break;
  786. {
  787. BYTE *list;
  788. BYTE *new;
  789. int i, found;
  790. // driver previously sent out directed or broadcast query
  791. // on network to detect boxes.
  792. // build a list of units which reply.
  793. // (rx+1) = ptr to reply address
  794. // *(rx+1+6) = flags byte which indicate if main-driver loaded.
  795. found = 0; // default to "did not find mac addr in list"
  796. new = rx+1;
  797. if (Driver.NumBoxMacs < MAX_NUM_BOXES)
  798. {
  799. for (i=0; i<Driver.NumBoxMacs; i++)
  800. {
  801. list = &Driver.BoxMacs[i*8];
  802. if (mac_match(list, new))
  803. found = 1; // found mac addr in list
  804. }
  805. }
  806. if (!found) // then add to list of mac addresses found on network
  807. {
  808. if (Driver.NumBoxMacs < MAX_NUM_BOXES)
  809. {
  810. memcpy(&Driver.BoxMacs[Driver.NumBoxMacs*8], rx+1, 8);
  811. Driver.BoxMacs[Driver.NumBoxMacs*8+7] = (BYTE)
  812. nic_handle_to_index(nic);
  813. Driver.BoxMacs[Driver.NumBoxMacs*8+6] = *(rx+1+6); // flags byte
  814. if (Driver.NumBoxMacs < (MAX_NUM_BOXES-1))
  815. ++Driver.NumBoxMacs;
  816. }
  817. }
  818. if (!Driver.TimerCreated) // init time(no hdlc levels active)
  819. break; // so don't try to use hdlc
  820. if ((hd = find_hdlc_handle(&pkt_hdr[6])) != NULL)
  821. {
  822. // stash the nic index in byte after flags byte
  823. *(rx+1+7) = (BYTE) nic_handle_to_index(nic);
  824. // tell upper layer(port-mananger) about ID reply
  825. if (hd->upper_layer_proc != NULL)
  826. (*hd->upper_layer_proc)(hd->context,
  827. EV_L2_ADMIN_REPLY,
  828. (DWORD) (rx+1));
  829. }
  830. else
  831. {
  832. #ifdef DO_AUTO_CONFIG
  833. PSERIAL_DEVICE_EXTENSION need_ext;
  834. MyKdPrint(D_Test,("Got Reply, Check AutoAssign\n"))
  835. if (!(*(rx+1+6) & FLAG_APPL_RUNNING)) // no box driver running
  836. {
  837. MyKdPrint(D_Test,("AutoAssign1\n"))
  838. // so probably free to auto-assign.
  839. // see if any extensions need auto assignment
  840. need_ext =need_mac_autoassign();
  841. if ((need_ext != NULL) && (Driver.AutoMacDevExt == NULL))
  842. {
  843. MyKdPrint(D_Test,("AutoAssigned!\n"))
  844. // set the mac addr for use
  845. memcpy(need_ext->config->MacAddr, (rx+1), 6);
  846. // signal the thread that auto-config needs
  847. // to be written out to registry
  848. Driver.AutoMacDevExt = need_ext;
  849. }
  850. }
  851. #endif
  852. }
  853. }
  854. break;
  855. case 4: // Loopback request
  856. TraceStr("aloop");
  857. //eth_loop_back(rx, pkt_hdr, len);
  858. break;
  859. case 5: // Command, Reset
  860. TraceStr("reset");
  861. //eth_command_reset(rx, pkt_hdr, len);
  862. break;
  863. default:
  864. TraceErr("admin, badpkt!");
  865. break;
  866. }
  867. }
  868. /*----------------------------------------------------------------------
  869. find_hdlc_handle - find the Hdlc object with the same mac-address
  870. as the ethernet header source mac address.
  871. |----------------------------------------------------------------------*/
  872. Hdlc *find_hdlc_handle(BYTE *rx)
  873. {
  874. PSERIAL_DEVICE_EXTENSION ext;
  875. ext = Driver.board_ext;
  876. while (ext != NULL)
  877. {
  878. if (mac_match(rx, ext->hd->dest_addr))
  879. {
  880. return ext->hd;
  881. }
  882. ext = ext->board_ext; // next one
  883. }
  884. TraceStr("find,NoMac Match!");
  885. return NULL;
  886. }
  887. /*----------------------------------------------------------------------
  888. need_mac_autoassign - Used for autoconfig of mac-address.
  889. |----------------------------------------------------------------------*/
  890. static PSERIAL_DEVICE_EXTENSION need_mac_autoassign(void)
  891. {
  892. PSERIAL_DEVICE_EXTENSION board_ext;
  893. board_ext = Driver.board_ext;
  894. while (board_ext != NULL)
  895. {
  896. // see if not configured
  897. if ( (mac_match(board_ext->config->MacAddr, mac_zero_addr)) ||
  898. (mac_match(board_ext->config->MacAddr, mac_bogus_addr)) )
  899. return board_ext; // needs auto-assignment
  900. board_ext = board_ext->board_ext;
  901. }
  902. return NULL; // its not used
  903. }
  904. /*----------------------------------------------------------------------
  905. PacketReceiveComplete -
  906. |----------------------------------------------------------------------*/
  907. VOID PacketReceiveComplete(IN NDIS_HANDLE ProtocolBindingContext)
  908. {
  909. //Nic *nic = (Nic *)ProtocolBindingContext;
  910. TraceStr("PcktRxComp");
  911. //MyDeb(NULL, 0xffff, "PktRecComp, 1\n");
  912. //lan_rec_proc(Driver->lan, nic->RxBuf, nic->len);
  913. //netio_got_packet(Driver->lan, nic->RxBuf);
  914. return;
  915. }
  916. /*----------------------------------------------------------------------
  917. PacketTransferDataComplete -
  918. |----------------------------------------------------------------------*/
  919. VOID PacketTransferDataComplete (
  920. IN NDIS_HANDLE ProtocolBindingContext,
  921. IN PNDIS_PACKET pPacket,
  922. IN NDIS_STATUS Status,
  923. IN UINT BytesTransfered)
  924. {
  925. Nic *nic = (Nic *)ProtocolBindingContext;
  926. TraceStr("nic, pend rx complete");
  927. if ((nic->RxBuf[HDR_SIZE] != ASYNC_PRODUCT_HEADER_ID) &&
  928. (nic->RxBuf[HDR_SIZE] != 0xff) )
  929. {
  930. TraceStr("not ours");
  931. ++nic->pkt_rcvd_not_ours;
  932. nic->RxPackets[0]->ProtocolReserved[1] = 0; // mark as not use
  933. return;
  934. }
  935. ++nic->pkt_rcvd_ours;
  936. GotOurPkt(nic);
  937. return;
  938. }
  939. /*----------------------------------------------------------------------
  940. PacketOpenAdapterComplete - Callback.
  941. |----------------------------------------------------------------------*/
  942. VOID PacketOpenAdapterComplete(
  943. IN NDIS_HANDLE ProtocolBindingContext,
  944. IN NDIS_STATUS Status,
  945. IN NDIS_STATUS OpenErrorStatus)
  946. {
  947. Nic *nic = (Nic *)ProtocolBindingContext;
  948. nic->PendingStatus = Status;
  949. TraceStr("PcktOpenAd");
  950. KeSetEvent(&nic->CompletionEvent, 0L, FALSE);
  951. return;
  952. }
  953. /*----------------------------------------------------------------------
  954. PacketCloseAdapterComplete -
  955. |----------------------------------------------------------------------*/
  956. VOID PacketCloseAdapterComplete(
  957. IN NDIS_HANDLE ProtocolBindingContext,
  958. IN NDIS_STATUS Status)
  959. {
  960. Nic *nic = (Nic *)ProtocolBindingContext;
  961. TraceStr("PcktCloseAd");
  962. nic->PendingStatus = Status;
  963. KeSetEvent(&nic->CompletionEvent, 0L, FALSE);
  964. return;
  965. }
  966. /*----------------------------------------------------------------------
  967. PacketResetComplete -
  968. |----------------------------------------------------------------------*/
  969. VOID PacketResetComplete(
  970. IN NDIS_HANDLE ProtocolBindingContext,
  971. IN NDIS_STATUS Status)
  972. {
  973. Nic *nic = (Nic *)ProtocolBindingContext;
  974. TraceStr("PcktResetComplete");
  975. nic->PendingStatus = Status;
  976. KeSetEvent(&nic->CompletionEvent, 0L, FALSE);
  977. return;
  978. }
  979. /*----------------------------------------------------------------------
  980. PacketStatus -
  981. |----------------------------------------------------------------------*/
  982. VOID PacketStatus(
  983. IN NDIS_HANDLE ProtocolBindingContext,
  984. IN NDIS_STATUS Status,
  985. IN PVOID StatusBuffer,
  986. IN UINT StatusBufferSize)
  987. {
  988. TraceStr("PcktStat");
  989. return;
  990. }
  991. /*----------------------------------------------------------------------
  992. PacketStatusComplete -
  993. |----------------------------------------------------------------------*/
  994. VOID PacketStatusComplete(IN NDIS_HANDLE ProtocolBindingContext)
  995. {
  996. TraceStr("PcktStatComplete");
  997. return;
  998. }
  999. /*----------------------------------------------------------------------
  1000. NicSetNICInfo -
  1001. |----------------------------------------------------------------------*/
  1002. NDIS_STATUS NicSetNICInfo(Nic *nic, NDIS_OID Oid, PVOID Data, ULONG Size)
  1003. {
  1004. NDIS_STATUS Status;
  1005. NDIS_REQUEST Request;
  1006. // Setup the request to send
  1007. Request.RequestType=NdisRequestSetInformation;
  1008. Request.DATA.SET_INFORMATION.Oid=Oid;
  1009. Request.DATA.SET_INFORMATION.InformationBuffer=Data;
  1010. Request.DATA.SET_INFORMATION.InformationBufferLength=Size;
  1011. NdisRequest(&Status,
  1012. nic->NICHandle,
  1013. &Request);
  1014. if (Status == NDIS_STATUS_SUCCESS)
  1015. {}
  1016. else if (Status == NDIS_STATUS_PENDING)
  1017. Status = NicWaitForCompletion(nic); // wait for completion
  1018. if (Status != NDIS_STATUS_SUCCESS)
  1019. {
  1020. MyKdPrint (D_Init,("NdisRequest Failed- Status %x\n",Status))
  1021. }
  1022. return Status;
  1023. }
  1024. /*----------------------------------------------------------------------
  1025. NicGetNICInfo - To call the NICs QueryInformationHandler
  1026. |----------------------------------------------------------------------*/
  1027. NDIS_STATUS NicGetNICInfo(Nic *nic, NDIS_OID Oid, PVOID Data, ULONG Size)
  1028. {
  1029. NDIS_STATUS Status;
  1030. NDIS_REQUEST Request;
  1031. // Setup the request to send
  1032. Request.RequestType=NdisRequestQueryInformation;
  1033. Request.DATA.SET_INFORMATION.Oid=Oid;
  1034. Request.DATA.SET_INFORMATION.InformationBuffer=Data;
  1035. Request.DATA.SET_INFORMATION.InformationBufferLength=Size;
  1036. NdisRequest(&Status,
  1037. nic->NICHandle,
  1038. &Request);
  1039. if (Status == NDIS_STATUS_SUCCESS)
  1040. {}
  1041. else if (Status == NDIS_STATUS_PENDING)
  1042. Status = NicWaitForCompletion(nic); // wait for completion
  1043. if (Status != NDIS_STATUS_SUCCESS)
  1044. {
  1045. MyKdPrint (D_Init,("NdisRequest Failed- Status %x\n",Status))
  1046. }
  1047. return Status;
  1048. }
  1049. /*--------------------------------------------------------------------------
  1050. | nic_send_pkt -
  1051. |--------------------------------------------------------------------------*/
  1052. int nic_send_pkt(Nic *nic, BYTE *buf, int len)
  1053. {
  1054. // BYTE *bptr;
  1055. // int cnt;
  1056. NTSTATUS Status;
  1057. //int pkt_num;
  1058. if (nic == NULL)
  1059. {
  1060. MyKdPrint(D_Error, ("E1\n"))
  1061. TraceErr("snd1a");
  1062. return 1;
  1063. }
  1064. if (nic->TxBufTemp == NULL)
  1065. {
  1066. MyKdPrint(D_Error, ("E2\n"))
  1067. TraceErr("snd1b");
  1068. return 1;
  1069. }
  1070. if (nic->TxPacketsTemp == NULL)
  1071. {
  1072. MyKdPrint(D_Error, ("E3\n"))
  1073. TraceErr("snd1c");
  1074. return 1;
  1075. }
  1076. if (nic->Open == 0)
  1077. {
  1078. MyKdPrint(D_Error, ("E4\n"))
  1079. TraceErr("snd1d");
  1080. return 1;
  1081. }
  1082. DbgNicSet(nic);
  1083. TraceStr("send_pkt");
  1084. if (nic->TxPacketsTemp->ProtocolReserved[1] & 1) // marked as pending
  1085. {
  1086. TraceErr("snd1e");
  1087. // reset in case it got stuck
  1088. // nic->TxPacketsTemp->ProtocolReserved[1] = 0;
  1089. return 3;
  1090. }
  1091. memcpy(nic->TxBufTemp, buf, len);
  1092. nic->TxPacketsTemp->Private.TotalLength = len;
  1093. NdisAdjustBufferLength(nic->TxPacketsTemp->Private.Head, len);
  1094. nic->TxPacketsTemp->ProtocolReserved[1] = 1; // mark as pending
  1095. NdisSend(&Status, nic->NICHandle, nic->TxPacketsTemp);
  1096. if (Status == NDIS_STATUS_SUCCESS)
  1097. {
  1098. TraceStr("snd ok");
  1099. nic->TxPacketsTemp->ProtocolReserved[1] = 0; // free for use
  1100. }
  1101. else if (Status == NDIS_STATUS_PENDING)
  1102. {
  1103. TraceStr("snd pend");
  1104. // Status = NicWaitForCompletion(nic); // wait for completion
  1105. }
  1106. else
  1107. {
  1108. nic->TxPacketsTemp->ProtocolReserved[1] = 0; // free for use
  1109. TraceErr("send1A");
  1110. return 1;
  1111. }
  1112. ++nic->pkt_sent; // statistics
  1113. nic->send_bytes += len; // statistics
  1114. return 0;
  1115. }
  1116. #ifdef TRY_DYNAMIC_BINDING
  1117. /*----------------------------------------------------------------------
  1118. PacketBind - Called when nic card ready to use. Passes in name of
  1119. nic card. NDIS40 protocol only.
  1120. |----------------------------------------------------------------------*/
  1121. VOID PacketBind(
  1122. OUT PNDIS_STATUS Status,
  1123. IN NDIS_HANDLE BindContext,
  1124. IN PNDIS_STRING DeviceName,
  1125. IN PVOID SystemSpecific1,
  1126. IN PVOID SystemSpecific2)
  1127. {
  1128. int i,stat;
  1129. MyKdPrint(D_Init,("Dyn. Bind\n"))
  1130. TraceErr("DynBind");
  1131. TraceErr(UToC1(DeviceName));
  1132. // NIC not open - retry open
  1133. for (i=0; i<VS1000_MAX_NICS; i++)
  1134. {
  1135. MyKdPrint(D_Init,("D1\n"))
  1136. if((Driver.nics[i].NICHandle == NULL) &&
  1137. (Driver.NicName[i].Buffer == NULL))
  1138. {
  1139. MyKdPrint(D_Init,("D2\n"))
  1140. // make a copy of the nic-name
  1141. Driver.NicName[i].Buffer =
  1142. our_locked_alloc(DeviceName->Length + sizeof(WCHAR), "pkbd");
  1143. memcpy(Driver.NicName[i].Buffer, DeviceName->Buffer, DeviceName->Length);
  1144. Driver.NicName[i].Length = DeviceName->Length;
  1145. Driver.NicName[i].MaximumLength = DeviceName->Length;
  1146. stat = NicOpen(&Driver.nics[i], &Driver.NicName[i]);
  1147. if (stat)
  1148. {
  1149. TraceErr("Bad NicOpen");
  1150. *Status = NDIS_STATUS_NOT_ACCEPTED;
  1151. return;
  1152. }
  1153. else
  1154. {
  1155. MyKdPrint(D_Init,("D3\n"))
  1156. Driver.BindContext[i] = BindContext; // save this for the unbind
  1157. *Status = NDIS_STATUS_SUCCESS;
  1158. return;
  1159. }
  1160. }
  1161. }
  1162. MyKdPrint(D_Init,("D4\n"))
  1163. *Status = NDIS_STATUS_NOT_ACCEPTED;
  1164. return;
  1165. //if (pended)
  1166. // NdisCompleteBindAdapter(BindContext);
  1167. }
  1168. /*----------------------------------------------------------------------
  1169. PacketUnBind - Called when nic card is shutting down, going away.
  1170. NDIS40 protocol only.
  1171. |----------------------------------------------------------------------*/
  1172. VOID PacketUnBind(
  1173. OUT PNDIS_STATUS Status,
  1174. IN NDIS_HANDLE ProtocolBindingContext,
  1175. IN NDIS_HANDLE UnbindContext)
  1176. {
  1177. int i, pi;
  1178. TraceErr("DynUnBind");
  1179. //if (pend)
  1180. // NdisCompleteUnBindAdapter(BindContext);
  1181. // NIC not open - retry open
  1182. // find the nic card which is closing up shop
  1183. for (i=0; i<Driver.num_nics; i++)
  1184. {
  1185. if (Driver.BindContext[i] == ProtocolBindingContext) // a match!
  1186. {
  1187. TraceErr("fnd UnBind");
  1188. if((Driver.nics[i].NICHandle != NULL) &&
  1189. (Driver.nics[i].Open))
  1190. {
  1191. // first find all the box objects, and shut them down
  1192. // BUGBUG: we should use some spinlocks here, we are in danger of
  1193. // doing two things at once(pulling the rug out from under
  1194. // port.c operations while it is running.
  1195. ext = Driver.board_ext;
  1196. while (ext)
  1197. {
  1198. if (Driver.pm[pi].nic_index == i) // its using this nic card
  1199. {
  1200. if (Driver.pm[pi].state == Driver.pm[i].state)
  1201. {
  1202. TraceErr("Shutdown box");
  1203. Driver.pm[pi].state = ST_INIT;
  1204. }
  1205. }
  1206. ext = ext->board_ext;
  1207. }
  1208. NicClose(&Driver.nics[i]);
  1209. if (Driver.NicName[i].Buffer)
  1210. {
  1211. our_free(Driver.NicName[i].Buffer, "pkbd"); // free up the unicode buf
  1212. Driver.NicName[i].Buffer = 0;
  1213. }
  1214. }
  1215. Driver.BindContext[i] = 0;
  1216. }
  1217. }
  1218. *Status = NDIS_STATUS_SUCCESS;
  1219. return;
  1220. }
  1221. #endif
  1222. /*----------------------------------------------------------------------
  1223. nic_handle_to_index - given a nic handle, give the index into the
  1224. linked list, or array.
  1225. |----------------------------------------------------------------------*/
  1226. static int nic_handle_to_index(Nic *nic)
  1227. {
  1228. int i;
  1229. for (i=0; i<VS1000_MAX_NICS; i++)
  1230. {
  1231. if ((&Driver.nics[i]) == nic)
  1232. return i;
  1233. }
  1234. TraceErr("BadIndex");
  1235. return 0;
  1236. }
  1237. #if 0
  1238. /*----------------------------------------------------------------------
  1239. PacketTranslate -
  1240. |----------------------------------------------------------------------*/
  1241. VOID PacketTranslate(
  1242. OUT PNDIS_STATUS Status,
  1243. IN NDIS_HANDLE ProtocolBindingContext,
  1244. OUT PNET_PNP_ID IdList,
  1245. IN ULONG IdListLength,
  1246. OUT PULONG BytesReturned)
  1247. {
  1248. }
  1249. /*----------------------------------------------------------------------
  1250. PacketUnLoad -
  1251. |----------------------------------------------------------------------*/
  1252. VOID PacketUnLoad(VOID)
  1253. {
  1254. }
  1255. #endif