atl1chw.c 69 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288128912901291129212931294129512961297129812991300130113021303130413051306130713081309131013111312131313141315131613171318131913201321132213231324132513261327132813291330133113321333133413351336133713381339134013411342134313441345134613471348134913501351135213531354135513561357135813591360136113621363136413651366136713681369137013711372137313741375137613771378137913801381138213831384138513861387138813891390139113921393139413951396139713981399140014011402140314041405140614071408140914101411141214131414141514161417141814191420142114221423142414251426142714281429143014311432143314341435143614371438143914401441144214431444144514461447144814491450145114521453145414551456145714581459146014611462146314641465146614671468146914701471147214731474147514761477147814791480148114821483148414851486148714881489149014911492149314941495149614971498149915001501150215031504150515061507150815091510151115121513151415151516151715181519152015211522152315241525152615271528152915301531153215331534153515361537153815391540154115421543154415451546154715481549155015511552155315541555155615571558155915601561156215631564156515661567156815691570157115721573157415751576157715781579158015811582158315841585158615871588158915901591159215931594159515961597159815991600160116021603160416051606160716081609161016111612161316141615161616171618161916201621162216231624162516261627162816291630163116321633163416351636163716381639164016411642164316441645164616471648164916501651165216531654165516561657165816591660166116621663166416651666166716681669167016711672167316741675167616771678167916801681168216831684168516861687168816891690169116921693169416951696169716981699170017011702170317041705170617071708170917101711171217131714171517161717171817191720172117221723172417251726172717281729173017311732173317341735173617371738173917401741174217431744174517461747174817491750175117521753175417551756175717581759176017611762176317641765176617671768176917701771177217731774177517761777177817791780178117821783178417851786178717881789179017911792179317941795179617971798179918001801180218031804180518061807180818091810181118121813181418151816181718181819182018211822182318241825182618271828182918301831183218331834183518361837183818391840184118421843184418451846184718481849185018511852185318541855185618571858185918601861186218631864186518661867186818691870187118721873187418751876187718781879188018811882188318841885188618871888188918901891189218931894189518961897189818991900190119021903190419051906190719081909191019111912191319141915191619171918191919201921192219231924192519261927192819291930193119321933193419351936193719381939194019411942194319441945194619471948194919501951195219531954195519561957195819591960196119621963196419651966196719681969197019711972197319741975197619771978197919801981198219831984198519861987198819891990199119921993199419951996199719981999200020012002200320042005200620072008200920102011201220132014201520162017201820192020202120222023202420252026202720282029203020312032203320342035203620372038203920402041204220432044204520462047204820492050205120522053205420552056205720582059206020612062206320642065206620672068206920702071207220732074207520762077207820792080208120822083208420852086208720882089209020912092209320942095209620972098209921002101210221032104210521062107210821092110211121122113211421152116211721182119212021212122212321242125212621272128212921302131213221332134213521362137213821392140214121422143214421452146214721482149215021512152215321542155215621572158215921602161216221632164216521662167216821692170217121722173217421752176217721782179218021812182218321842185218621872188218921902191219221932194219521962197219821992200220122022203220422052206220722082209221022112212221322142215221622172218221922202221222222232224222522262227222822292230223122322233223422352236223722382239224022412242224322442245224622472248224922502251225222532254225522562257225822592260226122622263226422652266226722682269227022712272227322742275227622772278227922802281228222832284228522862287228822892290229122922293229422952296229722982299230023012302230323042305230623072308230923102311231223132314231523162317231823192320232123222323232423252326232723282329233023312332233323342335233623372338233923402341234223432344234523462347234823492350235123522353235423552356235723582359236023612362236323642365236623672368236923702371237223732374237523762377237823792380238123822383238423852386238723882389239023912392239323942395239623972398239924002401240224032404240524062407240824092410241124122413241424152416241724182419242024212422242324242425242624272428242924302431243224332434243524362437243824392440244124422443244424452446244724482449245024512452245324542455245624572458245924602461246224632464246524662467246824692470247124722473247424752476247724782479248024812482248324842485248624872488248924902491249224932494249524962497249824992500250125022503250425052506250725082509251025112512251325142515251625172518251925202521252225232524252525262527252825292530253125322533253425352536253725382539254025412542254325442545254625472548254925502551255225532554255525562557255825592560256125622563256425652566256725682569257025712572257325742575257625772578257925802581258225832584258525862587258825892590259125922593259425952596259725982599260026012602260326042605260626072608260926102611261226132614261526162617261826192620262126222623262426252626262726282629263026312632263326342635263626372638263926402641264226432644264526462647264826492650265126522653265426552656265726582659266026612662266326642665266626672668266926702671267226732674267526762677267826792680268126822683268426852686268726882689269026912692269326942695269626972698269927002701270227032704270527062707270827092710271127122713271427152716271727182719272027212722272327242725272627272728272927302731273227332734273527362737273827392740274127422743274427452746274727482749275027512752275327542755275627572758275927602761276227632764276527662767276827692770277127722773277427752776277727782779278027812782278327842785278627872788278927902791279227932794279527962797279827992800280128022803280428052806280728082809281028112812281328142815281628172818281928202821282228232824282528262827282828292830283128322833283428352836283728382839284028412842284328442845284628472848284928502851285228532854285528562857285828592860286128622863286428652866286728682869287028712872287328742875287628772878287928802881288228832884288528862887288828892890289128922893289428952896289728982899290029012902290329042905290629072908290929102911291229132914291529162917291829192920292129222923292429252926292729282929293029312932293329342935293629372938293929402941294229432944294529462947294829492950295129522953295429552956295729582959296029612962296329642965296629672968296929702971297229732974297529762977297829792980298129822983298429852986298729882989299029912992299329942995299629972998
  1. /*++
  2. Copyright (c) 2013 Minoca Corp. All Rights Reserved
  3. Module Name:
  4. atl1chw.c
  5. Abstract:
  6. This module implements the portion of the ATL1c driver that actually
  7. interacts with the hardware.
  8. Author:
  9. Evan Green 18-Apr-2013
  10. Environment:
  11. Kernel
  12. --*/
  13. //
  14. // ------------------------------------------------------------------- Includes
  15. //
  16. #include <minoca/kernel/driver.h>
  17. #include <minoca/net/netdrv.h>
  18. #include "atl1c.h"
  19. //
  20. // ---------------------------------------------------------------- Definitions
  21. //
  22. //
  23. // Define the maximum amount of packets that ATL will keep queued before it
  24. // starts to drop packets.
  25. //
  26. //
  27. #define ATL_MAX_TRANSMIT_PACKET_LIST_COUNT (ATL1C_TRANSMIT_DESCRIPTOR_COUNT * 2)
  28. //
  29. // ------------------------------------------------------ Data Type Definitions
  30. //
  31. //
  32. // ----------------------------------------------- Internal Function Prototypes
  33. //
  34. VOID
  35. AtlpReapCompletedTransmitDescriptors (
  36. PATL1C_DEVICE Device
  37. );
  38. VOID
  39. AtlpSendPendingPackets (
  40. PATL1C_DEVICE Device
  41. );
  42. VOID
  43. AtlpReapReceivedFrames (
  44. PATL1C_DEVICE Device
  45. );
  46. VOID
  47. AtlpDisableL0sAndL1 (
  48. PATL1C_DEVICE Device
  49. );
  50. BOOL
  51. AtlpResetPhy (
  52. PATL1C_DEVICE Device
  53. );
  54. BOOL
  55. AtlpApplyChipReset (
  56. PATL1C_DEVICE Device
  57. );
  58. BOOL
  59. AtlpStopController (
  60. PATL1C_DEVICE Device
  61. );
  62. BOOL
  63. AtlpStopMac (
  64. PATL1C_DEVICE Device
  65. );
  66. BOOL
  67. AtlpStopQueue (
  68. PATL1C_DEVICE Device
  69. );
  70. VOID
  71. AtlpSetupReceiveFilters (
  72. PATL1C_DEVICE Device
  73. );
  74. KSTATUS
  75. AtlpEnableDevice (
  76. PATL1C_DEVICE Device
  77. );
  78. VOID
  79. AtlpStartQueue (
  80. PATL1C_DEVICE Device
  81. );
  82. VOID
  83. AtlpConfigureMac (
  84. PATL1C_DEVICE Device
  85. );
  86. BOOL
  87. AtlpReadPhyDebugRegister (
  88. PATL1C_DEVICE Device,
  89. USHORT Register,
  90. PUSHORT Data
  91. );
  92. BOOL
  93. AtlpWritePhyDebugRegister (
  94. PATL1C_DEVICE Device,
  95. USHORT Register,
  96. USHORT Data
  97. );
  98. BOOL
  99. AtlpPerformPhyRegisterIo (
  100. PATL1C_DEVICE Device,
  101. BOOL Write,
  102. BOOL Extension,
  103. UCHAR Address,
  104. USHORT Register,
  105. PUSHORT Data
  106. );
  107. ULONG
  108. AtlpWaitForIdleUnit (
  109. PATL1C_DEVICE Device,
  110. ULONG BitsToBecomeClear
  111. );
  112. BOOL
  113. AtlpReadMacAddress (
  114. PATL1C_DEVICE Device
  115. );
  116. BOOL
  117. AtlpDoesEepromExist (
  118. PATL1C_DEVICE Device
  119. );
  120. BOOL
  121. AtlpReadCurrentMacAddress (
  122. PATL1C_DEVICE Device
  123. );
  124. VOID
  125. AtlpDisableDeviceInterrupts (
  126. PATL1C_DEVICE Device
  127. );
  128. VOID
  129. AtlpEnableDeviceInterrupts (
  130. PATL1C_DEVICE Device
  131. );
  132. VOID
  133. AtlpSetActiveStatePowerManagement (
  134. PATL1C_DEVICE Device,
  135. ATL_SPEED Speed
  136. );
  137. VOID
  138. AtlpResetTransmitRing (
  139. PATL1C_DEVICE Device
  140. );
  141. VOID
  142. AtlpResetReceiveRing (
  143. PATL1C_DEVICE Device
  144. );
  145. BOOL
  146. AtlpGetLinkCharacteristics (
  147. PATL1C_DEVICE Device,
  148. PATL_SPEED Speed,
  149. PATL_DUPLEX_MODE Duplex
  150. );
  151. ULONG
  152. AtlpHashAddress (
  153. PUCHAR MacAddress
  154. );
  155. RUNLEVEL
  156. AtlpAcquireInterruptLock (
  157. PATL1C_DEVICE Device
  158. );
  159. VOID
  160. AtlpReleaseInterruptLock (
  161. PATL1C_DEVICE Device,
  162. RUNLEVEL OldRunLevel
  163. );
  164. //
  165. // -------------------------------------------------------------------- Globals
  166. //
  167. BOOL AtlDisablePacketDropping = FALSE;
  168. //
  169. // ------------------------------------------------------------------ Functions
  170. //
  171. KSTATUS
  172. AtlSend (
  173. PVOID DeviceContext,
  174. PNET_PACKET_LIST PacketList
  175. )
  176. /*++
  177. Routine Description:
  178. This routine sends data through the network.
  179. Arguments:
  180. DeviceContext - Supplies a pointer to the device context associated with
  181. the link down which this data is to be sent.
  182. PacketList - Supplies a pointer to a list of network packets to send. Data
  183. in these packets may be modified by this routine, but must not be used
  184. once this routine returns.
  185. Return Value:
  186. STATUS_SUCCESS if all packets were sent.
  187. STATUS_RESOURCE_IN_USE if some or all of the packets were dropped due to
  188. the hardware being backed up with too many packets to send.
  189. Other failure codes indicate that none of the packets were sent.
  190. --*/
  191. {
  192. PATL1C_DEVICE Device;
  193. UINTN PacketListCount;
  194. KSTATUS Status;
  195. ASSERT(KeGetRunLevel() == RunLevelLow);
  196. Device = (PATL1C_DEVICE)DeviceContext;
  197. KeAcquireQueuedLock(Device->TransmitLock);
  198. if (Device->LinkActive == FALSE) {
  199. Status = STATUS_NO_NETWORK_CONNECTION;
  200. goto SendEnd;
  201. }
  202. //
  203. // If there is any room in the packet list (or dropping packets is
  204. // disabled), add all of the packets to the list waiting to be sent.
  205. //
  206. PacketListCount = Device->TransmitPacketList.Count;
  207. if ((PacketListCount < ATL_MAX_TRANSMIT_PACKET_LIST_COUNT) ||
  208. (AtlDisablePacketDropping != FALSE)) {
  209. NET_APPEND_PACKET_LIST(PacketList, &(Device->TransmitPacketList));
  210. AtlpSendPendingPackets(Device);
  211. Status = STATUS_SUCCESS;
  212. //
  213. // Otherwise report that the resource is use as it is too busy to handle
  214. // more packets.
  215. //
  216. } else {
  217. Status = STATUS_RESOURCE_IN_USE;
  218. }
  219. SendEnd:
  220. KeReleaseQueuedLock(Device->TransmitLock);
  221. return Status;
  222. }
  223. KSTATUS
  224. AtlGetSetInformation (
  225. PVOID DeviceContext,
  226. NET_LINK_INFORMATION_TYPE InformationType,
  227. PVOID Data,
  228. PUINTN DataSize,
  229. BOOL Set
  230. )
  231. /*++
  232. Routine Description:
  233. This routine gets or sets the network device layer's link information.
  234. Arguments:
  235. DeviceContext - Supplies a pointer to the device context associated with
  236. the link for which information is being set or queried.
  237. InformationType - Supplies the type of information being queried or set.
  238. Data - Supplies a pointer to the data buffer where the data is either
  239. returned for a get operation or given for a set operation.
  240. DataSize - Supplies a pointer that on input contains the size of the data
  241. buffer. On output, contains the required size of the data buffer.
  242. Set - Supplies a boolean indicating if this is a get operation (FALSE) or a
  243. set operation (TRUE).
  244. Return Value:
  245. Status code.
  246. --*/
  247. {
  248. PULONG Flags;
  249. KSTATUS Status;
  250. switch (InformationType) {
  251. case NetLinkInformationChecksumOffload:
  252. if (*DataSize != sizeof(ULONG)) {
  253. return STATUS_INVALID_PARAMETER;
  254. }
  255. if (Set != FALSE) {
  256. return STATUS_NOT_SUPPORTED;
  257. }
  258. Flags = (PULONG)Data;
  259. *Flags = 0;
  260. break;
  261. default:
  262. Status = STATUS_NOT_SUPPORTED;
  263. break;
  264. }
  265. return Status;
  266. }
  267. KSTATUS
  268. AtlpInitializeDeviceStructures (
  269. PATL1C_DEVICE Device
  270. )
  271. /*++
  272. Routine Description:
  273. This routine performs housekeeping preparation for resetting and enabling
  274. an ATL1c device.
  275. Arguments:
  276. Device - Supplies a pointer to the device.
  277. Return Value:
  278. Status code.
  279. --*/
  280. {
  281. ULONG AllocationSize;
  282. ULONG IoBufferFlags;
  283. PHYSICAL_ADDRESS PhysicalAddress;
  284. ULONG Size;
  285. ULONG SlotIndex;
  286. KSTATUS Status;
  287. KeInitializeSpinLock(&(Device->InterruptLock));
  288. Device->Speed = AtlSpeedOff;
  289. Device->Duplex = AtlDuplexInvalid;
  290. Device->EnabledInterrupts = ATL_INTERRUPT_DEFAULT_MASK;
  291. //
  292. // Allocate the transmit and receive locks.
  293. //
  294. Device->TransmitLock = KeCreateQueuedLock();
  295. if (Device->TransmitLock == NULL) {
  296. Status = STATUS_INSUFFICIENT_RESOURCES;
  297. goto InitializeDeviceStructuresEnd;
  298. }
  299. Device->ReceiveLock = KeCreateQueuedLock();
  300. if (Device->ReceiveLock == NULL) {
  301. Status = STATUS_INSUFFICIENT_RESOURCES;
  302. goto InitializeDeviceStructuresEnd;
  303. }
  304. //
  305. // Allocate the descriptor buffer to hold the transmit descriptors,
  306. // transmit buffer array, receive slot array, received packet status array,
  307. // and the received frame data itself. The transmit queue has one extra
  308. // descriptor for the empty high priority queue.
  309. //
  310. AllocationSize = ((ATL1C_TRANSMIT_DESCRIPTOR_COUNT + 1) *
  311. sizeof(ATL1C_TRANSMIT_DESCRIPTOR)) +
  312. (ATL1C_TRANSMIT_DESCRIPTOR_COUNT * sizeof(PVOID)) +
  313. (ATL1C_RECEIVE_FRAME_COUNT *
  314. (sizeof(ATL1C_RECEIVE_SLOT) +
  315. sizeof(ATL1C_RECEIVED_PACKET) +
  316. ATL1C_RECEIVE_FRAME_DATA_SIZE));
  317. ASSERT(Device->DescriptorIoBuffer == NULL);
  318. IoBufferFlags = IO_BUFFER_FLAG_PHYSICALLY_CONTIGUOUS;
  319. Device->DescriptorIoBuffer = MmAllocateNonPagedIoBuffer(0,
  320. MAX_ULONG,
  321. 8,
  322. AllocationSize,
  323. IoBufferFlags);
  324. if (Device->DescriptorIoBuffer == NULL) {
  325. Status = STATUS_INSUFFICIENT_RESOURCES;
  326. goto InitializeDeviceStructuresEnd;
  327. }
  328. ASSERT(Device->DescriptorIoBuffer->FragmentCount == 1);
  329. //
  330. // Zero out everything except the receive packet data buffers.
  331. //
  332. Size = AllocationSize -
  333. (ATL1C_RECEIVE_FRAME_DATA_SIZE * ATL1C_RECEIVE_FRAME_COUNT);
  334. RtlZeroMemory(Device->DescriptorIoBuffer->Fragment[0].VirtualAddress, Size);
  335. //
  336. // Carve up the buffer and give each array its piece.
  337. //
  338. Device->TransmitDescriptor =
  339. Device->DescriptorIoBuffer->Fragment[0].VirtualAddress;
  340. Device->TransmitBuffer =
  341. (PNET_PACKET_BUFFER *)(Device->TransmitDescriptor +
  342. (ATL1C_TRANSMIT_DESCRIPTOR_COUNT + 1));
  343. Device->ReceiveSlot =
  344. (PATL1C_RECEIVE_SLOT)(Device->TransmitBuffer +
  345. ATL1C_TRANSMIT_DESCRIPTOR_COUNT);
  346. Device->ReceivedPacket =
  347. (PATL1C_RECEIVED_PACKET)(Device->ReceiveSlot +
  348. ATL1C_RECEIVE_FRAME_COUNT);
  349. Device->ReceivedPacketData =
  350. (PVOID)(Device->ReceivedPacket + ATL1C_RECEIVE_FRAME_COUNT);
  351. //
  352. // Initialize the receive slots.
  353. //
  354. PhysicalAddress = Device->DescriptorIoBuffer->Fragment[0].PhysicalAddress +
  355. AllocationSize -
  356. (ATL1C_RECEIVE_FRAME_COUNT *
  357. ATL1C_RECEIVE_FRAME_DATA_SIZE);
  358. for (SlotIndex = 0; SlotIndex < ATL1C_RECEIVE_FRAME_COUNT; SlotIndex += 1) {
  359. Device->ReceiveSlot[SlotIndex].PhysicalAddress = PhysicalAddress;
  360. PhysicalAddress += ATL1C_RECEIVE_FRAME_DATA_SIZE;
  361. }
  362. NET_INITIALIZE_PACKET_LIST(&(Device->TransmitPacketList));
  363. Device->ReceiveNextToClean = 0;
  364. Device->TransmitNextToClean = 0;
  365. Device->TransmitNextToUse = 0;
  366. Status = STATUS_SUCCESS;
  367. InitializeDeviceStructuresEnd:
  368. if (!KSUCCESS(Status)) {
  369. if (Device->DescriptorIoBuffer != NULL) {
  370. MmFreeIoBuffer(Device->DescriptorIoBuffer);
  371. Device->TransmitDescriptor = NULL;
  372. Device->TransmitBuffer = NULL;
  373. Device->ReceiveSlot = NULL;
  374. Device->ReceivedPacket = NULL;
  375. }
  376. }
  377. return Status;
  378. }
  379. KSTATUS
  380. AtlpResetDevice (
  381. PATL1C_DEVICE Device
  382. )
  383. /*++
  384. Routine Description:
  385. This routine resets the ATL1c device.
  386. Arguments:
  387. Device - Supplies a pointer to the device.
  388. Return Value:
  389. Status code.
  390. --*/
  391. {
  392. PHYSICAL_ADDRESS PhysicalAddress;
  393. BOOL Result;
  394. KSTATUS Status;
  395. ULONG Value;
  396. ASSERT(KeGetRunLevel() == RunLevelLow);
  397. Status = STATUS_DEVICE_IO_ERROR;
  398. Device->Speed = AtlSpeedOff;
  399. Device->Duplex = AtlDuplexInvalid;
  400. //
  401. // Clear any lingering PCI express protocol errors.
  402. //
  403. Value = ATL_READ_REGISTER32(Device, AtlRegisterPexUncErrSev);
  404. Value &= ~(ATL_PEX_UNC_ERR_SEV_DLP | ATL_PEX_UNC_ERR_SEV_FCP);
  405. ATL_WRITE_REGISTER32(Device, AtlRegisterPexUncErrSev, Value);
  406. //
  407. // Reset the Link Training and Status State Machine.
  408. //
  409. Value = ATL_READ_REGISTER32(Device, AtlRegisterLtssmIdControl);
  410. Value &= ~ATL_LTSSM_ID_ENABLE_WRO;
  411. ATL_WRITE_REGISTER32(Device, AtlRegisterLtssmIdControl, Value);
  412. Value = ATL_READ_REGISTER32(Device, AtlRegisterPhyMiscellaneous);
  413. Value |= ATL_PHY_MISCELLANEOUS_FORCE_RECEIVE_DETECT;
  414. ATL_WRITE_REGISTER32(Device, AtlRegisterPhyMiscellaneous, Value);
  415. AtlpDisableL0sAndL1(Device);
  416. Result = AtlpResetPhy(Device);
  417. if (Result == FALSE) {
  418. goto ResetDeviceEnd;
  419. }
  420. //
  421. // Stop anything currently going on.
  422. //
  423. Result = AtlpStopController(Device);
  424. if (Result == FALSE) {
  425. goto ResetDeviceEnd;
  426. }
  427. //
  428. // Apply a reset to the master control register to get the chip in a
  429. // known state.
  430. //
  431. Result = AtlpApplyChipReset(Device);
  432. if (Result == FALSE) {
  433. goto ResetDeviceEnd;
  434. }
  435. Result = AtlpReadMacAddress(Device);
  436. if (Result == FALSE) {
  437. goto ResetDeviceEnd;
  438. }
  439. //
  440. // Notify the networking core of this new link now that the device is ready
  441. // to send and receive data, pending media being present.
  442. //
  443. if (Device->NetworkLink == NULL) {
  444. Status = AtlpAddNetworkDevice(Device);
  445. if (!KSUCCESS(Status)) {
  446. goto ResetDeviceEnd;
  447. }
  448. }
  449. KeAcquireQueuedLock(Device->ReceiveLock);
  450. AtlpResetReceiveRing(Device);
  451. KeReleaseQueuedLock(Device->ReceiveLock);
  452. KeAcquireQueuedLock(Device->TransmitLock);
  453. AtlpResetTransmitRing(Device);
  454. KeReleaseQueuedLock(Device->TransmitLock);
  455. //
  456. // Enable all clocks and disable WOL (which would interfere with normal
  457. // operation).
  458. //
  459. ATL_WRITE_REGISTER32(Device, AtlRegisterClockGatingControl, 0);
  460. ATL_READ_REGISTER32(Device, AtlRegisterWakeOnLanControl);
  461. ATL_WRITE_REGISTER32(Device, AtlRegisterWakeOnLanControl, 0);
  462. //
  463. // Configure the descriptor rings, starting with the transmit queue. The
  464. // normal priority queue (priority 0) gets all the descriptors. The high
  465. // priority queue, which is unused, gets a single descriptor to pacify it.
  466. //
  467. PhysicalAddress = Device->DescriptorIoBuffer->Fragment[0].PhysicalAddress;
  468. ATL_WRITE_REGISTER32(
  469. Device,
  470. AtlRegisterTransmitBaseAddressHigh,
  471. (ULONG)(PhysicalAddress >> ATL_RING_HIGH_ADDRESS_SHIFT));
  472. ATL_WRITE_REGISTER32(Device,
  473. AtlRegisterTransmitBaseAddressLow,
  474. (ULONG)PhysicalAddress);
  475. PhysicalAddress += sizeof(ATL1C_TRANSMIT_DESCRIPTOR) *
  476. ATL1C_TRANSMIT_DESCRIPTOR_COUNT;
  477. ATL_WRITE_REGISTER32(Device,
  478. AtlRegisterTransmitBaseAddressLowHighPriority,
  479. 0);
  480. ATL_WRITE_REGISTER32(Device,
  481. AtlRegisterTransmitRingSize,
  482. ATL1C_TRANSMIT_DESCRIPTOR_COUNT);
  483. //
  484. // Set up the Receive Free Descriptor ring. Only the first queue is used.
  485. //
  486. PhysicalAddress += sizeof(ATL1C_TRANSMIT_DESCRIPTOR) +
  487. (sizeof(PVOID) * ATL1C_TRANSMIT_DESCRIPTOR_COUNT);
  488. ATL_WRITE_REGISTER32(
  489. Device,
  490. AtlRegisterReceiveBaseAddressHigh,
  491. (ULONG)(PhysicalAddress >> ATL_RING_HIGH_ADDRESS_SHIFT));
  492. ATL_WRITE_REGISTER32(Device,
  493. AtlRegisterReceiveBaseAddressLow,
  494. (ULONG)PhysicalAddress);
  495. ATL_WRITE_REGISTER32(Device, AtlRegisterReceive1BaseAddressLow, 0);
  496. ATL_WRITE_REGISTER32(Device, AtlRegisterReceive2BaseAddressLow, 0);
  497. ATL_WRITE_REGISTER32(Device, AtlRegisterReceive3BaseAddressLow, 0);
  498. ATL_WRITE_REGISTER32(Device,
  499. AtlRegisterReceiveSlotRingSize,
  500. ATL1C_RECEIVE_FRAME_COUNT);
  501. ATL_WRITE_REGISTER32(Device,
  502. AtlRegisterReceiveBufferSize,
  503. ATL1C_RECEIVE_FRAME_DATA_SIZE);
  504. //
  505. // Set up the Received Packet Status ring.
  506. //
  507. PhysicalAddress += sizeof(ATL1C_RECEIVE_SLOT) * ATL1C_RECEIVE_FRAME_COUNT;
  508. ATL_WRITE_REGISTER32(Device,
  509. AtlRegisterReceiveRingBaseAddressLow,
  510. (ULONG)PhysicalAddress);
  511. ATL_WRITE_REGISTER32(Device, AtlRegisterReceiveRing1BaseAddressLow, 0);
  512. ATL_WRITE_REGISTER32(Device, AtlRegisterReceiveRing2BaseAddressLow, 0);
  513. ATL_WRITE_REGISTER32(Device, AtlRegisterReceiveRing3BaseAddressLow, 0);
  514. ATL_WRITE_REGISTER32(Device,
  515. AtlRegisterReceiveStatusRingSize,
  516. ATL1C_RECEIVE_FRAME_COUNT);
  517. //
  518. // The CMB and SMB pointers aren't used.
  519. //
  520. ATL_WRITE_REGISTER32(Device, AtlRegisterCmbBaseAddressLow, 0);
  521. ATL_WRITE_REGISTER32(Device, AtlRegisterSmbBaseAddressHigh, 0);
  522. ATL_WRITE_REGISTER32(Device, AtlRegisterSmbBaseAddressLow, 0);
  523. //
  524. // Officially load all those ring pointers into the device.
  525. //
  526. ATL_WRITE_REGISTER32(Device,
  527. AtlRegisterLoadRingPointers,
  528. ATL_LOAD_POINTERS_COMMAND_GO);
  529. //
  530. // Set up the interrupt moderator timer.
  531. //
  532. Value = ((ATL_MICROSECONDS(ATL_TRANSMIT_INTERRUPT_TIMER_VALUE) &
  533. ATL_INTERRUPT_TIMER_TRANSMIT_MASK) <<
  534. ATL_INTERRUPT_TIMER_TRANSMIT_SHIFT) |
  535. ((ATL_MICROSECONDS(ATL_RECEIVE_INTERRUPT_TIMER_VALUE) &
  536. ATL_INTERRUPT_TIMER_RECEIVE_MASK) <<
  537. ATL_INTERRUPT_TIMER_RECEIVE_SHIFT);
  538. ATL_WRITE_REGISTER32(Device, AtlRegisterInterruptTimers, Value);
  539. //
  540. // Set the timers to be enabled, and disable interrupt status clear on
  541. // read.
  542. //
  543. Value = ATL_MASTER_CONTROL_SYSTEM_ALIVE_TIMER |
  544. ATL_MASTER_CONTROL_TRANSMIT_ITIMER_ENABLE |
  545. ATL_MASTER_CONTROL_RECEIVE_ITIMER_ENABLE;
  546. ATL_WRITE_REGISTER32(Device, AtlRegisterMasterControl, Value);
  547. //
  548. // Disable the interrupt retrigger timer to prevent unserviced interrupts
  549. // from coming back.
  550. //
  551. ATL_WRITE_REGISTER32(Device, AtlRegisterInterruptRetriggerTimer, 0);
  552. //
  553. // Disable the CMB and SMB timers.
  554. //
  555. ATL_WRITE_REGISTER32(Device, AtlRegisterCmbTransmitTimer, 0);
  556. ATL_WRITE_REGISTER32(Device, AtlRegisterSmbStatTimer, 0);
  557. //
  558. // Set the Maximum Transmission Unit.
  559. //
  560. ATL_WRITE_REGISTER32(Device,
  561. AtlRegisterMaximumTransmissionUnit,
  562. ATL_L2CB_MAX_TRANSMIT_LENGTH);
  563. ATL_WRITE_REGISTER32(Device, AtlRegisterHdsControl, 0);
  564. ATL_WRITE_REGISTER32(Device, AtlRegisterIpgIfgControl, ATL_IPG_IFG_VALUE);
  565. ATL_WRITE_REGISTER32(Device,
  566. AtlRegisterHalfDuplexControl,
  567. ATL_HALF_DUPLEX_CONTROL_VALUE);
  568. //
  569. // Set up the transmit parameters.
  570. //
  571. Value = (ATL_TRANSMIT_TCP_SEGMENTATION_OFFSET_FRAME_SIZE >>
  572. ATL_TCP_SEGMENTATION_OFFLOAD_THRESHOLD_DOWNSHIFT) &
  573. ATL_TCP_SEGMENTATION_OFFLOAD_THRESHOLD_MASK;
  574. ATL_WRITE_REGISTER32(Device,
  575. AtlRegisterTcpSegmentationOffloadThreshold,
  576. Value);
  577. Value = ((ATL_TRANSMIT_DESCRIPTOR_BURST_COUNT &
  578. ATL_TRANSMIT_QUEUE_CONTROL_BURST_MASK) <<
  579. ATL_TRANSMIT_QUEUE_CONTROL_BURST_SHIFT) |
  580. ATL_TRANSMIT_QUEUE_CONTROL_ENHANCED_MODE |
  581. ((ATL_L2CB_TRANSMIT_TXF_BURST_PREF &
  582. ATL_TRANSMIT_QUEUE_CONTROL_BURST_NUMBER_MASK) <<
  583. ATL_TRANSMIT_QUEUE_CONTROL_BURST_NUMBER_SHIFT);
  584. ATL_WRITE_REGISTER32(Device, AtlRegisterTransmitQueueControl, Value);
  585. //
  586. // Configure receive free slot pre-fetching.
  587. //
  588. ATL_WRITE_REGISTER32(Device,
  589. AtlRegisterReceiveFreeThreshold,
  590. ATL_RECEIVE_FREE_THRESHOLD_VALUE);
  591. //
  592. // Disable RSS.
  593. //
  594. ATL_WRITE_REGISTER32(Device, AtlRegisterRssIdtTable0, 0);
  595. ATL_WRITE_REGISTER32(Device, AtlRegisterRssCpu, 0);
  596. //
  597. // Configure the receive queue.
  598. //
  599. Value = ((ATL_RECEIVE_DESCRIPTOR_BURST_COUNT &
  600. ATL_RECEIVE_QUEUE_CONTROL_BURST_MASK) <<
  601. ATL_RECEIVE_QUEUE_CONTROL_BURST_SHIFT);
  602. ATL_WRITE_REGISTER32(Device, AtlRegisterReceiveQueueControl, Value);
  603. //
  604. // Configure DMA.
  605. //
  606. ATL_WRITE_REGISTER32(Device, AtlRegisterDmaControl, ATL_DMA_CONTROL_VALUE);
  607. //
  608. // Configure the MAC. The speed/duplex settings get reconfigured a bit once
  609. // the link is determined to be established.
  610. //
  611. Value = ATL_MAC_CONTROL_ADD_CRC | ATL_MAC_CONTROL_PAD |
  612. ATL_MAC_CONTROL_DUPLEX |
  613. ((ATL_PREAMBLE_LENGTH &
  614. ATL_MAC_CONTROL_PREAMBLE_LENGTH_MASK) <<
  615. ATL_MAC_CONTROL_PREAMBLE_LENGTH_SHIFT) |
  616. (ATL_MAC_CONTROL_SPEED_10_100 << ATL_MAC_CONTROL_SPEED_SHIFT);
  617. ATL_WRITE_REGISTER32(Device, AtlRegisterMacControl, Value);
  618. AtlpSetupReceiveFilters(Device);
  619. //
  620. // Disable hardware stripping of the VLAN tag. If VLAN support is added,
  621. // this bit would need to be set here.
  622. //
  623. Value = ATL_READ_REGISTER32(Device, AtlRegisterMacControl);
  624. Value &= ~ATL_MAC_CONTROL_STRIP_VLAN;
  625. ATL_WRITE_REGISTER32(Device, AtlRegisterMacControl, Value);
  626. //
  627. // Write the current producer index of the transmit ring.
  628. //
  629. ATL_WRITE_REGISTER16(Device,
  630. AtlRegisterTransmitNextIndex,
  631. Device->TransmitNextToClean);
  632. //
  633. // Clear any pending interrupts.
  634. //
  635. ATL_WRITE_REGISTER32(Device,
  636. AtlRegisterInterruptStatus,
  637. ATL_INTERRUPT_MASK);
  638. //
  639. // Everything's set up, re-enable interrupts and fire up the device.
  640. //
  641. Status = AtlpEnableDevice(Device);
  642. if (!KSUCCESS(Status)) {
  643. goto ResetDeviceEnd;
  644. }
  645. AtlpEnableDeviceInterrupts(Device);
  646. ResetDeviceEnd:
  647. return Status;
  648. }
  649. INTERRUPT_STATUS
  650. AtlpInterruptService (
  651. PVOID Context
  652. )
  653. /*++
  654. Routine Description:
  655. This routine implements the ATL1c interrupt service routine.
  656. Arguments:
  657. Context - Supplies the context pointer given to the system when the
  658. interrupt was connected. In this case, this points to the ATL1c device
  659. structure.
  660. Return Value:
  661. Interrupt status.
  662. --*/
  663. {
  664. PATL1C_DEVICE Device;
  665. INTERRUPT_STATUS InterruptStatus;
  666. ULONG PendingBits;
  667. USHORT Value;
  668. Device = (PATL1C_DEVICE)Context;
  669. InterruptStatus = InterruptStatusNotClaimed;
  670. //
  671. // Read the status register, and if nothing is set then return immediately.
  672. //
  673. PendingBits = ATL_READ_REGISTER32(Device, AtlRegisterInterruptStatus);
  674. if (((PendingBits & Device->EnabledInterrupts) == 0) ||
  675. ((PendingBits & ATL_INTERRUPT_DISABLE) != 0)) {
  676. return InterruptStatus;
  677. }
  678. InterruptStatus = InterruptStatusClaimed;
  679. //
  680. // There are interrupt bits set, so mark this interrupt as claimed.
  681. //
  682. KeAcquireSpinLock(&(Device->InterruptLock));
  683. RtlAtomicOr32(&(Device->PendingInterrupts), PendingBits);
  684. //
  685. // The GPHY bit cannot be masked or cleared by the controller directly.
  686. // Read the PHY interrupt status register to clear the interrupt.
  687. //
  688. if ((PendingBits & ATL_INTERRUPT_GPHY) != 0) {
  689. AtlpPerformPhyRegisterIo(Device,
  690. FALSE,
  691. FALSE,
  692. 0,
  693. ATL_PHY_MII_INTERRUPT_STATUS,
  694. &Value);
  695. }
  696. ATL_WRITE_REGISTER32(Device,
  697. AtlRegisterInterruptStatus,
  698. PendingBits | ATL_INTERRUPT_DISABLE);
  699. KeReleaseSpinLock(&(Device->InterruptLock));
  700. return InterruptStatus;
  701. }
  702. INTERRUPT_STATUS
  703. AtlpInterruptServiceWorker (
  704. PVOID Parameter
  705. )
  706. /*++
  707. Routine Description:
  708. This routine processes interrupts for the ATL1c controller at low level.
  709. Arguments:
  710. Parameter - Supplies an optional parameter passed in by the creator of the
  711. work item.
  712. Return Value:
  713. Interrupt Status.
  714. --*/
  715. {
  716. PATL1C_DEVICE Device;
  717. ULONG PendingBits;
  718. INTERRUPT_STATUS Status;
  719. Device = (PATL1C_DEVICE)(Parameter);
  720. ASSERT(KeGetRunLevel() == RunLevelLow);
  721. //
  722. // Clear out the pending bits.
  723. //
  724. PendingBits = RtlAtomicExchange32(&(Device->PendingInterrupts), 0);
  725. if (PendingBits == 0) {
  726. Status = InterruptStatusNotClaimed;
  727. goto InterruptServiceWorkerEnd;
  728. }
  729. Status = InterruptStatusClaimed;
  730. if ((PendingBits & ATL_INTERRUPT_BUFFER_ERROR_MASK) != 0) {
  731. RtlDebugPrint("ATL: Buffer Error 0x%08x.\n", PendingBits);
  732. }
  733. //
  734. // If the interrupt indicates new packets are coming in, grab them.
  735. //
  736. if ((PendingBits & ATL_INTERRUPT_RECEIVE_PACKET_MASK) != 0) {
  737. AtlpReapReceivedFrames(Device);
  738. }
  739. //
  740. // If packets were sent out, reap the completed transmissions.
  741. //
  742. if ((PendingBits & ATL_INTERRUPT_TRANSMIT_PACKET) != 0) {
  743. AtlpReapCompletedTransmitDescriptors(Device);
  744. }
  745. //
  746. // If an error occurred, reset the MAC.
  747. //
  748. if ((PendingBits & ATL_INTERRUPT_ERROR_MASK) != 0) {
  749. NetSetLinkState(Device->NetworkLink, FALSE, 0);
  750. AtlpStopController(Device);
  751. AtlpEnableDevice(Device);
  752. }
  753. //
  754. // Handle a link event change.
  755. //
  756. if ((PendingBits & (ATL_INTERRUPT_MANUAL | ATL_INTERRUPT_GPHY)) != 0) {
  757. AtlpDisableDeviceInterrupts(Device);
  758. AtlpEnableDevice(Device);
  759. AtlpEnableDeviceInterrupts(Device);
  760. }
  761. InterruptServiceWorkerEnd:
  762. ATL_WRITE_REGISTER32(Device, AtlRegisterInterruptStatus, 0);
  763. return Status;
  764. }
  765. //
  766. // --------------------------------------------------------- Internal Functions
  767. //
  768. VOID
  769. AtlpReapCompletedTransmitDescriptors (
  770. PATL1C_DEVICE Device
  771. )
  772. /*++
  773. Routine Description:
  774. This routine cleans out any transmit descriptors that have already been
  775. handled by the controller. This routine must be called at low level and
  776. assumes the transmit lock is already held.
  777. Arguments:
  778. Device - Supplies a pointer to the device.
  779. Return Value:
  780. None.
  781. --*/
  782. {
  783. USHORT CurrentIndex;
  784. PATL1C_TRANSMIT_DESCRIPTOR Descriptor;
  785. BOOL DescriptorReaped;
  786. USHORT HardwareIndex;
  787. KeAcquireQueuedLock(Device->TransmitLock);
  788. HardwareIndex = ATL_READ_REGISTER16(Device,
  789. AtlRegisterTransmitCurrentIndex);
  790. DescriptorReaped = FALSE;
  791. if (Device->TransmitNextToClean != HardwareIndex) {
  792. DescriptorReaped = TRUE;
  793. }
  794. while (Device->TransmitNextToClean != HardwareIndex) {
  795. CurrentIndex = Device->TransmitNextToClean;
  796. Descriptor = &(Device->TransmitDescriptor[CurrentIndex]);
  797. ASSERT(Device->TransmitBuffer[CurrentIndex] != NULL);
  798. NetFreeBuffer(Device->TransmitBuffer[CurrentIndex]);
  799. Device->TransmitBuffer[CurrentIndex] = NULL;
  800. Descriptor->PhysicalAddress = 0;
  801. Descriptor->BufferLength = 0;
  802. Device->TransmitNextToClean += 1;
  803. if (Device->TransmitNextToClean == ATL1C_TRANSMIT_DESCRIPTOR_COUNT) {
  804. Device->TransmitNextToClean = 0;
  805. }
  806. }
  807. //
  808. // If space was freed up, signal the event unblocking any parties waiting
  809. // for transmit descriptors.
  810. //
  811. if (DescriptorReaped != FALSE) {
  812. AtlpSendPendingPackets(Device);
  813. }
  814. KeReleaseQueuedLock(Device->TransmitLock);
  815. return;
  816. }
  817. VOID
  818. AtlpSendPendingPackets (
  819. PATL1C_DEVICE Device
  820. )
  821. /*++
  822. Routine Description:
  823. This routine sends as many packets as can fit in the hardware descriptor
  824. buffer. This routine assumes the transmit lock is already held.
  825. Arguments:
  826. Device - Supplies a pointer to the device.
  827. Return Value:
  828. None.
  829. --*/
  830. {
  831. PATL1C_TRANSMIT_DESCRIPTOR Descriptor;
  832. ULONG DescriptorIndex;
  833. PNET_PACKET_BUFFER Packet;
  834. BOOL PacketQueued;
  835. ASSERT(KeIsQueuedLockHeld(Device->TransmitLock) != FALSE);
  836. //
  837. // Fill up the open descriptors with as many pending packets as possible.
  838. //
  839. PacketQueued = FALSE;
  840. while (NET_PACKET_LIST_EMPTY(&(Device->TransmitPacketList)) == FALSE) {
  841. Packet = LIST_VALUE(Device->TransmitPacketList.Head.Next,
  842. NET_PACKET_BUFFER,
  843. ListEntry);
  844. DescriptorIndex = Device->TransmitNextToUse;
  845. Descriptor = &(Device->TransmitDescriptor[DescriptorIndex]);
  846. //
  847. // If the length isn't zero, this is an active or unreaped entry.
  848. // Quit to try another day. The active packets should interrupt on
  849. // completion and drive more packets to be send.
  850. //
  851. if (Descriptor->BufferLength != 0) {
  852. break;
  853. }
  854. NET_REMOVE_PACKET_FROM_LIST(Packet, &(Device->TransmitPacketList));
  855. //
  856. // Success, a free transmit descriptor. Let's fill it out!
  857. //
  858. ASSERT(Device->TransmitBuffer[DescriptorIndex] == NULL);
  859. Device->TransmitBuffer[DescriptorIndex] = Packet;
  860. Descriptor->BufferLength = Packet->FooterOffset - Packet->DataOffset;
  861. Descriptor->PhysicalAddress = Packet->BufferPhysicalAddress +
  862. Packet->DataOffset;
  863. Descriptor->Flags = ATL_TRANSMIT_DESCRIPTOR_END_OF_PACKET;
  864. //
  865. // Advance the list past this entry.
  866. //
  867. Device->TransmitNextToUse += 1;
  868. if (Device->TransmitNextToUse == ATL1C_TRANSMIT_DESCRIPTOR_COUNT) {
  869. Device->TransmitNextToUse = 0;
  870. }
  871. PacketQueued = TRUE;
  872. }
  873. //
  874. // If some packets were queued, then send them now.
  875. //
  876. if (PacketQueued != FALSE) {
  877. RtlMemoryBarrier();
  878. ATL_WRITE_REGISTER16(Device,
  879. AtlRegisterTransmitNextIndex,
  880. Device->TransmitNextToUse);
  881. }
  882. return;
  883. }
  884. VOID
  885. AtlpReapReceivedFrames (
  886. PATL1C_DEVICE Device
  887. )
  888. /*++
  889. Routine Description:
  890. This routine processes any received frames from the network.
  891. Arguments:
  892. Device - Supplies a pointer to the device.
  893. Return Value:
  894. None.
  895. --*/
  896. {
  897. USHORT CurrentIndex;
  898. ULONG ErrorFlags;
  899. ULONG FramesProcessed;
  900. USHORT FreeIndex;
  901. USHORT OriginalNextToClean;
  902. NET_PACKET_BUFFER Packet;
  903. PATL1C_RECEIVED_PACKET ReceivedPacket;
  904. ULONG Value;
  905. ASSERT(KeGetRunLevel() == RunLevelLow);
  906. //
  907. // Loop grabbing completed frames.
  908. //
  909. FramesProcessed = 0;
  910. Packet.Flags = 0;
  911. KeAcquireQueuedLock(Device->ReceiveLock);
  912. OriginalNextToClean = Device->ReceiveNextToClean;
  913. while (TRUE) {
  914. CurrentIndex = Device->ReceiveNextToClean;
  915. ReceivedPacket = &(Device->ReceivedPacket[CurrentIndex]);
  916. //
  917. // If the packet is not valid, then stop.
  918. //
  919. if ((ReceivedPacket->FlagsAndLength &
  920. ATL_RECIEVED_PACKET_FLAG_VALID) == 0) {
  921. break;
  922. }
  923. //
  924. // This is a valid packet that needs to be reaped. Currently only
  925. // single packets are supported.
  926. //
  927. ASSERT(((ReceivedPacket->FreeIndex >>
  928. ATL_RECEIVED_PACKET_COUNT_SHIFT) &
  929. ATL_RECEIVED_PACKET_COUNT_MASK) == 1);
  930. //
  931. // Process the packet, unless the error flags are set.
  932. //
  933. ErrorFlags = ATL_RECEIVED_PACKET_FLAG_802_3_LENGTH_ERROR |
  934. ATL_RECEIVED_PACKET_FLAG_CHECKSUM_ERROR;
  935. if ((ReceivedPacket->FlagsAndLength & ErrorFlags) == 0) {
  936. FreeIndex = (ReceivedPacket->FreeIndex >>
  937. ATL_RECEIVED_PACKET_FREE_INDEX_SHIFT) &
  938. ATL_RECEIVED_PACKET_FREE_INDEX_MASK;
  939. ASSERT(FreeIndex < ATL1C_RECEIVE_FRAME_COUNT);
  940. Packet.Buffer = Device->ReceivedPacketData +
  941. (FreeIndex * ATL1C_RECEIVE_FRAME_DATA_SIZE);
  942. Packet.BufferPhysicalAddress =
  943. Device->ReceiveSlot[FreeIndex].PhysicalAddress;
  944. Packet.BufferSize = ReceivedPacket->FlagsAndLength &
  945. ATL_RECEIVED_PACKET_SIZE_MASK;
  946. Packet.DataSize = Packet.BufferSize;
  947. Packet.DataOffset = 0;
  948. Packet.FooterOffset = Packet.DataSize;
  949. NetProcessReceivedPacket(Device->NetworkLink, &Packet);
  950. }
  951. //
  952. // Clear the flag set by the hardware and move the index forward.
  953. //
  954. FramesProcessed += 1;
  955. ReceivedPacket->FlagsAndLength &= ~ATL_RECIEVED_PACKET_FLAG_VALID;
  956. Device->ReceiveNextToClean += 1;
  957. if (Device->ReceiveNextToClean == ATL1C_RECEIVE_FRAME_COUNT) {
  958. Device->ReceiveNextToClean = 0;
  959. }
  960. }
  961. //
  962. // If progress was made, let the controller know.
  963. //
  964. if (FramesProcessed != 0) {
  965. ASSERT(Device->ReceiveNextToClean != OriginalNextToClean);
  966. if (Device->ReceiveNextToClean == 0) {
  967. Value = ATL1C_RECEIVE_FRAME_COUNT - 1;
  968. } else {
  969. Value = Device->ReceiveNextToClean - 1;
  970. }
  971. ATL_WRITE_REGISTER32(Device, AtlRegisterReceiveFrameIndex, Value);
  972. }
  973. KeReleaseQueuedLock(Device->ReceiveLock);
  974. return;
  975. }
  976. VOID
  977. AtlpDisableL0sAndL1 (
  978. PATL1C_DEVICE Device
  979. )
  980. /*++
  981. Routine Description:
  982. This routine disables the L0s and L1 link states.
  983. Arguments:
  984. Device - Supplies a pointer to the device.
  985. Return Value:
  986. None.
  987. --*/
  988. {
  989. ULONG Value;
  990. //
  991. // Read the power management register and clear out the bits that are going
  992. // to be set by this function.
  993. //
  994. Value = ATL_READ_REGISTER32(Device, AtlRegisterPowerManagementControl);
  995. Value &= ~((ATL_POWER_MANAGEMENT_CONTROL_L1_ENTRY_TIME_MASK <<
  996. ATL_POWER_MANAGEMENT_CONTROL_L1_ENTRY_TIME_SHIFT) |
  997. ATL_POWER_MANAGEMENT_CONTROL_CLK_SWH_L1 |
  998. ATL_POWER_MANAGEMENT_CONTROL_L0S_ENABLE |
  999. ATL_POWER_MANAGEMENT_CONTROL_L1_ENABLE |
  1000. ATL_POWER_MANAGEMENT_CONTROL_ASPM_MAC_CHECK |
  1001. ATL_POWER_MANAGEMENT_CONTROL_SERDES_PD_EX_L1);
  1002. Value |= ATL_POWER_MANAGEMENT_CONTROL_SERDES_BUFS_RECEIVE_L1_ENABLE |
  1003. ATL_POWER_MANAGEMENT_CONTROL_SERDES_PLL_L1_ENABLE |
  1004. ATL_POWER_MANAGEMENT_CONTROL_SERDES_L1_ENABLE;
  1005. ATL_WRITE_REGISTER32(Device, AtlRegisterPowerManagementControl, Value);
  1006. return;
  1007. }
  1008. BOOL
  1009. AtlpResetPhy (
  1010. PATL1C_DEVICE Device
  1011. )
  1012. /*++
  1013. Routine Description:
  1014. This routine resets the ATL1c device PHY.
  1015. Arguments:
  1016. Device - Supplies a pointer to the device.
  1017. Return Value:
  1018. TRUE on success.
  1019. FALSE on failure.
  1020. --*/
  1021. {
  1022. RUNLEVEL OldRunLevel;
  1023. USHORT PhyValue;
  1024. BOOL Result;
  1025. USHORT ShortValue;
  1026. ULONG Value;
  1027. Value = ATL_PHY_CONTROL_SEL_ANA_RESET;
  1028. ATL_WRITE_REGISTER16(Device, AtlRegisterPhyControl, Value);
  1029. ATL_READ_REGISTER16(Device, AtlRegisterPhyControl);
  1030. HlBusySpin(10000);
  1031. Value = ATL_PHY_CONTROL_EXT_RESET | ATL_PHY_CONTROL_SEL_ANA_RESET;
  1032. ATL_WRITE_REGISTER16(Device, AtlRegisterPhyControl, Value);
  1033. ATL_READ_REGISTER16(Device, AtlRegisterPhyControl);
  1034. HlBusySpin(10000);
  1035. OldRunLevel = AtlpAcquireInterruptLock(Device);
  1036. Result = AtlpWritePhyDebugRegister(Device,
  1037. ATL_PHY_DEBUG_LEGCYPS_REGISTER,
  1038. ATL_PHY_DEBUG_LEGCYPS_VALUE);
  1039. if (Result == FALSE) {
  1040. goto ResetPhyEnd;
  1041. }
  1042. PhyValue = ATL_PHY_TST10BTCFG_LOOP_SEL_10BT |
  1043. ATL_PHY_TST10BTCFG_EN_MASK_TB |
  1044. ATL_PHY_TST10BTCFG_EN_10BT_IDLE |
  1045. ATL_PHY_TST10BTCFG_INTERVAL_SEL_TIMER_VALUE;
  1046. Result = AtlpWritePhyDebugRegister(Device,
  1047. ATL_PHY_DEBUG_TST10BTCFG_REGISTER,
  1048. PhyValue);
  1049. if (Result == FALSE) {
  1050. goto ResetPhyEnd;
  1051. }
  1052. PhyValue = ATL_PHY_SRDSYSMOD_SERDES_CDR_BW_VALUE |
  1053. ATL_PHY_SRDSYSMOD_SERDES_EN_DEEM |
  1054. ATL_PHY_SRDSYSMOD_SERDES_SEL_HSP |
  1055. ATL_PHY_SRDSYSMOD_SERDES_ENABLE_PLL |
  1056. ATL_PHY_SRDSYSMOD_SERDES_EN_LCKDT;
  1057. Result = AtlpWritePhyDebugRegister(Device,
  1058. ATL_PHY_DEBUG_SRDSYSMOD_REGISTER,
  1059. PhyValue);
  1060. if (Result == FALSE) {
  1061. goto ResetPhyEnd;
  1062. }
  1063. PhyValue = ATL_PHY_TST100BTCFG_LONG_CABLE_TH_100_VALUE |
  1064. ATL_PHY_TST100BTCFG_SHORT_CABLE_TH_100_VALUE |
  1065. ATL_PHY_TST100BTCFG_BP_BAD_LINK_ACCUM |
  1066. ATL_PHY_TST100BTCFG_BP_SMALL_BW;
  1067. Result = AtlpWritePhyDebugRegister(Device,
  1068. ATL_PHY_DEBUG_TST100BTCFG_REGISTER,
  1069. PhyValue);
  1070. if (Result == FALSE) {
  1071. goto ResetPhyEnd;
  1072. }
  1073. PhyValue = ATL_PHY_SYSMODCTRL_IECHO_ADJ_3_VALUE |
  1074. ATL_PHY_SYSMODCTRL_IECHO_ADJ_2_VALUE |
  1075. ATL_PHY_SYSMODCTRL_IECHO_ADJ_1_VALUE |
  1076. ATL_PHY_SYSMODCTRL_IECHO_ADJ_0_VALUE;
  1077. Result = AtlpWritePhyDebugRegister(Device,
  1078. ATL_PHY_DEBUG_SYSMODCTRL_REGISTER,
  1079. PhyValue);
  1080. if (Result == FALSE) {
  1081. goto ResetPhyEnd;
  1082. }
  1083. PhyValue = ATL_PHY_ANA_CONTROL_MANUAL_SWITCH_ON_VALUE |
  1084. ATL_PHY_ANA_CONTROL_RESTART_CAL |
  1085. ATL_PHY_ANA_CONTROL_MAN_ENABLE | ATL_PHY_ANA_CONTROL_SEL_HSP |
  1086. ATL_PHY_ANA_CONTROL_EN_HB | ATL_PHY_ANA_CONTROL_OEN_125M;
  1087. Result = AtlpWritePhyDebugRegister(Device,
  1088. ATL_PHY_DEBUG_ANA_CONTROL_REGISTER,
  1089. PhyValue);
  1090. if (Result == FALSE) {
  1091. goto ResetPhyEnd;
  1092. }
  1093. HlBusySpin(1000);
  1094. //
  1095. // Disable hibernation.
  1096. //
  1097. Result = AtlpReadPhyDebugRegister(Device,
  1098. ATL_PHY_DEBUG_LEGCYPS_REGISTER,
  1099. &PhyValue);
  1100. if (Result == FALSE) {
  1101. goto ResetPhyEnd;
  1102. }
  1103. PhyValue &= ~ATL_PHY_ANA_CONTROL_SEL_CLK125M_DSP;
  1104. Result = AtlpWritePhyDebugRegister(Device,
  1105. ATL_PHY_DEBUG_LEGCYPS_REGISTER,
  1106. PhyValue);
  1107. if (Result == FALSE) {
  1108. goto ResetPhyEnd;
  1109. }
  1110. Result = AtlpReadPhyDebugRegister(Device,
  1111. ATL_PHY_DEBUG_HIBNEG_REGISTER,
  1112. &PhyValue);
  1113. if (Result == FALSE) {
  1114. goto ResetPhyEnd;
  1115. }
  1116. PhyValue &= ~ATL_PHY_HIBNEG_PSHIB_ENABLE;
  1117. Result = AtlpWritePhyDebugRegister(Device,
  1118. ATL_PHY_DEBUG_HIBNEG_REGISTER,
  1119. PhyValue);
  1120. if (Result == FALSE) {
  1121. goto ResetPhyEnd;
  1122. }
  1123. //
  1124. // Enable interrupts from the PHY whenever the link changes.
  1125. //
  1126. ShortValue = ATL_PHY_INTERRUPT_ENABLE_LINK_UP |
  1127. ATL_PHY_INTERRUPT_ENABLE_LINK_DOWN;
  1128. Result = AtlpPerformPhyRegisterIo(Device,
  1129. TRUE,
  1130. FALSE,
  1131. 0,
  1132. ATL_PHY_INTERRUPT_ENABLE_REGISTER,
  1133. &ShortValue);
  1134. if (Result == FALSE) {
  1135. goto ResetPhyEnd;
  1136. }
  1137. //
  1138. // Try some other things too.
  1139. //
  1140. ShortValue = ATL_PHY_ADVERTISE_PAUSE | ATL_PHY_ADVERTISE_ASYMMETRIC_PAUSE |
  1141. ATL_PHY_ADVERTISE_10_HALF | ATL_PHY_ADVERTISE_10_FULL |
  1142. ATL_PHY_ADVERTISE_100_HALF | ATL_PHY_ADVERTISE_100_FULL;
  1143. Result = AtlpPerformPhyRegisterIo(Device,
  1144. TRUE,
  1145. FALSE,
  1146. 0,
  1147. ATL_PHY_ADVERTISE_REGISTER,
  1148. &ShortValue);
  1149. if (Result == FALSE) {
  1150. goto ResetPhyEnd;
  1151. }
  1152. ShortValue = 0;
  1153. Result = AtlpPerformPhyRegisterIo(Device,
  1154. TRUE,
  1155. FALSE,
  1156. 0,
  1157. ATL_PHY_GIGABIT_CONTROL_REGISTER,
  1158. &ShortValue);
  1159. if (Result == FALSE) {
  1160. goto ResetPhyEnd;
  1161. }
  1162. ShortValue = ATL_PHY_AUTONEGOTIATE_RESTART | ATL_PHY_AUTONEGOTIATE_ENABLE;
  1163. Result = AtlpPerformPhyRegisterIo(Device,
  1164. TRUE,
  1165. FALSE,
  1166. 0,
  1167. ATL_PHY_BASIC_MODE_CONTROL_REGISTER,
  1168. &ShortValue);
  1169. if (Result == FALSE) {
  1170. goto ResetPhyEnd;
  1171. }
  1172. Result = TRUE;
  1173. ResetPhyEnd:
  1174. AtlpReleaseInterruptLock(Device, OldRunLevel);
  1175. return TRUE;
  1176. }
  1177. BOOL
  1178. AtlpApplyChipReset (
  1179. PATL1C_DEVICE Device
  1180. )
  1181. /*++
  1182. Routine Description:
  1183. This routine applies a reset to the ATL1c controller.
  1184. Arguments:
  1185. Device - Supplies a pointer to the device.
  1186. Return Value:
  1187. TRUE on success.
  1188. FALSE on failure.
  1189. --*/
  1190. {
  1191. ULONG Value;
  1192. Value = ATL_READ_REGISTER32(Device, AtlRegisterMasterControl) & 0xFFFF;
  1193. Value |= ATL_MASTER_CONTROL_OOB_DISABLE | ATL_MASTER_CONTROL_SOFT_RESET;
  1194. ATL_WRITE_REGISTER32(Device, AtlRegisterMasterControl, Value);
  1195. HlBusySpin(10000);
  1196. Value = ATL_READ_REGISTER32(Device, AtlRegisterMasterControl);
  1197. if ((Value & ATL_MASTER_CONTROL_SOFT_RESET) != 0) {
  1198. return FALSE;
  1199. }
  1200. if (AtlpWaitForIdleUnit(Device, ATL_IDLE_IO_MASK) != 0) {
  1201. return FALSE;
  1202. }
  1203. return TRUE;
  1204. }
  1205. BOOL
  1206. AtlpStopController (
  1207. PATL1C_DEVICE Device
  1208. )
  1209. /*++
  1210. Routine Description:
  1211. This routine stops the ATL1c ethernet controller.
  1212. Arguments:
  1213. Device - Supplies a pointer to the device.
  1214. Return Value:
  1215. TRUE on success.
  1216. FALSE on failure.
  1217. --*/
  1218. {
  1219. BOOL Result;
  1220. ULONG Value;
  1221. AtlpDisableDeviceInterrupts(Device);
  1222. Result = AtlpStopQueue(Device);
  1223. if (Result == FALSE) {
  1224. return FALSE;
  1225. }
  1226. //
  1227. // Disable DMA.
  1228. //
  1229. Value = ATL_READ_REGISTER32(Device, AtlRegisterDmaControl);
  1230. Value &= ~(ATL_DMA_CONTROL_CMB_ENABLE | ATL_DMA_CONTROL_SMB_ENABLE);
  1231. ATL_WRITE_REGISTER32(Device, AtlRegisterDmaControl, Value);
  1232. HlBusySpin(1000);
  1233. //
  1234. // Stop the MAC.
  1235. //
  1236. Result = AtlpStopMac(Device);
  1237. if (Result == FALSE) {
  1238. return FALSE;
  1239. }
  1240. //
  1241. // Disable interrupts one more time in case the work item came through
  1242. // and re-enabled them.
  1243. //
  1244. AtlpDisableDeviceInterrupts(Device);
  1245. return TRUE;
  1246. }
  1247. BOOL
  1248. AtlpStopMac (
  1249. PATL1C_DEVICE Device
  1250. )
  1251. /*++
  1252. Routine Description:
  1253. This routine disables the MAC.
  1254. Arguments:
  1255. Device - Supplies a pointer to the device.
  1256. Return Value:
  1257. TRUE on success.
  1258. FALSE on failure.
  1259. --*/
  1260. {
  1261. ULONG Value;
  1262. Value = ATL_READ_REGISTER32(Device, AtlRegisterMacControl);
  1263. Value &= ~(ATL_MAC_CONTROL_TRANSMIT_ENABLED |
  1264. ATL_MAC_CONTROL_RECEIVE_ENABLED);
  1265. ATL_WRITE_REGISTER32(Device, AtlRegisterMacControl, Value);
  1266. if (AtlpWaitForIdleUnit(Device, ATL_IDLE_IO_MASK) != 0) {
  1267. return FALSE;
  1268. }
  1269. return TRUE;
  1270. }
  1271. BOOL
  1272. AtlpStopQueue (
  1273. PATL1C_DEVICE Device
  1274. )
  1275. /*++
  1276. Routine Description:
  1277. This routine disables the ethernet controller transmit and receive
  1278. queues.
  1279. Arguments:
  1280. Device - Supplies a pointer to the device.
  1281. Return Value:
  1282. TRUE on success.
  1283. FALSE on failure.
  1284. --*/
  1285. {
  1286. ULONG Value;
  1287. Value = ATL_READ_REGISTER32(Device, AtlRegisterReceiveQueueControl);
  1288. Value &= ~ATL_RECEIVE_QUEUE_CONTROL_ENABLED;
  1289. ATL_WRITE_REGISTER32(Device, AtlRegisterReceiveQueueControl, Value);
  1290. Value = ATL_READ_REGISTER32(Device, AtlRegisterTransmitQueueControl);
  1291. Value &= ~ATL_TRANSMIT_QUEUE_CONTROL_ENABLED;
  1292. ATL_WRITE_REGISTER32(Device, AtlRegisterTransmitQueueControl, Value);
  1293. if (AtlpWaitForIdleUnit(Device, ATL_IDLE_IO_MASK) != 0) {
  1294. return FALSE;
  1295. }
  1296. return TRUE;
  1297. }
  1298. VOID
  1299. AtlpSetupReceiveFilters (
  1300. PATL1C_DEVICE Device
  1301. )
  1302. /*++
  1303. Routine Description:
  1304. This routine sets up the hardware receive filters, including promiscuous
  1305. mode and multicast setup.
  1306. Arguments:
  1307. Device - Supplies a pointer to the device.
  1308. Return Value:
  1309. None.
  1310. --*/
  1311. {
  1312. ULONG Value;
  1313. Value = ATL_READ_REGISTER32(Device, AtlRegisterMacControl);
  1314. Value &= ~(ATL_MAC_CONTROL_ALL_MULTICAST_ENABLE |
  1315. ATL_MAC_CONTROL_PROMISCUOUS_MODE_ENABLE);
  1316. Value |= ATL_MAC_CONTROL_BROADCAST_ENABLED;
  1317. //
  1318. // If there were multiple addresses to receive, this would be the place
  1319. // to set the hash bits for each one. For now, just zero them out to only
  1320. // receive at the current station address.
  1321. //
  1322. ATL_WRITE_REGISTER32(Device, AtlRegisterReceiveHashTable, 0);
  1323. ATL_WRITE_REGISTER32(Device,
  1324. AtlRegisterReceiveHashTable + sizeof(ULONG),
  1325. 0);
  1326. ATL_WRITE_REGISTER32(Device, AtlRegisterMacControl, Value);
  1327. return;
  1328. }
  1329. KSTATUS
  1330. AtlpEnableDevice (
  1331. PATL1C_DEVICE Device
  1332. )
  1333. /*++
  1334. Routine Description:
  1335. This routine brings up the ATL1c device.
  1336. Arguments:
  1337. Device - Supplies a pointer to the device.
  1338. Return Value:
  1339. Status code.
  1340. --*/
  1341. {
  1342. ATL_DUPLEX_MODE Duplex;
  1343. ULONGLONG LinkSpeed;
  1344. RUNLEVEL OldRunLevel;
  1345. BOOL Result;
  1346. USHORT ShortValue;
  1347. ATL_SPEED Speed;
  1348. KSTATUS Status;
  1349. ULONG Value;
  1350. ASSERT(KeGetRunLevel() == RunLevelLow);
  1351. Status = STATUS_DEVICE_IO_ERROR;
  1352. //
  1353. // Read the PHY status register, twice.
  1354. //
  1355. ShortValue = 0;
  1356. OldRunLevel = AtlpAcquireInterruptLock(Device);
  1357. AtlpPerformPhyRegisterIo(Device,
  1358. FALSE,
  1359. FALSE,
  1360. 0,
  1361. ATL_PHY_BASIC_MODE_STATUS_REGISTER,
  1362. &ShortValue);
  1363. Result = AtlpPerformPhyRegisterIo(Device,
  1364. FALSE,
  1365. FALSE,
  1366. 0,
  1367. ATL_PHY_BASIC_MODE_STATUS_REGISTER,
  1368. &ShortValue);
  1369. AtlpReleaseInterruptLock(Device, OldRunLevel);
  1370. if (Result == FALSE) {
  1371. RtlDebugPrint("ATL1c: Failed to read Basic Mode Status Register.\n");
  1372. goto EnableDeviceEnd;
  1373. }
  1374. //
  1375. // Tear things down if the link is down.
  1376. //
  1377. if ((ShortValue & ATL_PHY_BASIC_MODE_STATUS_LINK_UP) == 0) {
  1378. NetSetLinkState(Device->NetworkLink, FALSE, 0);
  1379. Result = AtlpStopController(Device);
  1380. if (Result == FALSE) {
  1381. goto EnableDeviceEnd;
  1382. }
  1383. AtlpSetActiveStatePowerManagement(Device, AtlSpeedOff);
  1384. //
  1385. // Reset the descriptor rings.
  1386. //
  1387. KeAcquireQueuedLock(Device->TransmitLock);
  1388. Device->LinkActive = FALSE;
  1389. AtlpResetTransmitRing(Device);
  1390. KeReleaseQueuedLock(Device->TransmitLock);
  1391. KeAcquireQueuedLock(Device->ReceiveLock);
  1392. AtlpResetReceiveRing(Device);
  1393. KeReleaseQueuedLock(Device->ReceiveLock);
  1394. //
  1395. // Go on, the link is up!
  1396. //
  1397. } else {
  1398. Result = AtlpGetLinkCharacteristics(Device, &Speed, &Duplex);
  1399. if (Result == FALSE) {
  1400. RtlDebugPrint("ATL1c: Link up, but failed to get speed/duplex "
  1401. "information.\n");
  1402. goto EnableDeviceEnd;
  1403. }
  1404. Device->LinkActive = TRUE;
  1405. Device->Speed = Speed;
  1406. Device->Duplex = Duplex;
  1407. AtlpSetActiveStatePowerManagement(Device, Speed);
  1408. switch (Device->Speed) {
  1409. case AtlSpeed10:
  1410. LinkSpeed = NET_SPEED_10_MBPS;
  1411. break;
  1412. case AtlSpeed100:
  1413. LinkSpeed = NET_SPEED_100_MBPS;
  1414. break;
  1415. case AtlSpeed1000:
  1416. LinkSpeed = NET_SPEED_1000_MBPS;
  1417. break;
  1418. default:
  1419. ASSERT(FALSE);
  1420. LinkSpeed = 0;
  1421. break;
  1422. }
  1423. NetSetLinkState(Device->NetworkLink, TRUE, LinkSpeed);
  1424. AtlpStartQueue(Device);
  1425. AtlpConfigureMac(Device);
  1426. //
  1427. // Start the MAC, it's go time.
  1428. //
  1429. Value = ATL_READ_REGISTER32(Device, AtlRegisterMacControl);
  1430. Value |= ATL_MAC_CONTROL_RECEIVE_ENABLED |
  1431. ATL_MAC_CONTROL_TRANSMIT_ENABLED;
  1432. ATL_WRITE_REGISTER32(Device, AtlRegisterMacControl, Value);
  1433. }
  1434. Status = STATUS_SUCCESS;
  1435. EnableDeviceEnd:
  1436. return Status;
  1437. }
  1438. VOID
  1439. AtlpStartQueue (
  1440. PATL1C_DEVICE Device
  1441. )
  1442. /*++
  1443. Routine Description:
  1444. This routine starts the device's transmit and receive queues.
  1445. Arguments:
  1446. Device - Supplies a pointer to the device.
  1447. Return Value:
  1448. None.
  1449. --*/
  1450. {
  1451. ULONG Value;
  1452. Value = ATL_READ_REGISTER32(Device, AtlRegisterReceiveQueueControl);
  1453. Value |= ATL_RECEIVE_QUEUE_CONTROL_ENABLED0;
  1454. ATL_WRITE_REGISTER32(Device, AtlRegisterReceiveQueueControl, Value);
  1455. Value = ATL_READ_REGISTER32(Device, AtlRegisterTransmitQueueControl);
  1456. Value |= ATL_TRANSMIT_QUEUE_CONTROL_ENABLED;
  1457. ATL_WRITE_REGISTER32(Device, AtlRegisterTransmitQueueControl, Value);
  1458. return;
  1459. }
  1460. VOID
  1461. AtlpConfigureMac (
  1462. PATL1C_DEVICE Device
  1463. )
  1464. /*++
  1465. Routine Description:
  1466. This routine configures the MAC after a link has been established with the
  1467. correct speed and duplex settings.
  1468. Arguments:
  1469. Device - Supplies a pointer to the device.
  1470. Return Value:
  1471. None.
  1472. --*/
  1473. {
  1474. ULONG Value;
  1475. Value = ATL_READ_REGISTER32(Device, AtlRegisterMacControl);
  1476. Value &= ~(ATL_MAC_CONTROL_DUPLEX |
  1477. ATL_MAC_CONTROL_RECEIVE_FLOW_ENABLED |
  1478. ATL_MAC_CONTROL_TRANSMIT_FLOW_ENABLED |
  1479. (ATL_MAC_CONTROL_SPEED_MASK << ATL_MAC_CONTROL_SPEED_SHIFT));
  1480. switch (Device->Speed) {
  1481. case AtlSpeedOff:
  1482. break;
  1483. case AtlSpeed10:
  1484. case AtlSpeed100:
  1485. Value |= ATL_MAC_CONTROL_SPEED_10_100 << ATL_MAC_CONTROL_SPEED_SHIFT;
  1486. break;
  1487. case AtlSpeed1000:
  1488. Value |= ATL_MAC_CONTROL_SPEED_1000 << ATL_MAC_CONTROL_SPEED_SHIFT;
  1489. break;
  1490. default:
  1491. ASSERT(FALSE);
  1492. return;
  1493. }
  1494. if (Device->Duplex == AtlDuplexFull) {
  1495. Value |= ATL_MAC_CONTROL_DUPLEX |
  1496. ATL_MAC_CONTROL_RECEIVE_FLOW_ENABLED |
  1497. ATL_MAC_CONTROL_TRANSMIT_FLOW_ENABLED;
  1498. }
  1499. ATL_WRITE_REGISTER32(Device, AtlRegisterMacControl, Value);
  1500. return;
  1501. }
  1502. BOOL
  1503. AtlpReadPhyDebugRegister (
  1504. PATL1C_DEVICE Device,
  1505. USHORT Register,
  1506. PUSHORT Data
  1507. )
  1508. /*++
  1509. Routine Description:
  1510. This routine reads a PHY debug register.
  1511. Arguments:
  1512. Device - Supplies a pointer to the device.
  1513. Register - Supplies the register to read.
  1514. Data - Supplies a pointer where the data will be returned.
  1515. Return Value:
  1516. TRUE on success.
  1517. FALSE on failure.
  1518. --*/
  1519. {
  1520. BOOL Result;
  1521. *Data = 0;
  1522. //
  1523. // Write the address register.
  1524. //
  1525. Result = AtlpPerformPhyRegisterIo(Device,
  1526. TRUE,
  1527. FALSE,
  1528. 0,
  1529. ATL_PHY_DEBUG_ADDRESS,
  1530. &Register);
  1531. if (Result == FALSE) {
  1532. return FALSE;
  1533. }
  1534. //
  1535. // Read the data register.
  1536. //
  1537. Result = AtlpPerformPhyRegisterIo(Device,
  1538. FALSE,
  1539. FALSE,
  1540. 0,
  1541. ATL_PHY_DEBUG_DATA,
  1542. Data);
  1543. return Result;
  1544. }
  1545. BOOL
  1546. AtlpWritePhyDebugRegister (
  1547. PATL1C_DEVICE Device,
  1548. USHORT Register,
  1549. USHORT Data
  1550. )
  1551. /*++
  1552. Routine Description:
  1553. This routine writes to a PHY debug register.
  1554. Arguments:
  1555. Device - Supplies a pointer to the device.
  1556. Register - Supplies the register to write.
  1557. Data - Supplies the data to write.
  1558. Return Value:
  1559. TRUE on success.
  1560. FALSE on failure.
  1561. --*/
  1562. {
  1563. BOOL Result;
  1564. //
  1565. // Write the address register.
  1566. //
  1567. Result = AtlpPerformPhyRegisterIo(Device,
  1568. TRUE,
  1569. FALSE,
  1570. 0,
  1571. ATL_PHY_DEBUG_ADDRESS,
  1572. &Register);
  1573. if (Result == FALSE) {
  1574. return FALSE;
  1575. }
  1576. //
  1577. // Write the data register.
  1578. //
  1579. Result = AtlpPerformPhyRegisterIo(Device,
  1580. TRUE,
  1581. FALSE,
  1582. 0,
  1583. ATL_PHY_DEBUG_DATA,
  1584. &Data);
  1585. return Result;
  1586. }
  1587. BOOL
  1588. AtlpPerformPhyRegisterIo (
  1589. PATL1C_DEVICE Device,
  1590. BOOL Write,
  1591. BOOL Extension,
  1592. UCHAR Address,
  1593. USHORT Register,
  1594. PUSHORT Data
  1595. )
  1596. /*++
  1597. Routine Description:
  1598. This routine performs a PHY register read or write using the MDIO register.
  1599. Arguments:
  1600. Device - Supplies a pointer to the device.
  1601. Write - Supplies TRUE if this is a write operation or FALSE if this is a
  1602. read operation.
  1603. Extension - Supplies a boolean indicating whether or not this access is an
  1604. extension register.
  1605. Address - Supplies the address of the device (usually 0).
  1606. Register - Supplies the register to access on the device.
  1607. Data - Supplies a pointer that for writes supplies the data to write and
  1608. for writes contains the value to write.
  1609. Return Value:
  1610. TRUE on success.
  1611. FALSE on failure.
  1612. --*/
  1613. {
  1614. USHORT ClockSelect;
  1615. ULONG LoopIndex;
  1616. ULONG MdioValue;
  1617. BOOL Result;
  1618. ULONG Value;
  1619. ASSERT(KeIsSpinLockHeld(&(Device->InterruptLock)) != FALSE);
  1620. ASSERT(KeGetRunLevel() >= RunLevelDispatch);
  1621. //
  1622. // Set up the MDIO control register, and potentially the extension register
  1623. // for an extended register read.
  1624. //
  1625. ClockSelect = ATL_MDIO_CONTROL_CLOCK_25MHZ_DIVIDE_4;
  1626. MdioValue = ATL_MDIO_CONTROL_SPRES_PRMBL |
  1627. ((ClockSelect & ATL_MDIO_CONTROL_CLOCK_SELECT_MASK) <<
  1628. ATL_MDIO_CONTROL_CLOCK_SELECT_SHIFT) |
  1629. ATL_MDIO_CONTROL_START;
  1630. if (Extension != FALSE) {
  1631. MdioValue |= ATL_MDIO_CONTROL_EXTENSION_MODE;
  1632. Value = ((Address & ATL_MDIO_EXTENSION_DEVICE_ADDRESS_MASK) <<
  1633. ATL_MDIO_EXTENSION_DEVICE_ADDRESS_SHIFT) |
  1634. ((Register & ATL_MDIO_EXTENSION_REGISTER_MASK) <<
  1635. ATL_MDIO_EXTENSION_REGISTER_SHIFT);
  1636. ATL_WRITE_REGISTER32(Device, AtlRegisterMdioExtension, Value);
  1637. } else {
  1638. MdioValue |= (Register & ATL_MDIO_CONTROL_REGISTER_MASK) <<
  1639. ATL_MDIO_CONTROL_REGISTER_SHIFT;
  1640. }
  1641. if (Write != FALSE) {
  1642. MdioValue |= (*Data & ATL_MDIO_CONTROL_DATA_MASK) <<
  1643. ATL_MDIO_CONTROL_DATA_SHIFT;
  1644. } else {
  1645. MdioValue |= ATL_MDIO_CONTROL_READ_OPERATION;
  1646. }
  1647. ATL_WRITE_REGISTER32(Device, AtlRegisterMdioControl, MdioValue);
  1648. //
  1649. // Wait for the MDIO module to become idle again.
  1650. //
  1651. for (LoopIndex = 0; LoopIndex < ATL_MDIO_WAIT_LOOP_COUNT; LoopIndex += 1) {
  1652. Value = ATL_READ_REGISTER32(Device, AtlRegisterMdioControl);
  1653. if ((Value & (ATL_MDIO_CONTROL_BUSY | ATL_MDIO_CONTROL_START)) == 0) {
  1654. break;
  1655. }
  1656. HlBusySpin(ATL_MDIO_WAIT_LOOP_DELAY);
  1657. }
  1658. if (LoopIndex == ATL_MDIO_WAIT_LOOP_COUNT) {
  1659. Result = FALSE;
  1660. goto PerformPhyRegisterIoEnd;
  1661. }
  1662. //
  1663. // Read the result out if this is a read.
  1664. //
  1665. if (Write == FALSE) {
  1666. Value = ATL_READ_REGISTER32(Device, AtlRegisterMdioControl);
  1667. *Data = (USHORT)((Value >> ATL_MDIO_CONTROL_DATA_SHIFT) &
  1668. ATL_MDIO_CONTROL_DATA_MASK);
  1669. }
  1670. Result = TRUE;
  1671. PerformPhyRegisterIoEnd:
  1672. return Result;
  1673. }
  1674. ULONG
  1675. AtlpWaitForIdleUnit (
  1676. PATL1C_DEVICE Device,
  1677. ULONG BitsToBecomeClear
  1678. )
  1679. /*++
  1680. Routine Description:
  1681. This routine attempts to wait for the device to become idle.
  1682. Arguments:
  1683. Device - Supplies a pointer to the device.
  1684. BitsToBecomeClear - Supplies the bitmask of bits in the idle status register
  1685. to read until they clear.
  1686. Return Value:
  1687. 0 if all the specified bits cleared.
  1688. Returns the bitmask of bits that are stuck on if the operation timed out.
  1689. --*/
  1690. {
  1691. ULONG IdleRegister;
  1692. ULONG LoopIndex;
  1693. IdleRegister = 0;
  1694. for (LoopIndex = 0; LoopIndex < ATL_IDLE_WAIT_LOOP_COUNT; LoopIndex += 1) {
  1695. IdleRegister = ATL_READ_REGISTER32(Device, AtlRegisterIdleStatus);
  1696. if ((IdleRegister & BitsToBecomeClear) == 0) {
  1697. return 0;
  1698. }
  1699. HlBusySpin(ATL_IDLE_WAIT_LOOP_DELAY);
  1700. }
  1701. return IdleRegister;
  1702. }
  1703. BOOL
  1704. AtlpReadMacAddress (
  1705. PATL1C_DEVICE Device
  1706. )
  1707. /*++
  1708. Routine Description:
  1709. This routine reads the MAC address from the device.
  1710. Arguments:
  1711. Device - Supplies a pointer to the device. The MAC address will be set in
  1712. the device structure.
  1713. Return Value:
  1714. TRUE on success.
  1715. FALSE on failure.
  1716. --*/
  1717. {
  1718. ULONG LoopIndex;
  1719. ULONG OtpControl;
  1720. ULONG TwsiControl;
  1721. //
  1722. // First check the current address to see if a valid MAC address is already
  1723. // programmed in. If so, use it. It may have been set by the BIOS.
  1724. //
  1725. if (AtlpReadCurrentMacAddress(Device) != FALSE) {
  1726. return TRUE;
  1727. }
  1728. OtpControl = ATL_READ_REGISTER32(Device, AtlRegisterOtpControl);
  1729. if (AtlpDoesEepromExist(Device) != FALSE) {
  1730. //
  1731. // Enable the OTP clock if it's not already on.
  1732. //
  1733. if ((OtpControl & ATL_OTP_CONTROL_CLOCK_ENABLE) == 0) {
  1734. OtpControl |= ATL_OTP_CONTROL_CLOCK_ENABLE;
  1735. ATL_WRITE_REGISTER32(Device, AtlRegisterOtpControl, OtpControl);
  1736. HlBusySpin(1000);
  1737. }
  1738. TwsiControl = ATL_READ_REGISTER32(Device, AtlRegisterTwsiControl);
  1739. TwsiControl |= ATL_TWSI_CONTROL_SOFTWARE_LOAD_START;
  1740. ATL_WRITE_REGISTER32(Device, AtlRegisterTwsiControl, TwsiControl);
  1741. for (LoopIndex = 0;
  1742. LoopIndex < ATL_TWSI_EEPROM_LOOP_COUNT;
  1743. LoopIndex += 1) {
  1744. HlBusySpin(ATL_TWSI_EEPROM_LOOP_DELAY);
  1745. TwsiControl = ATL_READ_REGISTER32(Device, AtlRegisterTwsiControl);
  1746. if ((TwsiControl & ATL_TWSI_CONTROL_SOFTWARE_LOAD_START) == 0) {
  1747. break;
  1748. }
  1749. }
  1750. if (LoopIndex == ATL_TWSI_EEPROM_LOOP_COUNT) {
  1751. return FALSE;
  1752. }
  1753. }
  1754. //
  1755. // Disable the OTP clock.
  1756. //
  1757. OtpControl &= ~ATL_OTP_CONTROL_CLOCK_ENABLE;
  1758. ATL_WRITE_REGISTER32(Device, AtlRegisterOtpControl, OtpControl);
  1759. HlBusySpin(1000);
  1760. //
  1761. // Now check to see if the current address is loaded.
  1762. //
  1763. if (AtlpReadCurrentMacAddress(Device) != FALSE) {
  1764. return TRUE;
  1765. }
  1766. return FALSE;
  1767. }
  1768. BOOL
  1769. AtlpDoesEepromExist (
  1770. PATL1C_DEVICE Device
  1771. )
  1772. /*++
  1773. Routine Description:
  1774. This routine determines if there is an EEPROM attached to the ethernet
  1775. device.
  1776. Arguments:
  1777. Device - Supplies a pointer to the device.
  1778. Return Value:
  1779. TRUE if an EEPROM is present.
  1780. FALSE if no EEPROM is connected.
  1781. --*/
  1782. {
  1783. ULONG Value;
  1784. Value = ATL_READ_REGISTER32(Device, AtlRegisterTwsiDebug);
  1785. if ((Value & ATL_TWSI_DEBUG_DEVICE_EXISTS) != 0) {
  1786. return TRUE;
  1787. }
  1788. Value = ATL_READ_REGISTER32(Device, AtlRegisterMasterControl);
  1789. if ((Value & ATL_MASTER_CONTROL_OTP_SEL) != 0) {
  1790. return TRUE;
  1791. }
  1792. return FALSE;
  1793. }
  1794. BOOL
  1795. AtlpReadCurrentMacAddress (
  1796. PATL1C_DEVICE Device
  1797. )
  1798. /*++
  1799. Routine Description:
  1800. This routine reads the current MAC address programmed into the device and
  1801. if valid, saves it into the device structure.
  1802. Arguments:
  1803. Device - Supplies a pointer to the device. If the current MAC address is
  1804. valid, it will be saved into this structure.
  1805. Return Value:
  1806. TRUE if the current address was valid.
  1807. FALSE if the address was not programmed (was an invalid address).
  1808. --*/
  1809. {
  1810. ULONG Address1;
  1811. USHORT Address2;
  1812. BOOL InvalidAddress;
  1813. Address1 = ATL_READ_REGISTER32(Device, AtlRegisterMacAddress1);
  1814. Address2 = (USHORT)ATL_READ_REGISTER32(Device, AtlRegisterMacAddress2);
  1815. InvalidAddress = FALSE;
  1816. if ((Address1 == MAX_ULONG) && (Address2 == MAX_USHORT)) {
  1817. InvalidAddress = TRUE;
  1818. }
  1819. if ((Address1 == 0) && (Address2 == 0)) {
  1820. InvalidAddress = TRUE;
  1821. }
  1822. if (InvalidAddress == FALSE) {
  1823. Address1 = CPU_TO_NETWORK32(Address1);
  1824. Address2 = CPU_TO_NETWORK16(Address2);
  1825. RtlCopyMemory(Device->EepromMacAddress, &Address2, sizeof(USHORT));
  1826. RtlCopyMemory(&(Device->EepromMacAddress[sizeof(USHORT)]),
  1827. &Address1,
  1828. sizeof(ULONG));
  1829. return TRUE;
  1830. }
  1831. return FALSE;
  1832. }
  1833. VOID
  1834. AtlpDisableDeviceInterrupts (
  1835. PATL1C_DEVICE Device
  1836. )
  1837. /*++
  1838. Routine Description:
  1839. This routine disables interrupt generation for the device.
  1840. Arguments:
  1841. Device - Supplies a pointer to the device.
  1842. Return Value:
  1843. None.
  1844. --*/
  1845. {
  1846. ATL_WRITE_REGISTER32(Device, AtlRegisterInterruptMask, 0);
  1847. ATL_WRITE_REGISTER32(Device,
  1848. AtlRegisterInterruptStatus,
  1849. ATL_INTERRUPT_DISABLE);
  1850. return;
  1851. }
  1852. VOID
  1853. AtlpEnableDeviceInterrupts (
  1854. PATL1C_DEVICE Device
  1855. )
  1856. /*++
  1857. Routine Description:
  1858. This routine enables interrupt generation for the device.
  1859. Arguments:
  1860. Device - Supplies a pointer to the device.
  1861. Return Value:
  1862. None.
  1863. --*/
  1864. {
  1865. ATL_WRITE_REGISTER32(Device,
  1866. AtlRegisterInterruptStatus,
  1867. ATL_INTERRUPT_MASK);
  1868. ATL_WRITE_REGISTER32(Device,
  1869. AtlRegisterInterruptMask,
  1870. Device->EnabledInterrupts);
  1871. return;
  1872. }
  1873. VOID
  1874. AtlpSetActiveStatePowerManagement (
  1875. PATL1C_DEVICE Device,
  1876. ATL_SPEED Speed
  1877. )
  1878. /*++
  1879. Routine Description:
  1880. This routine sets the PCI Express Active State Power Management
  1881. configuration for the device based on the link speed.
  1882. Arguments:
  1883. Device - Supplies a pointer to the device.
  1884. Speed - Supplies the speed of the link.
  1885. Return Value:
  1886. None.
  1887. --*/
  1888. {
  1889. ULONG Value;
  1890. //
  1891. // Read the power management register and clear out the bits that are going
  1892. // to be set by this function.
  1893. //
  1894. Value = ATL_READ_REGISTER32(Device, AtlRegisterPowerManagementControl);
  1895. Value &= ~((ATL_POWER_MANAGEMENT_CONTROL_L1_ENTRY_TIME_MASK <<
  1896. ATL_POWER_MANAGEMENT_CONTROL_L1_ENTRY_TIME_SHIFT) |
  1897. ATL_POWER_MANAGEMENT_CONTROL_L0S_ENABLE |
  1898. ATL_POWER_MANAGEMENT_CONTROL_L1_ENABLE |
  1899. ATL_POWER_MANAGEMENT_CONTROL_ASPM_MAC_CHECK);
  1900. //
  1901. // Enable L0s and/or L1.
  1902. //
  1903. if (Speed != AtlSpeedOff) {
  1904. Value |= ATL_POWER_MANAGEMENT_CONTROL_SERDES_L1_ENABLE |
  1905. ATL_POWER_MANAGEMENT_CONTROL_SERDES_PLL_L1_ENABLE |
  1906. ATL_POWER_MANAGEMENT_CONTROL_SERDES_BUFS_RECEIVE_L1_ENABLE |
  1907. ATL_POWER_MANAGEMENT_CONTROL_ASPM_MAC_CHECK;
  1908. Value &= ~(ATL_POWER_MANAGEMENT_CONTROL_SERDES_PD_EX_L1 |
  1909. ATL_POWER_MANAGEMENT_CONTROL_CLK_SWH_L1 |
  1910. ATL_POWER_MANAGEMENT_CONTROL_L0S_ENABLE |
  1911. ATL_POWER_MANAGEMENT_CONTROL_L1_ENABLE);
  1912. //
  1913. // The link is down.
  1914. //
  1915. } else {
  1916. Value |= ATL_POWER_MANAGEMENT_CONTROL_CLK_SWH_L1;
  1917. Value &= ~(ATL_POWER_MANAGEMENT_CONTROL_SERDES_L1_ENABLE |
  1918. ATL_POWER_MANAGEMENT_CONTROL_SERDES_PLL_L1_ENABLE |
  1919. ATL_POWER_MANAGEMENT_CONTROL_SERDES_BUFS_RECEIVE_L1_ENABLE |
  1920. ATL_POWER_MANAGEMENT_CONTROL_L0S_ENABLE);
  1921. }
  1922. ATL_WRITE_REGISTER32(Device, AtlRegisterPowerManagementControl, Value);
  1923. return;
  1924. }
  1925. VOID
  1926. AtlpResetTransmitRing (
  1927. PATL1C_DEVICE Device
  1928. )
  1929. /*++
  1930. Routine Description:
  1931. This routine clears out and resets the transmit descriptor ring. This
  1932. routine assumes the transmit lock is already held (or doesn't need to be).
  1933. Arguments:
  1934. Device - Supplies a pointer to the device.
  1935. Return Value:
  1936. None.
  1937. --*/
  1938. {
  1939. USHORT CurrentIndex;
  1940. USHORT DescriptorIndex;
  1941. ASSERT(KeIsQueuedLockHeld(Device->TransmitLock) != FALSE);
  1942. //
  1943. // Clean out and free all descriptors.
  1944. //
  1945. for (DescriptorIndex = 0;
  1946. DescriptorIndex < ATL1C_TRANSMIT_DESCRIPTOR_COUNT;
  1947. DescriptorIndex += 1) {
  1948. if (Device->TransmitBuffer[DescriptorIndex] != NULL) {
  1949. ASSERT(Device->TransmitDescriptor[DescriptorIndex].BufferLength !=
  1950. 0);
  1951. NetFreeBuffer(Device->TransmitBuffer[DescriptorIndex]);
  1952. Device->TransmitBuffer[DescriptorIndex] = NULL;
  1953. }
  1954. }
  1955. //
  1956. // Clean out the pending transmit descriptors.
  1957. //
  1958. RtlZeroMemory(Device->TransmitDescriptor,
  1959. sizeof(ATL1C_TRANSMIT_DESCRIPTOR) *
  1960. (ATL1C_TRANSMIT_DESCRIPTOR_COUNT + 1));
  1961. //
  1962. // Destroy the list of packets waiting to be sent.
  1963. //
  1964. NetDestroyBufferList(&(Device->TransmitPacketList));
  1965. //
  1966. // Reset the counters in software and hardware based on the current index.
  1967. // The current index cannot be reset by software.
  1968. //
  1969. CurrentIndex = ATL_READ_REGISTER16(Device,
  1970. AtlRegisterTransmitCurrentIndex);
  1971. Device->TransmitNextToUse = CurrentIndex;
  1972. Device->TransmitNextToClean = CurrentIndex;
  1973. ATL_WRITE_REGISTER16(Device,
  1974. AtlRegisterTransmitNextIndex,
  1975. Device->TransmitNextToUse);
  1976. return;
  1977. }
  1978. VOID
  1979. AtlpResetReceiveRing (
  1980. PATL1C_DEVICE Device
  1981. )
  1982. /*++
  1983. Routine Description:
  1984. This routine clears out the receive descriptor ring, discarding any
  1985. packets that had come in but not been processed. This routine does not
  1986. acquire the receive lock, it is assumed that the receive lock is already
  1987. held or does not need to be.
  1988. Arguments:
  1989. Device - Supplies a pointer to the device.
  1990. Return Value:
  1991. None.
  1992. --*/
  1993. {
  1994. ULONG Value;
  1995. RtlZeroMemory(Device->ReceivedPacket,
  1996. sizeof(ATL1C_RECEIVED_PACKET) * ATL1C_RECEIVE_FRAME_COUNT);
  1997. if (Device->ReceiveNextToClean == 0) {
  1998. Value = ATL1C_RECEIVE_FRAME_COUNT - 1;
  1999. } else {
  2000. Value = Device->ReceiveNextToClean - 1;
  2001. }
  2002. ATL_WRITE_REGISTER32(Device, AtlRegisterReceiveFrameIndex, Value);
  2003. return;
  2004. }
  2005. BOOL
  2006. AtlpGetLinkCharacteristics (
  2007. PATL1C_DEVICE Device,
  2008. PATL_SPEED Speed,
  2009. PATL_DUPLEX_MODE Duplex
  2010. )
  2011. /*++
  2012. Routine Description:
  2013. This routine gets the link information, including link speed and duplex
  2014. status.
  2015. Arguments:
  2016. Device - Supplies a pointer to the device with the link to query.
  2017. Speed - Supplies a pointer where the link speed will be returned.
  2018. Duplex - Supplies a pointer where the link duplex status will be returned.
  2019. Return Value:
  2020. TRUE on success.
  2021. FALSE if the link could not be queried.
  2022. --*/
  2023. {
  2024. RUNLEVEL OldRunLevel;
  2025. BOOL Result;
  2026. USHORT Value;
  2027. OldRunLevel = AtlpAcquireInterruptLock(Device);
  2028. Result = AtlpPerformPhyRegisterIo(Device,
  2029. FALSE,
  2030. FALSE,
  2031. 0,
  2032. ATL_PHY_GIGA_PSSR_REGISTER,
  2033. &Value);
  2034. AtlpReleaseInterruptLock(Device, OldRunLevel);
  2035. if (Result == FALSE) {
  2036. return FALSE;
  2037. }
  2038. if ((Value & ATL_PHY_GIGA_PSSR_SPEED_AND_DUPLEX_RESOLVED) == 0) {
  2039. return FALSE;
  2040. }
  2041. switch (Value & ATL_PHY_GIGA_PSSR_SPEED_MASK) {
  2042. case ATL_PHY_GIGA_PSSR_SPEED_1000:
  2043. *Speed = AtlSpeed1000;
  2044. break;
  2045. case ATL_PHY_GIGA_PSSR_SPEED_100:
  2046. *Speed = AtlSpeed100;
  2047. break;
  2048. case ATL_PHY_GIGA_PSSR_SPEED_10:
  2049. *Speed = AtlSpeed10;
  2050. break;
  2051. default:
  2052. return FALSE;
  2053. }
  2054. if ((Value & ATL_PHY_GIGA_PSSR_DUPLEX) != 0) {
  2055. *Duplex = AtlDuplexFull;
  2056. } else {
  2057. *Duplex = AtlDuplexHalf;
  2058. }
  2059. return TRUE;
  2060. }
  2061. ULONG
  2062. AtlpHashAddress (
  2063. PUCHAR MacAddress
  2064. )
  2065. /*++
  2066. Routine Description:
  2067. This routine computes the value to put in a device's hash table for the
  2068. given MAC address.
  2069. Arguments:
  2070. MacAddress - Supplies a pointer to the six byte MAC address.
  2071. Return Value:
  2072. Returns the hashed value.
  2073. --*/
  2074. {
  2075. ULONG BitIndex;
  2076. ULONG Crc32;
  2077. ULONG Hash;
  2078. Hash = 0;
  2079. //
  2080. // The hash is the CRC32, but with all the bits reversed.
  2081. //
  2082. Crc32 = RtlComputeCrc32(0, MacAddress, 6);
  2083. for (BitIndex = 0;
  2084. BitIndex < (sizeof(ULONG) * BITS_PER_BYTE);
  2085. BitIndex += 1) {
  2086. Hash |= ((Crc32 >> BitIndex) & 0x1) <<
  2087. ((sizeof(ULONG) * BITS_PER_BYTE) - 1 - BitIndex);
  2088. }
  2089. return Hash;
  2090. }
  2091. RUNLEVEL
  2092. AtlpAcquireInterruptLock (
  2093. PATL1C_DEVICE Device
  2094. )
  2095. /*++
  2096. Routine Description:
  2097. This routine acquires the interrupt lock from outside the interrupt
  2098. handler.
  2099. Arguments:
  2100. Device - Supplies a pointer to the device.
  2101. Return Value:
  2102. Returns the original run-level.
  2103. --*/
  2104. {
  2105. RUNLEVEL OldRunLevel;
  2106. ASSERT(KeGetRunLevel() <= RunLevelDispatch);
  2107. if (Device->InterruptHandle != INVALID_HANDLE) {
  2108. OldRunLevel = IoRaiseToInterruptRunLevel(Device->InterruptHandle);
  2109. } else {
  2110. OldRunLevel = KeRaiseRunLevel(RunLevelDispatch);
  2111. }
  2112. KeAcquireSpinLock(&(Device->InterruptLock));
  2113. return OldRunLevel;
  2114. }
  2115. VOID
  2116. AtlpReleaseInterruptLock (
  2117. PATL1C_DEVICE Device,
  2118. RUNLEVEL OldRunLevel
  2119. )
  2120. /*++
  2121. Routine Description:
  2122. This routine releases the interrupt lock from outside the interrupt
  2123. handler.
  2124. Arguments:
  2125. Device - Supplies a pointer to the device.
  2126. OldRunLevel - Supplies the original run-level returned by the acquire
  2127. function.
  2128. Return Value:
  2129. None.
  2130. --*/
  2131. {
  2132. ASSERT(KeGetRunLevel() >= RunLevelDispatch);
  2133. KeReleaseSpinLock(&(Device->InterruptLock));
  2134. KeLowerRunLevel(OldRunLevel);
  2135. return;
  2136. }