NetworkMii.Mod 24 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601
  1. MODULE NetworkMii; (** AUTHOR "staubesv"; PURPOSE "Media Independent Interface (MII) management interface support"; *)
  2. (**
  3. * The Media Independent Interface (MII) is an interface between the MAC Layer and the PHY. The MII Management Interface's purpose is
  4. * to control the PHY and gather status from the PHY. This module defines constants and implements some basic functionality for both
  5. * the MII management interface and its superset GMII.
  6. *
  7. * References:
  8. *
  9. * [1] IEEE Std 802.3-2005 Edition, www.ieee.org
  10. *
  11. * History:
  12. *
  13. * 03.11.2006 First release (staubesv)
  14. *
  15. * Status:
  16. *
  17. * BETA
  18. * - 1GB auto-negotiation not yet supported
  19. * - Handling of devices that don't support auto-negotiation not supported
  20. *)
  21. IMPORT
  22. SYSTEM, KernelLog, Objects, Kernel, Network;
  23. CONST
  24. Ok* = 0;
  25. Unsupported* = 1;
  26. ParametersInvalid* = 2;
  27. NotAvailable* = 3;
  28. ErrorRead* = 5;
  29. ErrorWrite* = 6;
  30. Timeout* = 7;
  31. AutoNegotiationTimeout = 1000; (* ms *)
  32. TraceAutoNegotiation = {0};
  33. TraceCommands = {1};
  34. Trace = {};
  35. Debug = TRUE;
  36. ModuleName = "NetworkMii";
  37. (** MII register offsets *)
  38. (** Basic Registers *)
  39. BMCR* = 0H; (** Basic Mode Control Register *)
  40. BMSR* = 1H; (** Basic Mode Status Register *)
  41. BMESR* = 15H; (** Basic Mode Extended Status Register (GMII only) *)
  42. (** Extended Registers *)
  43. PHYIDR1* = 2H; (** PHY Identifier Register 1 *)
  44. PHYIDR2* = 3H; (** PHY Identifier Register 2 *)
  45. ANAR* = 4H; (** Auto-Negotiation Advertisement Register *)
  46. ANLPAR* = 5H; (** Auto-Negotiation Link Partner Ability Register *)
  47. ANER* = 6H; (** Auto-Negotiation Expansion Register *)
  48. ANNPTR* = 7H; (** Auto-Negotiation Next Page Transmit Register *)
  49. ANLPRNPR* = 8H; (** Auto-Negotiation Link Partner Received Next Page Register *)
  50. MSCR* = 9H; (** Master-Slave Control Register *)
  51. MSSR* = 10H; (** Master-Slave Status Register *)
  52. PSECR* = 11H; (** PSE Control Register *)
  53. PSESR* = 12H; (** PSE Status Register *)
  54. MMDACR* = 13H; (** MMD Access Control Register *)
  55. MMDAADR* = 14H; (** MMD Access Address Data Register *)
  56. (* 16H-31H: Vendor-Specific extended registers *)
  57. (* Basic Mode Control Register (BMCR) *)
  58. BMCR_Reset* = {15}; (* self-clearing, default: 0 *)
  59. BMCR_Loopback* = {14}; (* default: 0 *)
  60. BMCR_SpeedSelectionLsb* = {13};
  61. BMCR_AutoNegotiationEnable* = {12}; (* default: 1 *)
  62. BMCR_PowerDown* = {11}; (* default: 0 *)
  63. BMCR_Isolate* = {10}; (* default: 0 *)
  64. BMCR_RestartAutoNegotiation* = {9}; (* self-clearing *)
  65. BMCR_DuplexMode* = {8};
  66. BMCR_CollisionTest* = {7}; (* default: 0 *)
  67. BMCR_SpeedSelectionMsb* = {6};
  68. BMCR_UnidirectionalEnable* = {5};
  69. BMCR_Reserved* = {0..4}; (* write as zero *)
  70. (* Basic Mode Status Register (BMSR), all fields are read-only *)
  71. BMSR_100BaseT4* = {15};
  72. BMSR_100BaseTXFullDuplex* = {14};
  73. BMSR_100BaseTXHalfDuplex* = {13};
  74. BMSR_10BaseTFullDuplex* = {12};
  75. BMSR_10BaseTHalfDuplex* = {11};
  76. BMSR_100BaseT2FullDuplex* = {10};
  77. BMSR_100BaseT2HalfDuplex* = {9};
  78. BMSR_ExtendedStatus* = {8}; (* Extended status information in register 15 (BMESR) *)
  79. BMSR_UnidirectionalAbility* = {7};
  80. BMSR_MfPreambleSuppression* = {6};
  81. BMSR_AutoNegotiationComplete* = {5};
  82. BMSR_RemoteFault* = {4};
  83. BMSR_AutoNegotiationAbility* = {3};
  84. BMSR_LinkStatus* = {2};
  85. BMSR_JabberDetect* = {1};
  86. BMSR_ExtendedCapability* = {0}; (* Extended register available *)
  87. (* Basic Mode Extended Status Register (BMESR), all fields are read-only *)
  88. BMESR_1000BaseXFullDuplex* = {15};
  89. BMESR_1000BaseXHalfDuplex* = {14};
  90. BMESR_1000BaseTFullDuplex* = {13};
  91. BMESR_1000BaseTHalfDuplex* = {12};
  92. BMESR_Reserved* = {0..11};
  93. (* PHY Identifier Register 1 (PHYIDR1) *)
  94. PHYIDR1_OuiMSB* = {0..15};
  95. (* PHY Identifier Register 2 (PHYIDR2) *)
  96. PHYIDR2_OuiLSB* = {10..15};
  97. PHYIDR2_VendorModel* = {4..9};
  98. PHYIDR2_ModelRevision* = {0..3};
  99. (* Auto Negotiation Advertisement Register (ANAR) *)
  100. (* Auto Negotiation Link Partner Ability Register (ANLPAR) *)
  101. ANAR_NextPageIndication* = {15};
  102. ANAR_Ackknowlegdement* = {14};
  103. ANAR_RemoteFault* = {13};
  104. ANAR_Reserved* = {11..12}; (* write as zero *)
  105. ANAR_AsymmetricPause* = {11};
  106. ANAR_Pause* = {10};
  107. ANAR_100BaseT4Support* = {9};
  108. ANAR_100BaseTXFullDuplex* = {8};
  109. ANAR_100BaseTXHalfDuplex* = {7};
  110. ANAR_10BaseTFullDuplex* = {6};
  111. ANAR_10BaseTHalfDuplex* = {5};
  112. ANAR_Selector* = {0..4};
  113. (* ANAR/ANLPAR Selector field *)
  114. Selector_IEEE_STD802_3* = 1;
  115. Selector_IEEE_STD802_9ISLAN16T* = 2;
  116. (* Auto Negotiation Expansion Register (ANER) *)
  117. ANER_Reserved* = {5..15}; (* write as zero *)
  118. ANER_ParallelDetectionFault* = {4};
  119. ANER_LinkPartnerNextPageEnable* = {3};
  120. ANER_PhyNextPageEnable* = {2};
  121. ANER_NewPageReception* = {1};
  122. ANER_LinkPartnerAnEnable* = {0};
  123. TYPE
  124. Identifier* = RECORD
  125. oui- : LONGINT; (* Organizationally Unique Identifier *)
  126. model- : LONGINT;
  127. revision- : LONGINT;
  128. END;
  129. TYPE
  130. MII* = OBJECT
  131. VAR
  132. phyId- : LONGINT;
  133. lockedBy : ANY;
  134. timer : Kernel.Timer;
  135. (** Abstract interface to be implemented by the implementor *)
  136. (** Acqurie PHY ownership *)
  137. PROCEDURE AcquirePhyOwnership*() : BOOLEAN; (* abstract *)
  138. BEGIN HALT(301); END AcquirePhyOwnership;
  139. (** Release PHY ownership *)
  140. PROCEDURE ReleasePhyOwnership*() : BOOLEAN; (* abstract *)
  141. BEGIN HALT(301); END ReleasePhyOwnership;
  142. PROCEDURE HasPhyOwnership() : BOOLEAN; (* abstract *)
  143. BEGIN HALT(301); END HasPhyOwnership;
  144. (** Read a MII/GMII register *)
  145. PROCEDURE ReadRegister16*(register: LONGINT; VAR value : SET; VAR res : WORD); (* abstract *)
  146. BEGIN HALT(301); END ReadRegister16;
  147. (** Write a MII/GMII register *)
  148. PROCEDURE WriteRegister16*(register : LONGINT; value : SET; VAR res : WORD); (* abstract *)
  149. BEGIN HALT(301); END WriteRegister16;
  150. (** MII Management Interface *)
  151. PROCEDURE Acquire*;
  152. VAR me : ANY;
  153. BEGIN {EXCLUSIVE}
  154. me := Objects.ActiveObject();
  155. ASSERT(lockedBy # me); (* no recursive locking *)
  156. AWAIT(lockedBy = NIL);
  157. IF ~AcquirePhyOwnership() THEN
  158. Show("Serious error: Software could not acquire PHY ownership."); KernelLog.Ln;
  159. END;
  160. lockedBy := me;
  161. END Acquire;
  162. PROCEDURE Release*;
  163. BEGIN {EXCLUSIVE}
  164. ASSERT(lockedBy = Objects.ActiveObject());
  165. IF ~ReleasePhyOwnership() THEN
  166. Show("Fatal error: Software could not release PHY ownership."); KernelLog.Ln;
  167. END;
  168. lockedBy := NIL;
  169. END Release;
  170. (** Enable/disable auto-negotiation *)
  171. PROCEDURE EnableAutoNegotiation*(enable : BOOLEAN; VAR res : WORD);
  172. VAR anar, bmcr, bmsr : SET;
  173. BEGIN
  174. ASSERT(lockedBy = Objects.ActiveObject());
  175. (* Check wether PHY supports auto-negotiation *)
  176. ReadRegister16(BMSR, bmsr, res);
  177. IF res # Ok THEN RETURN; END;
  178. IF bmsr * BMSR_AutoNegotiationAbility = {} THEN
  179. IF Trace * TraceCommands # {} THEN Show("Auto-Negotiation not supported."); KernelLog.Ln; END;
  180. res := Unsupported;
  181. RETURN;
  182. END;
  183. IF bmsr * BMSR_ExtendedCapability = {} THEN
  184. IF Trace * TraceCommands # {} THEN Show("Extended registers not available."); KernelLog.Ln; END;
  185. res := Unsupported;
  186. RETURN;
  187. END;
  188. (* Set abilities to be advertised *)
  189. anar := SYSTEM.VAL(SET, Selector_IEEE_STD802_3) * ANAR_Selector;
  190. IF bmsr * BMSR_100BaseT4 # {} THEN anar := anar + ANAR_100BaseT4Support; END;
  191. IF bmsr * BMSR_100BaseTXFullDuplex # {} THEN anar := anar + ANAR_100BaseTXFullDuplex; END;
  192. IF bmsr * BMSR_100BaseTXHalfDuplex # {} THEN anar := anar + ANAR_100BaseTXHalfDuplex; END;
  193. IF bmsr * BMSR_10BaseTFullDuplex # {} THEN anar := anar + ANAR_10BaseTFullDuplex; END;
  194. IF bmsr * BMSR_10BaseTHalfDuplex # {} THEN anar := anar + ANAR_10BaseTHalfDuplex; END;
  195. IF bmsr * BMSR_100BaseT2FullDuplex # {} THEN (* TODO *) END;
  196. IF bmsr * BMSR_100BaseT2HalfDuplex # {} THEN (* TODO *) END;
  197. (* TODO: 1GB *)
  198. anar := anar + ANAR_Pause;
  199. WriteRegister16(ANAR, anar, res);
  200. IF res # Ok THEN RETURN END;
  201. ReadRegister16(BMCR, bmcr, res);
  202. IF res # Ok THEN RETURN; END;
  203. IF enable THEN bmcr := bmcr + BMCR_AutoNegotiationEnable; ELSE bmcr := bmcr - BMCR_AutoNegotiationEnable; END;
  204. WriteRegister16(BMCR, bmcr, res);
  205. IF res # Ok THEN RETURN; END;
  206. IF enable THEN
  207. WriteRegister16(BMCR, bmcr + BMCR_RestartAutoNegotiation, res);
  208. END;
  209. END EnableAutoNegotiation;
  210. (** Get link configuration negotiated by auto-negotiation *)
  211. PROCEDURE GetAutoNegotiationResult*(VAR linkspeed : LONGINT; VAR fullDuplex : BOOLEAN; VAR res : WORD);
  212. VAR bmsr, anar, aner, anlpar, supported : SET; timeout : LONGINT; string : ARRAY 64 OF CHAR;
  213. BEGIN
  214. ASSERT(lockedBy = Objects.ActiveObject());
  215. ReadRegister16(BMSR, bmsr, res);
  216. IF res # Ok THEN RETURN; END;
  217. IF bmsr * BMSR_AutoNegotiationAbility = {} THEN
  218. IF Trace * TraceAutoNegotiation # {} THEN Show("Auto-Negotiation not supported."); KernelLog.Ln; END;
  219. res := Unsupported;
  220. RETURN;
  221. END;
  222. IF bmsr * BMSR_ExtendedCapability = {} THEN
  223. IF Trace * TraceAutoNegotiation# {} THEN Show("Extended registers not available."); KernelLog.Ln; END;
  224. res := Unsupported;
  225. RETURN;
  226. END;
  227. ReadRegister16(ANER, aner, res);
  228. IF res # Ok THEN RETURN; END;
  229. IF aner * ANER_LinkPartnerAnEnable = {} THEN
  230. IF Trace * TraceAutoNegotiation # {} THEN Show("Link partner has not enabled auto-negotiation."); KernelLog.Ln; END;
  231. res := NotAvailable;
  232. RETURN;
  233. END;
  234. timeout := AutoNegotiationTimeout;
  235. REPEAT
  236. ReadRegister16(BMSR, bmsr, res);
  237. IF res # Ok THEN RETURN END;
  238. timer.Sleep(20);
  239. DEC(timeout, 20);
  240. UNTIL (bmsr * BMSR_AutoNegotiationComplete # {}) OR (timeout <= 0);
  241. IF bmsr * BMSR_AutoNegotiationComplete = {} THEN
  242. IF Trace * TraceAutoNegotiation # {} THEN Show("Auto-Negotiation not complete."); KernelLog.Ln; END;
  243. res := NotAvailable;
  244. RETURN;
  245. END;
  246. ReadRegister16(ANAR, anar, res);
  247. IF res # Ok THEN RETURN; END;
  248. ReadRegister16(ANLPAR, anlpar, res);
  249. IF res # Ok THEN RETURN; END;
  250. IF SYSTEM.VAL(LONGINT, anlpar * ANAR_Selector) # Selector_IEEE_STD802_3 THEN
  251. Show("Link partner doesn't use IEEE 802.3 Auto-Negotiation _ Other types not supported."); KernelLog.Ln;
  252. res := Unsupported;
  253. RETURN;
  254. END;
  255. supported := anar * anlpar;
  256. (* Priority Resolution according [1], Annex 28B *)
  257. IF supported * ANAR_100BaseTXFullDuplex # {} THEN
  258. linkspeed := 100; fullDuplex := TRUE; string := "100BASETX Full Duplex";
  259. ELSIF supported * ANAR_100BaseTXHalfDuplex # {} THEN
  260. linkspeed := 100; fullDuplex := FALSE; string := "100BASETX Half Duplex";
  261. ELSIF supported * ANAR_100BaseT4Support # {} THEN
  262. linkspeed := 100; fullDuplex := TRUE; string := "100BASET4";
  263. ELSIF supported * ANAR_10BaseTFullDuplex # {} THEN
  264. linkspeed := 10; fullDuplex := TRUE; string := "10BASET Full Duplex";
  265. ELSIF supported * ANAR_10BaseTHalfDuplex # {} THEN
  266. linkspeed := 10; fullDuplex := FALSE; string := "10BASET Half Duplex";
  267. ELSE
  268. END;
  269. IF Trace * TraceAutoNegotiation # {} THEN Show("Detected "); KernelLog.String(string); KernelLog.Ln; END;
  270. END GetAutoNegotiationResult;
  271. (** Get the current link status *)
  272. PROCEDURE GetLinkStatus*(VAR linkStatus: LONGINT; VAR res : WORD);
  273. VAR value : SET;
  274. BEGIN
  275. ASSERT(lockedBy = Objects.ActiveObject());
  276. ReadRegister16(BMSR, value, res);
  277. IF res = Ok THEN
  278. IF value * BMSR_LinkStatus # {} THEN linkStatus := Network.LinkLinked;
  279. ELSE linkStatus := Network.LinkNotLinked;
  280. END;
  281. END;
  282. END GetLinkStatus;
  283. (** Manually set the link speed and operating mode. This disables auto-negotiation as side-effect. *)
  284. PROCEDURE ConfigureLink*(speed : LONGINT; fullDuplex : BOOLEAN; VAR res : WORD);
  285. VAR value : SET;
  286. BEGIN
  287. ASSERT(lockedBy = Objects.ActiveObject());
  288. ASSERT((speed = 10) OR (speed = 100) OR (speed = 1000));
  289. (* determine whether PHY supports the desired link configuration *)
  290. ReadRegister16(BMSR, value, res);
  291. IF res # Ok THEN RETURN; END;
  292. (* BMSR_100BaseT4 ???? *)
  293. IF (speed = 10) & ((fullDuplex & (value * BMSR_10BaseTFullDuplex = {})) OR (~fullDuplex & (value * BMSR_10BaseTHalfDuplex = {}))) THEN
  294. res := ParametersInvalid; RETURN;
  295. ELSIF (speed = 100) & ((fullDuplex & (value * (BMSR_100BaseTXFullDuplex + BMSR_100BaseT2FullDuplex) = {})) OR
  296. (~fullDuplex & (value * (BMSR_100BaseTXHalfDuplex + BMSR_100BaseT2HalfDuplex) = {}))) THEN
  297. res := ParametersInvalid; RETURN;
  298. ELSIF (speed = 1000) THEN
  299. IF value * BMSR_ExtendedStatus = {} THEN res := ParametersInvalid; RETURN; END;
  300. ReadRegister16(BMESR, value, res);
  301. IF res # Ok THEN RETURN; END;
  302. IF (fullDuplex & (value * (BMESR_1000BaseXFullDuplex + BMESR_1000BaseTFullDuplex) = {})) OR
  303. (~fullDuplex & (value * (BMESR_1000BaseXHalfDuplex + BMESR_1000BaseTHalfDuplex) = {})) THEN
  304. res := ParametersInvalid; RETURN;
  305. END;
  306. END;
  307. (* disable auto-negotiation if it's enabled *)
  308. ReadRegister16(BMCR, value, res);
  309. IF res # Ok THEN RETURN; END;
  310. IF value * BMCR_AutoNegotiationEnable # {} THEN
  311. WriteRegister16(BMCR, value - BMCR_AutoNegotiationEnable, res);
  312. IF res # Ok THEN RETURN; END;
  313. END;
  314. (* set link speed and duplex mode *)
  315. IF fullDuplex THEN value := value + BMCR_DuplexMode; ELSE value := value - BMCR_DuplexMode; END;
  316. IF speed = 10 THEN
  317. value := value - BMCR_SpeedSelectionMsb - BMCR_SpeedSelectionLsb;
  318. ELSIF speed = 100 THEN
  319. value := value - BMCR_SpeedSelectionMsb + BMCR_SpeedSelectionLsb;
  320. ELSE
  321. value := value + BMCR_SpeedSelectionMsb - BMCR_SpeedSelectionLsb;
  322. END;
  323. WriteRegister16(BMCR, value, res);
  324. END ConfigureLink;
  325. PROCEDURE EnableLoopback*(enable : BOOLEAN; VAR res : WORD);
  326. VAR value : SET;
  327. BEGIN
  328. ASSERT(lockedBy = Objects.ActiveObject());
  329. IF Trace * TraceCommands # {} THEN
  330. IF enable THEN Show("Enable "); ELSE Show("Disable "); END; KernelLog.String("loopback."); KernelLog.Ln;
  331. END;
  332. ReadRegister16(BMCR, value, res);
  333. IF res # Ok THEN RETURN; END;
  334. IF enable THEN value := value + BMCR_Loopback; ELSE value := value - BMCR_Loopback; END;
  335. WriteRegister16(BMCR, value + BMCR_Loopback, res);
  336. END EnableLoopback;
  337. (** Reset the PHY. Sets the Control and the Status registers to their default values. *)
  338. PROCEDURE Reset*(VAR res : WORD);
  339. VAR timeout, interval : LONGINT; value : SET;
  340. BEGIN (* {EXCLUSIVE} *)
  341. ASSERT(lockedBy = Objects.ActiveObject());
  342. IF Trace * TraceCommands # {} THEN Show("Reset PHY... "); END;
  343. WriteRegister16(BMCR, BMCR_Reset, res);
  344. IF res # Ok THEN RETURN; END;
  345. (* 0.5s timeout according to [1], page 512 *)
  346. timeout := 500; interval := 10;
  347. LOOP
  348. timer.Sleep(interval);
  349. ReadRegister16(BMCR, value, res);
  350. IF (value * BMCR_Reset = {}) OR (res # Ok) THEN EXIT; END;
  351. DEC(timeout, interval);
  352. IF timeout <= 0 THEN res := Timeout; EXIT; END
  353. END;
  354. IF Trace * TraceCommands # {} THEN KernelLog.String("done."); KernelLog.Ln; END;
  355. END Reset;
  356. PROCEDURE GetIdentifier*(VAR identifier : Identifier; VAR res : WORD);
  357. VAR phyIdr1, phyIdr2 : SET;
  358. BEGIN
  359. ASSERT(lockedBy = Objects.ActiveObject());
  360. ReadRegister16(PHYIDR1, phyIdr1, res);
  361. IF res # Ok THEN
  362. IF Debug THEN Show("Could not read PHYIDR1 register."); KernelLog.Ln; END;
  363. RETURN;
  364. END;
  365. ReadRegister16(PHYIDR2, phyIdr2, res);
  366. IF res # Ok THEN
  367. IF Debug THEN Show("Could not read PHYIDR2 register."); KernelLog.Ln; END;
  368. RETURN;
  369. END;
  370. identifier.oui := SYSTEM.VAL(LONGINT, LSH(phyIdr1 * PHYIDR1_OuiMSB, 3) + LSH(phyIdr2 * PHYIDR2_OuiLSB, 9));
  371. identifier.model := SYSTEM.VAL(LONGINT, LSH(phyIdr2 * PHYIDR2_VendorModel, -4));
  372. identifier.revision := SYSTEM.VAL(LONGINT, phyIdr2 * PHYIDR2_ModelRevision);
  373. END GetIdentifier;
  374. PROCEDURE Diag*;
  375. VAR identifier : Identifier; res : WORD; bmsr, anar, anlpar, register : SET;
  376. BEGIN
  377. ASSERT(lockedBy = Objects.ActiveObject());
  378. KernelLog.String("MII information:"); KernelLog.Ln;
  379. KernelLog.String(" PHY ID: "); KernelLog.Hex(phyId, 0); KernelLog.Ln;
  380. GetIdentifier(identifier, res);
  381. IF res = Ok THEN
  382. KernelLog.String(" OUI: "); KernelLog.Hex(identifier.oui, 0); KernelLog.String(", Vendor model: "); KernelLog.Int(identifier.model, 0);
  383. KernelLog.String(", Revision: "); KernelLog.Int(identifier.revision, 0);
  384. ELSE
  385. KernelLog.String("Error: Could not read PHY Identification registers."); KernelLog.Ln;
  386. END;
  387. KernelLog.Ln;
  388. ReadRegister16(BMCR, register, res);
  389. IF res = Ok THEN ShowControlRegister(register);
  390. ELSE KernelLog.String("Error: Could not read BMCR register."); KernelLog.Ln;
  391. END;
  392. ReadRegister16(BMSR, bmsr, res);
  393. IF res = Ok THEN ShowStatusRegister(bmsr);
  394. ELSE KernelLog.String("Error: Could not read BMSR register."); KernelLog.Ln;
  395. END;
  396. KernelLog.String("Extended registers: "); KernelLog.Ln;
  397. IF bmsr * BMSR_ExtendedCapability # {} THEN
  398. ReadRegister16(ANAR, anar, res);
  399. IF res = Ok THEN
  400. ReadRegister16(ANLPAR, anlpar, res);
  401. IF res = Ok THEN
  402. ShowAdvertisementRegisters(anar, anlpar);
  403. ELSE KernelLog.String("Error: Could not read ANLPAR register."); KernelLog.Ln;
  404. END;
  405. ELSE KernelLog.String("Error: Could not read ANAR register."); KernelLog.Ln;
  406. END;
  407. ReadRegister16(ANER, register, res);
  408. IF res = Ok THEN
  409. ShowAnerRegister(register);
  410. ELSE KernelLog.String("Error: Could not read ANER register."); KernelLog.Ln;
  411. END;
  412. ELSE
  413. KernelLog.String("Extended registers not available."); KernelLog.Ln;
  414. END;
  415. IF bmsr * BMSR_ExtendedStatus # {} THEN
  416. ReadRegister16(BMESR, register, res);
  417. IF res = Ok THEN ShowExtendedStatusRegister(register);
  418. ELSE KernelLog.String("Error: Could not read BMESR register."); KernelLog.Ln;
  419. END;
  420. END;
  421. IF bmsr * BMSR_ExtendedCapability # {} THEN
  422. END;
  423. END Diag;
  424. PROCEDURE &Init*(phyId : LONGINT);
  425. BEGIN
  426. SELF.phyId := phyId;
  427. NEW(timer);
  428. lockedBy := NIL;
  429. END Init;
  430. END MII;
  431. PROCEDURE ShowControlRegister(bmcr : SET);
  432. BEGIN
  433. KernelLog.String("Basic Mode Control Register (BMCR):"); KernelLog.Ln;
  434. KernelLog.String(" Reset PHY: "); KernelLog.Boolean(bmcr * BMCR_Reset # {}); KernelLog.Ln;
  435. KernelLog.String(" Loopback: "); KernelLog.Boolean(bmcr * BMCR_Loopback # {}); KernelLog.Ln;
  436. KernelLog.String(" Auto-Negotiation Enable: "); KernelLog.Boolean(bmcr * BMCR_AutoNegotiationEnable # {}); KernelLog.Ln;
  437. KernelLog.String(" Power Down: "); KernelLog.Boolean(bmcr * BMCR_PowerDown # {}); KernelLog.Ln;
  438. KernelLog.String(" Isolate: "); KernelLog.Boolean(bmcr * BMCR_Isolate # {}); KernelLog.Ln;
  439. KernelLog.String(" Restart Auto-Negotiation: "); KernelLog.Boolean(bmcr * BMCR_RestartAutoNegotiation # {}); KernelLog.Ln;
  440. KernelLog.String(" Collision Test: "); KernelLog.Boolean(bmcr * BMCR_CollisionTest # {}); KernelLog.Ln;
  441. KernelLog.String(" Link Speed: ");
  442. IF bmcr * BMCR_AutoNegotiationEnable = {} THEN
  443. IF bmcr * BMCR_SpeedSelectionMsb = {} THEN
  444. IF bmcr * BMCR_SpeedSelectionLsb # {} THEN KernelLog.String("100 Mbps");
  445. ELSE KernelLog.String("10 Mbps");
  446. END;
  447. ELSE
  448. IF bmcr * BMCR_SpeedSelectionMsb # {} THEN KernelLog.String("1000 Mbps");
  449. ELSE KernelLog.String("Invalid setting");
  450. END;
  451. END;
  452. IF bmcr * BMCR_DuplexMode # {} THEN KernelLog.String(" (Full Duplex)"); ELSE KernelLog.String(" (Half Duplex)"); END;
  453. ELSE KernelLog.String("Reported in BMSR since Auto-negotiation is enabled");
  454. END;
  455. KernelLog.Ln;
  456. END ShowControlRegister;
  457. PROCEDURE ShowStatusRegister(bmsr : SET);
  458. BEGIN
  459. KernelLog.String("Basic Mode Status Register (BMSR):"); KernelLog.Ln;
  460. KernelLog.String(" Link Capabilities:"); KernelLog.Ln;
  461. KernelLog.String(" 100BaseT4: "); KernelLog.Boolean(bmsr * BMSR_100BaseT4 # {}); KernelLog.Ln;
  462. KernelLog.String(" 100BaseX Full Duplex: "); KernelLog.Boolean(bmsr * BMSR_100BaseTXFullDuplex # {}); KernelLog.Ln;
  463. KernelLog.String(" 100BaseX Half Duplex: "); KernelLog.Boolean(bmsr * BMSR_100BaseTXHalfDuplex # {}); KernelLog.Ln;
  464. KernelLog.String(" 10Mb/s Full Duplex: "); KernelLog.Boolean(bmsr * BMSR_10BaseTFullDuplex # {}); KernelLog.Ln;
  465. KernelLog.String(" 10Mb/s Half Fuplex: "); KernelLog.Boolean(bmsr * BMSR_10BaseTHalfDuplex # {}); KernelLog.Ln;
  466. KernelLog.String(" 100BaseT2FullDuplex: "); KernelLog.Boolean(bmsr * BMSR_100BaseT2FullDuplex # {}); KernelLog.Ln;
  467. KernelLog.String(" 100BaseT2HalfDuplex: "); KernelLog.Boolean(bmsr * BMSR_100BaseT2HalfDuplex # {}); KernelLog.Ln;
  468. KernelLog.String(" Extended Status Register available: "); KernelLog.Boolean(bmsr * BMSR_ExtendedStatus # {}); KernelLog.Ln;
  469. KernelLog.String(" MF Preamble Suppression: "); KernelLog.Boolean(bmsr * BMSR_MfPreambleSuppression # {}); KernelLog.Ln;
  470. KernelLog.String(" Auto-Negotiation complete: "); KernelLog.Boolean(bmsr * BMSR_AutoNegotiationComplete # {}); KernelLog.Ln;
  471. KernelLog.String(" Remote Fault: "); KernelLog.Boolean(bmsr * BMSR_RemoteFault # {}); KernelLog.Ln;
  472. KernelLog.String(" Auto-Negotiation Ability: "); KernelLog.Boolean(bmsr * BMSR_AutoNegotiationAbility # {}); KernelLog.Ln;
  473. KernelLog.String(" Link status: ");
  474. IF bmsr * BMSR_LinkStatus # {} THEN KernelLog.String("UP"); ELSE KernelLog.String("DOWN"); END; KernelLog.Ln;
  475. KernelLog.String(" Jabber Detected: "); KernelLog.Boolean(bmsr * BMSR_JabberDetect # {}); KernelLog.Ln;
  476. KernelLog.String(" Extended Capability: "); KernelLog.Boolean(bmsr * BMSR_ExtendedCapability # {}); KernelLog.Ln;
  477. END ShowStatusRegister;
  478. PROCEDURE ShowAdvertisementRegisters(anar, anlpar : SET);
  479. PROCEDURE ShowBit(CONST title : ARRAY OF CHAR; bit : SET);
  480. BEGIN
  481. KernelLog.String(title); KernelLog.Boolean(anar * bit # {});
  482. KernelLog.String(", Link partner: "); KernelLog.Boolean(anlpar * bit # {}); KernelLog.Ln;
  483. END ShowBit;
  484. BEGIN
  485. KernelLog.String("Auto-Negotiation Advertisement Registers (ANAR/ANLPAR):"); KernelLog.Ln;
  486. ShowBit(" Next page indication: ", ANAR_NextPageIndication);
  487. ShowBit(" Ackknowlegdement: ", ANAR_Ackknowlegdement);
  488. ShowBit(" Remote Fault: ", ANAR_RemoteFault);
  489. ShowBit(" Asymmetric Pause: ", ANAR_AsymmetricPause);
  490. ShowBit(" Pause: ", ANAR_Pause);
  491. ShowBit(" 100BaseT4 support: ", ANAR_100BaseT4Support);
  492. ShowBit(" 100BaseTX Full Duplex support: ", ANAR_100BaseTXFullDuplex);
  493. ShowBit(" 100BaseTX Half Duplex support: ", ANAR_100BaseTXHalfDuplex);
  494. ShowBit(" 10BaseT Full Duplex support: ", ANAR_10BaseTFullDuplex);
  495. ShowBit(" 10BaseT Half Duplex support: ", ANAR_10BaseTHalfDuplex);
  496. KernelLog.String(" Selector: "); KernelLog.Int(SYSTEM.VAL(LONGINT, anar * ANAR_Selector), 0);
  497. KernelLog.String(", Link partner: "); KernelLog.Int(SYSTEM.VAL(LONGINT, anlpar * ANAR_Selector), 0);
  498. KernelLog.Ln;
  499. END ShowAdvertisementRegisters;
  500. PROCEDURE ShowAnerRegister(aner : SET);
  501. BEGIN
  502. KernelLog.String("Auto-Negotiation Extension Register (ANER):"); KernelLog.Ln;
  503. KernelLog.String(" Parallel Detection Fault: "); KernelLog.Boolean(aner * ANER_ParallelDetectionFault # {}); KernelLog.Ln;
  504. KernelLog.String(" Link Partner Next Page Enable: "); KernelLog.Boolean(aner * ANER_LinkPartnerNextPageEnable # {}); KernelLog.Ln;
  505. KernelLog.String(" PHY Next Page Enable: "); KernelLog.Boolean(aner * ANER_PhyNextPageEnable # {}); KernelLog.Ln;
  506. KernelLog.String(" New Page Reception: "); KernelLog.Boolean(aner * ANER_NewPageReception # {}); KernelLog.Ln;
  507. KernelLog.String(" Link Partner Auto-Negotiation Enable: "); KernelLog.Boolean(aner * ANER_LinkPartnerAnEnable # {}); KernelLog.Ln;
  508. END ShowAnerRegister;
  509. PROCEDURE ShowExtendedStatusRegister(bmesr : SET);
  510. BEGIN
  511. KernelLog.String("Base Mode Extended Status Register (BMESR):"); KernelLog.Ln;
  512. KernelLog.String(" Link Capabilities:"); KernelLog.Ln;
  513. KernelLog.String(" 1000BaseX Full Duplex: "); KernelLog.Boolean(bmesr * BMESR_1000BaseXFullDuplex # {}); KernelLog.Ln;
  514. KernelLog.String(" 1000BaseX Half Duplex: "); KernelLog.Boolean(bmesr * BMESR_1000BaseXHalfDuplex # {}); KernelLog.Ln;
  515. KernelLog.String(" 1000BaseT Full Duplex: "); KernelLog.Boolean(bmesr * BMESR_1000BaseTFullDuplex # {}); KernelLog.Ln;
  516. KernelLog.String(" 1000BaseT Half Duplex: "); KernelLog.Boolean(bmesr * BMESR_1000BaseTHalfDuplex # {}); KernelLog.Ln;
  517. END ShowExtendedStatusRegister;
  518. PROCEDURE Show(CONST string : ARRAY OF CHAR);
  519. BEGIN
  520. KernelLog.String(ModuleName); KernelLog.String(": "); KernelLog.String(string);
  521. END Show;
  522. END NetworkMii.