Back to home page

LXR

 
 

    


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; /* disable FEC RX_INTF interrupt */
0040     MCF_FEC_EIR |= MCF_FEC_EIR_RXF; /* clear pending interrupt event */
0041     
0042     rtems_event_send(net_task_id,RTEMS_EVENT_0);
0043     
0044     MCF_INTC0_IMRL &= ~MCF_INTC_IMRL_MASK27; /* enable FEC RX_INTF interrupt */
0045 }
0046 
0047 void handle_rx_frame(struct netif* netif)
0048 {
0049     /* Scan the Rx buffer rescriptor ring */
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; /* 1: receive process pending, pbuf still allocated, 2: Buffer empty, quit, 3: frame too long */ 
0051     else if (rx_bd.ctl & MCF_FEC_RXBD_L) { /* Last buffer in frame, finalize */
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; /* Reception error */
0053         else { //pass_frame_to_upper_layer(&rx_bd);
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                 /* IP or ARP packet? */
0060                     case ETHTYPE_IP:
0061                         /* full packet send to tcpip_thread to process */
0062                         /* skip Ethernet header */
0063                         if (netif->input(lwip_buf, netif) != ERR_OK) pbuf_free(lwip_buf);
0064                         break;
0065                     case ETHTYPE_ARP:
0066                         /* pass p to ARP module */
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  * This function does the actual transmission of the packet. The packet is
0083  * contained in the pbuf that is passed to the function. This pbuf
0084  * might be chained.
0085  *
0086  * @param netif the lwip network interface structure for this ethernetif
0087  * @param p the MAC packet to send (e.g. IP packet including MAC addresses and type)
0088  * @return ERR_OK if the packet could be sent
0089  *         an err_t value if the packet couldn't be sent
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   /* Suppress 'argument not used' warning */
0100   netif = netif;
0101 
0102   if (p->tot_len > MAX_FRAME_LEN)
0103     /* Frame too long, drop it */
0104     return ERR_MEM;
0105   
0106     tx_bd[txbd_index].len = p->tot_len; // < 64 ? p->tot_len+(64-p->tot_len) : p->tot_len;
0107   
0108   /* Walk the pbuf chain, fill the Tx packet buffer */
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; /* Start transmission */
0119   
0120   while (MCF_FEC_TDAR != 0); /* wait for transmission complete */
0121   
0122   MCF_FEC_EIR |= MCF_FEC_EIR_TXF | MCF_FEC_EIR_TXB;
0123   
0124   /* JUST debugging stuff */
0125    //~ unsigned int my_q_len=0;
0126     //~ while (my_q_len<tx_bd[txbd_index].len)
0127         //~ printf("%02x ",tx_bd[txbd_index].buf[my_q_len++]);
0128 
0129     //~ printf("buf.len: %d, buf.ctl: 0x%x, tx_bd.buf: 0x%x\n",tx_bd[txbd_index].len,tx_bd[txbd_index].ctl,tx_bd[txbd_index].buf);
0130 
0131   txbd_index=!txbd_index;
0132     
0133   return ERR_OK;
0134 }
0135 
0136 /**
0137  * Should be called at the beginning of the program to set up the
0138  * network interface. It does the
0139  * actual setup of the hardware.
0140  *
0141  * This function should be passed as a parameter to netif_add().
0142  *
0143  * @param netif the lwip network interface structure for this ethernetif
0144  * @return ERR_OK if the interface is initialized
0145  *         We always return ERR_OK
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     /* We directly use etharp_output() here to save a function call.
0156     * You can instead declare your own function an call etharp_output()
0157     * from it if you have to do some checks before sending (e.g. if link
0158     * is available...) */
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);  /* set the mac address configured by the application */
0172     netif->mtu = if_config->mtu ; /* maximum transfer unit, configured by application */
0173     netif->flags = if_config->flags;    /* device capabilities, configured by application */
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();  /* call application specific optional extern phy initialization function */
0181   
0182   MCF_FEC_EIMR = 0;
0183   MCF_FEC_EIR= 0xFFFFFFFF;
0184   
0185   //~ Set MAC hardware address:
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   /* Do whatever else is needed to initialize interface. */  
0194   MCF_FEC_OPD |= MCF_FEC_OPD_PAUSE_DUR(2); /* pause duration: send 2 pause frames */
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); //<<4;  //RX_RING_SIZE*PBUF_POOL_BUFSIZE; //1536;
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; /* avoid address clashing of receive and transmit data in FEC fifo */
0204     
0205     MCF_FEC_TCR = MCF_FEC_TCR_FDEN | MCF_FEC_TCR_HBC;
0206     
0207     MCF_FEC_MIBC = MCF_FEC_MIBC_MIB_DISABLE;
0208     /* TODO: clear MIB RAM??? */
0209     MCF_FEC_MIBC =~MCF_FEC_MIBC_MIB_DISABLE; /* enable MIBC */
0210   
0211     MCF_FEC_EIMR = 0;
0212     
0213     rtems_interrupt_catch(rx_frame_handler,91,&old_isr_handler); /* register ISR for RX_INTF interrupt*/
0214     MCF_INTC0_ICR27=0x10; /* set interrupt level */
0215     MCF_FEC_EIR= 0xFFFFFFFF; /* clear all pending interrupts */
0216     MCF_FEC_EIMR |= MCF_FEC_EIR_RXF; /* enable RX_INTF interrupt */
0217     MCF_INTC0_IMRL &= ~MCF_INTC_IMRL_MASK27; /* enable FEC RX_INTF interrupt */
0218     
0219     /* enable FEC */
0220     MCF_FEC_ECR |= MCF_FEC_ECR_ETHER_EN;
0221     /* Start reception, if it's not started already */
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()); /* enable MII clock speed after MMFR is written */
0236     while ((MCF_FEC_EIR & MCF_FEC_EIR_MII) == 0) { __asm__ ("nop"); }
0237     smi_init(0); /* MII frame sent, disable clock until next operation */
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()); /* enable MII clock speed after MMFR is written */
0245     while ((MCF_FEC_EIR & MCF_FEC_EIR_MII) == 0) { __asm__ ("nop"); }
0246     smi_init(0); /* MII frame sent, disable clock until next operation */
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); /* get phy status */    
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