27 #include <eth/fec_buffer.h> 
   28 #include <eth/phy/mii.h> 
   36 #define DPRINT(...) rprintp ("FEC: "__VA_ARGS__) 
   42 #define DUMP_PACKET(p, l) fec_ecat_dump_packet (p, l) 
   44 #define DUMP_PACKET(p, l) 
   47 #define ETHERNET_FCS_SIZE_IN_BYTES     4  
   49 #define DELAY(ms) task_delay (tick_from_ms (ms) + 1) 
   51 #define ETH_PHY_ADDRESS 0x1  
   54 #define FEC_ALLIGNED __attribute__((section(".dma"),aligned(16))) 
   63 #define FEC_MIN_MODULE_CLOCK_Hz (25 * 1000 * 1000) 
   66 #define FEC_MODULE_CLOCK_Hz CFG_IPG_CLOCK 
  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) 
  219 #define FEC_RDAR_R_DES_ACTIVE (0x01000000) 
  222 #define FEC_TDAR_X_DES_ACTIVE (0x01000000) 
  225 #define FEC_ECR_DBSWP         (0x00000100) 
  226 #define FEC_ECR_ETHER_EN      (0x00000002) 
  227 #define FEC_ECR_RESET         (0x00000001) 
  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) 
  241 #define FEC_MSCR_DIS_PREAMBLE (0x00000080) 
  242 #define FEC_MSCR_MII_SPEED(x) (((x)&0x3F)<<1) 
  245 #define FEC_MIBC_MIB_DISABLE      (0x80000000) 
  246 #define FEC_MIBC_MIB_IDLE      (0x40000000) 
  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) 
  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) 
  277 #define FEC_PAUR_PADDR2(x)    (((x)&0xFFFF)<<16) 
  278 #define FEC_PAUR_TYPE(x)      ((x)&0xFFFF) 
  281 #define FEC_OPD_PAUSE_DUR(x)  (((x)&0x0000FFFF)<<0) 
  282 #define FEC_OPD_OPCODE(x)     (((x)&0x0000FFFF)<<16) 
  285 #define FEC_TFWR_STR_FWD      BIT (8)  
  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) 
  292 #define FEC_FRBR_R_BOUND(x)   (((x)&0xFF)<<2) 
  295 #define FEC_FRSR_R_FSTART(x)  (((x)&0xFF)<<2) 
  298 #define FEC_ERDSR_R_DES_START(x)    (((x)&0x3FFFFFFF)<<2) 
  301 #define FEC_ETDSR_X_DES_START(x)    (((x)&0x3FFFFFFF)<<2) 
  304 #define FEC_EMRBR_R_BUF_SIZE(x)     (((x)&0x7F)<<4) 
  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 
  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)) 
  333 #define FEC_MII_TIMEOUT         10 // 1 * 10 ms 
  334 #define FEC_MII_TICK        1 // 1 ms 
  339 #define PKT_MAXBUF_SIZE         1518 
  390 const char * fec_ecat_link_duplex_name (
uint8_t link_state)
 
  392    if (link_state & PHY_LINK_OK)
 
  394       if (link_state & PHY_LINK_FULL_DUPLEX)
 
  396          return "full duplex";
 
  400          return "half duplex";
 
  405       return "no duplex (link down)";
 
  409 const char * fec_ecat_link_speed_name (
uint8_t link_state)
 
  411    if (link_state & PHY_LINK_OK)
 
  413       if (link_state & PHY_LINK_10MBIT)
 
  417       else if (link_state & PHY_LINK_100MBIT)
 
  421       else if (link_state & PHY_LINK_1000MBIT)
 
  427          return "unknown speed";
 
  432       return "0 Mbps (link down)";
 
  437 #ifdef RTK_DEBUG_DATA 
  439 static void fec_ecat_dump_packet (
const uint8_t * payload, 
size_t len)
 
  444    ASSERT (payload != NULL);
 
  446    for (i = 0; i < len; i += 16)
 
  449       for (
j = 0; 
j < 16 && (i + 
j) < len; 
j++)
 
  451          ASSERT (n <= 
sizeof(s));
 
  452          n += rsnprintf (s + n, 
sizeof(s) - n, 
"%02x ", payload[i + 
j]);
 
  456          ASSERT (n <= 
sizeof(s));
 
  457          n += rsnprintf (s + n, 
sizeof(s) - n, 
"   ");
 
  459       ASSERT (n <= 
sizeof(s));
 
  460       n += rsnprintf (s + n, 
sizeof(s) - n, 
"|");
 
  461       for (
j = 0; 
j < 16 && (i + 
j) < len; 
j++)
 
  464          c = (isprint (c)) ? c : 
