Ejemplo n.º 1
0
static void net_iface_init(struct net_if *iface)
{
	u8_t *mac = net_iface_get_mac(net_if_get_device(iface));

	net_if_set_link_addr(iface, mac, sizeof(struct net_eth_addr),
			     NET_LINK_ETHERNET);
}
Ejemplo n.º 2
0
static void slip_iface_init(struct net_if *iface)
{
	struct slip_context *slip = net_if_get_device(iface)->driver_data;
	struct net_linkaddr *ll_addr = slip_get_mac(slip);

	slip->init_done = true;
	slip->iface = iface;

	if (CONFIG_SLIP_MAC_ADDR[0] != 0) {
		if (_slip_mac_addr_from_str(slip, CONFIG_SLIP_MAC_ADDR) < 0) {
			goto use_random_mac;
		}
	} else {
use_random_mac:
		/* 00-00-5E-00-53-xx Documentation RFC 7042 */
		slip->mac_addr[0] = 0x00;
		slip->mac_addr[1] = 0x00;
		slip->mac_addr[2] = 0x5E;
		slip->mac_addr[3] = 0x00;
		slip->mac_addr[4] = 0x53;
		slip->mac_addr[5] = sys_rand32_get();
	}
	net_if_set_link_addr(iface, ll_addr->addr, ll_addr->len,
			     NET_LINK_ETHERNET);
}
Ejemplo n.º 3
0
static int bt_connect(u32_t mgmt_request, struct net_if *iface, void *data,
		      size_t len)
{
	struct bt_context *ctxt = net_if_get_device(iface)->driver_data;
	bt_addr_le_t *addr = data;

	if (len != sizeof(*addr)) {
		NET_ERR("Invalid address");
		return -EINVAL;
	}

	if (ctxt->ipsp_chan.chan.conn) {
		NET_ERR("No channels available");
		return -ENOMEM;
	}

	if (default_conn) {
		return bt_l2cap_chan_connect(default_conn,
					     &ctxt->ipsp_chan.chan,
					     L2CAP_IPSP_PSM);
	}

	default_conn = bt_conn_create_le(addr, BT_LE_CONN_PARAM_DEFAULT);

	return 0;
}
Ejemplo n.º 4
0
static void eth_iface_init(struct net_if *iface)
{
	struct eth_context *ctx = net_if_get_device(iface)->driver_data;
	struct net_linkaddr *ll_addr = eth_get_mac(ctx);

	ctx->iface = iface;

	ethernet_init(iface);

	if (ctx->init_done) {
		return;
	}

	net_lldp_set_lldpdu(iface);

	ctx->init_done = true;

#if defined(CONFIG_ETH_NATIVE_POSIX_RANDOM_MAC)
	/* 00-00-5E-00-53-xx Documentation RFC 7042 */
	ctx->mac_addr[0] = 0x00;
	ctx->mac_addr[1] = 0x00;
	ctx->mac_addr[2] = 0x5E;
	ctx->mac_addr[3] = 0x00;
	ctx->mac_addr[4] = 0x53;
	ctx->mac_addr[5] = sys_rand32_get();

	/* The TUN/TAP setup script will by default set the MAC address of host
	 * interface to 00:00:5E:00:53:FF so do not allow that.
	 */
	if (ctx->mac_addr[5] == 0xff) {
		ctx->mac_addr[5] = 0x01;
	}
#else
	if (CONFIG_ETH_NATIVE_POSIX_MAC_ADDR[0] != 0) {
		if (net_bytes_from_str(ctx->mac_addr, sizeof(ctx->mac_addr),
				       CONFIG_ETH_NATIVE_POSIX_MAC_ADDR) < 0) {
			LOG_ERR("Invalid MAC address %s",
				CONFIG_ETH_NATIVE_POSIX_MAC_ADDR);
		}
	}
#endif

	net_if_set_link_addr(iface, ll_addr->addr, ll_addr->len,
			     NET_LINK_ETHERNET);

	ctx->if_name = ETH_NATIVE_POSIX_DRV_NAME;

	ctx->dev_fd = eth_iface_create(ctx->if_name, false);
	if (ctx->dev_fd < 0) {
		LOG_ERR("Cannot create %s (%d)", ctx->if_name, ctx->dev_fd);
	} else {
		/* Create a thread that will handle incoming data from host */
		create_rx_handler(ctx);

		eth_setup_host(ctx->if_name);

		eth_start_script(ctx->if_name);
	}
}
Ejemplo n.º 5
0
static void bt_iface_init(struct net_if *iface)
{
	struct bt_context *ctxt = net_if_get_device(iface)->driver_data;

	NET_DBG("iface %p", iface);

	ctxt->iface = iface;
}
Ejemplo n.º 6
0
static int net_bt_enable(struct net_if *iface, bool state)
{
	struct bt_context *ctxt = net_if_get_device(iface)->driver_data;

	NET_DBG("iface %p %s", iface, state ? "up" : "down");

	if (state && !ctxt->ipsp_chan.chan.conn) {
		return -ENETDOWN;
	}

	return 0;
}
Ejemplo n.º 7
0
static void upipe_iface_init(struct net_if *iface)
{
	struct device *dev = net_if_get_device(iface);
	struct upipe_context *upipe = dev->driver_data;
	u8_t *mac = get_mac(dev);

	net_if_set_link_addr(iface, mac, 8, NET_LINK_IEEE802154);

	upipe_dev = dev;
	upipe->iface = iface;

	ieee802154_init(iface);
}
Ejemplo n.º 8
0
static int bt_iface_send(struct net_if *iface, struct net_buf *buf)
{
	struct bt_context *ctxt = net_if_get_device(iface)->driver_data;
	int ret;

	NET_DBG("iface %p buf %p len %u", iface, buf, net_buf_frags_len(buf));

	ret = bt_l2cap_chan_send(&ctxt->ipsp_chan.chan, buf);
	if (ret < 0) {
		return ret;
	}

	return ret;
}
Ejemplo n.º 9
0
static void bt_iface_init(struct net_if *iface)
{
	struct bt_context *ctxt = net_if_get_device(iface)->driver_data;

	NET_DBG("iface %p", iface);

	ctxt->iface = iface;

#if defined(CONFIG_NET_L2_BLUETOOTH_ZEP1656)
	/* Workaround Linux bug, see:
	 * https://jira.zephyrproject.org/browse/ZEP-1656
	 */
	atomic_set_bit(iface->flags, NET_IF_POINTOPOINT);
#endif
}
Ejemplo n.º 10
0
static void nrf5_iface_init(struct net_if *iface)
{
	struct device *dev = net_if_get_device(iface);
	struct nrf5_802154_data *nrf5_radio = NRF5_802154_DATA(dev);

	SYS_LOG_DBG("");

	nrf5_get_eui64(nrf5_radio->mac);
	net_if_set_link_addr(iface,
			     nrf5_radio->mac,
			     sizeof(nrf5_radio->mac),
			     NET_LINK_IEEE802154);

	nrf5_radio->iface = iface;
	ieee802154_init(iface);
}
Ejemplo n.º 11
0
static int bt_disconnect(u32_t mgmt_request, struct net_if *iface,
			 void *data, size_t len)
{
	struct bt_context *ctxt = net_if_get_device(iface)->driver_data;

	if (!ctxt->ipsp_chan.chan.conn) {
		NET_ERR("Not connected");
		return -ENOTCONN;
	}

	/* Release connect reference in case of central/router role */
	if (default_conn) {
		bt_conn_unref(default_conn);
		default_conn = NULL;
	}

	return bt_l2cap_chan_disconnect(&ctxt->ipsp_chan.chan);
}
Ejemplo n.º 12
0
static enum net_verdict net_bt_send(struct net_if *iface, struct net_buf *buf)
{
	struct bt_context *ctxt = net_if_get_device(iface)->driver_data;

