net: L2 might need private data per-interface

Allocate the right amount of space for L2's context.

Change-Id: Ia2f4f4162334e9e9c26dc95230abdfde5986e052
Signed-off-by: Tomasz Bursztyka <tomasz.bursztyka@linux.intel.com>
This commit is contained in:
Tomasz Bursztyka 2016-06-16 13:50:38 +02:00 committed by Jukka Rissanen
commit 3560f58293
9 changed files with 66 additions and 9 deletions

View file

@ -434,10 +434,12 @@ static struct slip_context slip_context_data;
#if defined(CONFIG_SLIP_TAP) && defined(CONFIG_NET_L2_ETHERNET)
#define _SLIP_L2_LAYER ETHERNET_L2
#define _SLIP_L2_CTX_TYPE NET_L2_GET_CTX_TYPE(ETHERNET_L2)
#else
#define _SLIP_L2_LAYER DUMMY_L2
#define _SLIP_L2_CTX_TYPE NET_L2_GET_CTX_TYPE(DUMMY_L2)
#endif
NET_DEVICE_INIT(slip, CONFIG_SLIP_DRV_NAME, slip_init, &slip_context_data,
NULL, CONFIG_KERNEL_INIT_PRIORITY_DEFAULT, &slip_if_api,
_SLIP_L2_LAYER, 127);
_SLIP_L2_LAYER, _SLIP_L2_CTX_TYPE, 127);

View file

@ -173,6 +173,14 @@
__net_if_end = .;
} GROUP_DATA_LINK_IN(RAMABLE_REGION, ROMABLE_REGION)
SECTION_DATA_PROLOGUE(net_l2_data, (OPTIONAL),)
{
__net_l2_data_start = .;
*(".net_l2.data")
KEEP(*(SORT_BY_NAME(".net_l2.data*")))
__net_l2_data_end = .;
} GROUP_DATA_LINK_IN(RAMABLE_REGION, ROMABLE_REGION)
SECTION_DATA_PROLOGUE(net_nbr, (OPTIONAL),)
{
__net_nbr_start = .;

View file

@ -33,3 +33,18 @@
__devconfig_end = .;
} GROUP_LINK_IN(ROMABLE_REGION)
SECTION_PROLOGUE(net_l2_init, (OPTIONAL),)
{
__net_l2_start = .;
*(".net_l2.init")
KEEP(*(SORT_BY_NAME(".net_l2.init*")))
__net_l2_end = .;
} GROUP_LINK_IN(ROMABLE_REGION)
SECTION_PROLOGUE(net_l2, (OPTIONAL),)
{
__net_l2_start = .;
*(".net_l2.init")
KEEP(*(SORT_BY_NAME(".net_l2.init*")))
__net_l2_end = .;
} GROUP_LINK_IN(ROMABLE_REGION)

View file

@ -150,6 +150,9 @@ struct net_if {
/** Interface's L2 layer */
const struct net_l2 const *l2;
/** Interfaces's private L2 data pointer */
void *l2_data;
/** The hardware link address */
struct net_linkaddr link_addr;
@ -264,6 +267,18 @@ static inline uint16_t net_if_get_ll_reserve(struct net_if *iface,
return iface->l2->reserve(iface, (void *)dst_ip6);
}
/**
* @brief Get a pointer on L2's private data
*
* @param iface a valid pointer to a network interface structure
*
* @return a pointer on the iface's l2 data
*/
static inline void *net_if_l2_data(struct net_if *iface)
{
return iface->l2_data;
}
/**
* @brief Get an network interface's device
*
@ -865,22 +880,26 @@ struct net_if_api {
};
#define NET_IF_GET_NAME(dev_name, sfx) (__net_if_##dev_name_##sfx)
#define NET_IF_GET(dev_name, sfx) (&NET_IF_GET_NAME(dev_name, sfx))
#define NET_IF_GET(dev_name, sfx) \
((struct net_if *)&NET_IF_GET_NAME(dev_name, sfx))
#define NET_IF_INIT(dev_name, sfx, _l2, _mtu) \
static struct net_if (NET_IF_GET_NAME(dev_name, sfx)) __used \
__attribute__((__section__(".net_if.data"))) = { \
.dev = &(__device_##dev_name), \
.l2 = &(NET_L2_GET_NAME(_l2)), \
.l2_data = &(NET_L2_GET_DATA(dev_name, sfx)), \
.mtu = _mtu, \
}
/* Network device intialization macro */
#define NET_DEVICE_INIT(dev_name, drv_name, init_fn, \
data, cfg_info, prio, api, l2, mtu) \
data, cfg_info, prio, api, l2, \
l2_ctx_type, mtu) \
DEVICE_AND_API_INIT(dev_name, drv_name, init_fn, data, \
cfg_info, NANOKERNEL, prio, api); \
NET_L2_DATA_INIT(dev_name, 0, l2_ctx_type); \
NET_IF_INIT(dev_name, 0, l2, mtu)
#ifdef __cplusplus

