Zynq.EnetEmacPs7.Mod 80 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288128912901291129212931294129512961297129812991300130113021303130413051306130713081309131013111312131313141315131613171318131913201321132213231324132513261327132813291330133113321333133413351336133713381339134013411342134313441345134613471348134913501351135213531354135513561357135813591360136113621363136413651366136713681369137013711372137313741375137613771378137913801381138213831384138513861387138813891390139113921393139413951396139713981399140014011402140314041405140614071408140914101411141214131414141514161417141814191420142114221423142414251426142714281429143014311432143314341435143614371438143914401441144214431444144514461447144814491450145114521453145414551456145714581459146014611462146314641465146614671468146914701471147214731474147514761477147814791480148114821483148414851486148714881489149014911492149314941495149614971498149915001501150215031504150515061507150815091510151115121513151415151516151715181519152015211522152315241525152615271528152915301531153215331534153515361537153815391540154115421543154415451546154715481549155015511552155315541555155615571558155915601561156215631564156515661567156815691570157115721573157415751576157715781579158015811582158315841585158615871588158915901591159215931594159515961597159815991600160116021603160416051606160716081609161016111612161316141615161616171618161916201621162216231624162516261627162816291630163116321633163416351636163716381639164016411642164316441645164616471648164916501651165216531654165516561657165816591660166116621663166416651666166716681669167016711672167316741675167616771678167916801681168216831684168516861687168816891690169116921693169416951696169716981699170017011702170317041705170617071708170917101711171217131714171517161717171817191720172117221723172417251726172717281729173017311732173317341735173617371738173917401741174217431744174517461747174817491750175117521753175417551756175717581759176017611762176317641765176617671768176917701771177217731774177517761777177817791780178117821783178417851786178717881789179017911792179317941795179617971798179918001801180218031804180518061807180818091810181118121813181418151816181718181819182018211822182318241825182618271828182918301831183218331834183518361837183818391840184118421843184418451846184718481849185018511852185318541855185618571858185918601861186218631864186518661867186818691870187118721873187418751876187718781879188018811882188318841885188618871888188918901891189218931894189518961897189818991900190119021903190419051906190719081909191019111912191319141915191619171918191919201921192219231924192519261927192819291930193119321933193419351936193719381939194019411942194319441945194619471948194919501951195219531954195519561957195819591960196119621963196419651966196719681969197019711972197319741975197619771978197919801981198219831984198519861987198819891990199119921993199419951996199719981999200020012002200320042005200620072008200920102011201220132014201520162017201820192020202120222023
  1. MODULE EnetEmacPs7;
  2. (**
  3. AUTHOR: Alexey Morozov, HighDim GmbH, 2015
  4. PURPOSE: Ethernet networking stack, interface for Xilinx Processing System 7 Ethernet MAC device
  5. *)
  6. IMPORT
  7. S := SYSTEM, Platform, EnetEnvironment, EnetTiming, EnetBase, EnetPhy, Trace := EnetTrace;
  8. CONST
  9. GemBaseAddr0 = ADDRESS(0xE000B000);
  10. GemBaseAddr1 = ADDRESS(0xE000C000); (* Base addresses for GEM controllers *)
  11. EnableTrace = TRUE;
  12. LinkAutonegoTimeout* = 5000; (** link autonegotiation timeout in milliseconds *)
  13. TYPE
  14. Int8 = EnetBase.Int8;
  15. Int16 = EnetBase.Int16;
  16. Int = EnetBase.Int;
  17. UInt = EnetBase.UInt;
  18. CONST
  19. (**
  20. Supported MDIO divisor values
  21. *)
  22. MDC_DIV_8 = 0;
  23. MDC_DIV_16 = 1;
  24. MDC_DIV_32 = 2;
  25. MDC_DIV_48 = 3;
  26. MDC_DIV_64 = 4;
  27. MDC_DIV_96 = 5;
  28. MDC_DIV_128 = 6;
  29. MDC_DIV_224 = 7;
  30. MdioDivisor0* = MDC_DIV_224;
  31. MdioDivisor1* = MDC_DIV_224; (** MDIO divisor values for both GEM controllers (PHY hardware-specific) *)
  32. AllowZeroPhyAddr0* = FALSE;
  33. AllowZeroPhyAddr1* = FALSE; (** TRUE if PHY address 0 is allowed (can be only in the case of a single PHY) for both GEM controllers (PHY hardware-specific) *)
  34. (*
  35. Internally used constants
  36. *)
  37. DataCacheLineSize = 32; (* data cache line size in bytes *)
  38. RX_BUF_SIZE = 1536; (** Specify the receive buffer size in bytes, 64, 128, ... 10240 *)
  39. RX_BUF_UNIT = 64; (** Number of receive buffer bytes as a unit, this is HW setup *)
  40. (**
  41. network control register bit definitions
  42. *)
  43. NWCTRL_FLUSH_DPRAM_MASK = 0x00040000; (** Flush a packet from Rx SRAM *)
  44. NWCTRL_ZEROPAUSETX_MASK = 0x00000800; (** Transmit zero quantum pause frame *)
  45. NWCTRL_PAUSETX_MASK = 0x00000800; (** Transmit pause frame *)
  46. NWCTRL_HALTTX_MASK = 0x00000400; (** Halt transmission after current frame *)
  47. NWCTRL_STARTTX_MASK = 0x00000200; (** Start tx (tx_go) *)
  48. NWCTRL_STATWEN_MASK = 0x00000080; (** Enable writing to stat counters *)
  49. NWCTRL_STATINC_MASK = 0x00000040; (** Increment statistic registers *)
  50. NWCTRL_STATCLR_MASK = 0x00000020; (** Clear statistic registers *)
  51. NWCTRL_MDEN_MASK = 0x00000010; (** Enable MDIO port *)
  52. NWCTRL_TXEN_MASK = 0x00000008; (** Enable transmit *)
  53. NWCTRL_RXEN_MASK = 0x00000004; (** Enable receive *)
  54. NWCTRL_RXTXDIS_MASK = 0xFFFFFFF3; (** Disable both transmit and receiver *)
  55. NWCTRL_LOOPEN_MASK = 0x00000002; (** local loopback *)
  56. NWCTRL_DEFAULT_VALUE = 0x00000030; (** value of the register to be set at reset (NWCTRL_STATCLR_MASK | NWCTRL_MDEN_MASK) & ~NWCTRL_LOOPEN_MASK *)
  57. (**
  58. network configuration register bit definitions
  59. *)
  60. NWCFG_BADPREAMBEN_MASK = 0x20000000; (** disable rejection of non-standard preamble *)
  61. NWCFG_IPDSTRETCH_MASK = 0x10000000; (** enable transmit IPG *)
  62. NWCFG_FCSIGNORE_MASK = 0x04000000; (** disable rejection of FCS error *)
  63. NWCFG_HDRXEN_MASK = 0x02000000; (** RX half duplex *)
  64. NWCFG_RXCHKSUMEN_MASK = 0x01000000; (** enable RX checksum offload *)
  65. NWCFG_PAUSECOPYDI_MASK = 0x00800000; (** Do not copy pause Frames to memory *)
  66. NWCFG_MDC_SHIFT_MASK = 18; (** shift bits for MDC *)
  67. NWCFG_MDCCLKDIV_MASK = 0x001C0000; (** MDC Mask PCLK divisor *)
  68. NWCFG_INV_MDCCLKDIV_MASK = 0xFFE3FFFF; (** Inverted mask for MDC Mask PCLK divisor *)
  69. NWCFG_FCSREM_MASK = 0x00020000; (** Discard FCS from received frames *)
  70. NWCFG_LENGTHERRDSCRD_MASK = 0x00010000; (** RX length error discard *)
  71. NWCFG_RXOFFS_MASK = 0x0000C000; (** RX buffer offset *)
  72. NWCFG_PAUSEEN_MASK = 0x00002000; (** Enable pause RX *)
  73. NWCFG_RETRYTESTEN_MASK = 0x00001000; (** Retry test *)
  74. NWCFG_EXTADDRMATCHEN_MASK = 0x00000200; (** External address match enable *)
  75. NWCFG_1000_MASK = 0x00000400; (** 1000 Mbps *)
  76. NWCFG_1536RXEN_MASK = 0x00000100; (** Enable 1536 byte frames reception *)
  77. NWCFG_UCASTHASHEN_MASK = 0x00000080; (** Receive unicast hash frames *)
  78. NWCFG_MCASTHASHEN_MASK = 0x00000040; (** Receive multicast hash frames *)
  79. NWCFG_BCASTDI_MASK = 0x00000020; (** Do not receive broadcast frames *)
  80. NWCFG_COPYALLEN_MASK = 0x00000010; (** Copy all frames *)
  81. NWCFG_JUMBO_MASK = 0x00000008; (** Jumbo frames *)
  82. NWCFG_NVLANDISC_MASK = 0x00000004; (** Receive only VLAN frames *)
  83. NWCFG_FDEN_MASK = 0x00000002; (** full duplex *)
  84. NWCFG_100_MASK = 0x00000001; (** 100 Mbps *)
  85. NWCFG_RESET_MASK = 0x00080000; (** reset value *)
  86. (**
  87. network status register bit definitaions
  88. *)
  89. NWSR_MDIOIDLE_MASK = 0x00000004; (** PHY management idle *)
  90. NWSR_MDIO_MASK = 0x00000002; (** Status of mdio_in *)
  91. (**
  92. DMA control register bit definitions
  93. *)
  94. DMACR_RXBUF_MASK = 0x00FF0000; (** Mask bit for RX buffer size *)
  95. DMACR_RXBUF_SHIFT = 16; (** Shift bit for RX buffer size *)
  96. DMACR_TCPCKSUM_MASK = 0x00000800; (** enable/disable TX checksum offload *)
  97. DMACR_TXSIZE_MASK = 0x00000400; (** TX buffer memory size *)
  98. DMACR_RXSIZE_MASK = 0x00000300; (** RX buffer memory size *)
  99. DMACR_ENDIAN_MASK = 0x00000080; (** endian configuration *)
  100. DMACR_BLENGTH_MASK = 0x0000001F; (** buffer burst length *)
  101. DMACR_SINGLE_AHB_BURST = 0x00000001; (** single AHB bursts *)
  102. DMACR_INCR4_AHB_BURST = 0x00000004; (** 4 bytes AHB bursts *)
  103. DMACR_INCR8_AHB_BURST = 0x00000008; (** 8 bytes AHB bursts *)
  104. DMACR_INCR16_AHB_BURST = 0x00000010; (** 16 bytes AHB bursts *)
  105. (**
  106. transmit status register bit definitions
  107. *)
  108. TXSR_HRESPNOK_MASK = 0x00000100; (** Transmit hresp not OK *)
  109. TXSR_URUN_MASK = 0x00000040; (** Transmit underrun *)
  110. TXSR_TXCOMPL_MASK = 0x00000020; (** Transmit completed OK *)
  111. TXSR_BUFEXH_MASK = 0x00000010; (** Transmit buffs exhausted mid frame *)
  112. TXSR_TXGO_MASK = 0x00000008; (** Status of go flag *)
  113. TXSR_RXOVR_MASK = 0x00000004; (** Retry limit exceeded *)
  114. TXSR_FRAMERX_MASK = 0x00000002; (** Collision tx frame *)
  115. TXSR_USEDREAD_MASK = 0x00000001; (** TX buffer used bit set *)
  116. TXSR_ERROR_MASK = TXSR_HRESPNOK_MASK + TXSR_URUN_MASK + TXSR_BUFEXH_MASK + TXSR_RXOVR_MASK + TXSR_FRAMERX_MASK + TXSR_USEDREAD_MASK;
  117. (**
  118. receive status register bit definitions
  119. *)
  120. RXSR_HRESPNOK_MASK = 0x00000008; (** Receive hresp not OK *)
  121. RXSR_RXOVR_MASK = 0x00000004; (** Receive overrun *)
  122. RXSR_FRAMERX_MASK = 0x00000002; (** Frame received OK *)
  123. RXSR_BUFFNA_MASK = 0x00000001; (** RX buffer used bit set *)
  124. RXSR_ERROR_MASK = RXSR_HRESPNOK_MASK + RXSR_RXOVR_MASK + RXSR_BUFFNA_MASK;
  125. (**
  126. interrupts bit definitions Bits definitions are same in ISR_OFFSET, IER_OFFSET, IDR_OFFSET, and IMR_OFFSET
  127. *)
  128. IXR_PTPPSTX_MASK = 0x02000000; (** PTP Psync transmitted *)
  129. IXR_PTPPDRTX_MASK = 0x01000000; (** PTP Pdelay_req transmitted *)
  130. IXR_PTPSTX_MASK = 0x00800000; (** PTP Sync transmitted *)
  131. IXR_PTPDRTX_MASK = 0x00400000; (** PTP Delay_req transmitted *)
  132. IXR_PTPPSRX_MASK = 0x00200000; (** PTP Psync received *)
  133. IXR_PTPPDRRX_MASK = 0x00100000; (** PTP Pdelay_req received *)
  134. IXR_PTPSRX_MASK = 0x00080000; (** PTP Sync received *)
  135. IXR_PTPDRRX_MASK = 0x00040000; (** PTP Delay_req received *)
  136. IXR_PAUSETX_MASK = 0x00004000; (** Pause frame transmitted *)
  137. IXR_PAUSEZERO_MASK = 0x00002000; (** Pause time has reached zero *)
  138. IXR_PAUSENZERO_MASK = 0x00001000; (** Pause frame received *)
  139. IXR_HRESPNOK_MASK = 0x00000800; (** hresp not ok *)
  140. IXR_RXOVR_MASK = 0x00000400; (** Receive overrun occurred *)
  141. IXR_TXCOMPL_MASK = 0x00000080; (** Frame transmitted ok *)
  142. IXR_TXEXH_MASK = 0x00000040; (** Transmit err occurred or no buffers*)
  143. IXR_RETRY_MASK = 0x00000020; (** Retry limit exceeded *)
  144. IXR_URUN_MASK = 0x00000010; (** Transmit underrun *)
  145. IXR_TXUSED_MASK = 0x00000008; (** Tx buffer used bit read *)
  146. IXR_RXUSED_MASK = 0x00000004; (** Rx buffer used bit read *)
  147. IXR_FRAMERX_MASK = 0x00000002; (** Frame received ok *)
  148. IXR_MGMNT_MASK = 0x00000001; (** PHY management complete *)
  149. IXR_ALL_MASK = 0x00007FFF; (** Everything! *)
  150. IXR_TX_ERR_MASK = IXR_TXEXH_MASK + IXR_RETRY_MASK + IXR_URUN_MASK (*+ IXR_TXUSED_MASK*);
  151. IXR_RX_ERR_MASK = IXR_HRESPNOK_MASK + IXR_RXUSED_MASK + IXR_RXOVR_MASK;
  152. (**
  153. PHY Maintenance bit definitions
  154. *)
  155. PHYMNTNC_OP_MASK = 0x40020000; (** operation mask bits *)
  156. PHYMNTNC_OP_R_MASK = 0x20000000; (** read operation *)
  157. PHYMNTNC_OP_W_MASK = 0x10000000; (** write operation *)
  158. PHYMNTNC_ADDR_MASK = 0x0F800000; (** Address bits *)
  159. PHYMNTNC_REG_MASK = 0x007C0000; (** register bits *)
  160. PHYMNTNC_DATA_MASK = 0x00000FFF; (** data bits *)
  161. PHYMNTNC_PHYAD_SHIFT_MASK = 23; (** Shift bits for PHYAD *)
  162. PHYMNTNC_PHREG_SHIFT_MASK = 18; (** Shift bits for PHREG *)
  163. (**
  164. Transmit buffer descriptor status words offset
  165. *)
  166. BD_ADDR_OFFSET = 0x00000000; (** word 0/addr of BDs *)
  167. BD_STAT_OFFSET = 0x00000004; (** word 1/status of BDs *)
  168. (**
  169. Transmit buffer descriptor status words bit positions.
  170. Transmit buffer descriptor consists of two 32-bit registers,
  171. the first - word0 contains a 32-bit address pointing to the location of
  172. the transmit data.
  173. The following register - word1, consists of various information to control
  174. the XEmacPs transmit process. After transmit, this is updated with status
  175. information, whether the frame was transmitted OK or why it had failed.
  176. *)
  177. TXBUF_USED_MASK = 0x80000000; (** Used bit. *)
  178. TXBUF_WRAP_MASK = 0x40000000; (** Wrap bit, last descriptor *)
  179. TXBUF_RETRY_MASK = 0x20000000; (** Retry limit exceeded *)
  180. TXBUF_URUN_MASK = 0x10000000; (** Transmit underrun occurred *)
  181. TXBUF_EXH_MASK = 0x08000000; (** Buffers exhausted *)
  182. TXBUF_TCP_MASK = 0x04000000; (** Late collision. *)
  183. TXBUF_NOCRC_MASK = 0x00010000; (** No CRC *)
  184. TXBUF_LAST_MASK = 0x00008000; (** Last buffer *)
  185. TXBUF_LEN_MASK = 0x00003FFF; (** Mask for length field *)
  186. (**
  187. Receive buffer descriptor status words bit positions.
  188. Receive buffer descriptor consists of two 32-bit registers,
  189. the first - word0 contains a 32-bit word aligned address pointing to the
  190. address of the buffer. The lower two bits make up the wrap bit indicating
  191. the last descriptor and the ownership bit to indicate it has been used by
  192. the XEmacPs.
  193. The following register - word1, contains status information regarding why
  194. the frame was received (the filter match condition) as well as other
  195. useful info.
  196. *)
  197. RXBUF_BCAST_MASK = 0x80000000; (** Broadcast frame *)
  198. RXBUF_MULTIHASH_MASK = 0x40000000; (** Multicast hashed frame *)
  199. RXBUF_UNIHASH_MASK = 0x20000000; (** Unicast hashed frame *)
  200. RXBUF_EXH_MASK = 0x08000000; (** buffer exhausted *)
  201. RXBUF_AMATCH_MASK = 0x06000000; (** Specific address matched *)
  202. RXBUF_IDFOUND_MASK = 0x01000000; (** Type ID matched *)
  203. RXBUF_IDMATCH_MASK = 0x00C00000; (** ID matched mask *)
  204. RXBUF_VLAN_MASK = 0x00200000; (** VLAN tagged *)
  205. RXBUF_PRI_MASK = 0x00100000; (** Priority tagged *)
  206. RXBUF_VPRI_MASK = 0x000E0000; (** Vlan priority *)
  207. RXBUF_CFI_MASK = 0x00010000; (** CFI frame *)
  208. RXBUF_EOF_MASK = 0x00008000; (** End of frame. *)
  209. RXBUF_SOF_MASK = 0x00004000; (** Start of frame. *)
  210. RXBUF_LEN_MASK = 0x00001FFF; (** Mask for length field *)
  211. RXBUF_WRAP_MASK = 0x00000002; (** Wrap bit, last BD *)
  212. RXBUF_NEW_MASK = 0x00000001; (** Used bit.. *)
  213. RXBUF_ADD_MASK = 0xFFFFFFFC; (** Mask for address *)
  214. (**
  215. Link device configuration options
  216. *)
  217. Promisc* = 0; (** Accept all incoming packets. This option defaults to disabled (cleared) *)
  218. Frame1536* = 1; (** Frame larger than 1516 support for Tx & Rx. This option defaults to disabled (cleared) *)
  219. Vlan* = 2; (** VLAN Rx & Tx frame support. This option defaults to disabled (cleared) *)
  220. FlowControl* = 4; (** Enable recognition of flow control frames on Rx. This option defaults to enabled (set) *)
  221. FcsStrip* = 5; (** Strip FCS and PAD from incoming frames. Note: PAD from VLAN frames is not stripped. This option defaults to enabled (set) *)
  222. FcsInsert* = 6; (** Generate FCS field and add PAD automatically for outgoing frames. This option defaults to disabled (cleared) *)
  223. LenTypeErr* = 7; (** Enable Length/TYPE error checking for incoming frames. When this option is set, the MAC will filter frames that have a mismatched TYPE/length field
  224. and if REPORT_RXERR is set, the user is notified when these TYPEs of frames are encountered. When this option is cleared, the MAC will
  225. allow these TYPEs of frames to be received. This option defaults to disabled (cleared)
  226. *)
  227. TransmitterEnable* = 8; (** Enable the transmitter. This option defaults to enabled (set) *)
  228. ReceiverEnable* = 9; (** Enable the receiver. This option defaults to enabled (set) *)
  229. Broadcast* = 10; (** Allow reception of the broadcast address. This option defaults to enabled (set) *)
  230. Multicast* = 11; (** Allows reception of multicast addresses programmed into hash. This option defaults to disabled (clear) *)
  231. RxChksumEnable* = 12; (** Enable the RX checksum offload. This option defaults to enabled (set) *)
  232. TxChksumEnable* = 13; (** Enable the TX checksum offload. This option defaults to enabled (set) *)
  233. DefaultOptions* = {Promisc, FlowControl, FcsInsert, FcsStrip, Broadcast, LenTypeErr, RxChksumEnable, TxChksumEnable, TransmitterEnable, ReceiverEnable};
  234. GemIrq0 = 54;
  235. GemIrq1 = 77; (* Interrupt number for GEM0 and GEM1 respectively *)
  236. TYPE
  237. (** Gigabit Ethernet Controller (GEM) registers definition *)
  238. GemRegisters* = POINTER{UNSAFE,UNTRACED} TO RECORD
  239. net_ctrl*: UInt; (** 0x00000000 32 mixed 0x00000000 Network Control *)
  240. net_cfg*: UInt; (** 0x00000004 32 rw 0x00080000 Network Configuration *)
  241. net_status*: UInt; (** 0x00000008 32 ro x Network Status *)
  242. padding0: UInt;
  243. dma_cfg*: UInt; (** 0x00000010 32 mixed 0x00020784 DMA Configuration *)
  244. tx_status*: UInt; (** 0x00000014 32 mixed 0x00000000 Transmit Status *)
  245. rx_qbar*: UInt; (** 0x00000018 32 mixed 0x00000000 Receive Buffer Queue Base Address *)
  246. tx_qbar*: UInt; (** 0x0000001C 32 mixed 0x00000000 Transmit Buffer Queue Base Address *)
  247. rx_status*: UInt; (** 0x00000020 32 mixed 0x00000000 Receive Status *)
  248. intr_status*: UInt; (** 0x00000024 32 mixed 0x00000000 Interrupt Status *)
  249. intr_en*: UInt; (** 0x00000028 32 wo x Interrupt Enable *)
  250. intr_dis*: UInt; (** 0x0000002C 32 wo x Interrupt Disable *)
  251. intr_mask*: UInt; (** 0x00000030 32 mixed x Interrupt Mask Status *)
  252. phy_maint*: UInt; (** 0x00000034 32 rw 0x00000000 PHY Maintenance *)
  253. rx_pauseq*: UInt; (** 0x00000038 32 ro 0x00000000 Received Pause Quantum *)
  254. tx_pauseq*: UInt; (** 0x0000003C 32 rw 0x0000FFFF Transmit Pause Quantum *)
  255. padding1: ARRAY 16 OF UInt;
  256. hash_bot*: UInt; (** 0x00000080 32 rw 0x00000000 Hash Register Bottom [31:0] *)
  257. hash_top*: UInt; (** 0x00000084 32 rw 0x00000000 Hash Register Top [63:32] *)
  258. spec_addr1_bot*: UInt; (** 0x00000088 32 rw 0x00000000 Specific Address 1 Bottom [31:0] *)
  259. spec_addr1_top*: UInt; (** 0x0000008C 32 mixed 0x00000000 Specific Address 1 Top [47:32] *)
  260. spec_addr2_bot*: UInt; (** 0x00000090 32 rw 0x00000000 Specific Address 2 Bottom [31:0] *)
  261. spec_addr2_top*: UInt; (** 0x00000094 32 mixed 0x00000000 Specific Address 2 Top [47:32] *)
  262. spec_addr3_bot*: UInt; (** 0x00000098 32 rw 0x00000000 Specific Address 3 Bottom [31:0] *)
  263. spec_addr3_top*: UInt; (** 0x0000009C 32 mixed 0x00000000 Specific Address 3 Top [47:32] *)
  264. spec_addr4_bot*: UInt; (** 0x000000A0 32 rw 0x00000000 Specific Address 4 Bottom [31:0] *)
  265. spec_addr4_top*: UInt; (** 0x000000A4 32 mixed 0x00000000 Specific Address 4 Top [47:32] *)
  266. type_id_match1*: UInt; (** 0x000000A8 32 mixed 0x00000000 Type ID Match 1 *)
  267. type_id_match2*: UInt; (** 0x000000AC 32 mixed 0x00000000 Type ID Match 2 *)
  268. type_id_match3*: UInt; (** 0x000000B0 32 mixed 0x00000000 Type ID Match 3 *)
  269. type_id_match4*: UInt; (** 0x000000B4 32 mixed 0x00000000 Type ID Match 4 *)
  270. wake_on_lan*: UInt; (** 0x000000B8 32 mixed 0x00000000 Wake on LAN Register *)
  271. ipg_stretch*: UInt; (** 0x000000BC 32 mixed 0x00000000 IPG stretch register *)
  272. stacked_vlan*: UInt; (** 0x000000C0 32 mixed 0x00000000 Stacked VLAN Register *)
  273. tx_pfc_pause*: UInt; (** 0x000000C4 32 mixed 0x00000000 Transmit PFC Pause Register *)
  274. spec_addr1_mask_bot*: UInt; (** 0x000000C8 32 rw 0x00000000 Specific Address Mask 1 Bottom [31:0] *)
  275. spec_addr1_mask_top*: UInt; (** 0x000000CC 32 mixed 0x00000000 Specific Address Mask 1 Top [47:32] *)
  276. padding2: ARRAY 11 OF UInt;
  277. module_id*: UInt; (** 0x000000FC 32 ro 0x00020118 Module ID *)
  278. octets_tx_bot*: UInt; (** 0x00000100 32 ro 0x00000000 Octets transmitted [31:0] (in frames without error) *)
  279. octets_tx_top*: UInt; (** 0x00000104 32 ro 0x00000000 Octets transmitted [47:32] (in frames without error) *)
  280. frames_tx*: UInt; (** 0x00000108 32 ro 0x00000000 Frames Transmitted *)
  281. broadcast_frames_tx*: UInt; (** 0x0000010C 32 ro 0x00000000 Broadcast frames Tx *)
  282. multi_frames_tx*: UInt; (* 0x00000110 32 ro 0x00000000 Multicast frames Tx *)
  283. pause_frames_tx*: UInt; (** 0x00000114 32 ro 0x00000000 Pause frames Tx *)
  284. frames_64b_tx*: UInt; (** 0x00000118 32 ro 0x00000000 Frames Tx, 64-byte length *)
  285. frames_65to127b_tx*: UInt; (** 0x0000011C 32 ro 0x00000000 Frames Tx, 65 to 127-byte length *)
  286. frames_128to255b_tx*: UInt; (** 0x00000120 32 ro 0x00000000 Frames Tx, 128 to 255-byte length *)
  287. frames_256to511b_tx*: UInt; (** 0x00000124 32 ro 0x00000000 Frames Tx, 256 to 511-byte length *)
  288. frames_512to1023b_tx*: UInt; (** 0x00000128 32 ro 0x00000000 Frames Tx, 512 to 1023-byte length *)
  289. frames_1024to1518b_tx*: UInt; (** 0x0000012C 32 ro 0x00000000 Frame Tx, 1024 to 1518-byte length *)
  290. padding3: UInt;
  291. tx_under_runs*: UInt; (** 0x00000134 32 ro 0x00000000 Transmit under runs *)
  292. single_collisn_frames*: UInt; (** 0x00000138 32 ro 0x00000000 Single Collision Frames *)
  293. multi_collisn_frames*: UInt; (** 0x0000013C 32 ro 0x00000000 Multiple Collision Frames excessive_collisns 0x00000140 32 ro 0x00000000 Excessive Collisions *)
  294. padding4: UInt;
  295. late_collisns*: UInt; (** 0x00000144 32 ro 0x00000000 Late Collisions *)
  296. deferred_tx_frames*: UInt; (** 0x00000148 32 ro 0x00000000 Deferred Transmission Frames *)
  297. carrier_sense_errs*: UInt; (** 0x0000014C 32 ro 0x00000000 Carrier Sense Errors. *)
  298. octets_rx_bot*: UInt; (** 0x00000150 32 ro 0x00000000 Octets Received [31:0] *)
  299. octets_rx_top*: UInt; (** 0x00000154 32 ro 0x00000000 Octets Received [47:32] *)
  300. frames_rx*: UInt; (** 0x00000158 32 ro 0x00000000 Frames Received *)
  301. bdcast_fames_rx*: UInt; (** 0x0000015C 32 ro 0x00000000 Broadcast Frames Rx *)
  302. multi_frames_rx*: UInt; (** 0x00000160 32 ro 0x00000000 Multicast Frames Rx *)
  303. pause_rx*: UInt; (** 0x00000164 32 ro 0x00000000 Pause Frames Rx *)
  304. frames_64b_rx*: UInt; (** 0x00000168 32 ro 0x00000000 Frames Rx, 64-byte length *)
  305. frames_65to127b_rx*: UInt; (** 0x0000016C 32 ro 0x00000000 Frames Rx, 65 to 127-byte length *)
  306. frames_128to255b_rx*: UInt; (** 0x00000170 32 ro 0x00000000 Frames Rx, 128 to 255-byte length *)
  307. frames_256to511b_rx*: UInt; (** 0x00000174 32 ro 0x00000000 Frames Rx, 256 to 511-byte length *)
  308. frames_512to1023b_rx*: UInt; (** 0x00000178 32 ro 0x00000000 Frames Rx, 512 to 1023-byte length *)
  309. frames_1024to1518b_rx*: UInt; (** 0x0000017C 32 ro 0x00000000 Frames Rx, 1024 to 1518-byte length *)
  310. padding5: UInt;
  311. undersz_rx*: UInt; (** 0x00000184 32 ro 0x00000000 Undersize frames received *)
  312. oversz_rx*: UInt; (** 0x00000188 32 ro 0x00000000 Oversize frames received *)
  313. jab_rx*: UInt; (** 0x0000018C 32 ro 0x00000000 Jabbers received *)
  314. fcs_errors*: UInt; (** 0x00000190 32 ro 0x00000000 Frame check sequence errors *)
  315. length_field_errors*: UInt; (** 0x00000194 32 ro 0x00000000 Length field frame errors *)
  316. rx_symbol_errors*: UInt; (** 0x00000198 32 ro 0x00000000 Receive symbol errors *)
  317. align_errors*: UInt; (** 0x0000019C 32 ro 0x00000000 Alignment errors *)
  318. rx_resource_errors*: UInt; (** 0x000001A0 32 ro 0x00000000 Receive resource errors *)
  319. rx_overrun_errors*: UInt; (** 0x000001A4 32 ro 0x00000000 Receive overrun errors *)
  320. ip_hdr_csum_errors*: UInt; (** 0x000001A8 32 ro 0x00000000 IP header checksum errors *)
  321. tcp_csum_errors*: UInt; (** 0x000001AC 32 ro 0x00000000 TCP checksum errors *)
  322. udp_csum_errors*: UInt; (** 0x000001B0 32 ro 0x00000000 UDP checksum error *)
  323. padding6: ARRAY 5 OF UInt;
  324. timer_strobe_s*: UInt; (** 0x000001C8 32 rw 0x00000000 1588 timer sync strobe seconds *)
  325. timer_strobe_ns*: UInt; (** 0x000001CC 32 mixed 0x00000000 1588 timer sync strobe nanoseconds *)
  326. timer_s*: UInt; (** 0x000001D0 32 rw 0x00000000 1588 timer seconds *)
  327. timer_ns*: UInt; (** 0x000001D4 32 mixed 0x00000000 1588 timer nanoseconds *)
  328. timer_adjust*: UInt; (** 0x000001D8 32 mixed 0x00000000 1588 timer adjust *)
  329. timer_incr*: UInt; (** 0x000001DC 32 mixed 0x00000000 1588 timer increment *)
  330. ptp_tx_s*: UInt; (** 0x000001E0 32 ro 0x00000000 PTP event frame transmitted seconds *)
  331. ptp_tx_ns*: UInt; (** 0x000001E4 32 ro 0x00000000 PTP event frame transmitted nanoseconds *)
  332. ptp_rx_s*: UInt; (** 0x000001E8 32 ro 0x00000000 PTP event frame received seconds *)
  333. ptp_rx_ns*: UInt; (** 0x000001EC 32 ro 0x00000000 PTP event frame received nanoseconds. *)
  334. ptp_peer_tx_s*: UInt; (** 0x000001F0 32 ro 0x00000000 PTP peer event frame transmitted seconds *)
  335. ptp_peer_tx_ns*: UInt; (** 0x000001F4 32 ro 0x00000000 PTP peer event frame transmitted nanoseconds *)
  336. ptp_peer_rx_s*: UInt; (** 0x000001F8 32 ro 0x00000000 PTP peer event frame received seconds *)
  337. ptp_peer_rx_ns*: UInt; (** 0x000001FC 32 ro 0x00000000 PTP peer event frame received nanoseconds. *)
  338. padding7: ARRAY 33 OF UInt;
  339. design_cfg2*: UInt; (** 0x00000284 32 ro x Design Configuration 2 *)
  340. design_cfg3*: UInt; (** 0x00000288 32 ro 0x00000000 Design Configuration 3 *)
  341. design_cfg4*: UInt; (** 0x0000028C 32 ro 0x00000000 Design Configuration 4 *)
  342. design_cfg5*: UInt; (** 0x00000290 32 ro x Design Configuration 5 *)
  343. END;
  344. (* DMA RX/TX buffer descriptor *)
  345. DmaBufDesc = RECORD
  346. w0: UInt; (* word 0 *)
  347. w1: UInt; (* word 1 *)
  348. END;
  349. (* RX/TX buffer descriptor used for handling by LinkDevice *)
  350. BufDesc = POINTER TO RECORD
  351. dmaBd: POINTER{UNSAFE,UNTRACED} TO DmaBufDesc; (* DMA buffer descriptor *)
  352. packet: EnetBase.Packet; (* attached packet *)
  353. next: BufDesc; (* reference to the next BufDesc element in the ring *)
  354. END;
  355. (**
  356. Xilinx EMAC PS7 Ethernet link device
  357. *)
  358. LinkDevice* = POINTER TO LinkDeviceDesc;
  359. LinkDeviceDesc* = RECORD(EnetBase.LinkDeviceDesc)
  360. id*: Int;
  361. regs*: GemRegisters; (** GEM controller registers *)
  362. phyAddr*: UInt;
  363. options: SET; (* device options *)
  364. dmaBdMem: EnetEnvironment.UncachedMemDesc(*POINTER TO ARRAY OF CHAR*); (* memory space for storing buffer descriptors *)
  365. rxBdRing, txBdRing: POINTER TO ARRAY OF BufDesc; (* RX/TX buffer descriptor rings *)
  366. rxBdRingStart, rxBdRingEnd, lastRxBd: BufDesc;
  367. txBdRingStart, txBdRingEnd, firstTxBd, lastTxBd: BufDesc;
  368. txBdRingFull, txBdRingEmpty: BOOLEAN; (* TRUE if all TX buffer descriptor ring is full *)
  369. recvPackets0: EnetBase.PacketFifo; (* internal buffer of received packets which will undergo data cache invalidation *)
  370. lastRecvFrmCount: UInt;
  371. sendTimeoutTimer: EnetTiming.Timer;
  372. END;
  373. Packet = POINTER TO PacketDesc;
  374. PacketDesc= RECORD(EnetBase.PacketDesc)
  375. txTaskHandler: EnetBase.TaskHandler; (* completion result for a transmitted packet *)
  376. numParts: Int; (* number of parts *)
  377. partAddr: ARRAY 128 OF ADDRESS; (* payload address in case of a splitted packet *)
  378. partLen: ARRAY 128 OF Int;
  379. END;
  380. VAR
  381. gem0, gem1: LinkDevice;
  382. (**
  383. Get interface for a GEM controller with given ID
  384. gemId: GEM controller ID (0 or 1)
  385. rxBdRingLen, txBdRingLen: receive/transmit buffer descriptor ring length
  386. rxPacketPoolSize, txPacketPoolSize: receive/transmit packet pool size
  387. *)
  388. PROCEDURE GetDevice*(gemId: Int; rxBdRingLen, txBdRingLen: Int; rxPacketPoolSize, txPacketPoolSize: Int; VAR device: EnetBase.LinkDevice; VAR res: Int): BOOLEAN;
  389. VAR
  390. dev: LinkDevice;
  391. init: BOOLEAN;
  392. pool: EnetBase.PacketFifo;
  393. i: Int;
  394. BEGIN
  395. IF (gemId < 0) OR (gemId > 1) THEN
  396. res := EnetBase.ErrInvalidValue;
  397. RETURN FALSE;
  398. END;
  399. IF rxPacketPoolSize < rxBdRingLen THEN (* RX packet pool cannot be smaller than the RX buffer descriptor ring size *)
  400. res := EnetBase.ErrInvalidValue;
  401. RETURN FALSE;
  402. END;
  403. IF gemId = 0 THEN
  404. IF gem0 = NIL THEN NEW(gem0); init := TRUE; END;
  405. dev := gem0;
  406. ELSE
  407. IF gem1 = NIL THEN NEW(gem1); init := TRUE; END;
  408. dev := gem1;
  409. END;
  410. IF init THEN
  411. dev.id := gemId;
  412. IF gemId = 0 THEN
  413. dev.regs := GemBaseAddr0;
  414. ELSE
  415. dev.regs := GemBaseAddr1;
  416. END;
  417. dev.phyAddr := EnetPhy.InvalidPhyAddr;
  418. dev.phyWrite := PhyWrite;
  419. dev.phyRead := PhyRead;
  420. dev.setMacAddr := SetMacAddr;
  421. dev.setLinkSpeed := SetLinkSpeed;
  422. dev.start := Start;
  423. dev.stop := Stop;
  424. dev.reset := Reset;
  425. dev.finalize := Finalize;
  426. dev.setPacketPayload := SetPacketPayload;
  427. dev.sendPacket := SendPacket;
  428. dev.updateRx := UpdateRx;
  429. dev.updateTx := UpdateTx;
  430. (*dev.dmaBdMem := NIL;*)
  431. END;
  432. (*
  433. allocate/reallocate RX/TX packet pools if required
  434. *)
  435. InitPacketPool(dev.rxPacketPool,rxPacketPoolSize);
  436. InitPacketPool(dev.txPacketPool,txPacketPoolSize);
  437. IF (dev.recvPackets = NIL) OR (LEN(dev.recvPackets.packets) # rxPacketPoolSize) THEN
  438. dev.recvPackets := EnetBase.NewPacketFifo(rxPacketPoolSize);
  439. dev.recvPackets0 := EnetBase.NewPacketFifo(rxPacketPoolSize);
  440. END;
  441. IF ~InitDma(dev,rxBdRingLen,txBdRingLen,res) THEN RETURN FALSE; END;
  442. IF ~Reset(dev,res) THEN END;
  443. EnetTiming.SetTimerMilli(dev.sendTimeoutTimer,10);
  444. device := dev;
  445. res := 0;
  446. RETURN TRUE;
  447. END GetDevice;
  448. PROCEDURE InitPacketPool(VAR pool: EnetBase.PacketFifo; poolSize: Int);
  449. VAR
  450. poolTmp: EnetBase.PacketFifo;
  451. packet: EnetBase.Packet;
  452. i: Int;
  453. BEGIN
  454. IF (pool = NIL) OR (poolSize # LEN(pool.packets)) THEN
  455. poolTmp := pool;
  456. pool := EnetBase.NewPacketFifo(poolSize);
  457. IF poolTmp # NIL THEN
  458. WHILE EnetBase.PacketFifoGet(poolTmp,packet) & EnetBase.PacketFifoPut(pool,packet) DO
  459. END;
  460. END;
  461. WHILE pool.count < poolSize DO
  462. packet := NewPacket();
  463. packet.ownerPool := pool;
  464. ASSERT(EnetBase.PacketFifoPut(pool,packet));
  465. END;
  466. ASSERT(pool.count = poolSize);
  467. FOR i := 0 TO poolSize-1 DO
  468. pool.packets[i].ownedByDev := FALSE;
  469. pool.packets[i].ownedByUser := FALSE;
  470. END;
  471. END;
  472. END InitPacketPool;
  473. (**
  474. Write to an Ethernet PHY device attached to a given GEM controller
  475. phyAddr: PHY address (5 bit)
  476. regAddr: register address (5 bit)
  477. data: data to write to the given register (16 bit)
  478. *)
  479. PROCEDURE PhyWrite*(dev: EnetBase.LinkDevice; phyAddr, regAddr, data: UInt; VAR res: Int): BOOLEAN;
  480. BEGIN
  481. ASSERT(phyAddr <= 31);
  482. ASSERT(regAddr <= 31);
  483. ASSERT(data <= 65535);
  484. WITH dev : LinkDevice DO
  485. IF S.MSK(dev.regs.net_status,NWSR_MDIOIDLE_MASK) = 0 THEN res := EnetBase.ErrMdioBusy; RETURN FALSE; END;
  486. dev.regs.phy_maint := PHYMNTNC_OP_MASK+PHYMNTNC_OP_W_MASK +
  487. LSH(phyAddr,PHYMNTNC_PHYAD_SHIFT_MASK) +
  488. LSH(regAddr,PHYMNTNC_PHREG_SHIFT_MASK) +
  489. data;
  490. (* wait for completion of the operation *)
  491. REPEAT UNTIL S.MSK(dev.regs.net_status,NWSR_MDIOIDLE_MASK) # 0;
  492. END;
  493. res := 0;
  494. RETURN TRUE;
  495. END PhyWrite;
  496. (**
  497. Read from an Ethernet PHY device attached to a given GEM controller
  498. phyAddr: PHY address (5 bit)
  499. regAddr: register address (5 bit)
  500. data: data read from the given register (16 bit)
  501. *)
  502. PROCEDURE PhyRead*(dev: EnetBase.LinkDevice; phyAddr, regAddr: UInt; VAR data: UInt; VAR res: Int): BOOLEAN;
  503. BEGIN
  504. ASSERT(phyAddr <= 31);
  505. ASSERT(regAddr <= 31);
  506. WITH dev : LinkDevice DO
  507. IF S.MSK(dev.regs.net_status,NWSR_MDIOIDLE_MASK) = 0 THEN res := EnetBase.ErrMdioBusy; RETURN FALSE; END;
  508. dev.regs.phy_maint := PHYMNTNC_OP_MASK+PHYMNTNC_OP_R_MASK +
  509. LSH(phyAddr,PHYMNTNC_PHYAD_SHIFT_MASK) +
  510. LSH(regAddr,PHYMNTNC_PHREG_SHIFT_MASK);
  511. (* wait for completion of the operation *)
  512. REPEAT UNTIL S.MSK(dev.regs.net_status,NWSR_MDIOIDLE_MASK) # 0;
  513. data := dev.regs.phy_maint MOD 10000H;
  514. END;
  515. res := 0;
  516. RETURN TRUE;
  517. END PhyRead;
  518. (**
  519. Setup MAC address for a given link device
  520. *)
  521. PROCEDURE SetMacAddr*(dev: EnetBase.LinkDevice; CONST macAddr: EnetBase.MacAddr; VAR res: Int): BOOLEAN;
  522. BEGIN
  523. IF dev.isActive THEN
  524. res := EnetBase.ErrCannotDoWhenActive;
  525. RETURN FALSE;
  526. END;
  527. WITH dev : LinkDevice DO
  528. SetSpecificMacAddr(dev,1,macAddr.addr);
  529. END;
  530. dev.macAddr := macAddr;
  531. res := 0;
  532. RETURN TRUE;
  533. END SetMacAddr;
  534. (**
  535. Setup link speed for a given device
  536. speed: link speed in Mbps
  537. *)
  538. PROCEDURE SetLinkSpeed*(dev: EnetBase.LinkDevice; CONST speed: ARRAY OF CHAR; fullDuplex: BOOLEAN; VAR res: Int): BOOLEAN;
  539. BEGIN
  540. IF dev.isActive THEN
  541. res := EnetBase.ErrCannotDoWhenActive;
  542. RETURN FALSE;
  543. END;
  544. WITH dev : LinkDevice DO
  545. (* Configure the PHY *)
  546. IF speed = EnetBase.LinkSpeedAuto THEN
  547. IF ~PhyAutonegotiateLink(dev,dev.phyAddr,dev.linkSpeed,fullDuplex,res) THEN
  548. RETURN FALSE;
  549. END;
  550. ELSE
  551. res := EnetBase.ErrInvalidValue;
  552. RETURN FALSE;
  553. END;
  554. SetControllerSpeed(dev,dev.linkSpeed,fullDuplex);
  555. COPY(speed,dev.linkSpeed);
  556. dev.fullDuplex := fullDuplex;
  557. END;
  558. res := 0;
  559. RETURN TRUE;
  560. END SetLinkSpeed;
  561. (**
  562. Setup device-specific options
  563. options: set of device options to enable, not included options will be disabled
  564. *)
  565. PROCEDURE SetOptions*(dev: EnetBase.LinkDevice; optionsPage: Int; options: SET; VAR res: Int): BOOLEAN;
  566. CONST
  567. NWCFG_OPTIONS_MASK = NWCFG_1536RXEN_MASK +
  568. NWCFG_NVLANDISC_MASK +
  569. NWCFG_FCSREM_MASK +
  570. NWCFG_LENGTHERRDSCRD_MASK +
  571. NWCFG_PAUSEEN_MASK +
  572. NWCFG_COPYALLEN_MASK +
  573. NWCFG_BCASTDI_MASK +
  574. NWCFG_MCASTHASHEN_MASK +
  575. NWCFG_RXCHKSUMEN_MASK;
  576. VAR
  577. d: UInt;
  578. BEGIN
  579. IF dev.isActive THEN
  580. res := EnetBase.ErrCannotDoWhenActive;
  581. RETURN FALSE;
  582. END;
  583. WITH dev : LinkDevice DO
  584. d := 0;
  585. (* Turn on promiscuous frame filtering (all frames are received) *)
  586. IF Promisc IN options THEN d := d + NWCFG_COPYALLEN_MASK; END;
  587. (* It is configured to max 1536 *)
  588. IF Frame1536 IN options THEN d := d + NWCFG_1536RXEN_MASK; END;
  589. (* Turn on VLAN packet only, only VLAN tagged will be accepted *)
  590. IF Vlan IN options THEN d := d + NWCFG_NVLANDISC_MASK; END;
  591. (* Turn on flow control *)
  592. IF FlowControl IN options THEN d := d + NWCFG_PAUSEEN_MASK; END;
  593. (* Turn on FCS stripping on receive packets *)
  594. IF FcsStrip IN options THEN d := d + NWCFG_FCSREM_MASK; END;
  595. (* Turn on length/type field checking on receive packets *)
  596. IF LenTypeErr IN options THEN d := d + NWCFG_LENGTHERRDSCRD_MASK; END;
  597. (* Allow broadcast address reception *)
  598. IF ~(Broadcast IN options) THEN d := d + NWCFG_BCASTDI_MASK; END;
  599. (* Allow multicast address filtering *)
  600. IF Multicast IN options THEN d := d + NWCFG_MCASTHASHEN_MASK; END;
  601. (* enable RX checksum offload *)
  602. IF RxChksumEnable IN options THEN d := d + NWCFG_RXCHKSUMEN_MASK; END;
  603. (* write all net_cfg options all at once *)
  604. dev.regs.net_cfg := S.MSK(dev.regs.net_cfg,-NWCFG_OPTIONS_MASK-1) + d;
  605. (* Enable TX checksum offload *)
  606. IF TxChksumEnable IN options THEN
  607. dev.regs.dma_cfg := S.MSK(dev.regs.dma_cfg,-DMACR_TCPCKSUM_MASK-1) + DMACR_TCPCKSUM_MASK;
  608. ELSE
  609. dev.regs.dma_cfg := S.MSK(dev.regs.dma_cfg,-DMACR_TCPCKSUM_MASK-1);
  610. END;
  611. dev.options := options;
  612. END;
  613. res := 0;
  614. RETURN TRUE;
  615. END SetOptions;
  616. (*! (PHY hardware-specific)
  617. Perform PHY link autonegotiation
  618. *)
  619. PROCEDURE PhyAutonegotiateLink(dev: LinkDevice; phyAddr: UInt; VAR speed: ARRAY OF CHAR; VAR fullDuplex: BOOLEAN; VAR res: Int): BOOLEAN;
  620. CONST
  621. RGMII_TXRX_CLOCK_DELAYED_MASK = 0x0030;
  622. MII_ADVERTISE_MASK = EnetPhy.ADVERTISE_PAUSE_CAP+EnetPhy.ADVERTISE_PAUSE_ASYM+EnetPhy.ADVERTISE_ALL;
  623. MII_CTRL1000_MASK = EnetPhy.ADVERTISE_1000HALF+EnetPhy.ADVERTISE_1000FULL;
  624. MII_BMCR_MASK = EnetPhy.BMCR_ANENABLE+EnetPhy.BMCR_ANRESTART;
  625. PAGE_ADDRESS_REGISTER = 22;
  626. CONTROL_REG_MAC = 21;
  627. COPPER_SPECIFIC_CONTROL_REG = 16;
  628. COPPER_SPECIFIC_CONTROL_REG_MASK = LSH(Int16(7),12)+LSH(Int16(1),11); (* max number of gigabit attempts + enable downshift *)
  629. SPECIFIC_STATUS_REG = 17;
  630. COPPER_SPECIFIC_STATUS_REG_2 = 19;
  631. AUTONEG_ERROR_MASK = 0x8000;
  632. VAR
  633. d, d1: UInt;
  634. t: EnetTiming.Timer;
  635. BEGIN
  636. speed := "";
  637. (* configure RX/TX clock delay settings *)
  638. IF ~PhyWrite(dev,phyAddr,PAGE_ADDRESS_REGISTER,2,res) THEN RETURN FALSE; END; (* select page 2 *)
  639. IF ~PhyRead(dev,phyAddr,CONTROL_REG_MAC,d,res) THEN RETURN FALSE; END;
  640. d := S.MSK(d,-Int16(RGMII_TXRX_CLOCK_DELAYED_MASK)-1) + RGMII_TXRX_CLOCK_DELAYED_MASK;
  641. IF ~PhyWrite(dev,phyAddr,CONTROL_REG_MAC,d,res) THEN RETURN FALSE; END;
  642. (* advertising 10 Mbps and 100 Mbps *)
  643. IF ~PhyWrite(dev,phyAddr,PAGE_ADDRESS_REGISTER,0,res) THEN RETURN FALSE; END; (* select page 0 *)
  644. IF ~PhyRead(dev,phyAddr,EnetPhy.MII_ADVERTISE,d,res) THEN RETURN FALSE; END;
  645. d := S.MSK(d,-MII_ADVERTISE_MASK-1) + MII_ADVERTISE_MASK;
  646. IF ~PhyWrite(dev,phyAddr,EnetPhy.MII_ADVERTISE,d,res) THEN RETURN FALSE; END;
  647. (* advertising 1000 Mbps *)
  648. IF ~PhyRead(dev,phyAddr,EnetPhy.MII_CTRL1000,d,res) THEN RETURN FALSE; END;
  649. d := S.MSK(d,-MII_CTRL1000_MASK-1) + MII_CTRL1000_MASK;
  650. IF ~PhyWrite(dev,phyAddr,EnetPhy.MII_CTRL1000,d,res) THEN RETURN FALSE; END;
  651. IF ~PhyWrite(dev,phyAddr,PAGE_ADDRESS_REGISTER,0,res) THEN RETURN FALSE; END; (* select page 0 *)
  652. IF ~PhyRead(dev,phyAddr,COPPER_SPECIFIC_CONTROL_REG,d,res) THEN RETURN FALSE; END;
  653. d := S.MSK(d,-COPPER_SPECIFIC_CONTROL_REG_MASK-1) + COPPER_SPECIFIC_CONTROL_REG_MASK;
  654. IF ~PhyWrite(dev,phyAddr,COPPER_SPECIFIC_CONTROL_REG,d,res) THEN RETURN FALSE; END;
  655. IF ~PhyRead(dev,phyAddr,EnetPhy.MII_BMCR,d,res) THEN RETURN FALSE; END;
  656. d := S.MSK(d,-MII_BMCR_MASK-1) + MII_BMCR_MASK;
  657. IF ~PhyWrite(dev,phyAddr,EnetPhy.MII_BMCR,d,res) THEN RETURN FALSE; END;
  658. IF EnableTrace THEN Trace.StringLn("resetting PHY ..."); END;
  659. (* resetting PHY *)
  660. IF ~EnetPhy.ResetPhy(dev,phyAddr,1000,res) THEN RETURN FALSE; END;
  661. IF EnableTrace THEN Trace.StringLn("PHY has been resetted"); END;
  662. IF EnableTrace THEN Trace.StringLn("autonegotiating link ..."); END;
  663. IF ~PhyRead(dev,phyAddr,EnetPhy.MII_BMSR,d,res) THEN RETURN FALSE; END;
  664. EnetTiming.SetTimerMilli(t,LinkAutonegoTimeout);
  665. EnetTiming.StartTimer(t);
  666. WHILE (S.MSK(d,EnetPhy.BMSR_ANEGCOMPLETE) = 0) & ~EnetTiming.IsTimerExpired(t) DO
  667. EnetTiming.WaitMilli(500);
  668. IF ~PhyRead(dev,phyAddr,COPPER_SPECIFIC_STATUS_REG_2,d,res) THEN RETURN FALSE; END;
  669. IF S.MSK(d,AUTONEG_ERROR_MASK) # 0 THEN
  670. res := EnetBase.ErrSpeedAutonegoFailure;
  671. RETURN FALSE;
  672. END;
  673. IF ~PhyRead(dev,phyAddr,EnetPhy.MII_BMSR,d,res) THEN RETURN FALSE; END;
  674. END;
  675. IF S.MSK(d,EnetPhy.BMSR_ANEGCOMPLETE) = 0 THEN
  676. IF EnableTrace THEN Trace.StringLn("[Error]: timeout has expired!"); END;
  677. RETURN FALSE;
  678. END;
  679. IF EnableTrace THEN Trace.StringLn("link autonegotiation has been completed"); END;
  680. IF ~PhyRead(dev,phyAddr,SPECIFIC_STATUS_REG,d,res) THEN RETURN FALSE; END;
  681. IF EnableTrace THEN Trace.StringLn("partner capabilities: " & Trace.Hx(d,4)); END;
  682. d1 := Int16(LSH(S.MSK(d,0xC000),-14));
  683. IF d1 = 2 THEN (* 1000 Mbps *)
  684. speed := EnetBase.Mbps1000;
  685. ELSIF d1 = 1 THEN (* 100 Mbps *)
  686. speed := EnetBase.Mbps100;
  687. ELSE (* 10 Mbps *)
  688. speed := EnetBase.Mbps10;
  689. END;
  690. fullDuplex := S.MSK(d,0x2000) # 0;
  691. IF EnableTrace THEN Trace.StringLn("link speed is " & speed & ", fullDuplex is " & fullDuplex); END;
  692. res := 0;
  693. RETURN TRUE;
  694. END PhyAutonegotiateLink;
  695. (**
  696. Start a given link device
  697. *)
  698. PROCEDURE Start*(dev: EnetBase.LinkDevice; VAR res: Int): BOOLEAN;
  699. VAR d: UInt;
  700. BEGIN
  701. IF dev.isActive THEN
  702. res := 0;
  703. RETURN TRUE;
  704. END;
  705. WITH dev : LinkDevice DO
  706. dev.lastRecvFrmCount := 0;
  707. (*
  708. Prepare DMA for start
  709. *)
  710. IF ~ConfigureDma(dev,res) THEN RETURN FALSE; END;
  711. dev.regs.rx_qbar := S.VAL(ADDRESS,dev.rxBdRingStart.dmaBd);
  712. dev.regs.tx_qbar := S.VAL(ADDRESS,dev.txBdRingStart.dmaBd);
  713. (* clear any existing interrupt status *)
  714. dev.regs.intr_status := IXR_ALL_MASK;
  715. (*
  716. Enable interrupts
  717. *)
  718. dev.regs.intr_en := IXR_TX_ERR_MASK + IXR_RX_ERR_MASK (*+ IXR_FRAMERX_MASK+ IXR_TXCOMPL_MASK*);
  719. ASSERT(S.MSK(dev.regs.intr_en,-IXR_ALL_MASK-1) = 0);
  720. (*
  721. Optionally enable transmitter and receiver
  722. *)
  723. d := 0;
  724. IF TransmitterEnable IN dev.options THEN d := d + NWCTRL_TXEN_MASK; END;
  725. IF ReceiverEnable IN dev.options THEN d := d + NWCTRL_RXEN_MASK; END;
  726. dev.regs.net_ctrl := S.MSK(dev.regs.net_ctrl,NWCTRL_RXTXDIS_MASK) + d;
  727. dev.isActive := TRUE;
  728. END;
  729. res := 0;
  730. RETURN TRUE;
  731. END Start;
  732. (**
  733. Stop of a given link device
  734. *)
  735. PROCEDURE Stop*(dev: EnetBase.LinkDevice; VAR res: Int): BOOLEAN;
  736. BEGIN
  737. StopController(dev(LinkDevice));
  738. dev.isActive := FALSE;
  739. res := 0;
  740. RETURN TRUE;
  741. END Stop;
  742. (**
  743. Resetting a given link device
  744. *)
  745. PROCEDURE Reset*(dev: EnetBase.LinkDevice; VAR res: Int): BOOLEAN;
  746. VAR
  747. allowZeroPhyAddr: BOOLEAN;
  748. BEGIN
  749. WITH dev : LinkDevice DO
  750. StopController(dev);
  751. IF EnableTrace THEN Trace.StringLn("[-] resetting Xilinx EmacPs7 controller " & dev.id & " ..."); END;
  752. ResetController(dev);
  753. dev.isActive := FALSE;
  754. IF EnableTrace THEN Trace.StringLn("[x] controller has been resetted"); END;
  755. IF EnableTrace THEN Trace.StringLn("[-] setting up default controller options ..."); END;
  756. IF ~SetOptions(dev,1,DefaultOptions,res) THEN RETURN FALSE; END;
  757. IF EnableTrace THEN Trace.StringLn("[x] controller options has been set up"); END;
  758. IF EnableTrace THEN Trace.StringLn("[-] detecting PHY ..."); END;
  759. IF dev.id = 0 THEN
  760. allowZeroPhyAddr := AllowZeroPhyAddr0;
  761. ELSE
  762. allowZeroPhyAddr := AllowZeroPhyAddr1;
  763. END;
  764. IF ~EnetPhy.DetectPhy(dev,dev.phyAddr,allowZeroPhyAddr,res) THEN RETURN FALSE; END;
  765. IF EnableTrace THEN Trace.StringLn("[x] PHY found at address 0x" & Trace.Hx(dev.phyAddr,2)); END;
  766. dev.lastRecvFrmCount := 0;
  767. END;
  768. res := 0;
  769. RETURN TRUE;
  770. END Reset;
  771. PROCEDURE Finalize*(dev: EnetBase.LinkDevice; VAR res: Int): BOOLEAN;
  772. BEGIN
  773. RETURN Stop(dev,res);
  774. END Finalize;
  775. (**
  776. Update the state of the receive path of a link device
  777. *)
  778. PROCEDURE UpdateRx*(dev: EnetBase.LinkDevice; VAR res: Int): BOOLEAN;
  779. VAR
  780. packet: EnetBase.Packet;
  781. intrStatus, rxStatus: UInt;
  782. BEGIN
  783. WITH dev : LinkDevice DO
  784. IF dev.isActive THEN
  785. ProcessRxBds(dev);
  786. ELSE
  787. res := EnetBase.ErrNotActive;
  788. RETURN FALSE;
  789. END;
  790. END;
  791. res := 0;
  792. RETURN TRUE;
  793. END UpdateRx;
  794. (**
  795. Update the state of the transmit path of a link device
  796. *)
  797. PROCEDURE UpdateTx*(dev: EnetBase.LinkDevice; VAR res: Int): BOOLEAN;
  798. VAR
  799. packet: EnetBase.Packet;
  800. txStatus: UInt;
  801. BEGIN
  802. WITH dev : LinkDevice DO
  803. IF dev.isActive THEN
  804. ProcessTxBds(dev);
  805. ELSE
  806. res := EnetBase.ErrNotActive;
  807. RETURN FALSE;
  808. END;
  809. END;
  810. res := 0;
  811. RETURN TRUE;
  812. END UpdateTx;
  813. (*
  814. Stop a given GEM controller
  815. *)
  816. PROCEDURE StopController(dev: LinkDevice);
  817. BEGIN
  818. (* disable all interrupts *)
  819. dev.regs.intr_dis := IXR_ALL_MASK;
  820. (* disable the receiver and transmitter *)
  821. dev.regs.net_ctrl := S.MSK(dev.regs.net_ctrl,NWCTRL_RXTXDIS_MASK);
  822. END StopController;
  823. (*
  824. Reset a given GEM controller
  825. *)
  826. PROCEDURE ResetController(dev: LinkDevice);
  827. VAR
  828. d: UInt;
  829. i: Int;
  830. t: EnetTiming.Timer;
  831. BEGIN
  832. (*
  833. Initialize the controller
  834. *)
  835. (* 1. Clear the Network Control register *)
  836. dev.regs.net_ctrl := 0;
  837. (* 2. Clear the Statistics registers *)
  838. dev.regs.net_ctrl := NWCTRL_STATCLR_MASK;
  839. (* 3. Clear the Status registers - write a 1 to the Status registers *)
  840. dev.regs.rx_status := 0x0F;
  841. dev.regs.tx_status := 0x1FF;
  842. (* 4. Disable all interrupts *)
  843. dev.regs.intr_dis := 0x7FFFEFF;
  844. (* 5. Clear the buffer queues *)
  845. dev.regs.rx_qbar := 0;
  846. dev.regs.tx_qbar := 0;
  847. (*
  848. Setup the controller to default configuration
  849. *)
  850. dev.regs.net_cfg := NWCFG_100_MASK+NWCFG_FDEN_MASK+NWCFG_UCASTHASHEN_MASK;
  851. IF RX_BUF_SIZE MOD RX_BUF_UNIT # 0 THEN
  852. d := RX_BUF_SIZE DIV RX_BUF_UNIT;
  853. ELSE
  854. d := (RX_BUF_SIZE DIV RX_BUF_UNIT) + 1;
  855. END;
  856. dev.regs.dma_cfg := S.MSK(LSH(d,DMACR_RXBUF_SHIFT),DMACR_RXBUF_MASK) + DMACR_RXSIZE_MASK + DMACR_TXSIZE_MASK;
  857. dev.regs.tx_status := 0;
  858. dev.regs.rx_status := 0;
  859. dev.regs.intr_status := dev.regs.intr_status;
  860. ClearHash(dev);
  861. (* clear MAC addresses and type ID matching *)
  862. FOR i := 1 TO 4 DO
  863. SetSpecificMacAddr(dev,i,EnetBase.NilMacAddr.addr);
  864. SetTypeIdMatch(dev,i,0,FALSE);
  865. END;
  866. (* clear all counters *)
  867. dev.regs.octets_tx_bot := 0;
  868. dev.regs.octets_tx_top := 0;
  869. dev.regs.frames_tx := 0;
  870. dev.regs.broadcast_frames_tx := 0;
  871. dev.regs.multi_frames_tx := 0;
  872. dev.regs.pause_frames_tx := 0;
  873. dev.regs.frames_64b_tx := 0;
  874. dev.regs.frames_65to127b_tx := 0;
  875. dev.regs.frames_128to255b_tx := 0;
  876. dev.regs.frames_256to511b_tx := 0;
  877. dev.regs.frames_512to1023b_tx := 0;
  878. dev.regs.frames_1024to1518b_tx := 0;
  879. dev.regs.tx_under_runs := 0;
  880. dev.regs.single_collisn_frames := 0;
  881. dev.regs.multi_collisn_frames := 0;
  882. dev.regs.late_collisns := 0;
  883. dev.regs.deferred_tx_frames := 0;
  884. dev.regs.carrier_sense_errs := 0;
  885. dev.regs.octets_rx_bot := 0;
  886. dev.regs.octets_rx_top := 0;
  887. dev.regs.frames_rx := 0;
  888. dev.regs.bdcast_fames_rx := 0;
  889. dev.regs.multi_frames_rx := 0;
  890. dev.regs.pause_rx := 0;
  891. dev.regs.frames_64b_rx := 0;
  892. dev.regs.frames_65to127b_rx := 0;
  893. dev.regs.frames_128to255b_rx := 0;
  894. dev.regs.frames_256to511b_rx := 0;
  895. dev.regs.frames_512to1023b_rx := 0;
  896. dev.regs.frames_1024to1518b_rx := 0;
  897. dev.regs.undersz_rx := 0;
  898. dev.regs.oversz_rx := 0;
  899. dev.regs.jab_rx := 0;
  900. dev.regs.fcs_errors := 0;
  901. dev.regs.length_field_errors := 0;
  902. dev.regs.rx_symbol_errors := 0;
  903. dev.regs.align_errors := 0;
  904. dev.regs.rx_resource_errors := 0;
  905. dev.regs.rx_overrun_errors := 0;
  906. dev.regs.ip_hdr_csum_errors := 0;
  907. dev.regs.tcp_csum_errors := 0;
  908. dev.regs.udp_csum_errors := 0;
  909. dev.regs.net_ctrl := S.MSK(dev.regs.net_ctrl,-NWCTRL_MDEN_MASK-1) + NWCTRL_MDEN_MASK; (* enable MDIO *)
  910. dev.regs.phy_maint := 0;
  911. (* setup the speed of MDIO line *)
  912. IF dev.id = 0 THEN
  913. SetMdioDivisor(dev,MdioDivisor0);
  914. ELSE
  915. SetMdioDivisor(dev,MdioDivisor1);
  916. END;
  917. (* wait for some time until MDIO line becomes available *)
  918. EnetTiming.SetTimerMilli(t,1000);
  919. EnetTiming.StartTimer(t);
  920. REPEAT
  921. UNTIL (S.MSK(dev.regs.net_status,NWSR_MDIOIDLE_MASK) # 0) OR EnetTiming.IsTimerExpired(t);
  922. END ResetController;
  923. (*! (PHY hardware-specific)
  924. Setup GEM controller according to specified link speed and full duplex settings
  925. *)
  926. PROCEDURE SetControllerSpeed(dev: LinkDevice; CONST speed: ARRAY OF CHAR; fullDuplex: BOOLEAN);
  927. CONST
  928. GEM_SLCR_DIV_MASK = 0xFC0FC0FF;
  929. (* IO PLL 1000 MHz, div0 = 8, div1 = 1 correspond to clock 125 MHz *)
  930. GEM_SLCR_1000MBPS_DIV0 = 0x8;
  931. GEM_SLCR_1000MBPS_DIV1 = 0x1;
  932. (* IO PLL 1000 MHz, div0 = 8, div1 = 5 correspond to clock 25 MHz *)
  933. GEM_SLCR_100MBPS_DIV0 = 0x8;
  934. GEM_SLCR_100MBPS_DIV1 = 0x5;
  935. (* IO PLL 1000 MHz, div0 = 8, div1 = 50 correspond to clock 2.5 MHz *)
  936. GEM_SLCR_10MBPS_DIV0 = 0x8;
  937. GEM_SLCR_10MBPS_DIV1 = 0x50;
  938. VAR
  939. d: UInt;
  940. BEGIN
  941. (*
  942. Setup RX/TX clocks
  943. *)
  944. IF speed = EnetBase.Mbps1000 THEN d := LSH(GEM_SLCR_1000MBPS_DIV1,20) + LSH(GEM_SLCR_1000MBPS_DIV0,8);
  945. ELSIF speed = EnetBase.Mbps100 THEN d := LSH(GEM_SLCR_100MBPS_DIV1,20) + LSH(GEM_SLCR_100MBPS_DIV0,8);
  946. ELSE (* 10 Mbps *)
  947. ASSERT(speed = EnetBase.Mbps10);
  948. d := LSH(GEM_SLCR_10MBPS_DIV1,20) + LSH(GEM_SLCR_10MBPS_DIV0,8);
  949. END;
  950. Platform.slcr.SLCR_UNLOCK := Platform.SlcrUnlockKey; (* enable writing to SLCR registers *)
  951. IF dev.id = 0 THEN
  952. Platform.slcr.GEM0_CLK_CTRL := S.MSK(Platform.slcr.GEM0_CLK_CTRL,GEM_SLCR_DIV_MASK) + d;
  953. ELSE
  954. Platform.slcr.GEM1_CLK_CTRL := S.MSK(Platform.slcr.GEM1_CLK_CTRL,GEM_SLCR_DIV_MASK) + d;
  955. END;
  956. Platform.slcr.SLCR_LOCK := Platform.SlcrLockKey; (* disable writing to SLCR registers *)
  957. (*
  958. Setup net_cfg register according to the link speed and full duplex settings
  959. *)
  960. d := S.MSK(dev.regs.net_cfg,-(NWCFG_1000_MASK+NWCFG_100_MASK+NWCFG_FDEN_MASK)-1);
  961. IF speed = EnetBase.Mbps1000 THEN d := d + NWCFG_1000_MASK;
  962. ELSIF speed = EnetBase.Mbps100 THEN d := d + NWCFG_100_MASK;
  963. END;
  964. IF fullDuplex THEN d := d + NWCFG_FDEN_MASK; END; (* enable full duplex *)
  965. dev.regs.net_cfg := d;
  966. END SetControllerSpeed;
  967. PROCEDURE ClearHash(dev: LinkDevice);
  968. BEGIN
  969. dev.regs.hash_bot := 0;
  970. dev.regs.hash_top := 0;
  971. END ClearHash;
  972. (*
  973. Setup a specific MAC address
  974. index: index of a specific address to setup (from 1 to 4)
  975. *)
  976. PROCEDURE SetSpecificMacAddr(dev: LinkDevice; index: Int; CONST mac: ARRAY 6 OF Int8);
  977. VAR dl, dh: UInt;
  978. BEGIN
  979. ASSERT((index >= 1) & (index <= 4));
  980. dl := UInt(mac[0]) MOD 100H + (UInt(mac[1]) MOD 100H) * 100H + (UInt(mac[2]) MOD 100H) * 10000H + (UInt(mac[3]) MOD 100H) * 1000000H;
  981. dh := UInt(mac[4]) MOD 100H + (UInt(mac[5]) MOD 100H) * 100H;
  982. CASE index OF
  983. |1:
  984. dev.regs.spec_addr1_bot := dl;
  985. dev.regs.spec_addr1_top := S.MSK(dev.regs.spec_addr1_top,0xFFFF0000) + dh; (* keep high 16 reserved bits untouched *)
  986. |2:
  987. dev.regs.spec_addr2_bot := dl;
  988. dev.regs.spec_addr2_top := S.MSK(dev.regs.spec_addr2_top,0xFFFF0000) + dh; (* keep high 16 reserved bits untouched *)
  989. |3:
  990. dev.regs.spec_addr3_bot := dl;
  991. dev.regs.spec_addr3_top := S.MSK(dev.regs.spec_addr3_top,0xFFFF0000) + dh; (* keep high 16 reserved bits untouched *)
  992. |4:
  993. dev.regs.spec_addr4_bot := dl;
  994. dev.regs.spec_addr4_top := S.MSK(dev.regs.spec_addr4_top,0xFFFF0000) + dh; (* keep high 16 reserved bits untouched *)
  995. END;
  996. END SetSpecificMacAddr;
  997. (*
  998. index: index of a type ID to setup (from 1 to 4)
  999. *)
  1000. PROCEDURE SetTypeIdMatch(dev: LinkDevice; index: Int; typeId: UInt; enable: BOOLEAN);
  1001. VAR d: UInt;
  1002. BEGIN
  1003. ASSERT((index >= 1) & (index <= 4));
  1004. d := typeId MOD 10000H;
  1005. IF enable THEN d := d +0x80000000; END; (* set bit 31 to enable matching *)
  1006. CASE index OF
  1007. |1: dev.regs.type_id_match1 := d;
  1008. |2: dev.regs.type_id_match2 := d;
  1009. |3: dev.regs.type_id_match3 := d;
  1010. |4: dev.regs.type_id_match4 := d;
  1011. END;
  1012. END SetTypeIdMatch;
  1013. (**
  1014. Set the MDIO clock divisor.
  1015. Calculating the divisor:
  1016. f[HOSTCLK]
  1017. f[MDC] = -----------------
  1018. (1 + Divisor) * 2
  1019. where f[HOSTCLK] is the bus clock frequency in MHz, and f[MDC] is the
  1020. MDIO clock frequency in MHz to the PHY. Typically, f[MDC] should not
  1021. exceed 2.5 MHz. Some PHYs can tolerate faster speeds which means faster
  1022. access. Here is the table to show values to generate MDC,
  1023. 000 : divide pclk by 8 (pclk up to 20 MHz)
  1024. 001 : divide pclk by 16 (pclk up to 40 MHz)
  1025. 010 : divide pclk by 32 (pclk up to 80 MHz)
  1026. 011 : divide pclk by 48 (pclk up to 120 MHz)
  1027. 100 : divide pclk by 64 (pclk up to 160 MHz)
  1028. 101 : divide pclk by 96 (pclk up to 240 MHz)
  1029. 110 : divide pclk by 128 (pclk up to 320 MHz)
  1030. 111 : divide pclk by 224 (pclk up to 540 MHz)
  1031. *)
  1032. PROCEDURE SetMdioDivisor(dev: LinkDevice; divisor: UInt);
  1033. VAR reg: UInt;
  1034. BEGIN
  1035. ASSERT((divisor >= MDC_DIV_8) & (divisor <= MDC_DIV_224));
  1036. dev.regs.net_cfg := S.MSK(dev.regs.net_cfg,NWCFG_INV_MDCCLKDIV_MASK) + LSH(divisor,NWCFG_MDC_SHIFT_MASK);
  1037. END SetMdioDivisor;
  1038. (**
  1039. Initialize DMA engine of a given GEM device
  1040. *)
  1041. PROCEDURE InitDma(dev: LinkDevice; rxBdRingLen, txBdRingLen: Int; VAR res: LONGINT): BOOLEAN;
  1042. CONST
  1043. MB = 1024*1024; (* one Mega byte *)
  1044. VAR
  1045. packet: EnetBase.Packet;
  1046. bdAddr: ADDRESS;
  1047. i: Int;
  1048. BEGIN
  1049. ASSERT(dev.dmaBdMem.addr = NIL);
  1050. ASSERT((rxBdRingLen+txBdRingLen)*SIZEOF(DmaBufDesc) <= MB);
  1051. EnetEnvironment.AllocateUncachedMemory(MB,dev.dmaBdMem);
  1052. bdAddr := dev.dmaBdMem.addr;
  1053. (*
  1054. (*
  1055. allocate 2 pages (each page is 1 MBytes) of memory in Heaps for
  1056. mapping one full page uncached without affecting any adjacent data
  1057. *)
  1058. NEW(dev.dmaBdMem,2*MB);
  1059. bdAddr := ADDRESSOF(dev.dmaBdMem[0]);
  1060. bdAddr := bdAddr + (MB - bdAddr MOD MB); (* align to 1 MB boundary *)
  1061. ASSERT(bdAddr MOD MB = 0);
  1062. Machine.DisableDCacheRange(bdAddr,MB);
  1063. *)
  1064. IF EnableTrace THEN Trace.StringLn("bdAddr=0x" & Trace.Hx(bdAddr,8)) END;
  1065. (*
  1066. RX buffer descriptor ring
  1067. *)
  1068. NEW(dev.rxBdRing,rxBdRingLen);
  1069. FOR i := 0 TO rxBdRingLen-1 DO
  1070. NEW(dev.rxBdRing[i]);
  1071. dev.rxBdRing[i].dmaBd := bdAddr;
  1072. dev.rxBdRing[i].packet := NIL;
  1073. INC(bdAddr,SIZEOF(DmaBufDesc));
  1074. END;
  1075. FOR i := 0 TO rxBdRingLen-2 DO
  1076. dev.rxBdRing[i].next := dev.rxBdRing[i+1];
  1077. END;
  1078. dev.rxBdRing[rxBdRingLen-1].next := dev.rxBdRing[0];
  1079. dev.rxBdRingStart := dev.rxBdRing[0];
  1080. dev.rxBdRingEnd := dev.rxBdRing[rxBdRingLen-1];
  1081. dev.lastRxBd := dev.rxBdRingStart;
  1082. (*
  1083. TX buffer descriptor ring
  1084. *)
  1085. NEW(dev.txBdRing,txBdRingLen);
  1086. FOR i := 0 TO txBdRingLen-1 DO
  1087. NEW(dev.txBdRing[i]);
  1088. dev.txBdRing[i].dmaBd := bdAddr;
  1089. dev.txBdRing[i].packet := NIL;
  1090. INC(bdAddr,SIZEOF(DmaBufDesc));
  1091. END;
  1092. FOR i := 0 TO txBdRingLen-2 DO
  1093. dev.txBdRing[i].next := dev.txBdRing[i+1];
  1094. END;
  1095. dev.txBdRing[txBdRingLen-1].next := dev.txBdRing[0];
  1096. dev.txBdRingStart := dev.txBdRing[0];
  1097. dev.txBdRingEnd := dev.txBdRing[txBdRingLen-1];
  1098. dev.firstTxBd := dev.txBdRingStart;
  1099. dev.lastTxBd := dev.txBdRingStart;
  1100. IF dev.id = 0 THEN
  1101. EnetEnvironment.InstallInterruptHandler(InterruptHandlerGem0,GemIrq0);
  1102. ELSE
  1103. EnetEnvironment.InstallInterruptHandler(InterruptHandlerGem1,GemIrq1);
  1104. END;
  1105. res := 0;
  1106. RETURN TRUE;
  1107. END InitDma;
  1108. (*
  1109. Configure DMA engine of a GEM device used just before starting
  1110. *)
  1111. PROCEDURE ConfigureDma(dev: LinkDevice; VAR res: LONGINT): BOOLEAN;
  1112. VAR
  1113. packet: EnetBase.Packet;
  1114. bd: BufDesc;
  1115. i: Int;
  1116. BEGIN
  1117. (* setup AHB burst size to INCR16 for higher performance *)
  1118. dev.regs.dma_cfg := S.MSK(dev.regs.dma_cfg,-DMACR_INCR16_AHB_BURST-1) + DMACR_INCR16_AHB_BURST;
  1119. (*
  1120. move packets from received packet buffers to the RX packet pool
  1121. *)
  1122. WHILE EnetBase.PacketFifoGet(dev.recvPackets0,packet) DO
  1123. ASSERT(~packet.ownedByUser & ~packet.ownedByDev);
  1124. ASSERT(EnetBase.PacketFifoPut(dev.rxPacketPool,packet));
  1125. END;
  1126. WHILE EnetBase.PacketFifoGet(dev.recvPackets,packet) DO
  1127. ASSERT(~packet.ownedByUser & ~packet.ownedByDev);
  1128. ASSERT(EnetBase.PacketFifoPut(dev.rxPacketPool,packet));
  1129. END;
  1130. ASSERT(dev.recvPackets0.count = 0);
  1131. ASSERT(dev.recvPackets.count = 0);
  1132. (*
  1133. assure that all RX BDs have packets assigned
  1134. *)
  1135. FOR i := 0 TO LEN(dev.rxBdRing)-1 DO
  1136. bd := dev.rxBdRing[i];
  1137. IF bd.packet = NIL THEN
  1138. IF EnetBase.PacketFifoGet(dev.rxPacketPool,bd.packet) THEN
  1139. bd.packet.ownedByDev := TRUE;
  1140. ELSE
  1141. IF EnableTrace THEN
  1142. Trace.StringLn("not enough packets in the RX packet pool");
  1143. END;
  1144. res := EnetBase.ErrRxPacketPoolEmpty;
  1145. RETURN FALSE;
  1146. END;
  1147. ELSE
  1148. ASSERT(bd.packet.ownerPool = dev.rxPacketPool);
  1149. END;
  1150. ASSERT(~bd.packet.ownedByUser);
  1151. ASSERT(bd.packet.ownedByDev);
  1152. END;
  1153. i := LEN(dev.rxBdRing) + dev.rxPacketPool.count;
  1154. IF i < LEN(dev.rxPacketPool.packets) THEN
  1155. Trace.StringLn("Warning: RX packet leakage is detected, packet pool size is " & LEN(dev.rxPacketPool.packets) & " while actual number of packets is " & i);
  1156. END;
  1157. (*
  1158. move packets from the TX BD packets to the owner pool (txPacketPool or rxPacketPool)
  1159. *)
  1160. FOR i := 0 TO LEN(dev.txBdRing)-1 DO
  1161. bd := dev.txBdRing[i];
  1162. IF bd.packet # NIL THEN
  1163. bd.packet.ownedByDev := FALSE;
  1164. ASSERT(~bd.packet.ownedByUser);
  1165. ASSERT(EnetBase.PacketFifoPut(bd.packet.ownerPool,bd.packet));
  1166. bd.packet := NIL;
  1167. END;
  1168. END;
  1169. IF dev.txPacketPool.count < LEN(dev.txPacketPool.packets) THEN
  1170. Trace.StringLn("Warning: TX packet leakage is detected, packet pool size is " & LEN(dev.txPacketPool.packets) & " while actual number of packets is " & dev.txPacketPool.count);
  1171. END;
  1172. (*
  1173. initialize RX BDs
  1174. *)
  1175. FOR i := 0 TO LEN(dev.rxBdRing)-1 DO
  1176. bd := dev.rxBdRing[i];
  1177. SetRxBd(dev,bd,S.VAL(ADDRESS,bd.packet.ethFrameHdr));
  1178. END;
  1179. dev.lastRxBd := dev.rxBdRingStart;
  1180. (*
  1181. Initialize TX buffer descriptors
  1182. *)
  1183. FOR i := 0 TO LEN(dev.txBdRing)-1 DO
  1184. SetTxBd(dev,dev.txBdRing[i],0,TXBUF_USED_MASK,FALSE);
  1185. END;
  1186. dev.firstTxBd := dev.txBdRingStart;
  1187. dev.lastTxBd := dev.txBdRingStart;
  1188. dev.txBdRingFull := FALSE;
  1189. dev.txBdRingEmpty := TRUE;
  1190. (* data synchronization barrier *)
  1191. CODE
  1192. DSB
  1193. END;
  1194. res := 0;
  1195. RETURN TRUE;
  1196. END ConfigureDma;
  1197. (* interrupt handler common for both GEM interfaces *)
  1198. PROCEDURE InterruptHandler(dev: LinkDevice);
  1199. VAR intrStatus, rxStatus, txStatus, d: UInt;
  1200. BEGIN
  1201. intrStatus := dev.regs.intr_status;
  1202. dev.regs.intr_status := intrStatus; (* clear interrupt status *)
  1203. (*
  1204. Receive complete interrupt
  1205. *)
  1206. IF S.MSK(intrStatus,IXR_FRAMERX_MASK) # 0 THEN
  1207. (* Clear RX status register RX complete indication but preserve error bits if there is any *)
  1208. dev.regs.rx_status := RXSR_FRAMERX_MASK + RXSR_BUFFNA_MASK;
  1209. (*ReceiveCompleteHandler(dev);*)
  1210. END;
  1211. (*
  1212. Transmit complete interrupt
  1213. *)
  1214. IF S.MSK(intrStatus,IXR_TXCOMPL_MASK) # 0 THEN
  1215. (* Clear TX status register TX complete indication but preserve error bits if there is any *)
  1216. dev.regs.tx_status := TXSR_TXCOMPL_MASK + TXSR_USEDREAD_MASK;
  1217. (*TransmitCompleteHandler(dev);*)
  1218. END;
  1219. (*
  1220. Receive error conditions interrupt
  1221. *)
  1222. IF S.MSK(intrStatus,IXR_RX_ERR_MASK) # 0 THEN
  1223. rxStatus := dev.regs.rx_status;
  1224. dev.regs.rx_status := rxStatus; (* clear RX status *)
  1225. (*
  1226. Fix for CR # 692702. Write to bit 18 of net_ctrl register to flush
  1227. a packet out of Rx SRAM upon an error for receive buffer not available
  1228. *)
  1229. IF S.MSK(intrStatus,IXR_RXUSED_MASK) # 0 THEN
  1230. dev.regs.net_ctrl := S.MSK(dev.regs.net_ctrl,-NWCTRL_FLUSH_DPRAM_MASK-1) + NWCTRL_FLUSH_DPRAM_MASK;
  1231. ELSE
  1232. IF S.MSK(intrStatus,IXR_RXOVR_MASK) # 0 THEN
  1233. Trace.StringLn("RXOVR");
  1234. ELSE
  1235. StopController(dev); dev.isActive := FALSE;
  1236. ShowState;
  1237. ShowRegs;
  1238. Trace.StringLn("Error: rx intr error, intrStatus=0x" & Trace.Hx(intrStatus,8) & ", rxStatus=0x" & Trace.Hx(rxStatus,8) & ", stopped the controller");
  1239. END;
  1240. END;
  1241. END;
  1242. (*
  1243. Transmit error conditions interrupt
  1244. When IXR_TXCOMPL_MASK is flaged, IXR_TXUSED_MASK will be asserted the same time.
  1245. Have to distinguish this bit to handle the real error condition.
  1246. *)
  1247. IF (S.MSK(intrStatus,IXR_TX_ERR_MASK) # 0) & (S.MSK(intrStatus,IXR_TXCOMPL_MASK) = 0) THEN
  1248. txStatus := dev.regs.tx_status;
  1249. dev.regs.tx_status := txStatus; (* clear TX status *)
  1250. IF (S.MSK(intrStatus,IXR_TX_ERR_MASK) = IXR_TXUSED_MASK) & (S.MSK(txStatus,TXSR_TXCOMPL_MASK) # 0) THEN
  1251. (*Trace.StringLn("txused-ok");*)
  1252. ELSE
  1253. StopController(dev); dev.isActive := FALSE;
  1254. ShowState;
  1255. ShowRegs;
  1256. Trace.StringLn("Error: tx intr error, intrStatus=0x" & Trace.Hx(intrStatus,8) & ", txStatus=0x" & Trace.Hx(txStatus,8) & ", stopped the controller");
  1257. END;
  1258. END;
  1259. END InterruptHandler;
  1260. (* GEM0 interrupt handler *)
  1261. PROCEDURE InterruptHandlerGem0();
  1262. BEGIN
  1263. InterruptHandler(gem0);
  1264. END InterruptHandlerGem0;
  1265. (* GEM1 interrupt handler *)
  1266. PROCEDURE InterruptHandlerGem1();
  1267. BEGIN
  1268. InterruptHandler(gem1);
  1269. END InterruptHandlerGem1;
  1270. PROCEDURE ReceiveCompleteHandler(dev: LinkDevice);
  1271. BEGIN
  1272. END ReceiveCompleteHandler;
  1273. PROCEDURE TransmitCompleteHandler(dev: LinkDevice);
  1274. BEGIN
  1275. END TransmitCompleteHandler;
  1276. (*!A workaround for a hardware bug
  1277. The EmacPs has a hardware bug (SI# 692601) on the Rx path for heavy Rx traffic.
  1278. Under heavy Rx traffic because of this bug there are times when the Rx path
  1279. becomes unresponsive. The workaround for it is to check for the Rx path for
  1280. traffic (by reading the stats registers regularly). If the stats register
  1281. does not increment for sometime (proving no Rx traffic), the function resets the Rx data path.
  1282. *)
  1283. PROCEDURE ResetRxPathOnNoRxData(dev: LinkDevice);
  1284. VAR d: UInt;
  1285. BEGIN
  1286. d := dev.regs.frames_rx;
  1287. IF (d = 0) & (dev.lastRecvFrmCount = 0) THEN
  1288. dev.regs.net_ctrl := S.MSK(dev.regs.net_ctrl,-NWCTRL_RXEN_MASK-1); (* disable the receiver *)
  1289. dev.regs.net_ctrl := dev.regs.net_ctrl + NWCTRL_RXEN_MASK; (* enable the receiver *)
  1290. END;
  1291. dev.lastRecvFrmCount := d;
  1292. END ResetRxPathOnNoRxData;
  1293. (*
  1294. Setup a TX buffer descriptor
  1295. dataAddr: data address
  1296. *)
  1297. PROCEDURE SetRxBd(dev: LinkDevice; bd: BufDesc; dataAddr: ADDRESS);
  1298. BEGIN
  1299. bd.dmaBd.w1 := 0; (* clear bd stat *)
  1300. IF bd # dev.rxBdRingEnd THEN bd.dmaBd.w0 := dataAddr;
  1301. ELSE bd.dmaBd.w0 := dataAddr+RXBUF_WRAP_MASK; (* reached the end of the ring - tell the hardware about that by asserting the WRAP flag *)
  1302. END;
  1303. END SetRxBd;
  1304. (*
  1305. Setup a TX buffer descriptor
  1306. dataAddr: data address
  1307. dataLen: data length
  1308. isLast: TRUE for setting LAST flag
  1309. *)
  1310. PROCEDURE SetTxBd(dev: LinkDevice; bd: BufDesc; dataAddr: ADDRESS; dataLen: UInt; isLast: BOOLEAN);
  1311. BEGIN
  1312. IF isLast THEN INC(dataLen,TXBUF_LAST_MASK); END;
  1313. IF bd = dev.txBdRingEnd THEN INC(dataLen,TXBUF_WRAP_MASK);
  1314. ELSIF bd = dev.txBdRingEnd THEN INC(dataLen,TXBUF_WRAP_MASK);
  1315. END;
  1316. bd.dmaBd.w0 := dataAddr;
  1317. bd.dmaBd.w1 := dataLen;
  1318. END SetTxBd;
  1319. (*
  1320. Process receive buffer descriptors
  1321. *)
  1322. PROCEDURE ProcessRxBds(dev: LinkDevice);
  1323. VAR
  1324. dataAddr: ADDRESS;
  1325. dataLen: UInt;
  1326. w0, w1: UInt;
  1327. bd: BufDesc;
  1328. t: EnetTiming.Time;
  1329. BEGIN
  1330. bd := dev.lastRxBd;
  1331. w0 := bd.dmaBd.w0;
  1332. WHILE dev.isActive & (S.MSK(w0,RXBUF_NEW_MASK) # 0) DO (* a received packet has been written to the memory and available for processing by the user *)
  1333. (*t := EnetTiming.getTimeCounter();*)
  1334. dataAddr := S.MSK(w0,0xFFFFFFFC); (* data address: mask out first two bits (corresponds to 4 byte alignment) *)
  1335. w1 := bd.dmaBd.w1;
  1336. IF w1 # 0 THEN
  1337. (* prepare the received packet to be processed by the user *)
  1338. bd.packet.dataLen := S.MSK(w1,RXBUF_LEN_MASK); (* received packet data length *)
  1339. bd.packet.ownedByDev := FALSE;
  1340. ASSERT(~bd.packet.ownedByUser);
  1341. EnetEnvironment.InvalidateDCacheRange(S.VAL(ADDRESS,bd.packet.ethFrameHdr),bd.packet.dataLen); (* since packet data was received by DMA it is necessary to invalidate packet data cache *)
  1342. IF EnetBase.PacketFifoPut(dev.recvPackets,bd.packet) THEN
  1343. IF EnetBase.PacketFifoGet(dev.rxPacketPool,bd.packet) THEN
  1344. dataAddr := S.VAL(ADDRESS,bd.packet.ethFrameHdr);
  1345. bd.packet.ownedByDev := TRUE;
  1346. bd.packet := bd.packet;
  1347. ELSE
  1348. bd.packet := NIL; (* packet was moved to dev.recvPackets *)
  1349. StopController(dev); dev.isActive := FALSE;
  1350. Trace.StringLn("Error: rx packet pool is empty, stopped the controller");
  1351. END;
  1352. ELSE
  1353. bd.packet.ownedByDev := TRUE;
  1354. StopController(dev); dev.isActive := FALSE;
  1355. Trace.StringLn("Error: device internal recv packet fifo is full, stopped the controller");
  1356. END;
  1357. ELSE
  1358. StopController(dev); dev.isActive := FALSE;
  1359. Trace.StringLn("Error: rx bd stat is 0, lastRxBd=0x" & Trace.Hx(S.VAL(ADDRESS,dev.lastRxBd.dmaBd),8) & ", stopped the controller");
  1360. END;
  1361. SetRxBd(dev,bd,dataAddr);
  1362. bd := bd.next;
  1363. w0 := bd.dmaBd.w0;
  1364. (*t := EnetTiming.getTimeCounter() - t; Trace.StringLn("receive: " & t);*)
  1365. END;
  1366. dev.lastRxBd := bd;
  1367. END ProcessRxBds;
  1368. (*
  1369. Process packets assigned to transmit buffer descriptors, which have been already trsnamitted by the hardware
  1370. *)
  1371. PROCEDURE ProcessTxBds(dev: LinkDevice);
  1372. VAR packet: EnetBase.Packet;
  1373. BEGIN
  1374. WHILE dev.isActive & CleanupNextTxBd(dev) DO
  1375. END;
  1376. END ProcessTxBds;
  1377. (**
  1378. Setup packet payload
  1379. *)
  1380. PROCEDURE SetPacketPayload*(dev: EnetBase.LinkDevice; packet: EnetBase.Packet; CONST data: ARRAY OF CHAR; offset: Int; flags: SET; VAR res: LONGINT): BOOLEAN;
  1381. VAR payloadLen: Int;
  1382. BEGIN
  1383. payloadLen := packet.dataLen-packet.payloadOffs;
  1384. ASSERT(offset+payloadLen <= LEN(data));
  1385. IF EnetBase.FlagNoDataCopy IN flags THEN
  1386. packet(Packet).numParts := 2;
  1387. packet(Packet).partAddr[0] := ADDRESSOF(data[offset]);
  1388. packet(Packet).partLen[0] := payloadLen;
  1389. ELSE
  1390. S.MOVE(ADDRESSOF(data[offset]),ADDRESSOF(packet.data[packet.payloadOffs+packet.dataOffs]),payloadLen);
  1391. END;
  1392. res := 0;
  1393. RETURN TRUE;
  1394. END SetPacketPayload;
  1395. (*
  1396. Cleanup next TX buffer descriptor released by the hardware
  1397. *)
  1398. PROCEDURE CleanupNextTxBd(dev: LinkDevice): BOOLEAN;
  1399. VAR
  1400. bd: BufDesc;
  1401. packet: EnetBase.Packet;
  1402. BEGIN
  1403. bd := dev.firstTxBd;
  1404. IF dev.txBdRingEmpty THEN RETURN FALSE; END;
  1405. IF S.MSK(bd.dmaBd.w1,TXBUF_USED_MASK) # 0 THEN (* hardware has released the buffer descriptor *)
  1406. IF bd.packet # NIL THEN
  1407. packet := bd.packet;
  1408. bd.packet := NIL;
  1409. WITH packet : Packet DO
  1410. WHILE packet.numParts > 1 DO (*! account for multiple packet parts *)
  1411. bd := bd.next;
  1412. ASSERT(S.MSK(bd.dmaBd.w1,TXBUF_USED_MASK) = 0);
  1413. SetTxBd(dev,bd,0,TXBUF_USED_MASK,FALSE); (* set USED bit not to let the HW to process this BD *)
  1414. DEC(packet.numParts);
  1415. END;
  1416. packet.ownedByDev := FALSE;
  1417. IF EnetBase.ThreadSafe THEN packet.ownerPool.acquire; END;
  1418. ASSERT(EnetBase.PacketFifoPut(packet.ownerPool,packet));
  1419. IF EnetBase.ThreadSafe THEN packet.ownerPool.release; END;
  1420. (* notify the user about the successfull packet transmission *) (*!TODO: consider to move notification to another place (e.g. putting it into a handler FIFO and executing later) *)
  1421. IF packet.txTaskHandler # NIL THEN
  1422. INC(packet.txTaskHandler.res);
  1423. IF packet.txTaskHandler.handle # NIL THEN
  1424. packet.txTaskHandler.handle(packet.txTaskHandler);
  1425. END;
  1426. packet.txTaskHandler := NIL;
  1427. END;
  1428. END;
  1429. END;
  1430. dev.firstTxBd := bd.next;
  1431. dev.txBdRingFull := FALSE;
  1432. IF dev.firstTxBd = dev.lastTxBd THEN dev.txBdRingEmpty := TRUE; END;
  1433. RETURN TRUE;
  1434. END;
  1435. RETURN FALSE;
  1436. END CleanupNextTxBd;
  1437. (*
  1438. Get a free (already released by the hardware) TX buffer descriptor
  1439. *)
  1440. PROCEDURE GetFreeTxBd(dev: LinkDevice; VAR bd: BufDesc): BOOLEAN;
  1441. BEGIN
  1442. bd := dev.lastTxBd;
  1443. IF ~dev.txBdRingFull THEN
  1444. dev.lastTxBd := bd.next;
  1445. IF dev.lastTxBd = dev.firstTxBd THEN dev.txBdRingFull := TRUE; END;
  1446. dev.txBdRingEmpty := FALSE;
  1447. ELSE
  1448. (* wait until BDs become available or timeout has expired *)
  1449. EnetTiming.StartTimer(dev.sendTimeoutTimer);
  1450. WHILE (S.MSK(bd.dmaBd.w1,TXBUF_USED_MASK) = 0) & ~EnetTiming.IsTimerExpired(dev.sendTimeoutTimer) DO END;
  1451. IF CleanupNextTxBd(dev) THEN
  1452. dev.lastTxBd := bd.next;
  1453. IF dev.lastTxBd = dev.firstTxBd THEN dev.txBdRingFull := TRUE; END;
  1454. dev.txBdRingEmpty := FALSE;
  1455. ELSE
  1456. RETURN FALSE;
  1457. END;
  1458. END;
  1459. ASSERT(S.MSK(bd.dmaBd.w1,TXBUF_USED_MASK) # 0);
  1460. ASSERT(bd.packet = NIL);
  1461. RETURN TRUE;
  1462. END GetFreeTxBd;
  1463. (**
  1464. Send a packet
  1465. *)
  1466. PROCEDURE SendPacket*(dev: EnetBase.LinkDevice; packet: EnetBase.Packet; flags: SET; txTaskHandler: EnetBase.TaskHandler; VAR res: Int): BOOLEAN;
  1467. VAR
  1468. bd0, bd1: BufDesc;
  1469. d0, d1: UInt;
  1470. (*t: EnetTiming.Time;*)
  1471. BEGIN
  1472. IF ~dev.isActive THEN res := EnetBase.ErrNotActive; RETURN FALSE; END;
  1473. (*t := EnetTiming.getTimeCounter();*)
  1474. ASSERT(~packet.ownedByUser);
  1475. WITH dev : LinkDevice DO
  1476. IF ~GetFreeTxBd(dev,bd0) THEN
  1477. Trace.StringLn("Error: no more space in TX BD ring");
  1478. res := EnetBase.ErrOutOfResources;
  1479. RETURN FALSE;
  1480. END;
  1481. IF ~(EnetBase.FlagNoDataCopy IN flags) THEN
  1482. (*! flush data cache before committing the buffer descriptor to the hardware *)
  1483. EnetEnvironment.FlushDCacheRange(S.VAL(ADDRESS,packet.ethFrameHdr),packet.dataLen);
  1484. (* commit BD to the hardware *)
  1485. SetTxBd(dev,bd0,S.VAL(ADDRESS,packet.ethFrameHdr),packet.dataLen,TRUE);
  1486. ELSE (* send header and data using separate buffer descriptors *)
  1487. IF ~GetFreeTxBd(dev,bd1) THEN
  1488. Trace.StringLn("Error: no more space in TX BD ring");
  1489. res := EnetBase.ErrOutOfResources;
  1490. RETURN FALSE;
  1491. END;
  1492. (*! flush data cache before committing the buffer descriptor to the hardware *)
  1493. EnetEnvironment.FlushDCacheRange(S.VAL(ADDRESS,packet.ethFrameHdr),packet.payloadOffs);
  1494. IF ~(EnetBase.FlagNoFlushDCache IN flags) THEN
  1495. EnetEnvironment.FlushDCacheRange(packet(Packet).partAddr[0],packet(Packet).partLen[0]);
  1496. END;
  1497. (* commit the BD to the hardware *)
  1498. SetTxBd(dev,bd1,packet(Packet).partAddr[0],packet(Packet).partLen[0],TRUE); (* write the second BD first, so that HW does not start to transmit *)
  1499. SetTxBd(dev,bd0,S.VAL(ADDRESS,packet.ethFrameHdr),packet.payloadOffs,FALSE);
  1500. END;
  1501. bd0.packet := packet;
  1502. packet.ownedByDev := TRUE;
  1503. packet(Packet).txTaskHandler := txTaskHandler;
  1504. (*
  1505. Make sure all pending memory operations get completed
  1506. *)
  1507. CODE
  1508. DSB
  1509. END;
  1510. (* trigger packet transmission - not a problem to start it while it is still transmitting *)
  1511. dev.regs.net_ctrl := S.MSK(dev.regs.net_ctrl,-NWCTRL_STARTTX_MASK-1) + NWCTRL_STARTTX_MASK;
  1512. END;
  1513. res := EnetBase.OpInProgress; (*! indicate that data has not yet been sent *)
  1514. IF txTaskHandler # NIL THEN
  1515. txTaskHandler.res := 0;
  1516. END;
  1517. (*t := EnetTiming.getTimeCounter() - t; Trace.StringLn("send: " & t);*)
  1518. RETURN TRUE;
  1519. END SendPacket;
  1520. PROCEDURE NewPacket*(): EnetBase.Packet;
  1521. VAR
  1522. packet: Packet;
  1523. addr: ADDRESS;
  1524. BEGIN
  1525. NEW(packet);
  1526. NEW(packet.data,RX_BUF_SIZE+DataCacheLineSize);
  1527. (*! required alignment of 4 bytes for the controller and DataCacheLineSize for the cache manipulation *)
  1528. packet.dataOffs := DataCacheLineSize - ADDRESSOF(packet.data[0]) MOD DataCacheLineSize;
  1529. ASSERT(ADDRESSOF(packet.data[packet.dataOffs]) MOD DataCacheLineSize = 0);
  1530. packet.numParts := 1;
  1531. EnetBase.InitPacket(packet);
  1532. RETURN packet;
  1533. END NewPacket;
  1534. (**
  1535. Show the state of Ethernet controller registers
  1536. *)
  1537. PROCEDURE ShowRegs*;
  1538. VAR dev: LinkDevice;
  1539. PROCEDURE ShowReg(CONST name: ARRAY OF CHAR; regAddr: ADDRESS);
  1540. BEGIN
  1541. Trace.StringLn(name & " (0x" & Trace.Hx(regAddr,8) & "): 0x" & Trace.Hx(S.GET32(regAddr),8));
  1542. END ShowReg;
  1543. PROCEDURE Show(dev: LinkDevice);
  1544. BEGIN
  1545. ShowReg("net_ctrl",ADDRESSOF(dev.regs.net_ctrl)); (** 0x00000000 32 mixed 0x00000000 Network Control *)
  1546. ShowReg("net_cfg",ADDRESSOF(dev.regs.net_cfg)); (** 0x00000004 32 rw 0x00080000 Network Configuration *)
  1547. ShowReg("net_status",ADDRESSOF(dev.regs.net_status)); (** 0x00000008 32 ro x Network Status *)
  1548. ShowReg("dma_cfg",ADDRESSOF(dev.regs.dma_cfg)); (** 0x00000010 32 mixed 0x00020784 DMA Configuration *)
  1549. ShowReg("tx_status",ADDRESSOF(dev.regs.tx_status)); (** 0x00000014 32 mixed 0x00000000 Transmit Status *)
  1550. ShowReg("rx_qbar",ADDRESSOF(dev.regs.rx_qbar)); (** 0x00000018 32 mixed 0x00000000 Receive Buffer Queue Base Address *)
  1551. ShowReg("tx_qbar",ADDRESSOF(dev.regs.tx_qbar)); (** 0x0000001C 32 mixed 0x00000000 Transmit Buffer Queue Base Address *)
  1552. ShowReg("rx_status",ADDRESSOF(dev.regs.rx_status)); (** 0x00000020 32 mixed 0x00000000 Receive Status *)
  1553. ShowReg("intr_status",ADDRESSOF(dev.regs.intr_status)); (** 0x00000024 32 mixed 0x00000000 Interrupt Status *)
  1554. ShowReg("intr_en",ADDRESSOF(dev.regs.intr_en)); (** 0x00000028 32 wo x Interrupt Enable *)
  1555. ShowReg("intr_dis",ADDRESSOF(dev.regs.intr_dis)); (** 0x0000002C 32 wo x Interrupt Disable *)
  1556. ShowReg("intr_mask",ADDRESSOF(dev.regs.intr_mask)); (** 0x00000030 32 mixed x Interrupt Mask Status *)
  1557. ShowReg("phy_maint",ADDRESSOF(dev.regs.phy_maint)); (** 0x00000034 32 rw 0x00000000 PHY Maintenance *)
  1558. ShowReg("rx_pauseq",ADDRESSOF(dev.regs.rx_pauseq)); (** 0x00000038 32 ro 0x00000000 Received Pause Quantum *)
  1559. ShowReg("tx_pauseq",ADDRESSOF(dev.regs.tx_pauseq)); (** 0x0000003C 32 rw 0x0000FFFF Transmit Pause Quantum *)
  1560. ShowReg("hash_bot",ADDRESSOF(dev.regs.hash_bot)); (** 0x00000080 32 rw 0x00000000 Hash Register Bottom [31:0] *)
  1561. ShowReg("hash_top",ADDRESSOF(dev.regs.hash_top)); (** 0x00000084 32 rw 0x00000000 Hash Register Top [63:32] *)
  1562. ShowReg("spec_addr1_bot",ADDRESSOF(dev.regs.spec_addr1_bot)); (** 0x00000088 32 rw 0x00000000 Specific Address 1 Bottom [31:0] *)
  1563. ShowReg("spec_addr1_top",ADDRESSOF(dev.regs.spec_addr1_top)); (** 0x0000008C 32 mixed 0x00000000 Specific Address 1 Top [47:32] *)
  1564. ShowReg("spec_addr2_bot",ADDRESSOF(dev.regs.spec_addr2_bot)); (** 0x00000090 32 rw 0x00000000 Specific Address 2 Bottom [31:0] *)
  1565. ShowReg("spec_addr2_top",ADDRESSOF(dev.regs.spec_addr2_top)); (** 0x00000094 32 mixed 0x00000000 Specific Address 2 Top [47:32] *)
  1566. ShowReg("spec_addr3_bot",ADDRESSOF(dev.regs.spec_addr3_bot)); (** 0x00000098 32 rw 0x00000000 Specific Address 3 Bottom [31:0] *)
  1567. ShowReg("spec_addr3_top",ADDRESSOF(dev.regs.spec_addr3_top)); (** 0x0000009C 32 mixed 0x00000000 Specific Address 3 Top [47:32] *)
  1568. ShowReg("spec_addr4_bot",ADDRESSOF(dev.regs.spec_addr4_bot)); (** 0x000000A0 32 rw 0x00000000 Specific Address 4 Bottom [31:0] *)
  1569. ShowReg("spec_addr4_top",ADDRESSOF(dev.regs.spec_addr4_top)); (** 0x000000A4 32 mixed 0x00000000 Specific Address 4 Top [47:32] *)
  1570. ShowReg("type_id_match1",ADDRESSOF(dev.regs.type_id_match1)); (** 0x000000A8 32 mixed 0x00000000 Type ID Match 1 *)
  1571. ShowReg("type_id_match2",ADDRESSOF(dev.regs.type_id_match2)); (** 0x000000AC 32 mixed 0x00000000 Type ID Match 2 *)
  1572. ShowReg("type_id_match3",ADDRESSOF(dev.regs.type_id_match3)); (** 0x000000B0 32 mixed 0x00000000 Type ID Match 3 *)
  1573. ShowReg("type_id_match4",ADDRESSOF(dev.regs.type_id_match4)); (** 0x000000B4 32 mixed 0x00000000 Type ID Match 4 *)
  1574. ShowReg("wake_on_lan",ADDRESSOF(dev.regs.wake_on_lan)); (** 0x000000B8 32 mixed 0x00000000 Wake on LAN Register *)
  1575. ShowReg("ipg_stretch",ADDRESSOF(dev.regs.ipg_stretch)); (** 0x000000BC 32 mixed 0x00000000 IPG stretch register *)
  1576. ShowReg("stacked_vlan",ADDRESSOF(dev.regs.stacked_vlan)); (** 0x000000C0 32 mixed 0x00000000 Stacked VLAN Register *)
  1577. ShowReg("tx_pfc_pause",ADDRESSOF(dev.regs.tx_pfc_pause)); (** 0x000000C4 32 mixed 0x00000000 Transmit PFC Pause Register *)
  1578. ShowReg("spec_addr1_mask_bot",ADDRESSOF(dev.regs.spec_addr1_mask_bot)); (** 0x000000C8 32 rw 0x00000000 Specific Address Mask 1 Bottom [31:0] *)
  1579. ShowReg("spec_addr1_mask_top",ADDRESSOF(dev.regs.spec_addr1_mask_top)); (** 0x000000CC 32 mixed 0x00000000 Specific Address Mask 1 Top [47:32] *)
  1580. ShowReg("module_id",ADDRESSOF(dev.regs.module_id)); (** 0x000000FC 32 ro 0x00020118 Module ID *)
  1581. ShowReg("octets_tx_bot",ADDRESSOF(dev.regs.octets_tx_bot)); (** 0x00000100 32 ro 0x00000000 Octets transmitted [31:0] (in frames without error) *)
  1582. ShowReg("octets_tx_top",ADDRESSOF(dev.regs.octets_tx_top)); (** 0x00000104 32 ro 0x00000000 Octets transmitted [47:32] (in frames without error) *)
  1583. ShowReg("frames_tx",ADDRESSOF(dev.regs.frames_tx)); (** 0x00000108 32 ro 0x00000000 Frames Transmitted *)
  1584. ShowReg("broadcast_frames_tx",ADDRESSOF(dev.regs.broadcast_frames_tx)); (** 0x0000010C 32 ro 0x00000000 Broadcast frames Tx *)
  1585. ShowReg("multi_frames_tx",ADDRESSOF(dev.regs.multi_frames_tx)); (* 0x00000110 32 ro 0x00000000 Multicast frames Tx *)
  1586. ShowReg("pause_frames_tx",ADDRESSOF(dev.regs.pause_frames_tx)); (** 0x00000114 32 ro 0x00000000 Pause frames Tx *)
  1587. ShowReg("frames_64b_tx",ADDRESSOF(dev.regs.frames_64b_tx)); (** 0x00000118 32 ro 0x00000000 Frames Tx, 64-byte length *)
  1588. ShowReg("frames_65to127b_tx",ADDRESSOF(dev.regs.frames_65to127b_tx)); (** 0x0000011C 32 ro 0x00000000 Frames Tx, 65 to 127-byte length *)
  1589. ShowReg("frames_128to255b_tx",ADDRESSOF(dev.regs.frames_128to255b_tx)); (** 0x00000120 32 ro 0x00000000 Frames Tx, 128 to 255-byte length *)
  1590. ShowReg("frames_256to511b_tx",ADDRESSOF(dev.regs.frames_256to511b_tx)); (** 0x00000124 32 ro 0x00000000 Frames Tx, 256 to 511-byte length *)
  1591. ShowReg("frames_512to1023b_tx",ADDRESSOF(dev.regs.frames_512to1023b_tx)); (** 0x00000128 32 ro 0x00000000 Frames Tx, 512 to 1023-byte length *)
  1592. ShowReg("frames_1024to1518b_tx",ADDRESSOF(dev.regs.frames_1024to1518b_tx)); (** 0x0000012C 32 ro 0x00000000 Frame Tx, 1024 to 1518-byte length *)
  1593. ShowReg("tx_under_runs",ADDRESSOF(dev.regs.tx_under_runs)); (** 0x00000134 32 ro 0x00000000 Transmit under runs *)
  1594. ShowReg("single_collisn_frames",ADDRESSOF(dev.regs.single_collisn_frames)); (** 0x00000138 32 ro 0x00000000 Single Collision Frames *)
  1595. ShowReg("multi_collisn_frames",ADDRESSOF(dev.regs.multi_collisn_frames)); (** 0x0000013C 32 ro 0x00000000 Multiple Collision Frames excessive_collisns 0x00000140 32 ro 0x00000000 Excessive Collisions *)
  1596. ShowReg("late_collisns",ADDRESSOF(dev.regs.late_collisns)); (** 0x00000144 32 ro 0x00000000 Late Collisions *)
  1597. ShowReg("deferred_tx_frames",ADDRESSOF(dev.regs.deferred_tx_frames)); (** 0x00000148 32 ro 0x00000000 Deferred Transmission Frames *)
  1598. ShowReg("carrier_sense_errs",ADDRESSOF(dev.regs.carrier_sense_errs)); (** 0x0000014C 32 ro 0x00000000 Carrier Sense Errors. *)
  1599. ShowReg("octets_rx_bot",ADDRESSOF(dev.regs.octets_rx_bot)); (** 0x00000150 32 ro 0x00000000 Octets Received [31:0] *)
  1600. ShowReg("octets_rx_top",ADDRESSOF(dev.regs.octets_rx_top)); (** 0x00000154 32 ro 0x00000000 Octets Received [47:32] *)
  1601. ShowReg("frames_rx",ADDRESSOF(dev.regs.frames_rx)); (** 0x00000158 32 ro 0x00000000 Frames Received *)
  1602. ShowReg("bdcast_fames_rx",ADDRESSOF(dev.regs.bdcast_fames_rx)); (** 0x0000015C 32 ro 0x00000000 Broadcast Frames Rx *)
  1603. ShowReg("multi_frames_rx",ADDRESSOF(dev.regs.multi_frames_rx)); (** 0x00000160 32 ro 0x00000000 Multicast Frames Rx *)
  1604. ShowReg("pause_rx",ADDRESSOF(dev.regs.pause_rx)); (** 0x00000164 32 ro 0x00000000 Pause Frames Rx *)
  1605. ShowReg("frames_64b_rx",ADDRESSOF(dev.regs.frames_64b_rx)); (** 0x00000168 32 ro 0x00000000 Frames Rx, 64-byte length *)
  1606. ShowReg("frames_65to127b_rx",ADDRESSOF(dev.regs.frames_65to127b_rx)); (** 0x0000016C 32 ro 0x00000000 Frames Rx, 65 to 127-byte length *)
  1607. ShowReg("frames_128to255b_rx",ADDRESSOF(dev.regs.frames_128to255b_rx)); (** 0x00000170 32 ro 0x00000000 Frames Rx, 128 to 255-byte length *)
  1608. ShowReg("frames_256to511b_rx",ADDRESSOF(dev.regs.frames_256to511b_rx)); (** 0x00000174 32 ro 0x00000000 Frames Rx, 256 to 511-byte length *)
  1609. ShowReg("frames_512to1023b_rx",ADDRESSOF(dev.regs.frames_512to1023b_rx)); (** 0x00000178 32 ro 0x00000000 Frames Rx, 512 to 1023-byte length *)
  1610. ShowReg("frames_1024to1518b_rx",ADDRESSOF(dev.regs.frames_1024to1518b_rx)); (** 0x0000017C 32 ro 0x00000000 Frames Rx, 1024 to 1518-byte length *)
  1611. ShowReg("undersz_rx",ADDRESSOF(dev.regs.undersz_rx)); (** 0x00000184 32 ro 0x00000000 Undersize frames received *)
  1612. ShowReg("oversz_rx",ADDRESSOF(dev.regs.oversz_rx)); (** 0x00000188 32 ro 0x00000000 Oversize frames received *)
  1613. ShowReg("jab_rx",ADDRESSOF(dev.regs.jab_rx)); (** 0x0000018C 32 ro 0x00000000 Jabbers received *)
  1614. ShowReg("fcs_errors",ADDRESSOF(dev.regs.fcs_errors)); (** 0x00000190 32 ro 0x00000000 Frame check sequence errors *)
  1615. ShowReg("length_field_errors",ADDRESSOF(dev.regs.length_field_errors)); (** 0x00000194 32 ro 0x00000000 Length field frame errors *)
  1616. ShowReg("rx_symbol_errors",ADDRESSOF(dev.regs.rx_symbol_errors)); (** 0x00000198 32 ro 0x00000000 Receive symbol errors *)
  1617. ShowReg("align_errors",ADDRESSOF(dev.regs.align_errors)); (** 0x0000019C 32 ro 0x00000000 Alignment errors *)
  1618. ShowReg("rx_resource_errors",ADDRESSOF(dev.regs.rx_resource_errors)); (** 0x000001A0 32 ro 0x00000000 Receive resource errors *)
  1619. ShowReg("rx_overrun_errors",ADDRESSOF(dev.regs.rx_overrun_errors)); (** 0x000001A4 32 ro 0x00000000 Receive overrun errors *)
  1620. ShowReg("ip_hdr_csum_errors",ADDRESSOF(dev.regs.ip_hdr_csum_errors)); (** 0x000001A8 32 ro 0x00000000 IP header checksum errors *)
  1621. ShowReg("tcp_csum_errors",ADDRESSOF(dev.regs.tcp_csum_errors)); (** 0x000001AC 32 ro 0x00000000 TCP checksum errors *)
  1622. ShowReg("udp_csum_errors",ADDRESSOF(dev.regs.udp_csum_errors)); (** 0x000001B0 32 ro 0x00000000 UDP checksum error *)
  1623. ShowReg("timer_strobe_s",ADDRESSOF(dev.regs.timer_strobe_s)); (** 0x000001C8 32 rw 0x00000000 1588 timer sync strobe seconds *)
  1624. ShowReg("timer_strobe_ns",ADDRESSOF(dev.regs.timer_strobe_ns)); (** 0x000001CC 32 mixed 0x00000000 1588 timer sync strobe nanoseconds *)
  1625. ShowReg("timer_s",ADDRESSOF(dev.regs.timer_s)); (** 0x000001D0 32 rw 0x00000000 1588 timer seconds *)
  1626. ShowReg("timer_ns",ADDRESSOF(dev.regs.timer_ns)); (** 0x000001D4 32 mixed 0x00000000 1588 timer nanoseconds *)
  1627. ShowReg("timer_adjust",ADDRESSOF(dev.regs.timer_adjust)); (** 0x000001D8 32 mixed 0x00000000 1588 timer adjust *)
  1628. ShowReg("timer_incr",ADDRESSOF(dev.regs.timer_incr)); (** 0x000001DC 32 mixed 0x00000000 1588 timer increment *)
  1629. ShowReg("ptp_tx_s",ADDRESSOF(dev.regs.ptp_tx_s)); (** 0x000001E0 32 ro 0x00000000 PTP event frame transmitted seconds *)
  1630. ShowReg("ptp_tx_ns",ADDRESSOF(dev.regs.ptp_tx_ns)); (** 0x000001E4 32 ro 0x00000000 PTP event frame transmitted nanoseconds *)
  1631. ShowReg("ptp_rx_s",ADDRESSOF(dev.regs.ptp_rx_s)); (** 0x000001E8 32 ro 0x00000000 PTP event frame received seconds *)
  1632. ShowReg("ptp_rx_ns",ADDRESSOF(dev.regs.ptp_rx_ns)); (** 0x000001EC 32 ro 0x00000000 PTP event frame received nanoseconds. *)
  1633. ShowReg("ptp_peer_tx_s",ADDRESSOF(dev.regs.ptp_peer_tx_s)); (** 0x000001F0 32 ro 0x00000000 PTP peer event frame transmitted seconds *)
  1634. ShowReg("ptp_peer_tx_ns",ADDRESSOF(dev.regs.ptp_peer_tx_ns)); (** 0x000001F4 32 ro 0x00000000 PTP peer event frame transmitted nanoseconds *)
  1635. ShowReg("ptp_peer_rx_s",ADDRESSOF(dev.regs.ptp_peer_rx_s)); (** 0x000001F8 32 ro 0x00000000 PTP peer event frame received seconds *)
  1636. ShowReg("ptp_peer_rx_ns",ADDRESSOF(dev.regs.ptp_peer_rx_ns)); (** 0x000001FC 32 ro 0x00000000 PTP peer event frame received nanoseconds. *)
  1637. ShowReg("design_cfg2",ADDRESSOF(dev.regs.design_cfg2)); (** 0x00000284 32 ro x Design Configuration 2 *)
  1638. ShowReg("design_cfg3",ADDRESSOF(dev.regs.design_cfg3)); (** 0x00000288 32 ro 0x00000000 Design Configuration 3 *)
  1639. ShowReg("design_cfg4",ADDRESSOF(dev.regs.design_cfg4)); (** 0x0000028C 32 ro 0x00000000 Design Configuration 4 *)
  1640. ShowReg("design_cfg5",ADDRESSOF(dev.regs.design_cfg5)); (** 0x00000290 32 ro x Design Configuration 5 *)
  1641. END Show;
  1642. BEGIN
  1643. IF gem0 # NIL THEN
  1644. Trace.StringLn("");
  1645. Trace.StringLn("GEM0 registers:");
  1646. Show(gem0);
  1647. END;
  1648. IF gem1 # NIL THEN
  1649. Trace.StringLn("");
  1650. Trace.StringLn("GEM1 registers:");
  1651. Show(gem1);
  1652. END;
  1653. END ShowRegs;
  1654. PROCEDURE ShowState*;
  1655. PROCEDURE Show(dev: LinkDevice);
  1656. BEGIN
  1657. Trace.StringLn("isActive=" & dev.isActive);
  1658. Trace.StringLn("phyAddr=" & Trace.Hx(dev.phyAddr,2));
  1659. Trace.StringLn("linkSpeed=" & dev.linkSpeed);
  1660. Trace.StringLn("fullDuplex=" & dev.fullDuplex);
  1661. Trace.StringLn("");
  1662. Trace.StringLn("rxBdRingStart=0x" & Trace.Hx(S.VAL(ADDRESS,dev.rxBdRingStart.dmaBd),8));
  1663. Trace.StringLn("rxBdRingEnd=0x" & Trace.Hx(S.VAL(ADDRESS,dev.rxBdRingEnd.dmaBd),8));
  1664. Trace.StringLn("lastRxBd=0x" & Trace.Hx(S.VAL(ADDRESS,dev.lastRxBd.dmaBd),8));
  1665. Trace.StringLn("");
  1666. Trace.StringLn("rxPacketPool.size=" & LEN(dev.rxPacketPool.packets));
  1667. Trace.StringLn("rxPacketPool.count=" & dev.rxPacketPool.count);
  1668. Trace.StringLn("rxPacketPool.wrPos=" & dev.rxPacketPool.wrPos);
  1669. Trace.StringLn("rxPacketPool.rdPos=" & dev.rxPacketPool.rdPos);
  1670. Trace.StringLn("");
  1671. Trace.StringLn("recvPackets.size=" & LEN(dev.recvPackets.packets));
  1672. Trace.StringLn("recvPackets.count=" & dev.recvPackets.count);
  1673. Trace.StringLn("recvPackets.wrPos=" & dev.recvPackets.wrPos);
  1674. Trace.StringLn("recvPackets.rdPos=" & dev.recvPackets.rdPos);
  1675. Trace.StringLn("");
  1676. Trace.StringLn("txBdRingStart=0x" & Trace.Hx(S.VAL(ADDRESS,dev.txBdRingStart.dmaBd),8));
  1677. Trace.StringLn("txBdRingEnd=0x" & Trace.Hx(S.VAL(ADDRESS,dev.txBdRingEnd.dmaBd),8));
  1678. Trace.StringLn("firstTxBd=0x" & Trace.Hx(S.VAL(ADDRESS,dev.firstTxBd.dmaBd),8));
  1679. Trace.StringLn("lastTxBd=0x" & Trace.Hx(S.VAL(ADDRESS,dev.lastTxBd.dmaBd),8));
  1680. Trace.StringLn("txBdRingFull=" & dev.txBdRingFull);
  1681. Trace.StringLn("txBdRingEmpty=" & dev.txBdRingEmpty);
  1682. Trace.StringLn("");
  1683. Trace.StringLn("txPacketPool.size=" & LEN(dev.txPacketPool.packets));
  1684. Trace.StringLn("txPacketPool.count=" & dev.txPacketPool.count);
  1685. Trace.StringLn("txPacketPool.wrPos=" & dev.txPacketPool.wrPos);
  1686. Trace.StringLn("txPacketPool.rdPos=" & dev.txPacketPool.rdPos);
  1687. END Show;
  1688. BEGIN
  1689. IF gem0 # NIL THEN
  1690. Trace.StringLn("");
  1691. Trace.StringLn("GEM0 link device state:");
  1692. Show(gem0);
  1693. END;
  1694. IF gem1 # NIL THEN
  1695. Trace.StringLn("");
  1696. Trace.StringLn("GEM1 link device state:");
  1697. Show(gem1);
  1698. END;
  1699. END ShowState;
  1700. (*
  1701. (**
  1702. Show the content of a buffer descriptor
  1703. syntax
  1704. ShowRxBd gemId bdType bdAddr
  1705. where
  1706. gemId: GEM controller ID (0 or 1)
  1707. bdType: type of the buffer descriptor ("rx" or "tx")
  1708. bdAddr: buffer descriptor address
  1709. *)
  1710. PROCEDURE ShowBd*(context: Commands.Context);
  1711. VAR
  1712. gemId, addr: Int;
  1713. bdType: ARRAY 8 OF CHAR;
  1714. bdAddr: ADDRESS;
  1715. dev: LinkDevice;
  1716. BEGIN
  1717. IF ~context.arg.GetInteger(gemId,FALSE) OR ~context.arg.GetString(bdType) OR ~context.arg.GetInteger(addr,TRUE) THEN
  1718. context.error.String('GEM controller ID (0 or 1), buffer descriptor type ("rx" or "tx") and buffer descriptor address are required');
  1719. context.result := 1;
  1720. RETURN;
  1721. END;
  1722. IF (gemId < 0) OR (gemId > 1) THEN
  1723. context.error.String("invalid GEM controller ID (0 or 1)");
  1724. context.result := 1;
  1725. RETURN;
  1726. END;
  1727. IF (bdType # "rx") & (bdType # "tx") THEN
  1728. context.error.String('invalid buffer descriptor type ("rx" or "tx")');
  1729. context.result := 1;
  1730. RETURN;
  1731. END;
  1732. IF gemId = 0 THEN dev := gem0; ELSE dev := gem1; END;
  1733. bdAddr := addr;
  1734. IF (bdAddr < S.VAL(ADDRESS,dev.rxBdRingStart.dmaBd)) OR (bdAddr > S.VAL(ADDRESS,dev.rxBdRingEnd.dmaBd)) OR (bdAddr MOD SIZEOF(DmaBufDesc) # 0) THEN
  1735. context.error.String("invalid buffer descriptor address");
  1736. context.result := 1;
  1737. RETURN;
  1738. END;
  1739. Trace.StringLn("BD dword0=0x" & Trace.Hx(S.GET32(bdAddr+BD_ADDR_OFFSET),8));
  1740. Trace.StringLn("BD dword1=0x" & Trace.Hx(S.GET32(bdAddr+BD_STAT_OFFSET),8));
  1741. END ShowBd;
  1742. *)
  1743. PROCEDURE InitMod;
  1744. BEGIN
  1745. END InitMod;
  1746. BEGIN
  1747. ASSERT(SIZEOF(EnetBase.UInt) = 4);
  1748. InitMod;
  1749. END EnetEmacPs7.