File indexing completed on 2025-05-11 08:23:47
0001 #include <stdint.h>
0002 #include <stddef.h>
0003
0004 #include <fec.h>
0005 #include <lwip/pbuf.h>
0006 #include <netif/etharp.h>
0007
0008 #include <rtems.h>
0009 #include <bsp.h>
0010
0011 #if LWIP_NETIF_STATUS_CALLBACK
0012 static void mcf5225xif_status(struct netif*);
0013 #endif
0014
0015
0016 #if LWIP_NETIF_LINK_CALLBACK
0017 static void mcf5225xif_link(struct netif*);
0018 #endif
0019
0020 static u8_t __attribute__((aligned (16))) rx_buf[MAX_FRAME_LEN];
0021 static u8_t __attribute__((aligned (16))) tx_buf[MAX_FRAME_LEN];
0022
0023 struct __attribute__((aligned(16))) rx_desc {
0024 u16_t ctl;
0025 u16_t len;
0026 u8_t* ptr;
0027 } rx_bd = { MCF_FEC_RXBD_E | MCF_FEC_RXBD_W ,0,rx_buf};
0028
0029 struct tx_desc {
0030 u16_t ctl;
0031 u16_t len;
0032 u8_t* buf;
0033 } tx_bd[2] ={{MCF_FEC_TXBD_R | MCF_FEC_TXBD_L | MCF_FEC_TXBD_TC ,0,tx_buf},{MCF_FEC_TXBD_L | MCF_FEC_TXBD_TC | MCF_FEC_TXBD_W ,0,tx_buf}};
0034
0035 static rtems_id net_task_id;
0036
0037 rtems_isr rx_frame_handler(rtems_vector_number vector)
0038 {
0039 MCF_INTC0_IMRL |= MCF_INTC_IMRL_MASK27;
0040 MCF_FEC_EIR |= MCF_FEC_EIR_RXF;
0041
0042 rtems_event_send(net_task_id,RTEMS_EVENT_0);
0043
0044 MCF_INTC0_IMRL &= ~MCF_INTC_IMRL_MASK27;
0045 }
0046
0047 void handle_rx_frame(struct netif* netif)
0048 {
0049
0050 if (rx_bd.ctl & (MCF_FEC_RXBD_RO1 | MCF_FEC_RXBD_E | MCF_FEC_RXBD_TR)) rx_bd.ctl = MCF_FEC_RXBD_E | MCF_FEC_RXBD_W;
0051 else if (rx_bd.ctl & MCF_FEC_RXBD_L) {
0052 if (rx_bd.ctl & (MCF_FEC_RXBD_LG | MCF_FEC_RXBD_NO | MCF_FEC_RXBD_CR | MCF_FEC_RXBD_OV)) rx_bd.ctl = MCF_FEC_RXBD_E | MCF_FEC_RXBD_W;
0053 else {
0054 register struct pbuf* lwip_buf=pbuf_alloc(PBUF_RAW,rx_bd.len,PBUF_RAM);
0055
0056 if (lwip_buf) {
0057 memcpy(lwip_buf->payload,rx_bd.ptr,lwip_buf->tot_len);
0058 switch (htons(((struct eth_hdr *)lwip_buf->payload)->type)) {
0059
0060 case ETHTYPE_IP:
0061
0062
0063 if (netif->input(lwip_buf, netif) != ERR_OK) pbuf_free(lwip_buf);
0064 break;
0065 case ETHTYPE_ARP:
0066
0067 etharp_arp_input(netif, (struct eth_addr *)&netif->hwaddr, lwip_buf);
0068 break;
0069 default:
0070 pbuf_free(lwip_buf);
0071 break;
0072 }
0073 lwip_buf = NULL;
0074 rx_bd.ctl = MCF_FEC_RXBD_E | MCF_FEC_RXBD_W;
0075 }
0076 }
0077 }
0078 MCF_FEC_RDAR=0;
0079 }
0080
0081
0082
0083
0084
0085
0086
0087
0088
0089
0090
0091
0092 static err_t
0093 low_level_output(struct netif *netif, struct pbuf *p)
0094 {
0095 struct pbuf *q;
0096 u8_t *ptr;
0097 static u8_t txbd_index;
0098
0099
0100 netif = netif;
0101
0102 if (p->tot_len > MAX_FRAME_LEN)
0103
0104 return ERR_MEM;
0105
0106 tx_bd[txbd_index].len = p->tot_len;
0107
0108
0109 q = p;
0110 ptr=tx_bd[txbd_index].buf;
0111 while (q != NULL) {
0112 memcpy(ptr, q->payload, q->len);
0113 ptr += q->len;
0114 q = q->next;
0115 }
0116 tx_bd[txbd_index].ctl |= MCF_FEC_TXBD_R;
0117
0118 MCF_FEC_TDAR = 0;
0119
0120 while (MCF_FEC_TDAR != 0);
0121
0122 MCF_FEC_EIR |= MCF_FEC_EIR_TXF | MCF_FEC_EIR_TXB;
0123
0124
0125
0126
0127
0128
0129
0130
0131 txbd_index=!txbd_index;
0132
0133 return ERR_OK;
0134 }
0135
0136
0137
0138
0139
0140
0141
0142
0143
0144
0145
0146
0147 err_t
0148 mcf5225xif_init(struct netif *netif)
0149 {
0150 rtems_isr_entry old_isr_handler;
0151 struct if_config* if_config=netif->state;
0152
0153 net_task_id=if_config->net_task;
0154
0155
0156
0157
0158
0159 netif->output = etharp_output;
0160 netif->linkoutput = low_level_output;
0161 #if LWIP_NETIF_STATUS_CALLBACK
0162 netif->status_callback = mcf5225xif_status;
0163 #endif
0164 #if LWIP_NETIF_LINK_CALLBACK
0165 netif->link_callback = mcf5225xif_link;
0166 #endif
0167
0168 netif->name[0]=if_config->name[0];
0169 netif->name[1]=if_config->name[1];
0170 netif->hwaddr_len = if_config->hwaddr_len;
0171 memcpy(netif->hwaddr,if_config->hwaddr,ETHARP_HWADDR_LEN);
0172 netif->mtu = if_config->mtu ;
0173 netif->flags = if_config->flags;
0174
0175
0176 MCF_FEC_ECR |= MCF_FEC_ECR_RESET;
0177
0178 while (MCF_FEC_ECR&MCF_FEC_ECR_RESET) __asm__ ("nop");
0179
0180 if (if_config->phy_init) if_config->phy_init();
0181
0182 MCF_FEC_EIMR = 0;
0183 MCF_FEC_EIR= 0xFFFFFFFF;
0184
0185
0186 MCF_FEC_PALR = (u32_t)( (netif->hwaddr[0] << 24)
0187 | (netif->hwaddr[1] << 16)
0188 | (netif->hwaddr[2] << 8 )
0189 | (netif->hwaddr[3] << 0 ) );
0190 MCF_FEC_PAUR = (u32_t)( (netif->hwaddr[4] << 24)
0191 | (netif->hwaddr[5] << 16) );
0192
0193
0194 MCF_FEC_OPD |= MCF_FEC_OPD_PAUSE_DUR(2);
0195 MCF_FEC_IAUR = 0;
0196 MCF_FEC_IALR = 0;
0197 MCF_FEC_GAUR = 0;
0198 MCF_FEC_GALR = 0;
0199 MCF_FEC_EMRBR = ((MAX_FRAME_LEN+15)&~15);
0200 MCF_FEC_ERDSR = (uint32_t)&rx_bd;
0201 MCF_FEC_ETDSR = (uint32_t)&tx_bd;
0202 MCF_FEC_RCR = (MAX_FRAME_LEN << 16) | MCF_FEC_RCR_MII_MODE;
0203 MCF_FEC_FRSR = 0x48<<2;
0204
0205 MCF_FEC_TCR = MCF_FEC_TCR_FDEN | MCF_FEC_TCR_HBC;
0206
0207 MCF_FEC_MIBC = MCF_FEC_MIBC_MIB_DISABLE;
0208
0209 MCF_FEC_MIBC =~MCF_FEC_MIBC_MIB_DISABLE;
0210
0211 MCF_FEC_EIMR = 0;
0212
0213 rtems_interrupt_catch(rx_frame_handler,91,&old_isr_handler);
0214 MCF_INTC0_ICR27=0x10;
0215 MCF_FEC_EIR= 0xFFFFFFFF;
0216 MCF_FEC_EIMR |= MCF_FEC_EIR_RXF;
0217 MCF_INTC0_IMRL &= ~MCF_INTC_IMRL_MASK27;
0218
0219
0220 MCF_FEC_ECR |= MCF_FEC_ECR_ETHER_EN;
0221
0222 MCF_FEC_RDAR = 0;
0223
0224 return ERR_OK;
0225 }
0226
0227 void smi_init(u32_t clk_speed)
0228 {
0229 MCF_FEC_MSCR = MSCR_MII_SPEED(clk_speed);
0230 }
0231
0232 void smi_write(u8_t phy_addr,u8_t reg_addr,u16_t data)
0233 {
0234 MCF_FEC_MMFR = MCF_FEC_MMFR_ST(0x1) | MCF_FEC_MMFR_OP_WRITE | (MCF_FEC_MMFR_PA(phy_addr)) | MCF_FEC_MMFR_RA(reg_addr) | MCF_FEC_MMFR_TA_10 | data;
0235 smi_init(bsp_get_CPU_clock_speed());
0236 while ((MCF_FEC_EIR & MCF_FEC_EIR_MII) == 0) { __asm__ ("nop"); }
0237 smi_init(0);
0238 MCF_FEC_EIR |= MCF_FEC_EIR_MII;
0239 }
0240
0241 u16_t smi_read(u8_t phy_addr,u8_t reg_addr)
0242 {
0243 MCF_FEC_MMFR = MCF_FEC_MMFR_ST(0x1) | MCF_FEC_MMFR_OP_READ | (MCF_FEC_MMFR_PA(phy_addr)) | MCF_FEC_MMFR_RA(reg_addr) | MCF_FEC_MMFR_TA_10;
0244 smi_init(bsp_get_CPU_clock_speed());
0245 while ((MCF_FEC_EIR & MCF_FEC_EIR_MII) == 0) { __asm__ ("nop"); }
0246 smi_init(0);
0247 MCF_FEC_EIR |= MCF_FEC_EIR_MII;
0248
0249 return MCF_FEC_MMFR&0xFFFF;
0250 }
0251
0252 #if LWIP_NETIF_STATUS_CALLBACK
0253 static void
0254 mcf5225xif_status(struct netif* netif)
0255 {
0256
0257 return;
0258 }
0259 #endif
0260
0261 #if LWIP_NETIF_LINK_CALLBACK
0262 static void
0263 mcf5225xif_link(struct netif* net_if)
0264 {
0265 u16_t phy_status=smi_read(1,1);
0266
0267 printf("received status: 0x%x\n",phy_status);
0268
0269 if (!(phy_status&0x4))
0270 phy_status=smi_read(1,1);
0271
0272 printf("received status: 0x%x\n",phy_status);
0273
0274 if (phy_status&0x4)
0275 MCF_GPIO_PORTTC |= MCF_GPIO_PORTTC_PORTTC1;
0276 else
0277 MCF_GPIO_PORTTC &=~MCF_GPIO_PORTTC_PORTTC1;
0278 }
0279 #endif