'.';
 
  465          ASSERT (n <= 
sizeof(s));
 
  466          n += rsnprintf (s + n, 
sizeof(s) - n, 
"%c", c);
 
  468       ASSERT (n <= 
sizeof(s));
 
  469       n += rsnprintf (s + n, 
sizeof(s) - n, 
"|\n");
 
  470       ASSERT (n <= 
sizeof(s));
 
  513    mii_speed = (
fec->
clock + 499999) / 5000000;
 
  548                          (mac_address->
octet[1] << 16) +
 
  549                          (mac_address->
octet[2] << 8)  +
 
  550                          (mac_address->
octet[3] << 0);
 
  552                          (mac_address->
octet[5] << 16) +
 
  561    fec_buffer_bd_t * bd;
 
  565    ASSERT (tot_len <= TX_BUFFER_SIZE);
 
  578       bd = fec_buffer_get_tx ();
 
  581    DPRINT (
"out (%u):\n", tot_len);
 
  585    memcpy (bd->data, payload, tot_len);
 
  586    bd->length = tot_len;
 
  588    fec_buffer_produce_tx (bd);
 
  608    fec_buffer_bd_t * bd;
 
  610    size_t frame_length_without_fcs;
 
  617    bd = fec_buffer_get_rx ();
 
  629    if ((bd->status & BD_RX_L)== 0){
 
  635       DPRINT (
"recv(): End of frame not found. Status: 0x%x\n", bd->status);
 
  638    else if (bd->status & (BD_RX_LG | BD_RX_NO | BD_RX_CR | BD_RX_OV))
 
  640       DPRINT (
"recv(): Frame is damaged. Status: 0x%x\n", bd->status);
 
  643    else if (buffer_length >= frame_length_without_fcs)
 
  646       ASSERT (frame_length_without_fcs > 0);
 
  648       memcpy (buffer, bd->data, frame_length_without_fcs);
 
  649       DPRINT (
"in (%u):\n", frame_length_without_fcs);
 
  651       return_value = frame_length_without_fcs;
 
  655       DPRINT (
"received_frame: User buffer is too small.\n");
 
  660    fec_buffer_produce_rx (bd);
 
  678    if (link_state & PHY_LINK_FULL_DUPLEX)
 
  690    if (link_state & PHY_LINK_10MBIT)
 
  738    DPRINT (
"Link up. Speed: %s. Mode: %s.\n", fec_ecat_link_speed_name (link_state),
 
  739          fec_ecat_link_duplex_name (link_state));
 
  748    return (link_state & PHY_LINK_OK) ? StateAttached : StateDetached;
 
  754       bool phy_loopback_mode)
 
  761       .tx_bd_base    = fec_tx_bd,
 
  762       .rx_bd_base    = fec_rx_bd,
 
  765    static phy_cfg_t phy_cfg =
 
  772    phy_cfg.loopback_mode = phy_loopback_mode;
 
  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);
 
  779    UASSERT (
fec != NULL, EMEM);
 
  787    fec->
phy               = mii_init (&phy_cfg);
 
  794    state = StateDetached;
 
  795    while (state == StateDetached)