Windows NT 4.0 source code leak
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.

1158 lines
33 KiB

4 years ago
  1. /***************************************************************************
  2. *
  3. * REQUEST.C
  4. *
  5. * FastMAC Plus based NDIS3 miniport driver routines for handling SRB
  6. * requests and ODI_ requsts.
  7. *
  8. * Copyright (c) Madge Networks Ltd 1994
  9. *
  10. * COMPANY CONFIDENTIAL
  11. *
  12. * Created: PBA 21/06/1994
  13. *
  14. ****************************************************************************/
  15. #include <ndis.h>
  16. #include "ftk_defs.h"
  17. #include "ftk_extr.h"
  18. #include "mdgmport.upd"
  19. #include "ndismod.h"
  20. /*---------------------------------------------------------------------------
  21. |
  22. | Global OIDs that we will support queries on.
  23. |
  24. ---------------------------------------------------------------------------*/
  25. NDIS_OID MadgeGlobalSupportedOids[] =
  26. {
  27. //
  28. // General, Operational, Mandatory.
  29. //
  30. OID_GEN_SUPPORTED_LIST,
  31. OID_GEN_HARDWARE_STATUS,
  32. OID_GEN_MEDIA_SUPPORTED,
  33. OID_GEN_MEDIA_IN_USE,
  34. OID_GEN_MAXIMUM_LOOKAHEAD,
  35. OID_GEN_MAXIMUM_FRAME_SIZE,
  36. OID_GEN_LINK_SPEED,
  37. OID_GEN_TRANSMIT_BUFFER_SPACE,
  38. OID_GEN_RECEIVE_BUFFER_SPACE,
  39. OID_GEN_TRANSMIT_BLOCK_SIZE,
  40. OID_GEN_RECEIVE_BLOCK_SIZE,
  41. OID_GEN_VENDOR_ID,
  42. OID_GEN_VENDOR_DESCRIPTION,
  43. OID_GEN_CURRENT_PACKET_FILTER,
  44. OID_GEN_CURRENT_LOOKAHEAD,
  45. OID_GEN_DRIVER_VERSION,
  46. OID_GEN_MAXIMUM_TOTAL_SIZE,
  47. OID_GEN_PROTOCOL_OPTIONS,
  48. OID_GEN_MAC_OPTIONS,
  49. //
  50. // General, Statistical, Mandatory.
  51. //
  52. OID_GEN_XMIT_OK,
  53. OID_GEN_RCV_OK,
  54. OID_GEN_XMIT_ERROR,
  55. OID_GEN_RCV_ERROR,
  56. OID_GEN_RCV_NO_BUFFER,
  57. //
  58. // Token Ring, Operational, Mandatory.
  59. //
  60. OID_802_5_PERMANENT_ADDRESS,
  61. OID_802_5_CURRENT_ADDRESS,
  62. OID_802_5_CURRENT_FUNCTIONAL,
  63. OID_802_5_CURRENT_GROUP,
  64. OID_802_5_LAST_OPEN_STATUS,
  65. OID_802_5_CURRENT_RING_STATUS,
  66. OID_802_5_CURRENT_RING_STATE,
  67. //
  68. // Token Ring, Statistical, Mandatory.
  69. //
  70. OID_802_5_LINE_ERRORS,
  71. OID_802_5_LOST_FRAMES,
  72. //
  73. // Token Ring Statistical, Optional.
  74. //
  75. OID_802_5_BURST_ERRORS,
  76. OID_802_5_AC_ERRORS,
  77. OID_802_5_FRAME_COPIED_ERRORS,
  78. OID_802_5_TOKEN_ERRORS
  79. //
  80. // There are three more Token Ring error stat's but TI MAC code does not
  81. // support them, so we go without! (ABORT_DELIMITERS, FREQUENCY_ERRORS,
  82. // and INTERNAL_ERRORS).
  83. //
  84. };
  85. /**************************************************************************
  86. *
  87. * Function - MadgeCompletePendingRequest
  88. *
  89. * Parameters - ndisAdap -> Pointer NDIS3 level adapter structure.
  90. *
  91. * Purpose - Complete a pending request on the adapter specified.
  92. *
  93. * Returns - Nothing.
  94. *
  95. ***************************************************************************/
  96. VOID
  97. MadgeCompletePendingRequest(PMADGE_ADAPTER ndisAdap)
  98. {
  99. BOOLEAN success;
  100. ADAPTER * ftkAdapter;
  101. ULONG * infoBuffer;
  102. // MadgePrint1("MadgeCompletePendingRequest started\n");
  103. success = ndisAdap->SrbRequestStatus;
  104. switch(ndisAdap->RequestType)
  105. {
  106. case NdisRequestQueryInformation:
  107. infoBuffer = (ULONG *) ndisAdap->InformationBuffer;
  108. if (success)
  109. {
  110. ftkAdapter = adapter_record[ndisAdap->FtkAdapterHandle];
  111. ndisAdap->ReceiveCongestionCount +=
  112. ftkAdapter->status_info->error_log.congestion_errors;
  113. ndisAdap->LineErrors +=
  114. ftkAdapter->status_info->error_log.line_errors;
  115. ndisAdap->BurstErrors +=
  116. ftkAdapter->status_info->error_log.burst_errors;
  117. ndisAdap->AcErrors +=
  118. ftkAdapter->status_info->error_log.ari_fci_errors;
  119. ndisAdap->TokenErrors +=
  120. ftkAdapter->status_info->error_log.token_errors;
  121. switch(ndisAdap->RequestOid)
  122. {
  123. case OID_GEN_RCV_NO_BUFFER:
  124. *infoBuffer = ndisAdap->ReceiveCongestionCount;
  125. break;
  126. case OID_802_5_LINE_ERRORS:
  127. *infoBuffer = ndisAdap->LineErrors;
  128. break;
  129. case OID_802_5_BURST_ERRORS:
  130. *infoBuffer = ndisAdap->BurstErrors;
  131. break;
  132. case OID_802_5_AC_ERRORS:
  133. *infoBuffer = ndisAdap->AcErrors;
  134. break;
  135. case OID_802_5_TOKEN_ERRORS:
  136. *infoBuffer = ndisAdap->TokenErrors;
  137. break;
  138. }
  139. ndisAdap->JustReadErrorLog = ndisAdap->RequestOid;
  140. }
  141. //
  142. // And complete the request.
  143. //
  144. NdisMQueryInformationComplete(
  145. ndisAdap->UsedInISR.MiniportHandle,
  146. (success) ? NDIS_STATUS_SUCCESS : NDIS_STATUS_FAILURE
  147. );
  148. break;
  149. case NdisRequestSetInformation:
  150. //
  151. // All we need to do is complete the request.
  152. //
  153. NdisMSetInformationComplete(
  154. ndisAdap->UsedInISR.MiniportHandle,
  155. (success) ? NDIS_STATUS_SUCCESS : NDIS_STATUS_FAILURE
  156. );
  157. break;
  158. }
  159. // MadgePrint1("MadgeCompletePendingRequest finished\n");
  160. }
  161. /***************************************************************************
  162. *
  163. * Function - MadgeQueryInformation
  164. *
  165. * Parameters - adapterContext -> Pointer NDIS3 level adapter structure.
  166. * oid -> The OID.
  167. * infoBuffer -> Pointer to the information buffer.
  168. * infoLength -> Length of the information buffer.
  169. * bytesWritten -> Pointer to a holder for the number of
  170. * bytes we've written.
  171. * bytesNeeded -> Pointer to a holder for the number of
  172. * bytes we need.
  173. *
  174. * Purpose - Set adapter information.
  175. *
  176. * Returns - An NDIS3 status code.
  177. *
  178. ***************************************************************************/
  179. NDIS_STATUS
  180. MadgeQueryInformation(
  181. NDIS_HANDLE adapterContext,
  182. NDIS_OID oid,
  183. PVOID infoBuffer,
  184. ULONG infoLength,
  185. PULONG bytesWritten,
  186. PULONG bytesNeeded
  187. )
  188. {
  189. PMADGE_ADAPTER ndisAdap;
  190. UINT supportedOids;
  191. UINT i;
  192. ULONG genericULong;
  193. USHORT genericUShort;
  194. UCHAR genericArray[6];
  195. PVOID sourceBuffer;
  196. ULONG sourceLength;
  197. UCHAR * vendorID;
  198. static UCHAR VendorDescription[] = DRIVER_VERSION;
  199. // MadgePrint2("MadgeQueryInformation Oid = %08x\n", (UINT) oid);
  200. //
  201. // Do some pre-calculation.
  202. //
  203. ndisAdap = PMADGE_ADAPTER_FROM_CONTEXT(adapterContext);
  204. sourceBuffer = (PVOID) &genericULong;
  205. sourceLength = (ULONG) sizeof(ULONG);
  206. vendorID = (UCHAR *) &genericULong;
  207. supportedOids = sizeof(MadgeGlobalSupportedOids) / sizeof(NDIS_OID);
  208. //
  209. // Check that we recognise the OID.
  210. //
  211. #ifdef OID_MADGE_MONITOR
  212. if (oid == OID_MADGE_MONITOR)
  213. {
  214. if (sizeof(MADGE_MONITOR) > infoLength)
  215. {
  216. *bytesNeeded = sizeof(MADGE_MONITOR);
  217. return NDIS_STATUS_BUFFER_TOO_SHORT;
  218. }
  219. MADGE_MOVE_MEMORY(
  220. infoBuffer,
  221. &(ndisAdap->MonitorInfo),
  222. sizeof(MADGE_MONITOR)
  223. );
  224. *bytesWritten = sizeof(MADGE_MONITOR);
  225. // Clear out the Monitor Structure
  226. for (i = 0; i < sizeof(MADGE_MONITOR); i++)
  227. {
  228. ((UCHAR *) &(ndisAdap->MonitorInfo))[i] = (UCHAR) 0;
  229. }
  230. return NDIS_STATUS_SUCCESS;
  231. }
  232. #endif
  233. for (i = 0; i < supportedOids; i++)
  234. {
  235. if (oid == MadgeGlobalSupportedOids[i])
  236. {
  237. break;
  238. }
  239. }
  240. if (i == supportedOids)
  241. {
  242. *bytesWritten = 0;
  243. MadgePrint1("OID not supported\n");
  244. return NDIS_STATUS_INVALID_OID;
  245. }
  246. //
  247. // Now decode the OID based on the component bytes - this should make
  248. // the switch statement slightly quicker than a simple linear list.
  249. //
  250. // The OIDs are classed by category (General or Media Specific) and type
  251. // (Operational or Statistical), so we'll deal with them thus :
  252. // General Operational
  253. // General Statistical
  254. // Media Specific Operational
  255. // Media Specific Statistical
  256. //
  257. switch (oid & OID_TYPE_MASK)
  258. {
  259. /*-----------------------------------------------------------------*/
  260. case OID_TYPE_GENERAL_OPERATIONAL:
  261. switch (oid)
  262. {
  263. case OID_GEN_SUPPORTED_LIST:
  264. sourceBuffer = MadgeGlobalSupportedOids;
  265. sourceLength = sizeof(MadgeGlobalSupportedOids);
  266. break;
  267. case OID_GEN_HARDWARE_STATUS:
  268. genericULong = ndisAdap->HardwareStatus;
  269. break;
  270. case OID_GEN_MEDIA_SUPPORTED:
  271. genericULong = NdisMedium802_5;
  272. break;
  273. case OID_GEN_MEDIA_IN_USE:
  274. genericULong = NdisMedium802_5;
  275. break;
  276. case OID_GEN_MAXIMUM_LOOKAHEAD:
  277. //
  278. // The maximum lookahead size is the size of the whole
  279. // frame, less the MAC header. It is NOT the maximum
  280. // frame size according to the ring speed.
  281. //
  282. genericULong = ndisAdap->MaxFrameSize - FRAME_HEADER_SIZE;
  283. //
  284. // WARNING: What about Source Routing in the header?
  285. //
  286. // MadgePrint2("OID_GEN_MAXIMUM_LOOKAHEAD = %ld\n",
  287. // genericULong);
  288. break;
  289. case OID_GEN_MAXIMUM_FRAME_SIZE:
  290. case OID_GEN_MAXIMUM_TOTAL_SIZE:
  291. //
  292. // Note that the MAXIMUM_FRAME_SIZE is the largest frame
  293. // supported, not including any MAC header, while the
  294. // MAXIMUM_TOTAL_SIZE does include the MAC header.
  295. //
  296. genericULong = ndisAdap->MaxFrameSize;
  297. if (oid == OID_GEN_MAXIMUM_FRAME_SIZE)
  298. {
  299. genericULong -= FRAME_HEADER_SIZE;
  300. }
  301. // MadgePrint2("OID_GEN_MAXIMUM_FRAME_SIZE = %ld\n",
  302. // genericULong);
  303. break;
  304. case OID_GEN_LINK_SPEED:
  305. //
  306. // Is this right? Shouldn't it be 16000000 and 4000000?
  307. //
  308. genericULong =
  309. (driver_ring_speed(ndisAdap->FtkAdapterHandle) == 16)
  310. ? 160000
  311. : 40000;
  312. break;
  313. case OID_GEN_TRANSMIT_BUFFER_SPACE:
  314. genericULong =
  315. ndisAdap->MaxFrameSize * ndisAdap->FastmacTxSlots;
  316. break;
  317. case OID_GEN_RECEIVE_BUFFER_SPACE:
  318. genericULong =
  319. ndisAdap->MaxFrameSize * ndisAdap->FastmacRxSlots;
  320. break;
  321. case OID_GEN_TRANSMIT_BLOCK_SIZE:
  322. genericULong = ndisAdap->MaxFrameSize;
  323. break;
  324. case OID_GEN_RECEIVE_BLOCK_SIZE:
  325. genericULong = ndisAdap->MaxFrameSize;
  326. break;
  327. case OID_GEN_VENDOR_ID:
  328. MADGE_MOVE_MEMORY(
  329. vendorID,
  330. &ndisAdap->PermanentNodeAddress,
  331. 3
  332. );
  333. vendorID[3] = 0x00;
  334. break;
  335. case OID_GEN_VENDOR_DESCRIPTION:
  336. sourceBuffer = VendorDescription;
  337. sourceLength = sizeof(VendorDescription);
  338. break;
  339. case OID_GEN_CURRENT_PACKET_FILTER:
  340. genericULong = (ULONG) ndisAdap->CurrentPacketFilter;
  341. break;
  342. case OID_GEN_CURRENT_LOOKAHEAD:
  343. genericULong = (ULONG) ndisAdap->CurrentLookahead;
  344. // MadgePrint2("OID_GEN_CURRENT_LOOKAHEAD = %ld\n",
  345. // genericULong);
  346. break;
  347. case OID_GEN_DRIVER_VERSION:
  348. genericUShort = (MADGE_NDIS_MAJOR_VERSION << 8) +
  349. MADGE_NDIS_MINOR_VERSION;
  350. sourceBuffer = &genericUShort;
  351. sourceLength = sizeof(USHORT);
  352. break;
  353. case OID_GEN_MAC_OPTIONS:
  354. genericULong = (ULONG)
  355. (NDIS_MAC_OPTION_TRANSFERS_NOT_PEND |
  356. NDIS_MAC_OPTION_RECEIVE_SERIALIZED);
  357. break;
  358. default:
  359. MadgePrint2("OID %x not recognised\n", oid);
  360. return NDIS_STATUS_INVALID_OID;
  361. }
  362. break;
  363. /*-----------------------------------------------------------------*/
  364. case OID_TYPE_GENERAL_STATISTICS:
  365. //
  366. // Might need these later.
  367. //
  368. *bytesWritten = sourceLength;
  369. ndisAdap->RequestType = NdisRequestQueryInformation;
  370. ndisAdap->RequestOid = oid;
  371. ndisAdap->InformationBuffer = infoBuffer;
  372. switch (oid)
  373. {
  374. case OID_GEN_XMIT_OK:
  375. genericULong = (ULONG) ndisAdap->FramesTransmitted;
  376. break;
  377. case OID_GEN_RCV_OK:
  378. genericULong = (ULONG) ndisAdap->FramesReceived;
  379. break;
  380. case OID_GEN_XMIT_ERROR:
  381. genericULong = (ULONG) ndisAdap->FrameTransmitErrors;
  382. break;
  383. case OID_GEN_RCV_ERROR:
  384. genericULong = (ULONG) ndisAdap->FrameReceiveErrors;
  385. break;
  386. case OID_GEN_RCV_NO_BUFFER:
  387. //
  388. // We need to issue a READ_ERROR_LOG SRB to recover an
  389. // up to date value for this counter.
  390. //
  391. if (ndisAdap->JustReadErrorLog != 0 &&
  392. ndisAdap->JustReadErrorLog != oid)
  393. {
  394. genericULong = (ULONG)
  395. ndisAdap->ReceiveCongestionCount;
  396. }
  397. else if (infoLength >= sourceLength)
  398. {
  399. driver_get_status(ndisAdap->FtkAdapterHandle);
  400. return NDIS_STATUS_PENDING;
  401. }
  402. break;
  403. default:
  404. MadgePrint2("OID %x not recognised\n", oid);
  405. return NDIS_STATUS_INVALID_OID;
  406. }
  407. break;
  408. /*-----------------------------------------------------------------*/
  409. case OID_TYPE_802_5_OPERATIONAL:
  410. switch (oid)
  411. {
  412. case OID_802_5_PERMANENT_ADDRESS:
  413. sourceBuffer = &genericArray;
  414. sourceLength = sizeof(ndisAdap->PermanentNodeAddress);
  415. MADGE_MOVE_MEMORY(
  416. sourceBuffer,
  417. &ndisAdap->PermanentNodeAddress,
  418. sizeof(ndisAdap->PermanentNodeAddress)
  419. );
  420. break;
  421. case OID_802_5_CURRENT_ADDRESS:
  422. sourceBuffer = &genericArray;
  423. sourceLength =
  424. sizeof(ndisAdap->OpeningNodeAddress);
  425. MADGE_MOVE_MEMORY(
  426. sourceBuffer,
  427. &ndisAdap->OpeningNodeAddress,
  428. sizeof(ndisAdap->OpeningNodeAddress)
  429. );
  430. break;
  431. case OID_802_5_CURRENT_FUNCTIONAL:
  432. genericULong =
  433. ndisAdap->FunctionalAddress & 0xffffffff;
  434. break;
  435. case OID_802_5_CURRENT_GROUP:
  436. genericULong =
  437. ndisAdap->GroupAddress & 0xffffffff;
  438. break;
  439. case OID_802_5_LAST_OPEN_STATUS:
  440. genericULong = ndisAdap->LastOpenStatus;
  441. break;
  442. case OID_802_5_CURRENT_RING_STATUS:
  443. genericULong = ndisAdap->CurrentRingStatus;
  444. break;
  445. case OID_802_5_CURRENT_RING_STATE:
  446. genericULong = NdisRingStateOpened;
  447. break;
  448. default:
  449. MadgePrint2("OID %x not recognised\n", oid);
  450. return NDIS_STATUS_INVALID_OID;
  451. }
  452. break;
  453. /*-----------------------------------------------------------------*/
  454. case OID_TYPE_802_5_STATISTICS:
  455. //
  456. // We do a bit of pre-processing here in case we have to queue
  457. // an SRB request. In this instance we want everything ready bar
  458. // the actual data.
  459. //
  460. if (sourceLength > infoLength)
  461. {
  462. break;
  463. }
  464. *bytesWritten = sourceLength;
  465. ndisAdap->RequestType = NdisRequestQueryInformation;
  466. ndisAdap->RequestOid = oid;
  467. ndisAdap->InformationBuffer = infoBuffer;
  468. //
  469. // Now get on with working out the data.
  470. //
  471. switch (oid)
  472. {
  473. case OID_802_5_LINE_ERRORS:
  474. //
  475. // We need to issue a READ_ERROR_LOG SRB to recover an
  476. // up to date value for this counter.
  477. //
  478. if (ndisAdap->JustReadErrorLog != 0 &&
  479. ndisAdap->JustReadErrorLog != oid)
  480. {
  481. genericULong = (ULONG) ndisAdap->LineErrors;
  482. }
  483. else
  484. {
  485. driver_get_status(ndisAdap->FtkAdapterHandle);
  486. return NDIS_STATUS_PENDING;
  487. }
  488. break;
  489. case OID_802_5_LOST_FRAMES:
  490. //
  491. // This counter is managed by the transmit process using
  492. // the transmit status returned by FastmacPlus.
  493. //
  494. genericULong = (ULONG) ndisAdap->LostFrames;
  495. break;
  496. case OID_802_5_BURST_ERRORS:
  497. if (ndisAdap->JustReadErrorLog != 0 &&
  498. ndisAdap->JustReadErrorLog != oid)
  499. {
  500. genericULong= (ULONG) ndisAdap->BurstErrors;
  501. }
  502. else
  503. {
  504. driver_get_status(ndisAdap->FtkAdapterHandle);
  505. return NDIS_STATUS_PENDING;
  506. }
  507. break;
  508. case OID_802_5_AC_ERRORS:
  509. if (ndisAdap->JustReadErrorLog != 0 &&
  510. ndisAdap->JustReadErrorLog != oid)
  511. {
  512. genericULong= (ULONG) ndisAdap->AcErrors;
  513. }
  514. else
  515. {
  516. driver_get_status(ndisAdap->FtkAdapterHandle);
  517. return NDIS_STATUS_PENDING;
  518. }
  519. break;
  520. case OID_802_5_FRAME_COPIED_ERRORS:
  521. //
  522. // This counter is managed by the receive process using
  523. // the receive status returned by FastmacPlus.
  524. //
  525. genericULong = (ULONG) ndisAdap->FrameCopiedErrors;
  526. break;
  527. case OID_802_5_TOKEN_ERRORS:
  528. if (ndisAdap->JustReadErrorLog != 0 &&
  529. ndisAdap->JustReadErrorLog != oid)
  530. {
  531. genericULong = (ULONG) ndisAdap->TokenErrors;
  532. }
  533. else
  534. {
  535. driver_get_status(ndisAdap->FtkAdapterHandle);
  536. return NDIS_STATUS_PENDING;
  537. }
  538. break;
  539. default:
  540. MadgePrint2("OID %x not recognised\n", oid);
  541. return NDIS_STATUS_INVALID_OID;
  542. }
  543. break;
  544. }
  545. //
  546. // Check memory allocation provided by caller - report required amount
  547. // if we haven't got enough.
  548. //
  549. if (sourceLength > infoLength)
  550. {
  551. *bytesNeeded = sourceLength;
  552. return NDIS_STATUS_BUFFER_TOO_SHORT;
  553. }
  554. MADGE_MOVE_MEMORY(
  555. infoBuffer,
  556. sourceBuffer,
  557. sourceLength
  558. );
  559. *bytesWritten = sourceLength;
  560. return NDIS_STATUS_SUCCESS;
  561. }
  562. /*---------------------------------------------------------------------------
  563. |
  564. | Function - MadgeChangeGroupAddress
  565. |
  566. | Parameters - ndisAdap -> Pointer to our NDIS level adapter structure.
  567. | newAddress -> The new group address.
  568. |
  569. | Purpose - Queue an SRB to change the group address.
  570. |
  571. | Returns - Nothing.
  572. |
  573. ---------------------------------------------------------------------------*/
  574. STATIC VOID
  575. MadgeChangeGroupAddress(
  576. PMADGE_ADAPTER ndisAdap,
  577. TR_FUNCTIONAL_ADDRESS newAddress
  578. )
  579. {
  580. MULTI_ADDRESS multiAddress;
  581. // MadgePrint1("MadgeChangeGroupAddress started\n");
  582. ndisAdap->GroupAddress = newAddress;
  583. multiAddress.all = (DWORD) newAddress;
  584. ndisAdap->RequestType = NdisRequestSetInformation;
  585. //
  586. // And call the FTK to change the address.
  587. //
  588. driver_set_group_address(ndisAdap->FtkAdapterHandle, &multiAddress);
  589. // MadgePrint1("MadgeChangeGroupAddress finished\n");
  590. }
  591. /*---------------------------------------------------------------------------
  592. |
  593. | Function - MadgeChangeFunctionalAddress
  594. |
  595. | Parameters - ndisAdap -> Pointer to our NDIS level adapter structure.
  596. | newAddress -> The new functional address.
  597. |
  598. | Purpose - Queue an SRB to change the functional address.
  599. |
  600. | Returns - Nothing.
  601. |
  602. ---------------------------------------------------------------------------*/
  603. STATIC VOID
  604. MadgeChangeFunctionalAddress(
  605. PMADGE_ADAPTER ndisAdap,
  606. TR_FUNCTIONAL_ADDRESS newAddress
  607. )
  608. {
  609. MULTI_ADDRESS multiAddress;
  610. // MadgePrint2("MadgeChangeFunctionalAddress started %08x\n",
  611. // (UINT) newAddress);
  612. ndisAdap->FunctionalAddress = newAddress;
  613. multiAddress.all = (DWORD) newAddress;
  614. ndisAdap->RequestType = NdisRequestSetInformation;
  615. //
  616. // And call the FTK to change the address.
  617. //
  618. driver_set_functional_address(ndisAdap->FtkAdapterHandle, &multiAddress);
  619. // MadgePrint1("MadgeChangeFunctionalAddress finished\n");
  620. }
  621. /*---------------------------------------------------------------------------
  622. |
  623. | Function - MadgeChangeFilter
  624. |
  625. | Parameters - ndisAdap -> Pointer to our NDIS level adapter structure.
  626. | newFilter -> The new packet filter.
  627. |
  628. | Purpose - Change the packet filter.
  629. |
  630. | Returns - NDIS_STATUS_PENDING if an SRB is required,
  631. | NDIS_STATUS_NOT_SUPPORTED if we don't support the filter
  632. | types, otherwise NDIS_STATUS_SUCCESS.
  633. |
  634. ---------------------------------------------------------------------------*/
  635. NDIS_STATUS
  636. MadgeChangeFilter(
  637. PMADGE_ADAPTER ndisAdap,
  638. UINT newFilter
  639. )
  640. {
  641. UINT index;
  642. UINT modifyOpenOptions;
  643. UINT oldFilter;
  644. //
  645. // Lookup table for the various ways we might want to modify the open
  646. // options of the adapter.
  647. //
  648. #define MOO_NO_CHANGE (0xffff)
  649. #define MOO_MASK ((WORD) (~(OPEN_OPT_COPY_ALL_MACS | OPEN_OPT_COPY_ALL_LLCS)))
  650. WORD MooLookupTable[] = {
  651. MOO_NO_CHANGE,
  652. OPEN_OPT_COPY_ALL_MACS | OPEN_OPT_COPY_ALL_LLCS,
  653. OPEN_OPT_COPY_ALL_MACS,
  654. OPEN_OPT_COPY_ALL_MACS | OPEN_OPT_COPY_ALL_LLCS,
  655. 0,
  656. MOO_NO_CHANGE,
  657. OPEN_OPT_COPY_ALL_MACS,
  658. MOO_NO_CHANGE,
  659. 0,
  660. OPEN_OPT_COPY_ALL_MACS | OPEN_OPT_COPY_ALL_LLCS,
  661. MOO_NO_CHANGE,
  662. OPEN_OPT_COPY_ALL_MACS | OPEN_OPT_COPY_ALL_LLCS,
  663. 0,
  664. MOO_NO_CHANGE,
  665. OPEN_OPT_COPY_ALL_MACS,
  666. MOO_NO_CHANGE
  667. };
  668. // MadgePrint2("MadgeChangeFilter started filter = %04x\n",
  669. // (UINT) newFilter);
  670. //
  671. // Do some pre-calculation.
  672. //
  673. modifyOpenOptions = 0;
  674. index = 0;
  675. oldFilter = ndisAdap->CurrentPacketFilter;
  676. // MadgePrint2("Old filter = %04x\n", oldFilter);
  677. //
  678. // By default, the card will receive directed frames, broadcast frames,
  679. // and matching functional and group address frames. Thus the following
  680. // filter types are handled automatically, whether we want them or not:
  681. // NDIS_PACKET_TYPE_DIRECTED NDIS_PACKET_TYPE_BROADCAST
  682. // NDIS_PACKET_TYPE_FUNCTIONAL NDIS_PACKET_TYPE_GROUP
  683. //
  684. // Of the remaining filters, the following are not supported (see below)
  685. // NDIS_PACKET_TYPE_MULTICAST NDIS_PACKET_TYPE_ALL_FUNCTIONAL
  686. // NDIS_PACKET_TYPE_ALL_MULTICAST NDIS_PACKET_TYPE_SOURCE_ROUTING
  687. //
  688. // This leaves NDIS_PACKET_TYPE_PROMISCUOUS and NDIS_PACKET_TYPE_MAC,
  689. // which we can handle if we want to.
  690. //
  691. if ((newFilter & (NDIS_PACKET_TYPE_MULTICAST |
  692. NDIS_PACKET_TYPE_ALL_FUNCTIONAL |
  693. NDIS_PACKET_TYPE_ALL_MULTICAST |
  694. NDIS_PACKET_TYPE_MAC_FRAME |
  695. NDIS_PACKET_TYPE_SOURCE_ROUTING)) != 0)
  696. {
  697. //
  698. // These filters are not supported - there is no way our MAC/hw can
  699. // be this selective, although the host software could do its own
  700. // filtering i.e. enable promiscuous mode, and then throw away all
  701. // frames except those indicated above. At some stage it might be
  702. // an idea to do this anyway, together with a caveat that it is not
  703. // going to be a high performance solution.
  704. //
  705. // Anyway, in the mean time, return NDIS_STATUS_NOT_SUPPORTED.
  706. //
  707. return NDIS_STATUS_NOT_SUPPORTED;
  708. }
  709. //
  710. // Only allow promiscuous mode if it has been enabled.
  711. //
  712. if ((newFilter & (NDIS_PACKET_TYPE_PROMISCUOUS |
  713. NDIS_PACKET_TYPE_MAC_FRAME)) != 0)
  714. {
  715. if (!ndisAdap->PromiscuousMode)
  716. {
  717. return NDIS_STATUS_NOT_SUPPORTED;
  718. }
  719. }
  720. //
  721. // We've weeded out the illegal ones now - note that no change has been
  722. // made to the current filter - this is as specified in the paperwork!
  723. //
  724. // Make a note of the _adapter_ notion of the filter. Each
  725. // binding will have its own idea of what it wants, but this is
  726. // the Filter Database's problem, not ours!
  727. //
  728. ndisAdap->CurrentPacketFilter = newFilter;
  729. //
  730. // Now we have to work out which bits need setting in the Modify Open
  731. // Options SRB - when I looked at this there didn't appear to be any
  732. // obvious way of simplifying the logic, so I use a look up table to do
  733. // the decoding instead. You'll just have to take my word for it that I
  734. // worked all the permutations out correctly!
  735. //
  736. if (oldFilter & NDIS_PACKET_TYPE_MAC_FRAME)
  737. {
  738. index |= 8;
  739. }
  740. if (oldFilter & NDIS_PACKET_TYPE_PROMISCUOUS)
  741. {
  742. index |= 4;
  743. }
  744. if (newFilter & NDIS_PACKET_TYPE_MAC_FRAME)
  745. {
  746. index |= 2;
  747. }
  748. if (newFilter & NDIS_PACKET_TYPE_PROMISCUOUS)
  749. {
  750. index |= 1;
  751. }
  752. // MadgePrint2("index = %d\n", index);
  753. modifyOpenOptions =
  754. (ndisAdap->OpenOptions & MOO_MASK) | MooLookupTable[index];
  755. // MadgePrint2("modifyOpenOptions = %04x\n", modifyOpenOptions);
  756. //
  757. // Now see if we need to issue an SRB - note that MOO_NO_CHANGE is not
  758. // zero, to distinguish from the case when we actually want to write out
  759. // zero to turn all the options off.
  760. //
  761. if (modifyOpenOptions != MOO_NO_CHANGE)
  762. {
  763. //
  764. // We have to issue a ModifyOpenOptions SRB.
  765. //
  766. ndisAdap->RequestType = NdisRequestSetInformation;
  767. ndisAdap->OpenOptions = (WORD) modifyOpenOptions;
  768. driver_modify_open_options(
  769. ndisAdap->FtkAdapterHandle,
  770. ndisAdap->OpenOptions
  771. );
  772. // MadgePrint1("MadgeChangeFilter pended\n");
  773. return NDIS_STATUS_PENDING;
  774. }
  775. // MadgePrint1("MadgeChangeFilter finished\n");
  776. return NDIS_STATUS_SUCCESS;
  777. }
  778. /***************************************************************************
  779. *
  780. * Function - MadgeSetInformation
  781. *
  782. * Parameters - adapterContext -> Pointer NDIS3 level adapter structure.
  783. * oid -> The OID.
  784. * infoBuffer -> Pointer to the information buffer.
  785. * infoLength -> Length of the information buffer.
  786. * bytesRead -> Pointer to a holder for the number of
  787. * bytes we've read.
  788. * bytesNeeded -> Pointer to a holder for the number of
  789. * bytes we need.
  790. *
  791. * Purpose - Set adapter information.
  792. *
  793. * Returns - An NDIS3 status code.
  794. *
  795. ***************************************************************************/
  796. NDIS_STATUS
  797. MadgeSetInformation(
  798. NDIS_HANDLE adapterContext,
  799. NDIS_OID oid,
  800. PVOID infoBuffer,
  801. ULONG infoLength,
  802. PULONG bytesRead,
  803. PULONG bytesNeeded
  804. )
  805. {
  806. PMADGE_ADAPTER ndisAdap;
  807. NDIS_STATUS retCode;
  808. // MadgePrint2("MadgeSetInformation Oid = %08x\n", (UINT) oid);
  809. //
  810. // Do some pre-calculation.
  811. //
  812. ndisAdap = PMADGE_ADAPTER_FROM_CONTEXT(adapterContext);
  813. //
  814. // Process the request.
  815. //
  816. switch (oid)
  817. {
  818. case OID_802_5_CURRENT_FUNCTIONAL:
  819. if (infoLength != TR_LENGTH_OF_FUNCTIONAL)
  820. {
  821. *bytesNeeded = TR_LENGTH_OF_FUNCTIONAL;
  822. retCode = NDIS_STATUS_INVALID_LENGTH;
  823. }
  824. else
  825. {
  826. MadgeChangeFunctionalAddress(
  827. ndisAdap,
  828. *((TR_FUNCTIONAL_ADDRESS *) infoBuffer)
  829. );
  830. *bytesRead = TR_LENGTH_OF_FUNCTIONAL;
  831. retCode = NDIS_STATUS_PENDING;
  832. }
  833. break;
  834. case OID_802_5_CURRENT_GROUP:
  835. if (infoLength != TR_LENGTH_OF_FUNCTIONAL)
  836. {
  837. *bytesNeeded = TR_LENGTH_OF_FUNCTIONAL;
  838. retCode = NDIS_STATUS_INVALID_LENGTH;
  839. }
  840. else
  841. {
  842. MadgeChangeGroupAddress(
  843. ndisAdap,
  844. *((TR_FUNCTIONAL_ADDRESS *) infoBuffer)
  845. );
  846. *bytesRead = TR_LENGTH_OF_FUNCTIONAL;
  847. retCode = NDIS_STATUS_PENDING;
  848. }
  849. break;
  850. case OID_GEN_CURRENT_PACKET_FILTER:
  851. if (infoLength != sizeof(UINT))
  852. {
  853. *bytesNeeded = sizeof(UINT);
  854. retCode = NDIS_STATUS_INVALID_LENGTH;
  855. }
  856. else
  857. {
  858. retCode = MadgeChangeFilter(
  859. ndisAdap,
  860. *((UINT *) infoBuffer)
  861. );
  862. *bytesRead = sizeof(UINT);
  863. }
  864. break;
  865. case OID_GEN_CURRENT_LOOKAHEAD:
  866. //
  867. // It IS important to record the current lookahead. On WFWG
  868. // machines it is not possible to indicate the whole frame
  869. // as lookahead, so take a note of it here.
  870. //
  871. // MadgePrint3("Set lookahead infoLength = %d (%d)\n", infoLength, sizeof(ULONG));
  872. if (infoLength != sizeof(ULONG))
  873. {
  874. *bytesNeeded = sizeof(ULONG);
  875. retCode = NDIS_STATUS_INVALID_LENGTH;
  876. }
  877. else
  878. {
  879. ndisAdap->CurrentLookahead =
  880. MIN(
  881. ndisAdap->MaxFrameSize - FRAME_HEADER_SIZE,
  882. MAX(
  883. *((ULONG *) infoBuffer),
  884. MADGE_MINIMUM_LOOKAHEAD
  885. )
  886. );
  887. *bytesRead = sizeof(ULONG);
  888. retCode = NDIS_STATUS_SUCCESS;
  889. }
  890. break;
  891. case OID_GEN_PROTOCOL_OPTIONS:
  892. //
  893. // This does nothing - we really don't care about the protocol
  894. // options at the moment since we are too stupid to make use of
  895. // them anyway.
  896. //
  897. *bytesRead = 4;
  898. retCode = NDIS_STATUS_SUCCESS;
  899. break;
  900. default:
  901. MadgePrint1("Invalid OID\n");
  902. retCode = NDIS_STATUS_INVALID_OID;
  903. break;
  904. }
  905. return retCode;
  906. }
  907. /******** End of REQUEST.C ************************************************/