@@ -22,6 +22,15 @@
#define ODP_NETMAP_RING_HW 0
#define ODP_NETMAP_RING_SW 1
+
+/* Since we allow more than one thread to open the same device
+ * this struct uinquely identifies a device so that proper locking
+ * can be implemented
+ */
+typedef struct {
+ char ifname[IFNAMSIZ];
+} netmap_dev_t;
+
/** Packet socket using netmap mmaped rings for both Rx and Tx */
typedef struct {
odp_buffer_pool_t pool;
@@ -35,7 +44,7 @@ typedef struct {
struct netmap_ring *txring;
odp_queue_t tx_access; /* exclusive access to send packets */
uint32_t if_flags;
- char ifname[32];
+ netmap_dev_t *nm_dev;
} pkt_netmap_t;
/**
@@ -60,9 +60,14 @@ static struct nm_desc mmap_desc; /** Used to store the mmap address;
subsequent calls to nm_open */
static odp_spinlock_t nm_global_lock;
+#define MAX_DEVS 32
+static netmap_dev_t netmap_devs[MAX_DEVS];
+static int nm_dev_cnt;
+
int odp_netmap_init_global(void)
{
odp_spinlock_init(&nm_global_lock);
+ memset(netmap_devs, 0, sizeof(netmap_devs));
return 0;
}
@@ -81,7 +86,7 @@ static int nm_do_ioctl(pkt_netmap_t * const pkt_nm, unsigned long cmd,
}
memset(&ifr, 0, sizeof(ifr));
- strncpy(ifr.ifr_name, pkt_nm->ifname, sizeof(ifr.ifr_name));
+ strncpy(ifr.ifr_name, pkt_nm->nm_dev->ifname, sizeof(ifr.ifr_name));
switch (cmd) {
case SIOCSIFFLAGS:
@@ -125,7 +130,12 @@ int setup_pkt_netmap(pkt_netmap_t * const pkt_nm, const char *netdev,
odp_packet_t pkt;
uint8_t *pkt_buf;
uint8_t *l2_hdr;
- int ret;
+ int i, ret;
+
+ if (nm_dev_cnt == MAX_DEVS) {
+ ODP_ERR("Maximum number of devices reached: %d\n", nm_dev_cnt);
+ return -1;
+ }
if (pool == ODP_BUFFER_POOL_INVALID)
return -1;
@@ -146,7 +156,6 @@ int setup_pkt_netmap(pkt_netmap_t * const pkt_nm, const char *netdev,
odph_packet_free(pkt);
- strncpy(pkt_nm->ifname, netdev, sizeof(pkt_nm->ifname));
snprintf(ifname, sizeof(ifname), "netmap:%s", netdev);
odp_spinlock_lock(&nm_global_lock);
@@ -170,6 +179,19 @@ int setup_pkt_netmap(pkt_netmap_t * const pkt_nm, const char *netdev,
mmap_desc.mem = pkt_nm->desc->mem;
mmap_desc.memsize = pkt_nm->desc->memsize;
}
+ /* Lookup dev */
+ for (i = 0; i < nm_dev_cnt; i++) {
+ if (!strcmp(netmap_devs[i].ifname, netdev)) {
+ pkt_nm->nm_dev = &netmap_devs[i];
+ break;
+ }
+ }
+ if (i == nm_dev_cnt) {
+ nm_dev_cnt++;
+ snprintf(netmap_devs[i].ifname, sizeof(netmap_devs[i].ifname),
+ "%s", netdev);
+ pkt_nm->nm_dev = &netmap_devs[i];
+ }
odp_spinlock_unlock(&nm_global_lock);
ODP_DBG("[%04d] mmap addr %p\n",
@@ -187,7 +209,7 @@ int setup_pkt_netmap(pkt_netmap_t * const pkt_nm, const char *netdev,
if ((pkt_nm->if_flags & IFF_UP) == 0) {
ODP_DBG("[%04d] %s is down, bringing up...\n",
odp_thread_id(),
- pkt_nm->ifname);
+ pkt_nm->nm_dev->ifname);
pkt_nm->if_flags |= IFF_UP;
}
if (ETH_PROMISC) {
Signed-off-by: Ciprian Barbu <ciprian.barbu@linaro.org> --- platform/linux-netmap/include/odp_packet_netmap.h | 11 ++++++++- platform/linux-netmap/odp_packet_netmap.c | 30 ++++++++++++++++++++--- 2 files changed, 36 insertions(+), 5 deletions(-)