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.

427 lines
12 KiB

  1. /*
  2. ************************************************************************
  3. *
  4. * REQUEST.c
  5. *
  6. *
  7. * (C) Copyright 1996 National Semiconductor Corp.
  8. * (C) Copyright 1996 Microsoft Corp.
  9. *
  10. *
  11. * (ep)
  12. *
  13. *************************************************************************
  14. */
  15. #include "nsc.h"
  16. #include "request.tmh"
  17. #include "newdong.h"
  18. const NDIS_OID NSCGlobalSupportedOids[] = {
  19. OID_GEN_SUPPORTED_LIST,
  20. OID_GEN_HARDWARE_STATUS,
  21. OID_GEN_MEDIA_SUPPORTED,
  22. OID_GEN_MEDIA_IN_USE,
  23. OID_GEN_MAXIMUM_LOOKAHEAD,
  24. OID_GEN_MAXIMUM_FRAME_SIZE,
  25. OID_GEN_MAXIMUM_SEND_PACKETS,
  26. OID_GEN_MAXIMUM_TOTAL_SIZE,
  27. OID_GEN_MAC_OPTIONS,
  28. OID_GEN_PROTOCOL_OPTIONS,
  29. OID_GEN_LINK_SPEED,
  30. OID_GEN_TRANSMIT_BUFFER_SPACE,
  31. OID_GEN_RECEIVE_BUFFER_SPACE,
  32. OID_GEN_TRANSMIT_BLOCK_SIZE,
  33. OID_GEN_RECEIVE_BLOCK_SIZE,
  34. OID_GEN_VENDOR_DESCRIPTION,
  35. OID_GEN_VENDOR_DRIVER_VERSION,
  36. OID_GEN_DRIVER_VERSION,
  37. OID_GEN_CURRENT_PACKET_FILTER,
  38. OID_GEN_CURRENT_LOOKAHEAD,
  39. OID_GEN_MEDIA_CONNECT_STATUS,
  40. OID_IRDA_RECEIVING,
  41. OID_IRDA_SUPPORTED_SPEEDS,
  42. OID_IRDA_LINK_SPEED,
  43. OID_IRDA_MEDIA_BUSY,
  44. OID_IRDA_TURNAROUND_TIME,
  45. OID_IRDA_MAX_RECEIVE_WINDOW_SIZE,
  46. OID_IRDA_EXTRA_RCV_BOFS,
  47. OID_IRDA_MAX_SEND_WINDOW_SIZE
  48. };
  49. //////////////////////////////////////////////////////////////////////////
  50. // //
  51. // Function: MiniportQueryInformation //
  52. // //
  53. // Description: //
  54. // Query the capabilities and status of the miniport driver. //
  55. // //
  56. //////////////////////////////////////////////////////////////////////////
  57. NDIS_STATUS MiniportQueryInformation (
  58. IN NDIS_HANDLE MiniportAdapterContext,
  59. IN NDIS_OID Oid,
  60. IN PVOID InformationBuffer,
  61. IN ULONG InformationBufferLength,
  62. OUT PULONG BytesWritten,
  63. OUT PULONG BytesNeeded)
  64. {
  65. NDIS_STATUS result = NDIS_STATUS_SUCCESS;
  66. IrDevice *thisDev = CONTEXT_TO_DEV(MiniportAdapterContext);
  67. INT i, speeds, speedSupported;
  68. UINT *infoPtr;
  69. NDIS_MEDIUM Medium = NdisMediumIrda;
  70. ULONG GenericUlong;
  71. PVOID SourceBuffer = (PVOID) (&GenericUlong);
  72. ULONG SourceLength = sizeof(ULONG);
  73. ULONG BaudRateTable[NUM_BAUDRATES];
  74. switch (Oid){
  75. case OID_GEN_SUPPORTED_LIST:
  76. SourceBuffer = (PVOID) (NSCGlobalSupportedOids);
  77. SourceLength = sizeof(NSCGlobalSupportedOids);
  78. break;
  79. case OID_GEN_HARDWARE_STATUS:
  80. GenericUlong = thisDev->hardwareStatus;
  81. break;
  82. case OID_GEN_MEDIA_SUPPORTED:
  83. case OID_GEN_MEDIA_IN_USE:
  84. SourceBuffer = (PVOID) (&Medium);
  85. SourceLength = sizeof(NDIS_MEDIUM);
  86. break;
  87. case OID_IRDA_RECEIVING:
  88. DBGOUT(("MiniportQueryInformation(OID_IRDA_RECEIVING)"));
  89. GenericUlong = (ULONG)thisDev->nowReceiving;
  90. break;
  91. case OID_IRDA_SUPPORTED_SPEEDS:
  92. DBGOUT(("MiniportQueryInformation(OID_IRDA_SUPPORTED_SPEEDS)"));
  93. speeds = thisDev->portInfo.hwCaps.supportedSpeedsMask &
  94. thisDev->AllowedSpeedMask &
  95. ALL_IRDA_SPEEDS;
  96. for (i = 0, infoPtr = (PUINT)BaudRateTable, SourceLength=0;
  97. (i < NUM_BAUDRATES) && speeds;
  98. i++){
  99. if (supportedBaudRateTable[i].ndisCode & speeds){
  100. *infoPtr++ = supportedBaudRateTable[i].bitsPerSec;
  101. SourceLength += sizeof(UINT);
  102. speeds &= ~supportedBaudRateTable[i].ndisCode;
  103. DBGOUT((" - supporting speed %d bps", supportedBaudRateTable[i].bitsPerSec));
  104. }
  105. }
  106. SourceBuffer = (PVOID) BaudRateTable;
  107. break;
  108. case OID_GEN_LINK_SPEED:
  109. // The maximum speed of NIC is 4Mbps
  110. GenericUlong = 40000; // 100bps increments
  111. break;
  112. case OID_IRDA_LINK_SPEED:
  113. DBGOUT(("MiniportQueryInformation(OID_IRDA_LINK_SPEED)"));
  114. if (thisDev->linkSpeedInfo){
  115. GenericUlong = (ULONG)thisDev->linkSpeedInfo->bitsPerSec;
  116. }
  117. else {
  118. GenericUlong = DEFAULT_BAUD_RATE;
  119. }
  120. break;
  121. case OID_IRDA_MEDIA_BUSY:
  122. DBGOUT(("MiniportQueryInformation(OID_IRDA_MEDIA_BUSY)"));
  123. GenericUlong = (UINT)thisDev->mediaBusy;
  124. break;
  125. case OID_GEN_CURRENT_LOOKAHEAD:
  126. case OID_GEN_MAXIMUM_LOOKAHEAD:
  127. DBGOUT(("MiniportQueryInformation(OID_GEN_MAXIMUM_LOOKAHEAD)"));
  128. GenericUlong = MAX_I_DATA_SIZE;
  129. break;
  130. case OID_GEN_MAXIMUM_TOTAL_SIZE:
  131. case OID_GEN_TRANSMIT_BLOCK_SIZE:
  132. case OID_GEN_RECEIVE_BLOCK_SIZE:
  133. case OID_GEN_MAXIMUM_FRAME_SIZE:
  134. DBGOUT(("MiniportQueryInformation(OID_GEN_MAXIMUM_LOOKAHEAD)"));
  135. // Normally there's some difference in these values, based on the
  136. // MAC header, but IrDA doesn't have one.
  137. GenericUlong = MAX_I_DATA_SIZE;
  138. break;
  139. case OID_GEN_RECEIVE_BUFFER_SPACE:
  140. case OID_GEN_TRANSMIT_BUFFER_SPACE:
  141. GenericUlong = (ULONG) (MAX_IRDA_DATA_SIZE * 8);
  142. break;
  143. case OID_GEN_MAC_OPTIONS:
  144. DBGOUT(("MiniportQueryInformation(OID_GEN_MAC_OPTIONS)"));
  145. GenericUlong = 0;
  146. break;
  147. case OID_GEN_MAXIMUM_SEND_PACKETS:
  148. DBGOUT(("MiniportQueryInformation(OID_GEN_MAXIMUM_SEND_PACKETS)"));
  149. GenericUlong = 16;
  150. break;
  151. case OID_IRDA_TURNAROUND_TIME:
  152. // Indicate the amount of time that the transceiver needs
  153. // to recuperate after a send.
  154. DBGOUT(("MiniportQueryInformation(OID_IRDA_TURNAROUND_TIME)"));
  155. GenericUlong =
  156. (ULONG)thisDev->portInfo.hwCaps.turnAroundTime_usec;
  157. break;
  158. case OID_IRDA_EXTRA_RCV_BOFS:
  159. // Pass back the number of _extra_ BOFs to be prepended
  160. // to packets sent to this unit at 115.2 baud, the
  161. // maximum Slow IR speed. This will be scaled for other
  162. // speed according to the table in the
  163. // Infrared Extensions to NDIS' spec.
  164. DBGOUT(("MiniportQueryInformation(OID_IRDA_EXTRA_RCV_BOFS)"));
  165. GenericUlong = (ULONG)thisDev->portInfo.hwCaps.extraBOFsRequired;
  166. break;
  167. case OID_GEN_CURRENT_PACKET_FILTER:
  168. DBGOUT(("MiniportQueryInformation(OID_GEN_CURRENT_PACKET_FILTER)"));
  169. GenericUlong = NDIS_PACKET_TYPE_PROMISCUOUS;
  170. break;
  171. case OID_IRDA_MAX_RECEIVE_WINDOW_SIZE:
  172. DBGOUT(("MiniportQueryInformation(OID_IRDA_MAX_RECEIVE_WINDOW_SIZE)"));
  173. GenericUlong = MAX_RX_PACKETS;
  174. //GenericUlong = 1;
  175. break;
  176. case OID_GEN_VENDOR_DESCRIPTION:
  177. SourceBuffer = (PVOID)"NSC Infrared Port";
  178. SourceLength = 18;
  179. break;
  180. case OID_GEN_VENDOR_DRIVER_VERSION:
  181. // This value is used to know whether to update driver.
  182. GenericUlong = (NSC_MAJOR_VERSION << 16) +
  183. (NSC_MINOR_VERSION << 8) +
  184. NSC_LETTER_VERSION;
  185. break;
  186. case OID_GEN_DRIVER_VERSION:
  187. GenericUlong = (NDIS_MAJOR_VERSION << 8) + NDIS_MINOR_VERSION;
  188. SourceLength = 2;
  189. break;
  190. case OID_IRDA_MAX_SEND_WINDOW_SIZE:
  191. GenericUlong = 7;
  192. break;
  193. case OID_GEN_MEDIA_CONNECT_STATUS:
  194. GenericUlong = (ULONG) NdisMediaStateConnected;
  195. break;
  196. default:
  197. DBGERR(("MiniportQueryInformation(%d=0x%x), unsupported OID", Oid, Oid));
  198. result = NDIS_STATUS_NOT_SUPPORTED;
  199. break;
  200. }
  201. if (result == NDIS_STATUS_SUCCESS) {
  202. if (SourceLength > InformationBufferLength) {
  203. *BytesNeeded = SourceLength;
  204. result = NDIS_STATUS_INVALID_LENGTH;
  205. } else {
  206. *BytesNeeded = 0;
  207. *BytesWritten = SourceLength;
  208. NdisMoveMemory(InformationBuffer, SourceBuffer, SourceLength);
  209. DBGOUT(("MiniportQueryInformation succeeded (info <- %d)", *(UINT *)InformationBuffer));
  210. }
  211. }
  212. return result;
  213. }
  214. //////////////////////////////////////////////////////////////////////////
  215. // //
  216. // Function: MiniportSetInformation //
  217. // //
  218. // Description: //
  219. // Allow other layers of the network software (e.g., a transport //
  220. // driver) to control the miniport driver by changing information that //
  221. // the miniport driver maintains in its OIDs, such as the packet //
  222. // or multicast addresses. //
  223. // //
  224. //////////////////////////////////////////////////////////////////////////
  225. NDIS_STATUS MiniportSetInformation (
  226. IN NDIS_HANDLE MiniportAdapterContext,
  227. IN NDIS_OID Oid,
  228. IN PVOID InformationBuffer,
  229. IN ULONG InformationBufferLength,
  230. OUT PULONG BytesRead,
  231. OUT PULONG BytesNeeded)
  232. {
  233. NDIS_STATUS result = NDIS_STATUS_SUCCESS;
  234. IrDevice *thisDev = CONTEXT_TO_DEV(MiniportAdapterContext);
  235. UINT i,speedSupported;
  236. const baudRateInfo * CurrentLinkSpeed;
  237. if (InformationBufferLength >= sizeof(UINT)){
  238. UINT info = *(UINT *)InformationBuffer;
  239. *BytesRead = sizeof(UINT);
  240. *BytesNeeded = 0;
  241. switch (Oid){
  242. case OID_IRDA_LINK_SPEED:
  243. DBGOUT(("MiniportSetInformation(OID_IRDA_LINK_SPEED, %xh)",
  244. info));
  245. result = NDIS_STATUS_INVALID_DATA;
  246. CurrentLinkSpeed=thisDev->linkSpeedInfo;
  247. // Find the appropriate speed and set it
  248. speedSupported = NUM_BAUDRATES;
  249. for (i = 0; i < speedSupported; i++){
  250. if (supportedBaudRateTable[i].bitsPerSec == info){
  251. thisDev->linkSpeedInfo = &supportedBaudRateTable[i];
  252. result = NDIS_STATUS_SUCCESS;
  253. break;
  254. }
  255. }
  256. if (result == NDIS_STATUS_SUCCESS){
  257. if (CurrentLinkSpeed != thisDev->linkSpeedInfo) {
  258. //
  259. // different from the current
  260. //
  261. BOOLEAN DoItNow=TRUE;
  262. NdisAcquireSpinLock(&thisDev->QueueLock);
  263. if (!IsListEmpty(&thisDev->SendQueue)){
  264. //
  265. // packets queued, change after this one
  266. //
  267. thisDev->lastPacketAtOldSpeed = CONTAINING_RECORD(thisDev->SendQueue.Blink,
  268. NDIS_PACKET,
  269. MiniportReserved);
  270. DBGOUT(("delaying set-speed because send pkts queued"));
  271. DoItNow=FALSE;
  272. } else {
  273. //
  274. // no packets in the queue
  275. //
  276. if (thisDev->CurrentPacket != NULL) {
  277. //
  278. // the current packet is the only one
  279. //
  280. thisDev->lastPacketAtOldSpeed=thisDev->CurrentPacket;
  281. thisDev->setSpeedAfterCurrentSendPacket = TRUE;
  282. DBGOUT(("delaying set-speed because send pkts queued"));
  283. DoItNow=FALSE;
  284. }
  285. }
  286. if (DoItNow) {
  287. if (!SetSpeed(thisDev)){
  288. result = NDIS_STATUS_FAILURE;
  289. }
  290. thisDev->TransmitIsIdle=FALSE;
  291. }
  292. NdisReleaseSpinLock(&thisDev->QueueLock);
  293. if (DoItNow) {
  294. ProcessSendQueue(thisDev);
  295. }
  296. }
  297. }
  298. else {
  299. *BytesRead = 0;
  300. *BytesNeeded = 0;
  301. }
  302. break;
  303. case OID_IRDA_MEDIA_BUSY:
  304. DBGOUT(("MiniportSetInformation(OID_IRDA_MEDIA_BUSY, %xh)",
  305. info));
  306. // The protocol can use this OID to reset the busy field
  307. // in order to check it later for intervening activity.
  308. //
  309. thisDev->mediaBusy = (BOOLEAN)info;
  310. InterlockedExchange(&thisDev->RxInterrupts,0);
  311. result = NDIS_STATUS_SUCCESS;
  312. break;
  313. case OID_GEN_CURRENT_PACKET_FILTER:
  314. DBGOUT(
  315. ("MiniportSetInformation(OID_GEN_CURRENT_PACKET_FILTER, %xh)",
  316. info));
  317. result = NDIS_STATUS_SUCCESS;
  318. break;
  319. case OID_GEN_CURRENT_LOOKAHEAD:
  320. result = (info<=MAX_I_DATA_SIZE) ? NDIS_STATUS_SUCCESS : NDIS_STATUS_INVALID_LENGTH;
  321. break;
  322. // We don't support these
  323. //
  324. case OID_IRDA_RATE_SNIFF:
  325. case OID_IRDA_UNICAST_LIST:
  326. // These are query-only parameters.
  327. //
  328. case OID_IRDA_SUPPORTED_SPEEDS:
  329. case OID_IRDA_MAX_UNICAST_LIST_SIZE:
  330. case OID_IRDA_TURNAROUND_TIME:
  331. default:
  332. DBGERR(("MiniportSetInformation(OID=%d=0x%x, value=%xh) - unsupported OID", Oid, Oid, info));
  333. *BytesRead = 0;
  334. *BytesNeeded = 0;
  335. result = NDIS_STATUS_NOT_SUPPORTED;
  336. break;
  337. }
  338. }
  339. else {
  340. *BytesRead = 0;
  341. *BytesNeeded = sizeof(UINT);
  342. result = NDIS_STATUS_INVALID_LENGTH;
  343. }
  344. DBGOUT(("MiniportSetInformation succeeded"));
  345. return result;
  346. }