Beispiel #1
0
int ethernet_service(struct sim *s) {
	/* fpga --> tap */
	ETH_SOURCE_ACK = 1;
	if(ETH_SOURCE_STB == 1) {
		s->eth_txbuffer[s->eth_txbuffer_len] = ETH_SOURCE_DATA;
		s->eth_txbuffer_len++;
	} else {
		if(s->eth_last_source_stb) {
			eth_write(s, s->eth_txbuffer, s->eth_txbuffer_len);
			s->eth_txbuffer_len = 0;
		}
	}
	s->eth_last_source_stb = ETH_SOURCE_STB;

	/* tap --> fpga */
	if(s->eth_rxbuffer_len == 0) {
		ETH_SINK_STB = 0;
		s->eth_rxbuffer_pos = 0;
		s->eth_rxbuffer_len = eth_read(s, s->eth_rxbuffer);
	} else {
		if(s->eth_rxbuffer_pos < MAX(s->eth_rxbuffer_len, 60)) {
			ETH_SINK_STB = 1;
			ETH_SINK_DATA = s->eth_rxbuffer[s->eth_rxbuffer_pos];
			s->eth_rxbuffer_pos++;
		} else {
			ETH_SINK_STB = 0;
			s->eth_rxbuffer_len = 0;
			memset(s->eth_rxbuffer, 0, 1532);
		}
	}
}
Beispiel #2
0
static void eth_rx(struct device *port)
{
	struct eth_runtime *context = port->driver_data;
	struct eth_config *config = port->config->config_info;
	uint32_t base_addr = config->base_addr;
	struct net_buf *buf;
	uint32_t frm_len = 0;

	/* Check whether the RX descriptor is still owned by the device.  If not,
	 * process the received frame or an error that may have occurred.
	 */
	if (context->rx_desc.own == 1) {
		ETH_ERR("Spurious receive interrupt from Ethernet MAC.\n");
		return;
	}

	if (!net_driver_ethernet_is_opened()) {
		goto release_desc;
	}

	if (context->rx_desc.err_summary) {
		ETH_ERR("Error receiving frame: RDES0 = %08x, RDES1 = %08x.\n",
			context->rx_desc.rdes0, context->rx_desc.rdes1);
		goto release_desc;
	}

	frm_len = context->rx_desc.frm_len;
	if (frm_len > UIP_BUFSIZE) {
		ETH_ERR("Frame too large: %u.\n", frm_len);
		goto release_desc;
	}

	buf = ip_buf_get_reserve_rx(0);
	if (buf == NULL) {
		ETH_ERR("Failed to obtain RX buffer.\n");
		goto release_desc;
	}

	memcpy(net_buf_add(buf, frm_len), (void *)context->rx_buf, frm_len);
	uip_len(buf) = frm_len;

	net_driver_ethernet_recv(buf);

release_desc:
	/* Return ownership of the RX descriptor to the device. */
	context->rx_desc.own = 1;

	/* Request that the device check for an available RX descriptor, since
	 * ownership of the descriptor was just transferred to the device.
	 */
	eth_write(base_addr, REG_ADDR_RX_POLL_DEMAND, 1);
}
Beispiel #3
0
/* @brief Transmit the current Ethernet frame.
 *
 *        This procedure will block indefinitely until the Ethernet device is
 *        ready to accept a new outgoing frame.  It then copies the current
 *        Ethernet frame from the global uip_buf buffer to the device DMA
 *        buffer and signals to the device that a new frame is available to be
 *        transmitted.
 */