	NET_DBG("iface %p buf %p len %u", iface, buf, net_buf_frags_len(buf));

	/* Only accept IPv6 packets */
	if (net_nbuf_family(buf) != AF_INET6) {
		return NET_DROP;
	}

	if (!net_6lo_compress(buf, true, NULL)) {
		NET_DBG("Packet compression failed");
		return NET_DROP;
	}

	net_if_queue_tx(ctxt->iface, buf);

	return NET_OK;
}
Ejemplo n.º 13
0
static enum net_verdict net_bt_send(struct net_if *iface, struct net_pkt *pkt)
{
	struct bt_context *ctxt = net_if_get_device(iface)->driver_data;

	NET_DBG("iface %p pkt %p len %zu", iface, pkt, net_pkt_get_len(pkt));

	/* Only accept IPv6 packets */
	if (net_pkt_family(pkt) != AF_INET6) {
		return NET_DROP;
	}

	if (!net_6lo_compress(pkt, true, NULL)) {
		NET_DBG("Packet compression failed");
		return NET_DROP;
	}

	net_if_queue_tx(ctxt->iface, pkt);

	return NET_OK;
}
Ejemplo n.º 14
0
static int bt_iface_send(struct net_if *iface, struct net_pkt *pkt)
{
	struct bt_context *ctxt = net_if_get_device(iface)->driver_data;
	struct net_buf *frags;
	int ret;

	NET_DBG("iface %p pkt %p len %zu", iface, pkt, net_pkt_get_len(pkt));

	/* Dettach data fragments for packet */
	frags = pkt->frags;
	pkt->frags = NULL;

	net_pkt_unref(pkt);

	ret = bt_l2cap_chan_send(&ctxt->ipsp_chan.chan, frags);
	if (ret < 0) {
		return ret;
	}

	return ret;
}
Ejemplo n.º 15
0
static void eth0_iface_init(struct net_if *iface)
{
	struct device *const dev = net_if_get_device(iface);
	struct eth_sam_dev_data *const dev_data = DEV_DATA(dev);
	const struct eth_sam_dev_cfg *const cfg = DEV_CFG(dev);
	u32_t gmac_ncfgr_val;
	u32_t link_status;
	int result;

	dev_data->iface = iface;

	/* Initialize GMAC driver, maximum frame length is 1518 bytes */
	gmac_ncfgr_val =
		  GMAC_NCFGR_MTIHEN  /* Multicast Hash Enable */
		| GMAC_NCFGR_LFERD   /* Length Field Error Frame Discard */
		| GMAC_NCFGR_RFCS    /* Remove Frame Check Sequence */
		| GMAC_NCFGR_RXCOEN; /* Receive Checksum Offload Enable */
	result = gmac_init(cfg->regs, gmac_ncfgr_val);
	if (result < 0) {
		SYS_LOG_ERR("Unable to initialize ETH driver");
		return;
	}

#ifdef CONFIG_ETH_SAM_GMAC_MAC_I2C_EEPROM
	/* Read MAC address from an external EEPROM */
	get_mac_addr_from_i2c_eeprom(dev_data->mac_addr);
#endif

	SYS_LOG_INF("MAC: %x:%x:%x:%x:%x:%x",
		    dev_data->mac_addr[0], dev_data->mac_addr[1],
		    dev_data->mac_addr[2], dev_data->mac_addr[3],
		    dev_data->mac_addr[4], dev_data->mac_addr[5]);

	/* Set MAC Address for frame filtering logic */
	mac_addr_set(cfg->regs, 0, dev_data->mac_addr);

	/* Register Ethernet MAC Address with the upper layer */
	net_if_set_link_addr(iface, dev_data->mac_addr,
			     sizeof(dev_data->mac_addr),
			     NET_LINK_ETHERNET);

	/* Initialize GMAC queues */
	/* Note: Queues 1 and 2 are not used, configured to stay idle */
	priority_queue_init_as_idle(cfg->regs, &dev_data->queue_list[2]);
	priority_queue_init_as_idle(cfg->regs, &dev_data->queue_list[1]);
	result = queue_init(cfg->regs, &dev_data->queue_list[0]);
	if (result < 0) {
		SYS_LOG_ERR("Unable to initialize ETH queue");
		return;
	}

	/* PHY initialize */
	result = phy_sam_gmac_init(&cfg->phy);
	if (result < 0) {
		SYS_LOG_ERR("ETH PHY Initialization Error");
		return;
	}
	/* PHY auto-negotiate link parameters */
	result = phy_sam_gmac_auto_negotiate(&cfg->phy, &link_status);
	if (result < 0) {
		SYS_LOG_ERR("ETH PHY auto-negotiate sequence failed");
		return;
	}

	/* Set up link parameters */
	link_configure(cfg->regs, link_status);
}
Ejemplo n.º 16
0
static int eth_tx(struct net_if *iface, struct net_pkt *pkt)
{
	struct device *const dev = net_if_get_device(iface);
	const struct eth_sam_dev_cfg *const cfg = DEV_CFG(dev);
	struct eth_sam_dev_data *const dev_data = DEV_DATA(dev);
	Gmac *gmac = cfg->regs;
	struct gmac_queue *queue = &dev_data->queue_list[0];
	struct gmac_desc_list *tx_desc_list = &queue->tx_desc_list;
	struct gmac_desc *tx_desc;
	struct net_buf *frag;
	u8_t *frag_data;
	u16_t frag_len;
	u32_t err_tx_flushed_count_at_entry = queue->err_tx_flushed_count;
	unsigned int key;

	__ASSERT(pkt, "buf pointer is NULL");
	__ASSERT(pkt->frags, "Frame data missing");

	SYS_LOG_DBG("ETH tx");

	/* First fragment is special - it contains link layer (Ethernet
	 * in our case) header. Modify the data pointer to account for more data
	 * in the beginning of the buffer.
	 */
	net_buf_push(pkt->frags, net_pkt_ll_reserve(pkt));

	frag = pkt->frags;
	while (frag) {
		frag_data = frag->data;
		frag_len = frag->len;

		/* Assure cache coherency before DMA read operation */
		DCACHE_CLEAN(frag_data, frag_len);

		k_sem_take(&queue->tx_desc_sem, K_FOREVER);

		/* The following section becomes critical and requires IRQ lock
		 * / unlock protection only due to the possibility of executing
		 * tx_error_handler() function.
		 */
		key = irq_lock();

		/* Check if tx_error_handler() function was executed */
		if (queue->err_tx_flushed_count != err_tx_flushed_count_at_entry) {
			irq_unlock(key);
			return -EIO;
		}

		tx_desc = &tx_desc_list->buf[tx_desc_list->head];

		/* Update buffer descriptor address word */
		tx_desc->w0 = (u32_t)frag_data;
		/* Guarantee that address word is written before the status
		 * word to avoid race condition.
		 */
		__DMB();  /* data memory barrier */
		/* Update buffer descriptor status word (clear used bit) */
		tx_desc->w1 =
			  (frag_len & GMAC_TXW1_LEN)
			| (!frag->frags ? GMAC_TXW1_LASTBUFFER : 0)
			| (tx_desc_list->head == tx_desc_list->len - 1
			   ? GMAC_TXW1_WRAP : 0);

		/* Update descriptor position */
		MODULO_INC(tx_desc_list->head, tx_desc_list->len);

		__ASSERT(tx_desc_list->head != tx_desc_list->tail,
			 "tx_desc_list overflow");

		irq_unlock(key);

		/* Continue with the rest of fragments (only data) */
		frag = frag->frags;
	}

	key = irq_lock();

	/* Check if tx_error_handler() function was executed */
	if (queue->err_tx_flushed_count != err_tx_flushed_count_at_entry) {
		irq_unlock(key);
		return -EIO;
	}

	/* Ensure the descriptor following the last one is marked as used */
	tx_desc = &tx_desc_list->buf[tx_desc_list->head];
	tx_desc->w1 |= GMAC_TXW1_USED;

	/* Account for a sent frame */
	ring_buf_put(&queue->tx_frames, POINTER_TO_UINT(pkt));

	irq_unlock(key);

	/* Start transmission */
	gmac->GMAC_NCR |= GMAC_NCR_TSTART;

	return 0;
}