View file

@ -55,16 +55,19 @@ struct net_l2 {
#define NET_L2_GET_NAME(_name) (__net_l2_##_name)
#define NET_L2_DECLARE_PUBLIC(_name) \
extern const struct net_l2 const NET_L2_GET_NAME(_name)
#define NET_L2_GET_CTX_TYPE(_name) _name##_CTX_TYPE
extern struct net_l2 __net_l2_start[];
#ifdef CONFIG_NET_L2_DUMMY
#define DUMMY_L2 dummy
#define DUMMY_L2 DUMMY
#define DUMMY_L2_CTX_TYPE void*
NET_L2_DECLARE_PUBLIC(DUMMY_L2);
#endif /* CONFIG_NET_L2_DUMMY */
#ifdef CONFIG_NET_L2_ETHERNET
#define ETHERNET_L2 ethernet
#define ETHERNET_L2 ETHERNET
#define ETHERNET_L2_CTX_TYPE void*
NET_L2_DECLARE_PUBLIC(ETHERNET_L2);
#endif /* CONFIG_NET_L2_ETHERNET */
@ -78,6 +81,12 @@ extern struct net_l2 __net_l2_end[];
.reserve = (_reserve_fn), \
}
#define NET_L2_GET_DATA(name, sfx) (__net_l2_data_##name##sfx)
#define NET_L2_DATA_INIT(name, sfx, ctx_type) \
static ctx_type NET_L2_GET_DATA(name, sfx) __used \
__attribute__((__section__(".net_l2.data")));
#ifdef __cplusplus
}
#endif

View file

@ -154,7 +154,7 @@ static struct net_if_api net_6lo_if_api = {
NET_DEVICE_INIT(net_6lo_test, "net_6lo_test",
net_6lo_dev_init, NULL, NULL,
CONFIG_KERNEL_INIT_PRIORITY_DEFAULT,
&net_6lo_if_api, DUMMY_L2, 127);
&net_6lo_if_api, DUMMY_L2, NET_L2_GET_CTX_TYPE(DUMMY_L2), 127);
static bool compare_data(struct net_buf *buf, struct net_6lo_data *data)
{

View file

@ -314,14 +314,16 @@ static struct net_if_api net_arp_if_api = {
#if defined(CONFIG_NET_ARP) && defined(CONFIG_NET_L2_ETHERNET)
#define _ETH_L2_LAYER ETHERNET_L2
#define _ETH_L2_CTX_TYPE NET_L2_GET_CTX_TYPE(ETHERNET_L2)
#else
#define _ETH_L2_LAYER DUMMY_L2
#define _ETH_L2_CTX_TYPE NET_L2_GET_CTX_TYPE(DUMMY_L2)
#endif
NET_DEVICE_INIT(net_arp_test, "net_arp_test",
net_arp_dev_init, &net_arp_context_data, NULL,
CONFIG_KERNEL_INIT_PRIORITY_DEFAULT,
&net_arp_if_api, _ETH_L2_LAYER, 127);
&net_arp_if_api, _ETH_L2_LAYER, _ETH_L2_CTX_TYPE, 127);
void main_fiber(void)
{

View file

@ -159,11 +159,12 @@ static struct net_if_api net_test_if_api = {
};
#define _ETH_L2_LAYER DUMMY_L2
#define _ETH_L2_CTX_TYPE NET_L2_GET_CTX_TYPE(DUMMY_L2)
NET_DEVICE_INIT(net_addr_test, "net_addr_test",
net_test_init, &net_test_context_data, NULL,
CONFIG_KERNEL_INIT_PRIORITY_DEFAULT,
&net_test_if_api, _ETH_L2_LAYER, 127);
&net_test_if_api, _ETH_L2_LAYER, _ETH_L2_CTX_TYPE, 127);
#ifdef CONFIG_MICROKERNEL
void mainloop(void)

View file

@ -124,11 +124,12 @@ static struct net_if_api net_udp_if_api = {
};
#define _ETH_L2_LAYER DUMMY_L2
#define _ETH_L2_CTX_TYPE NET_L2_GET_CTX_TYPE(DUMMY_L2)
NET_DEVICE_INIT(net_udp_test, "net_udp_test",
net_udp_dev_init, &net_udp_context_data, NULL,
CONFIG_KERNEL_INIT_PRIORITY_DEFAULT,
&net_udp_if_api, _ETH_L2_LAYER, 127);
&net_udp_if_api, _ETH_L2_LAYER, _ETH_L2_CTX_TYPE, 127);
struct ud {
const struct sockaddr *remote_addr;