static int eth_tx(struct device *port, struct net_buf *buf)
{
	struct eth_runtime *context = port->driver_data;
	struct eth_config *config = port->config->config_info;
	uint32_t base_addr = config->base_addr;

	/* Wait until the TX descriptor is no longer owned by the device. */
	while (context->tx_desc.own == 1) {
	}

#ifdef CONFIG_ETHERNET_DEBUG
	/* Check whether an error occurred transmitting the previous frame. */
	if (context->tx_desc.err_summary) {
		ETH_ERR("Error transmitting frame: TDES0 = %08x, TDES1 = %08x.\n",
			context->tx_desc.tdes0, context->tx_desc.tdes1);
	}
#endif

	/* Transmit the next frame. */
	if (uip_len(buf) > UIP_BUFSIZE) {
		ETH_ERR("Frame too large to TX: %u\n", uip_len(buf));

		return -1;
	}

	memcpy((void *)context->tx_buf, uip_buf(buf), uip_len(buf));

	context->tx_desc.tx_buf1_sz = uip_len(buf);

	context->tx_desc.own = 1;

	/* Request that the device check for an available TX descriptor, since
	 * ownership of the descriptor was just transferred to the device.
	 */
	eth_write(base_addr, REG_ADDR_TX_POLL_DEMAND, 1);

	return 1;
}
Beispiel #4
0
static void eth_dw_isr(struct device *port)
{
	struct eth_runtime *context = port->driver_data;
	uint32_t base_addr = context->base_addr;
	uint32_t int_status;

	int_status = eth_read(base_addr, REG_ADDR_STATUS);

#ifdef CONFIG_SHARED_IRQ
	/* If using with shared IRQ, this function will be called
	 * by the shared IRQ driver. So check here if the interrupt
	 * is coming from the GPIO controller (or somewhere else).
	 */
	if ((int_status & STATUS_RX_INT) == 0) {
		return;
	}
#endif

	eth_rx(port);

	/* Acknowledge the interrupt. */
	eth_write(base_addr, REG_ADDR_STATUS, STATUS_NORMAL_INT | STATUS_RX_INT);
}
int write_command(int num, int adr, char* block){
  if(DEBUG>10){
    if(block==0) std::cout<<"DEBUG[commands.cpp]  write_command("<<num<<",0,NULL)"<<std::endl;
    else std::cout<<"DEBUG[commands.cpp]  write_command("<<num<<","<<adr<<",{"<<HEX(0xff&block[0])<<HEX(0xff&block[1])<<"...})"<<DEC()<<std::endl;
  }
  nwdat=12; // so there are no troubles sending a small packet
  char* command = wdat;
  switch(num){
  case 0:
    command[0]=0xf0;
    command[1]=0xf0;
    command[2]=0x00;
    command[3]=0x00;
    break;
  case 1:
    command[0]=0xf1;
    command[1]=0xf1;
    command[2]=0x00;
    command[3]=0x00;
    break;
  case 2:
    command[0]=0xf2;
    command[1]=0xf2;
    command[2]=0x00;
    command[3]=0x00;
    break;
  case 3: // read command
    command[0]=0xf3;
    command[1]=0xf3;
    command[2]=adr&0x00ff;
    command[3]=(adr&0xff00)>>8;
    break;
  case 5:
    command[0]=0xf5;
    command[1]=0xf5;
    command[2]=0x00;
    command[3]=0x00;
    break;
  case 7: // write command
    command[0]=0xf7;
    command[1]=0xf7;
    command[2]=adr&0x00ff;
    command[3]=(adr&0xff00)>>8;
    memcpy((void*)&command[4], (const void*)&block[0], RAMPAGE_SIZE);  // fill 4KB
    nwdat=4+RAMPAGE_SIZE;
    break;
  case 0xe: // send out to otmb (not used now)
    command[0]=0xfe;
    command[1]=0xfe;
    command[2]=adr&0x00ff;
    command[3]=(adr&0xff00)>>8;
    break;
  case 0xd: // send out to otmb
    command[0]=0xfd;
    command[1]=0xfd;
    command[2]=adr&0x00ff;
    command[3]=0x00;
    break;
  default:
    if(DEBUG>10) std::cout<<"DEBUG[commands.cpp]  write_command return -1  <== command number "<<num<<" not recognized"<<std::endl;
    return -1;
  }

  // testing >>>
  //std::cout<<"TESTING: write_command return 0"<<std::endl;
  //return 0;
  // <<< testing
  
  int n=eth_write();
  
  if(n!=nwdat){
    if(DEBUG>10) std::cout<<"DEBUG[commands.cpp]  write_command return -2  <== n="<<n<<" != nwdat="<<nwdat<<std::endl;
    return -2;
  }
  if(DEBUG>10) std::cout<<"DEBUG[commands.cpp]  write_command return 0"<<std::endl;
  return 0;
}
Beispiel #6
0
static int eth_initialize(struct device *port)
{
	struct eth_runtime *context = port->driver_data;
	const struct eth_config *config = port->config->config_info;
	uint32_t base_addr;

	union {
		struct {
			uint8_t bytes[6];
			uint8_t pad[2];
		} __attribute__((packed));
		uint32_t words[2];
	} mac_addr;

	if (!eth_setup(port))
		return -EPERM;

	base_addr = context->base_addr;

	/* Read the MAC address from the device. */
	mac_addr.words[1] = eth_read(base_addr, REG_ADDR_MACADDR_HI);
	mac_addr.words[0] = eth_read(base_addr, REG_ADDR_MACADDR_LO);

	net_set_mac(mac_addr.bytes, sizeof(mac_addr.bytes));

	/* Initialize the frame filter enabling unicast messages */
	eth_write(base_addr, REG_ADDR_MAC_FRAME_FILTER, MAC_FILTER_4_PM);

	/* Initialize transmit descriptor. */
	context->tx_desc.tdes0 = 0;
	context->tx_desc.tdes1 = 0;

	context->tx_desc.buf1_ptr = (uint8_t *)context->tx_buf;
	context->tx_desc.tx_end_of_ring = 1;
	context->tx_desc.first_seg_in_frm = 1;
	context->tx_desc.last_seg_in_frm = 1;
	context->tx_desc.tx_end_of_ring = 1;

	/* Initialize receive descriptor. */
	context->rx_desc.rdes0 = 0;
	context->rx_desc.rdes1 = 0;

	context->rx_desc.buf1_ptr = (uint8_t *)context->rx_buf;
	context->rx_desc.own = 1;
	context->rx_desc.first_desc = 1;
	context->rx_desc.last_desc = 1;
	context->rx_desc.rx_buf1_sz = UIP_BUFSIZE;
	context->rx_desc.rx_end_of_ring = 1;

	/* Install transmit and receive descriptors. */
	eth_write(base_addr, REG_ADDR_RX_DESC_LIST, (uint32_t)&context->rx_desc);
	eth_write(base_addr, REG_ADDR_TX_DESC_LIST, (uint32_t)&context->tx_desc);

	eth_write(base_addr, REG_ADDR_MAC_CONF,
		  /* Set the RMII speed to 100Mbps */
		  MAC_CONF_14_RMII_100M |
		  /* Enable full-duplex mode */
		  MAC_CONF_11_DUPLEX |
		  /* Enable transmitter */
		  MAC_CONF_3_TX_EN |
		  /* Enable receiver */
		  MAC_CONF_2_RX_EN);

	eth_write(base_addr, REG_ADDR_INT_ENABLE,
		  INT_ENABLE_NORMAL |
		  /* Enable receive interrupts */
		  INT_ENABLE_RX);

	/* Mask all the MMC interrupts */
	eth_write(base_addr, REG_MMC_RX_INTR_MASK, MMC_DEFAULT_MASK);
	eth_write(base_addr, REG_MMC_TX_INTR_MASK, MMC_DEFAULT_MASK);
	eth_write(base_addr, REG_MMC_RX_IPC_INTR_MASK, MMC_DEFAULT_MASK);

	eth_write(base_addr, REG_ADDR_DMA_OPERATION,
		  /* Enable receive store-and-forward mode for simplicity. */
		  OP_MODE_25_RX_STORE_N_FORWARD |
		  /* Enable transmit store-and-forward mode for simplicity. */
		  OP_MODE_21_TX_STORE_N_FORWARD |
		  /* Place the transmitter state machine in the Running state. */
		  OP_MODE_13_START_TX |
		  /* Place the receiver state machine in the Running state. */
		  OP_MODE_1_START_RX);

	SYS_LOG_INF("Enabled 100M full-duplex mode.");

	net_driver_ethernet_register_tx(eth_net_tx);

	config->config_func(port);

	return 0;
}