fec_ecat.c
Go to the documentation of this file.
1 /******************************************************************************
2 * * *** ***
3 * *** *** ***
4 * *** **** ********** *** ***** *** **** *****
5 * ********* ********** *** ********* ************ *********
6 * **** *** *** *** *** **** ***
7 * *** *** ****** *** *********** *** **** *****
8 * *** *** ****** *** ************* *** **** *****
9 * *** **** **** *** *** *** **** ***
10 * *** ******* ***** ************** ************* *********
11 * *** ***** *** ******* ** ** ****** *****
12 * t h e r e a l t i m e t a r g e t e x p e r t s
13 *
14 * http://www.rt-labs.com
15 * Copyright (C) 2007. rt-labs AB, Sweden. All rights reserved.
16 *------------------------------------------------------------------------------
17 * $Id: fec_ecat.c 138 2014-04-11 09:11:48Z rtlfrm $
18 *------------------------------------------------------------------------------
19 */
20 
21 #include "fec_ecat.h"
22 
23 #include <dev.h>
24 #include <kern.h>
25 #include <string.h>
26 #include <uassert.h>
27 #include <eth/fec_buffer.h>
28 #include <eth/phy/mii.h>
29 #include <bsp.h>
30 #include <config.h>
31 
32 #undef RTK_DEBUG /* Print debugging info? */
33 #undef RTK_DEBUG_DATA /* Print packets? */
34 
35 #ifdef RTK_DEBUG
36 #define DPRINT(...) rprintp ("FEC: "__VA_ARGS__)
37 #else
38 #define DPRINT(...)
39 #endif /* DEBUG */
40 
41 #ifdef RTK_DEBUG_DATA
42 #define DUMP_PACKET(p, l) fec_ecat_dump_packet (p, l)
43 #else
44 #define DUMP_PACKET(p, l)
45 #endif /* RTK_DEBUG_DATA */
46 
47 #define ETHERNET_FCS_SIZE_IN_BYTES 4 /* Frame Check Sequence (32-bit CRC) */
48 
49 #define DELAY(ms) task_delay (tick_from_ms (ms) + 1)
50 
51 #define ETH_PHY_ADDRESS 0x1 /* Default jumper setting on TWR-K60F */
52 
53 #define NUM_BUFFERS 2
54 #define FEC_ALLIGNED __attribute__((section(".dma"),aligned(16)))
55 
56 /*
57  * "The device's system clock is connected to the module clock,
58  * as named in the Ethernet chapter. The minimum system clock frequency
59  * for 100 Mbps operation is 25 MHz."
60  *
61  * - Kinetis K60 manual ch. 3.9.1.1 "Ethernet Clocking Options"
62  */
63 #define FEC_MIN_MODULE_CLOCK_Hz (25 * 1000 * 1000)
64 
65 /* Note that the core clock and the system clock has the same clock frequency */
66 #define FEC_MODULE_CLOCK_Hz CFG_IPG_CLOCK
67 
68 //----------------------------------------------------------------------------//
69 
70 typedef struct fec_mac_t
71 {
72  uint32_t lower; /* octets 0, 1, 2, 3 */
73  uint32_t upper; /* octets 4, 5 */
74 } fec_mac_t;
75 
76 /* Message Information Block (MIB) Counters */
77 typedef struct fec_mib
78 {
79  uint32_t rmon_t_drop; /* MBAR_ETH + 0x200 */
80  uint32_t rmon_t_packets; /* MBAR_ETH + 0x204 */
81  uint32_t rmon_t_bc_pkt; /* MBAR_ETH + 0x208 */
82  uint32_t rmon_t_mc_pkt; /* MBAR_ETH + 0x20C */
83  uint32_t rmon_t_crc_align; /* MBAR_ETH + 0x210 */
84  uint32_t rmon_t_undersize; /* MBAR_ETH + 0x214 */
85  uint32_t rmon_t_oversize; /* MBAR_ETH + 0x218 */
86  uint32_t rmon_t_frag; /* MBAR_ETH + 0x21C */
87  uint32_t rmon_t_jab; /* MBAR_ETH + 0x220 */
88  uint32_t rmon_t_col; /* MBAR_ETH + 0x224 */
89  uint32_t rmon_t_p64; /* MBAR_ETH + 0x228 */
90  uint32_t rmon_t_p65to127; /* MBAR_ETH + 0x22C */
91  uint32_t rmon_t_p128to255; /* MBAR_ETH + 0x230 */
92  uint32_t rmon_t_p256to511; /* MBAR_ETH + 0x234 */
93  uint32_t rmon_t_p512to1023; /* MBAR_ETH + 0x238 */
94  uint32_t rmon_t_p1024to2047; /* MBAR_ETH + 0x23C */
95  uint32_t rmon_t_p_gte2048; /* MBAR_ETH + 0x240 */
96  uint32_t rmon_t_octets; /* MBAR_ETH + 0x244 */
97  uint32_t ieee_t_drop; /* MBAR_ETH + 0x248 */
98  uint32_t ieee_t_frame_ok; /* MBAR_ETH + 0x24C */
99  uint32_t ieee_t_1col; /* MBAR_ETH + 0x250 */
100  uint32_t ieee_t_mcol; /* MBAR_ETH + 0x254 */
101  uint32_t ieee_t_def; /* MBAR_ETH + 0x258 */
102  uint32_t ieee_t_lcol; /* MBAR_ETH + 0x25C */
103  uint32_t ieee_t_excol; /* MBAR_ETH + 0x260 */
104  uint32_t ieee_t_macerr; /* MBAR_ETH + 0x264 */
105  uint32_t ieee_t_cserr; /* MBAR_ETH + 0x268 */
106  uint32_t ieee_t_sqe; /* MBAR_ETH + 0x26C */
107  uint32_t t_fdxfc; /* MBAR_ETH + 0x270 */
108  uint32_t ieee_t_octets_ok; /* MBAR_ETH + 0x274 */
109  uint32_t res13[2]; /* MBAR_ETH + 0x278-27C */
110  uint32_t rmon_r_drop; /* MBAR_ETH + 0x280 */
111  uint32_t rmon_r_packets; /* MBAR_ETH + 0x284 */
112  uint32_t rmon_r_bc_pkt; /* MBAR_ETH + 0x288 */
113  uint32_t rmon_r_mc_pkt; /* MBAR_ETH + 0x28C */
114  uint32_t rmon_r_crc_align; /* MBAR_ETH + 0x290 */
115  uint32_t rmon_r_undersize; /* MBAR_ETH + 0x294 */
116  uint32_t rmon_r_oversize; /* MBAR_ETH + 0x298 */
117  uint32_t rmon_r_frag; /* MBAR_ETH + 0x29C */
118  uint32_t rmon_r_jab; /* MBAR_ETH + 0x2A0 */
119  uint32_t rmon_r_resvd_0; /* MBAR_ETH + 0x2A4 */
120  uint32_t rmon_r_p64; /* MBAR_ETH + 0x2A8 */
121  uint32_t rmon_r_p65to127; /* MBAR_ETH + 0x2AC */
122  uint32_t rmon_r_p128to255; /* MBAR_ETH + 0x2B0 */
123  uint32_t rmon_r_p256to511; /* MBAR_ETH + 0x2B4 */
124  uint32_t rmon_r_p512to1023; /* MBAR_ETH + 0x2B8 */
125  uint32_t rmon_r_p1024to2047; /* MBAR_ETH + 0x2BC */
126  uint32_t rmon_r_p_gte2048; /* MBAR_ETH + 0x2C0 */
127  uint32_t rmon_r_octets; /* MBAR_ETH + 0x2C4 */
128  uint32_t ieee_r_drop; /* MBAR_ETH + 0x2C8 */
129  uint32_t ieee_r_frame_ok; /* MBAR_ETH + 0x2CC */
130  uint32_t ieee_r_crc; /* MBAR_ETH + 0x2D0 */
131  uint32_t ieee_r_align; /* MBAR_ETH + 0x2D4 */
132  uint32_t r_macerr; /* MBAR_ETH + 0x2D8 */
133  uint32_t r_fdxfc; /* MBAR_ETH + 0x2DC */
134  uint32_t ieee_r_octets_ok; /* MBAR_ETH + 0x2E0 */
135  uint32_t res14[7]; /* MBAR_ETH + 0x2E4-2FC */
136 } fec_mib_t;
137 
138 COMPILETIME_ASSERT (sizeof (fec_mib_t) == 0x100);
139 
140 /* Register read/write struct */
141 typedef struct reg_fec
142 {
149  uint32_t resv2[3];
151  uint32_t resv3[6];
154  uint32_t resv4[7];
156  uint32_t resv5[7];
158  uint32_t resv6[15];
160  uint32_t resv7[7];
161  fec_mac_t pa; /* Physical address. PALR/PAUR */
163  uint32_t resv8[10];
168  uint32_t resv9[7];
173  uint32_t resv11[11];
178  uint32_t rx_section_full; /* Not present on all controllers */
179  uint32_t rx_section_empty; /* Not present on all controllers */
180  uint32_t rx_almost_empty; /* Not present on all controllers */
181  uint32_t rx_almost_full; /* Not present on all controllers */
182  uint32_t tx_section_empty; /* Not present on all controllers */
183  uint32_t tx_almost_empty; /* Not present on all controllers */
184  uint32_t tx_almost_full; /* Not present on all controllers */
185  uint32_t resv12[21];
186  const fec_mib_t mib;
187  uint32_t fec_miigsk_cfgr; /* Not present on all controllers */
189  uint32_t fec_miigsk_enr; /* Not present on all controllers */
190  uint32_t resv15[0x7d];
191  fec_mac_t smac[4]; /* Not present on all controllers */
192 } reg_fec_t;
193 
194 COMPILETIME_ASSERT (offsetof (reg_fec_t, emrbr) == 0x188);
195 COMPILETIME_ASSERT (offsetof (reg_fec_t, tx_almost_full) == 0x1A8);
196 COMPILETIME_ASSERT (offsetof (reg_fec_t, fec_miigsk_cfgr) == 0x300);
197 COMPILETIME_ASSERT (offsetof (reg_fec_t, smac) == 0x500);
198 COMPILETIME_ASSERT (offsetof (reg_fec_t, smac[3]) == 0x518);
199 
200 //----------------------------------------------------------------------------//
201 
202 /* Bit definitions and macros for FEC_EIR */
203 #define FEC_EIR_CLEAR_ALL (0xFFF80000)
204 #define FEC_EIR_HBERR (0x80000000)
205 #define FEC_EIR_BABR (0x40000000)
206 #define FEC_EIR_BABT (0x20000000)
207 #define FEC_EIR_GRA (0x10000000)
208 #define FEC_EIR_TXF (0x08000000)
209 #define FEC_EIR_TXB (0x04000000)
210 #define FEC_EIR_RXF (0x02000000)
211 #define FEC_EIR_RXB (0x01000000)
212 #define FEC_EIR_MII (0x00800000)
213 #define FEC_EIR_EBERR (0x00400000)
214 #define FEC_EIR_LC (0x00200000)
215 #define FEC_EIR_RL (0x00100000)
216 #define FEC_EIR_UN (0x00080000)
217 
218 /* Bit definitions and macros for FEC_RDAR */
219 #define FEC_RDAR_R_DES_ACTIVE (0x01000000)
220 
221 /* Bit definitions and macros for FEC_TDAR */
222 #define FEC_TDAR_X_DES_ACTIVE (0x01000000)
223 
224 /* Bit definitions and macros for FEC_ECR */
225 #define FEC_ECR_DBSWP (0x00000100)
226 #define FEC_ECR_ETHER_EN (0x00000002)
227 #define FEC_ECR_RESET (0x00000001)
228 
229 /* Bit definitions and macros for FEC_MMFR */
230 #define FEC_MMFR_DATA(x) (((x)&0xFFFF))
231 #define FEC_MMFR_ST(x) (((x)&0x03)<<30)
232 #define FEC_MMFR_ST_01 (0x40000000)
233 #define FEC_MMFR_OP_RD (0x20000000)
234 #define FEC_MMFR_OP_WR (0x10000000)
235 #define FEC_MMFR_PA(x) (((x)&0x1F)<<23)
236 #define FEC_MMFR_RA(x) (((x)&0x1F)<<18)
237 #define FEC_MMFR_TA(x) (((x)&0x03)<<16)
238 #define FEC_MMFR_TA_10 (0x00020000)
239 
240 /* Bit definitions and macros for FEC_MSCR */
241 #define FEC_MSCR_DIS_PREAMBLE (0x00000080)
242 #define FEC_MSCR_MII_SPEED(x) (((x)&0x3F)<<1)
243 
244 /* Bit definitions and macros for FEC_MIBC */
245 #define FEC_MIBC_MIB_DISABLE (0x80000000)
246 #define FEC_MIBC_MIB_IDLE (0x40000000)
247 
248 /* Bit definitions and macros for FEC_RCR */
249 #define FEC_RCR_GRS (0x80000000)
250 #define FEC_RCR_NO_LGTH_CHECK (0x40000000)
251 #define FEC_RCR_MAX_FL(x) (((x)&0x7FF)<<16)
252 #define FEC_RCR_CNTL_FRM_ENA (0x00008000)
253 #define FEC_RCR_CRC_FWD (0x00004000)
254 #define FEC_RCR_PAUSE_FWD (0x00002000)
255 #define FEC_RCR_PAD_EN (0x00001000)
256 #define FEC_RCR_RMII_ECHO (0x00000800)
257 #define FEC_RCR_RMII_LOOP (0x00000400)
258 #define FEC_RCR_RMII_10T (0x00000200)
259 #define FEC_RCR_RMII_MODE (0x00000100)
260 #define FEC_RCR_SGMII_ENA (0x00000080)
261 #define FEC_RCR_RGMII_ENA (0x00000040)
262 #define FEC_RCR_FCE (0x00000020)
263 #define FEC_RCR_BC_REJ (0x00000010)
264 #define FEC_RCR_PROM (0x00000008)
265 #define FEC_RCR_MII_MODE (0x00000004)
266 #define FEC_RCR_DRT (0x00000002)
267 #define FEC_RCR_LOOP (0x00000001)
268 
269 /* Bit definitions and macros for FEC_TCR */
270 #define FEC_TCR_RFC_PAUSE (0x00000010)
271 #define FEC_TCR_TFC_PAUSE (0x00000008)
272 #define FEC_TCR_FDEN (0x00000004)
273 #define FEC_TCR_HBC (0x00000002)
274 #define FEC_TCR_GTS (0x00000001)
275 
276 /* Bit definitions and macros for FEC_PAUR */
277 #define FEC_PAUR_PADDR2(x) (((x)&0xFFFF)<<16)
278 #define FEC_PAUR_TYPE(x) ((x)&0xFFFF)
279 
280 /* Bit definitions and macros for FEC_OPD */
281 #define FEC_OPD_PAUSE_DUR(x) (((x)&0x0000FFFF)<<0)
282 #define FEC_OPD_OPCODE(x) (((x)&0x0000FFFF)<<16)
283 
284 /* Bit definitions and macros for FEC_TFWR */
285 #define FEC_TFWR_STR_FWD BIT (8) /* Present on ENET but not on FEC */
286 #define FEC_TFWR_X_WMRK(x) ((x)&0x03)
287 #define FEC_TFWR_X_WMRK_64 (0x01)
288 #define FEC_TFWR_X_WMRK_128 (0x02)
289 #define FEC_TFWR_X_WMRK_192 (0x03)
290 
291 /* Bit definitions and macros for FEC_FRBR */
292 #define FEC_FRBR_R_BOUND(x) (((x)&0xFF)<<2)
293 
294 /* Bit definitions and macros for FEC_FRSR */
295 #define FEC_FRSR_R_FSTART(x) (((x)&0xFF)<<2)
296 
297 /* Bit definitions and macros for FEC_ERDSR */
298 #define FEC_ERDSR_R_DES_START(x) (((x)&0x3FFFFFFF)<<2)
299 
300 /* Bit definitions and macros for FEC_ETDSR */
301 #define FEC_ETDSR_X_DES_START(x) (((x)&0x3FFFFFFF)<<2)
302 
303 /* Bit definitions and macros for FEC_EMRBR */
304 #define FEC_EMRBR_R_BUF_SIZE(x) (((x)&0x7F)<<4)
305 
306 //----------------------------------------------------------------------------//
307 
308 /* the defines of MII operation */
309 #define FEC_MII_ST 0x40000000
310 #define FEC_MII_OP_OFF 28
311 #define FEC_MII_OP_MASK 0x03
312 #define FEC_MII_OP_RD 0x02
313 #define FEC_MII_OP_WR 0x01
314 #define FEC_MII_PA_OFF 23
315 #define FEC_MII_PA_MASK 0xFF
316 #define FEC_MII_RA_OFF 18
317 #define FEC_MII_RA_MASK 0xFF
318 #define FEC_MII_TA 0x00020000
319 #define FEC_MII_DATA_OFF 0
320 #define FEC_MII_DATA_MASK 0x0000FFFF
321 
322 #define FEC_MII_FRAME (FEC_MII_ST | FEC_MII_TA)
323 #define FEC_MII_OP(x) (((x) & FEC_MII_OP_MASK) << FEC_MII_OP_OFF)
324 #define FEC_MII_PA(pa) (((pa) & FEC_MII_PA_MASK) << FEC_MII_PA_OFF)
325 #define FEC_MII_RA(ra) (((ra) & FEC_MII_RA_MASK) << FEC_MII_RA_OFF)
326 #define FEC_MII_SET_DATA(v) (((v) & FEC_MII_DATA_MASK) << FEC_MII_DATA_OFF)
327 #define FEC_MII_GET_DATA(v) (((v) >> FEC_MII_DATA_OFF) & FEC_MII_DATA_MASK)
328 #define FEC_MII_READ(pa, ra) ((FEC_MII_FRAME | FEC_MII_OP(FEC_MII_OP_RD)) |\
329  FEC_MII_PA(pa) | FEC_MII_RA(ra))
330 #define FEC_MII_WRITE(pa, ra, v) (FEC_MII_FRAME | FEC_MII_OP(FEC_MII_OP_WR)|\
331  FEC_MII_PA(pa) | FEC_MII_RA(ra) | FEC_MII_SET_DATA(v))
332 
333 #define FEC_MII_TIMEOUT 10 // 1 * 10 ms
334 #define FEC_MII_TICK 1 // 1 ms
335 
336 //----------------------------------------------------------------------------//
337 
338 /* Ethernet Transmit and Receive Buffers */
339 #define PKT_MAXBUF_SIZE 1518
340 
341 //----------------------------------------------------------------------------//
342 
343 typedef enum fec_phy_inteface
344 {
357 
358 typedef struct fec_cfg
359 {
362  fec_buffer_bd_t * tx_bd_base;
363  fec_buffer_bd_t * rx_bd_base;
364  fec_phy_inteface_t phy_interface;
365 } fec_cfg_t;
366 
367 typedef struct fec
368 {
370  fec_buffer_bd_t * tx_bd_base;
371  fec_buffer_bd_t * rx_bd_base;
372  volatile reg_fec_t *base;
373  phy_t * phy;
374  fec_phy_inteface_t phy_interface;
375 } fec_t;
376 
377 /* Buffer descriptors. */
378 static fec_buffer_bd_t fec_tx_bd[NUM_BUFFERS] FEC_ALLIGNED;
379 static fec_buffer_bd_t fec_rx_bd[NUM_BUFFERS] FEC_ALLIGNED;
380 
381 /* Data buffers. */
382 static uint8_t fec_tx_data[NUM_BUFFERS * TX_BUFFER_SIZE] FEC_ALLIGNED;
383 static uint8_t fec_rx_data[NUM_BUFFERS * RX_BUFFER_SIZE] FEC_ALLIGNED;
384 
385 static fec_t *fec;
386 
387 //----------------------------------------------------------------------------//
388 
389 #ifdef RTK_DEBUG
390 const char * fec_ecat_link_duplex_name (uint8_t link_state)
391 {
392  if (link_state & PHY_LINK_OK)
393  {
394  if (link_state & PHY_LINK_FULL_DUPLEX)
395  {
396  return "full duplex";
397  }
398  else
399  {
400  return "half duplex";
401  }
402  }
403  else
404  {
405  return "no duplex (link down)";
406  }
407 }
408 
409 const char * fec_ecat_link_speed_name (uint8_t link_state)
410 {
411  if (link_state & PHY_LINK_OK)
412  {
413  if (link_state & PHY_LINK_10MBIT)
414  {
415  return "10 Mbps";
416  }
417  else if (link_state & PHY_LINK_100MBIT)
418  {
419  return "100 Mbps";
420  }
421  else if (link_state & PHY_LINK_1000MBIT)
422  {
423  return "1 Gbps";
424  }
425  else
426  {
427  return "unknown speed";
428  }
429  }
430  else
431  {
432  return "0 Mbps (link down)";
433  }
434 }
435 #endif /* RTK_DEBUG */
436 
437 #ifdef RTK_DEBUG_DATA
438 #include <ctype.h>
439 static void fec_ecat_dump_packet (const uint8_t * payload, size_t len)
440 {
441  size_t i, j, n;
442  char s[80];
443 
444  ASSERT (payload != NULL);
445 
446  for (i = 0; i < len; i += 16)
447  {
448  n = 0;
449  for (j = 0; j < 16 && (i + j) < len; j++)
450  {
451  ASSERT (n <= sizeof(s));
452  n += rsnprintf (s + n, sizeof(s) - n, "%02x ", payload[i + j]);
453  }
454  for (; j < 16; j++)
455  {
456  ASSERT (n <= sizeof(s));
457  n += rsnprintf (s + n, sizeof(s) - n, " ");
458  }
459  ASSERT (n <= sizeof(s));
460  n += rsnprintf (s + n, sizeof(s) - n, "|");
461  for (j = 0; j < 16 && (i + j) < len; j++)
462  {
463  uint8_t c = payload[i + j];
464  c = (isprint (c)) ? c : '.';
465  ASSERT (n <= sizeof(s));
466  n += rsnprintf (s + n, sizeof(s) - n, "%c", c);
467  }
468  ASSERT (n <= sizeof(s));
469  n += rsnprintf (s + n, sizeof(s) - n, "|\n");
470  ASSERT (n <= sizeof(s));
471  DPRINT ("%s", s);
472  }
473 }
474 #endif /* DEBUG_DATA */
475 
476 static uint16_t fec_ecat_read_phy (void * arg, uint8_t address, uint8_t reg)
477 {
478  fec->base->eir = FEC_EIR_MII; // Clear interrupt.
479  fec->base->mmfr = FEC_MII_READ(address, reg); // Write read command.
480  while (!(fec->base->eir & FEC_EIR_MII))
481  {
482  ; // Wait for interrupt.
483  }
484  fec->base->eir = FEC_EIR_MII; // Clear interrupt.
486  return data; // Return read data.
487 }
488 
489 static void fec_ecat_write_phy (void * arg, uint8_t address, uint8_t reg,
490  uint16_t value)
491 {
492  fec->base->eir = FEC_EIR_MII; // Clear interrupt.
493  fec->base->mmfr = FEC_MII_WRITE(address, reg, value); // Write data.
494  while (!(fec->base->eir & FEC_EIR_MII))
495  {
496  ; // Wait for interrupt.
497  }
498  fec->base->eir = FEC_EIR_MII; // Clear interrupt.
499 }
500 
501 static void fec_ecat_init_hw (const fec_mac_address_t * mac_address)
502 {
503  uint32_t mii_speed;
504 
505  /* Hard reset */
506  fec->base->ecr = FEC_ECR_RESET;
507  while (fec->base->ecr & FEC_ECR_RESET)
508  {
509  ;
510  }
511 
512  // Configure MDC clock.
513  mii_speed = (fec->clock + 499999) / 5000000;
514  fec->base->mscr = (fec->base->mscr & (~0x7E)) | (mii_speed << 1);
515 
516  // Receive control register
518 
519  // set RMII mode in RCR register.
520  if (fec->phy_interface == FEC_PHY_RMII)
521  {
522  fec->base->rcr |= FEC_RCR_RMII_MODE;
523  }
524  else if(fec->phy_interface == FEC_PHY_RGMII)
525  {
528  }
529 
530  // Reset phy
531  if (fec->phy->ops->reset)
532  {
533  fec->phy->ops->reset (fec->phy);
534  }
535 
536  /* Don't receive any unicast frames except those whose destination address
537  * equals our physical address.
538  */
539  fec->base->iaur = 0;
540  fec->base->ialr = 0;
541 
542  /* Receive all multicast frames. */
543  fec->base->gaur = UINT32_MAX;
544  fec->base->galr = UINT32_MAX;
545 
546  /* Set our physical address. */
547  fec->base->pa.lower = (mac_address->octet[0] << 24) +
548  (mac_address->octet[1] << 16) +
549  (mac_address->octet[2] << 8) +
550  (mac_address->octet[3] << 0);
551  fec->base->pa.upper = (mac_address->octet[4] << 24) +
552  (mac_address->octet[5] << 16) +
553  0x8808;
554 
555  /* Start link autonegotiation */
556  fec->phy->ops->start (fec->phy);
557 }
558 
559 int fec_ecat_send (const void *payload, size_t tot_len)
560 {
561  fec_buffer_bd_t * bd;
562 
563  /* Frames larger than the maximum Ethernet frame size are not allowed. */
564  ASSERT (tot_len <= PKT_MAXBUF_SIZE);
565  ASSERT (tot_len <= TX_BUFFER_SIZE);
566 
567  /* Bus errors should never occur, unless the MPU is enabled and forbids
568  * the Ethernet MAC DMA from accessing the descriptors or buffers.
569  */
570  ASSERT ((fec->base->eir & FEC_EIR_EBERR) == false);
571 
572  /* Allocate a transmit buffer. We wait here until the MAC has released at
573  * least one buffer. This could take a couple of microseconds.
574  */
575  bd = NULL;
576  while (bd == NULL)
577  {
578  bd = fec_buffer_get_tx ();
579  }
580 
581  DPRINT ("out (%u):\n", tot_len);
582  DUMP_PACKET (payload, tot_len);
583 
584  /* Copy frame to allocated buffer */
585  memcpy (bd->data, payload, tot_len);
586  bd->length = tot_len;
587 
588  fec_buffer_produce_tx (bd);
589 
590  /* Wait for previous transmissions to complete.
591  *
592  * This is a workaround for Freescale Kinetis errata e6358.
593  * See "Mask Set Errata for Mask 3N96B".
594  */
595  while (fec->base->tdar)
596  {
597  ;
598  }
599 
600  /* Transmit frame */
601  fec->base->tdar = 1;
602 
603  return tot_len;
604 }
605 
606 int fec_ecat_recv (void * buffer, size_t buffer_length)
607 {
608  fec_buffer_bd_t * bd;
609  int return_value;
610  size_t frame_length_without_fcs;
611 
612  /* Bus errors should never occur, unless the MPU is enabled and forbids
613  * the Ethernet MAC DMA from accessing the descriptors or buffers.
614  */
615  ASSERT ((fec->base->eir & FEC_EIR_EBERR) == false);
616 
617  bd = fec_buffer_get_rx ();
618  if (bd == NULL)
619  {
620  /* No frame received. Not an error. */
621  return_value = 0;
622  return return_value;
623  }
624 
625  /* The FCS CRC should not be returned to user, so subtract that. */
626  frame_length_without_fcs = bd->length - ETHERNET_FCS_SIZE_IN_BYTES;
627 
628  /* A frame was received. Handle it and then return its buffer to hardware */
629  if ((bd->status & BD_RX_L)== 0){
630  /* Buffer is not last buffer in frame. This really should never
631  * happen as our buffers are large enough to contain any
632  * Ethernet frame. Nevertheless, is has been observed to happen.
633  * Drop the packet and hope for the best.
634  */
635  DPRINT ("recv(): End of frame not found. Status: 0x%x\n", bd->status);
636  return_value = -1;
637  }
638  else if (bd->status & (BD_RX_LG | BD_RX_NO | BD_RX_CR | BD_RX_OV))
639  {
640  DPRINT ("recv(): Frame is damaged. Status: 0x%x\n", bd->status);
641  return_value = -1;
642  }
643  else if (buffer_length >= frame_length_without_fcs)
644  {
645  /* No errors detected, so frame should be valid. */
646  ASSERT (frame_length_without_fcs > 0);
647 
648  memcpy (buffer, bd->data, frame_length_without_fcs);
649  DPRINT ("in (%u):\n", frame_length_without_fcs);
650  DUMP_PACKET (buffer, frame_length_without_fcs);
651  return_value = frame_length_without_fcs;
652  }
653  else
654  {
655  DPRINT ("received_frame: User buffer is too small.\n");
656  return_value = -1;
657  }
658 
659  /* Tell the HW that there are new free RX buffers. */
660  fec_buffer_produce_rx (bd);
661  fec->base->rdar = 1;
662 
663  return return_value;
664 }
665 
666 static void fec_ecat_hotplug (void)
667 {
668  uint8_t link_state = 0;
669 
670  /* Disable frame reception/transmission */
671  fec->base->ecr &= ~FEC_ECR_ETHER_EN;
672 
673  /* Set duplex mode according to link state */
674 
675  link_state = fec->phy->ops->get_link_state (fec->phy);
676 
677  /* Set duplex */
678  if (link_state & PHY_LINK_FULL_DUPLEX)
679  {
680  fec->base->tcr |= FEC_TCR_FDEN;
681  fec->base->rcr &= ~FEC_RCR_DRT;
682  }
683  else
684  {
685  fec->base->tcr &= ~FEC_TCR_FDEN;
686  fec->base->rcr |= FEC_RCR_DRT;
687  }
688 
689  /* Set RMII 10-Mbps mode. */
690  if (link_state & PHY_LINK_10MBIT)
691  {
692  fec->base->rcr |= FEC_RCR_RMII_10T;
693  }
694  else
695  {
696  fec->base->rcr &= ~FEC_RCR_RMII_10T;
697  }
698 
699  /* Clear any pending interrupt */
700  fec->base->eir = 0xffffffff;
701 
702  // Disable all interrupts.
703  fec->base->eimr = 0x0;
704 
705  /* Configure the amount of data required in the
706  * transmit FIFO before transmission of a frame can begin.
707  */
708  /* All data in frame (i.e. store-and-forward mode). */
709  fec->base->tfwr = FEC_TFWR_STR_FWD;
710 
711  // Reset buffers.
712  fec_buffer_reset ();
713 
714  // FEC_ERDSR - Receive buffer descriptor ring start register
715  fec->base->erdsr = (uint32_t)fec->rx_bd_base;
716 
717  // FEC_ETDSR - Transmit buffer descriptor ring start register
718  fec->base->etdsr = (uint32_t)fec->tx_bd_base;
719 
720  // FEC_EMRBR - Maximum receive buffer size register
721  fec->base->emrbr = RX_BUFFER_SIZE - 1;
722 
723  /* Let controller count frames. Useful for debugging */
724  fec->base->mibc = 0x0;
725 
726  /* Now enable the transmit and receive processing.
727  *
728  * Also let MAC hardware convert DMA descriptor fields between little endian
729  * (as accessed by ARM core) and big endian (as used internally by the
730  * MAC hardware. Software would otherwise need to do the conversions.
731  */
733 
734  /* Indicate that there have been empty receive buffers produced */
735  // FEC_RDAR - Receive Descriptor ring - Receive descriptor active register
736  fec->base->rdar = 1;
737 
738  DPRINT ("Link up. Speed: %s. Mode: %s.\n", fec_ecat_link_speed_name (link_state),
739  fec_ecat_link_duplex_name (link_state));
740 }
741 
742 static dev_state_t fec_ecat_probe (void)
743 {
744  uint8_t link_state;
745 
746  link_state = fec->phy->ops->get_link_state (fec->phy);
747 
748  return (link_state & PHY_LINK_OK) ? StateAttached : StateDetached;
749 }
750 
752 
753 int fec_ecat_init (const fec_mac_address_t * mac_address,
754  bool phy_loopback_mode)
755 {
756  dev_state_t state;
757  static const fec_cfg_t eth_cfg =
758  {
759  .base = ENET_BASE,
760  .clock = FEC_MODULE_CLOCK_Hz,
761  .tx_bd_base = fec_tx_bd,
762  .rx_bd_base = fec_rx_bd,
763  .phy_interface = FEC_PHY_RMII,
764  };
765  static phy_cfg_t phy_cfg =
766  {
767  .address = ETH_PHY_ADDRESS,
768  .read = NULL, /* Set by MAC driver */
769  .write = NULL, /* Set by MAC driver */
770  };
771 
772  phy_cfg.loopback_mode = phy_loopback_mode;
773 
774  /* Initialise buffers and buffer descriptors.*/
775  fec_buffer_init_tx (fec_tx_bd, fec_tx_data, NUM_BUFFERS);
776  fec_buffer_init_rx (fec_rx_bd, fec_rx_data, NUM_BUFFERS);
777 
778  fec = malloc (sizeof (fec_t));
779  UASSERT (fec != NULL, EMEM);
780 
781  /* Initialise driver state */
782  fec->rx_bd_base = eth_cfg.rx_bd_base;
783  fec->tx_bd_base = eth_cfg.tx_bd_base;
784  fec->clock = eth_cfg.clock;
785  fec->base = (reg_fec_t *)eth_cfg.base;
786  fec->phy_interface = eth_cfg.phy_interface;
787  fec->phy = mii_init (&phy_cfg);
788  fec->phy->arg = fec;
789  fec->phy->read = fec_ecat_read_phy;
790  fec->phy->write = fec_ecat_write_phy;
791 
792  /* Initialize hardware */
793  fec_ecat_init_hw (mac_address);
794  state = StateDetached;
795  while (state == StateDetached)
796  {
797  state = fec_ecat_probe ();
798  }
799  fec_ecat_hotplug ();
800 
801  return 0;
802 }
uint32_t ieee_t_def
Definition: fec_ecat.c:101
uint32_t rmon_r_undersize
Definition: fec_ecat.c:115
uint32_t eimr
Definition: fec_ecat.c:145
uint32_t rmon_r_frag
Definition: fec_ecat.c:117
uint32_t rmon_r_bc_pkt
Definition: fec_ecat.c:112
uint32_t rmon_t_crc_align
Definition: fec_ecat.c:83
uint32_t base
Definition: fec_ecat.c:360
#define FEC_RCR_MAX_FL(x)
Definition: fec_ecat.c:251
uint32_t rmon_r_drop
Definition: fec_ecat.c:110
#define FEC_ECR_DBSWP
Definition: fec_ecat.c:225
#define FEC_MII_WRITE(pa, ra, v)
Definition: fec_ecat.c:330
uint32_t rmon_t_p64
Definition: fec_ecat.c:89
fec_buffer_bd_t * tx_bd_base
Definition: fec_ecat.c:362
#define NUM_BUFFERS
Definition: fec_ecat.c:53
#define FEC_RCR_RGMII_ENA
Definition: fec_ecat.c:261
uint32_t ecr
Definition: fec_ecat.c:150
#define FEC_MODULE_CLOCK_Hz
Definition: fec_ecat.c:66
fec_buffer_bd_t * rx_bd_base
Definition: fec_ecat.c:363
uint32_t ieee_t_sqe
Definition: fec_ecat.c:106
int fec_ecat_init(const fec_mac_address_t *mac_address, bool phy_loopback_mode)
Definition: fec_ecat.c:753
uint32_t resv14
Definition: fec_ecat.c:177
uint32_t tx_section_empty
Definition: fec_ecat.c:182
uint32_t ieee_r_frame_ok
Definition: fec_ecat.c:129
int fec_ecat_recv(void *buffer, size_t buffer_length)
Definition: fec_ecat.c:606
volatile reg_fec_t * base
Definition: fec_ecat.c:372
uint32_t ieee_r_align
Definition: fec_ecat.c:131
static void fec_ecat_write_phy(void *arg, uint8_t address, uint8_t reg, uint16_t value)
Definition: fec_ecat.c:489
uint32_t resv10
Definition: fec_ecat.c:170
#define FEC_ALLIGNED
Definition: fec_ecat.c:54
fec_buffer_bd_t * tx_bd_base
Definition: fec_ecat.c:370
#define FEC_RCR_MII_MODE
Definition: fec_ecat.c:265
static void fec_ecat_init_hw(const fec_mac_address_t *mac_address)
Definition: fec_ecat.c:501
unsigned short uint16_t
Definition: stdint.h:79
uint8_t octet[6]
Definition: fec_ecat.h:39
uint32_t erdsr
Definition: fec_ecat.c:174
uint32_t ieee_t_1col
Definition: fec_ecat.c:99
#define ETHERNET_FCS_SIZE_IN_BYTES
Definition: fec_ecat.c:47
unsigned char uint8_t
Definition: stdint.h:78
uint32_t rmon_t_drop
Definition: fec_ecat.c:79
fec_phy_inteface
Definition: fec_ecat.c:343
uint32_t rmon_r_packets
Definition: fec_ecat.c:111
uint32_t ieee_t_excol
Definition: fec_ecat.c:103
uint32_t rx_section_empty
Definition: fec_ecat.c:179
uint32_t rmon_r_p_gte2048
Definition: fec_ecat.c:126
const fec_mib_t mib
Definition: fec_ecat.c:186
fec_phy_inteface_t phy_interface
Definition: fec_ecat.c:364
#define FEC_RCR_DRT
Definition: fec_ecat.c:266
uint32_t tcr
Definition: fec_ecat.c:159
#define DUMP_PACKET(p, l)
Definition: fec_ecat.c:44
uint32_t frsr
Definition: fec_ecat.c:172
uint32_t ieee_t_octets_ok
Definition: fec_ecat.c:108
COMPILETIME_ASSERT(sizeof(fec_mib_t)==0x100)
uint32_t mscr
Definition: fec_ecat.c:153
static fec_t * fec
Definition: fec_ecat.c:385
uint32_t fec_miigsk_enr
Definition: fec_ecat.c:189
uint32_t lower
Definition: fec_ecat.c:72
uint32_t rmon_r_crc_align
Definition: fec_ecat.c:114
#define PKT_MAXBUF_SIZE
Definition: fec_ecat.c:339
uint32_t ieee_r_drop
Definition: fec_ecat.c:128
uint32_t ieee_r_octets_ok
Definition: fec_ecat.c:134
uint32_t rx_section_full
Definition: fec_ecat.c:178
uint32_t ialr
Definition: fec_ecat.c:165
uint32_t rmon_t_p1024to2047
Definition: fec_ecat.c:94
uint32_t rmon_r_resvd_0
Definition: fec_ecat.c:119
uint32_t rmon_r_jab
Definition: fec_ecat.c:118
#define FEC_EIR_MII
Definition: fec_ecat.c:212
unsigned int uint32_t
Definition: stdint.h:80
fec_buffer_bd_t * rx_bd_base
Definition: fec_ecat.c:371
#define DPRINT(...)
Definition: fec_ecat.c:38
static void fec_ecat_hotplug(void)
Definition: fec_ecat.c:666
fec_mac_t pa
Definition: fec_ecat.c:161
Definition: fec_ecat.c:367
uint32_t frbr
Definition: fec_ecat.c:171
uint32_t opd
Definition: fec_ecat.c:162
#define FEC_TCR_FDEN
Definition: fec_ecat.c:272
uint32_t rmon_t_octets
Definition: fec_ecat.c:96
int fec_ecat_send(const void *payload, size_t tot_len)
Definition: fec_ecat.c:559
uint32_t rmon_t_mc_pkt
Definition: fec_ecat.c:82
uint32_t emrbr
Definition: fec_ecat.c:176
uint32_t mmfr
Definition: fec_ecat.c:152
uint32_t rx_almost_empty
Definition: fec_ecat.c:180
#define FEC_EIR_EBERR
Definition: fec_ecat.c:213
struct fec_mac_t fec_mac_t
uint32_t resv13
Definition: fec_ecat.c:188
uint32_t ieee_t_cserr
Definition: fec_ecat.c:105
uint32_t rmon_r_p65to127
Definition: fec_ecat.c:121
uint32_t rmon_t_p512to1023
Definition: fec_ecat.c:93
uint32_t rmon_r_p256to511
Definition: fec_ecat.c:123
uint32_t gaur
Definition: fec_ecat.c:166
uint32_t rmon_t_jab
Definition: fec_ecat.c:87
#define FEC_RCR_RMII_10T
Definition: fec_ecat.c:258
uint32_t galr
Definition: fec_ecat.c:167
#define FEC_TFWR_STR_FWD
Definition: fec_ecat.c:285
uint32_t ieee_t_lcol
Definition: fec_ecat.c:102
uint32_t rmon_r_p1024to2047
Definition: fec_ecat.c:125
struct fec_mib fec_mib_t
struct fec_cfg fec_cfg_t
enum fec_phy_inteface fec_phy_inteface_t
uint32_t rmon_t_p128to255
Definition: fec_ecat.c:91
uint32_t rmon_t_col
Definition: fec_ecat.c:88
uint32_t rmon_t_oversize
Definition: fec_ecat.c:85
#define UINT32_MAX
Definition: stdint.h:142
#define ETH_PHY_ADDRESS
Definition: fec_ecat.c:51
uint32_t ieee_t_frame_ok
Definition: fec_ecat.c:98
uint32_t resv1
Definition: fec_ecat.c:146
uint32_t ieee_t_drop
Definition: fec_ecat.c:97
uint32_t iaur
Definition: fec_ecat.c:164
uint32_t etdsr
Definition: fec_ecat.c:175
uint32_t ieee_t_macerr
Definition: fec_ecat.c:104
#define FEC_ECR_RESET
Definition: fec_ecat.c:227
#define FEC_MII_READ(pa, ra)
Definition: fec_ecat.c:328
static dev_state_t fec_ecat_probe(void)
Definition: fec_ecat.c:742
uint32_t rdar
Definition: fec_ecat.c:147
#define FEC_RCR_RMII_MODE
Definition: fec_ecat.c:259
uint32_t fec_miigsk_cfgr
Definition: fec_ecat.c:187
uint32_t rmon_t_undersize
Definition: fec_ecat.c:84
uint32_t rmon_r_p64
Definition: fec_ecat.c:120
uint32_t rmon_t_p65to127
Definition: fec_ecat.c:90
uint32_t resv0
Definition: fec_ecat.c:143
uint32_t upper
Definition: fec_ecat.c:73
uint32_t clock
Definition: fec_ecat.c:369
uint32_t rmon_r_oversize
Definition: fec_ecat.c:116
struct fec fec_t
uint32_t r_fdxfc
Definition: fec_ecat.c:133
uint32_t rmon_r_p512to1023
Definition: fec_ecat.c:124
uint32_t rmon_r_mc_pkt
Definition: fec_ecat.c:113
uint32_t tx_almost_full
Definition: fec_ecat.c:184
fec_phy_inteface_t phy_interface
Definition: fec_ecat.c:374
struct reg_fec reg_fec_t
uint32_t rmon_t_bc_pkt
Definition: fec_ecat.c:81
uint32_t tx_almost_empty
Definition: fec_ecat.c:183
uint32_t rmon_t_packets
Definition: fec_ecat.c:80
uint32_t rx_almost_full
Definition: fec_ecat.c:181
uint32_t rcr
Definition: fec_ecat.c:157
phy_t * phy
Definition: fec_ecat.c:373
uint32_t r_macerr
Definition: fec_ecat.c:132
uint32_t t_fdxfc
Definition: fec_ecat.c:107
uint32_t ieee_r_crc
Definition: fec_ecat.c:130
uint32_t eir
Definition: fec_ecat.c:144
#define FEC_MII_GET_DATA(v)
Definition: fec_ecat.c:327
uint32_t rmon_r_p128to255
Definition: fec_ecat.c:122
#define FEC_MIN_MODULE_CLOCK_Hz
Definition: fec_ecat.c:63
uint32_t rmon_r_octets
Definition: fec_ecat.c:127
static uint16_t fec_ecat_read_phy(void *arg, uint8_t address, uint8_t reg)
Definition: fec_ecat.c:476
uint32_t clock
Definition: fec_ecat.c:361
uint32_t tfwr
Definition: fec_ecat.c:169
uint32_t rmon_t_p_gte2048
Definition: fec_ecat.c:95
uint32_t rmon_t_p256to511
Definition: fec_ecat.c:92
uint32_t ieee_t_mcol
Definition: fec_ecat.c:100
#define FEC_ECR_ETHER_EN
Definition: fec_ecat.c:226
uint32_t tdar
Definition: fec_ecat.c:148
uint32_t rmon_t_frag
Definition: fec_ecat.c:86
uint32_t mibc
Definition: fec_ecat.c:155


soem
Author(s): Arthur Ketels and M.J.G. van den Molengraft
autogenerated on Mon Feb 28 2022 23:46:57