summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMarcin Miklas <marcin.miklas@symphonyteleca.com>2015-09-23 16:34:24 +0200
committerMarcin Miklas <marcin.miklas@symphonyteleca.com>2015-09-23 21:34:50 +0200
commit3b38ccddce5649436fc70438009f518d3113103e (patch)
treec61ca87a9c808d942b6fa8f688c25c3c30f2fe94
parent639149eb1f552ac39a41b3846f604ade04cac9ec (diff)
downloadOpen-AVB-3b38ccddce5649436fc70438009f518d3113103e.tar.gz
Create pool of tx buffers from multiple dma pages.
-rw-r--r--lib/avtp_pipeline/platform/Linux/rawsock/igb_rawsock.c13
-rw-r--r--lib/avtp_pipeline/platform/Linux/rawsock/igb_rawsock.h2
-rw-r--r--lib/avtp_pipeline/platform/Linux/rawsock/openavb_rawsock.c1
-rw-r--r--lib/avtp_pipeline/platform/x86_i210/openavb_ether_hal.c147
-rw-r--r--lib/avtp_pipeline/platform/x86_i210/openavb_ether_hal.h11
5 files changed, 116 insertions, 58 deletions
diff --git a/lib/avtp_pipeline/platform/Linux/rawsock/igb_rawsock.c b/lib/avtp_pipeline/platform/Linux/rawsock/igb_rawsock.c
index 92952487..d4a6a8b7 100644
--- a/lib/avtp_pipeline/platform/Linux/rawsock/igb_rawsock.c
+++ b/lib/avtp_pipeline/platform/Linux/rawsock/igb_rawsock.c
@@ -151,7 +151,7 @@ U8 *igbRawsockGetTxFrame(void *pvRawsock, bool blocking, unsigned int *len)
U8 *ret = NULL;
- rawsock->tx_packet = igbGetTxPacket(rawsock->igb_dev, rawsock->queue);
+ rawsock->tx_packet = igbGetTxPacket(rawsock->igb_dev);
if (rawsock->tx_packet) {
*len = rawsock->base.frameSize;
@@ -218,3 +218,14 @@ int igbRawsockSend(void *pvRawsock)
AVB_TRACE_EXIT(AVB_TRACE_RAWSOCK_DETAIL);
return 1;
}
+
+int igbRawsockTxBufLevel(void *pvRawsock)
+{
+ AVB_TRACE_ENTRY(AVB_TRACE_RAWSOCK_DETAIL);
+ igb_rawsock_t *rawsock = (igb_rawsock_t*)pvRawsock;
+
+ int nInUse = igbTxBufLevel(rawsock->igb_dev);
+
+ AVB_TRACE_EXIT(AVB_TRACE_RAWSOCK_DETAIL);
+ return nInUse;
+}
diff --git a/lib/avtp_pipeline/platform/Linux/rawsock/igb_rawsock.h b/lib/avtp_pipeline/platform/Linux/rawsock/igb_rawsock.h
index e1fed118..dd811308 100644
--- a/lib/avtp_pipeline/platform/Linux/rawsock/igb_rawsock.h
+++ b/lib/avtp_pipeline/platform/Linux/rawsock/igb_rawsock.h
@@ -56,4 +56,6 @@ bool igbRawsockTxFrameReady(void *pvRawsock, U8 *pBuffer, unsigned int len);
int igbRawsockSend(void *pvRawsock);
+int igbRawsockTxBufLevel(void *pvRawsock);
+
#endif
diff --git a/lib/avtp_pipeline/platform/Linux/rawsock/openavb_rawsock.c b/lib/avtp_pipeline/platform/Linux/rawsock/openavb_rawsock.c
index 101541da..baf7a0f3 100644
--- a/lib/avtp_pipeline/platform/Linux/rawsock/openavb_rawsock.c
+++ b/lib/avtp_pipeline/platform/Linux/rawsock/openavb_rawsock.c
@@ -194,6 +194,7 @@ void *openavbRawsockOpen(const char *ifname_uri, bool rx_mode, bool tx_mode, U16
cb->txFillHdr = baseRawsockTxFillHdr;
cb->txFrameReady = igbRawsockTxFrameReady;
cb->send = igbRawsockSend;
+ cb->txBufLevel = igbRawsockTxBufLevel;
cb->getRxFrame = pcapRawsockGetRxFrame;
cb->rxParseHdr = simpleRawsockRxParseHdr;
cb->rxMulticast = pcapRawsockRxMulticast;
diff --git a/lib/avtp_pipeline/platform/x86_i210/openavb_ether_hal.c b/lib/avtp_pipeline/platform/x86_i210/openavb_ether_hal.c
index f74565f9..fd57e263 100644
--- a/lib/avtp_pipeline/platform/x86_i210/openavb_ether_hal.c
+++ b/lib/avtp_pipeline/platform/x86_i210/openavb_ether_hal.c
@@ -43,16 +43,64 @@ static pthread_mutex_t gIgbDeviceMutex = PTHREAD_MUTEX_INITIALIZER;
#define LOCK() pthread_mutex_lock(&gIgbDeviceMutex)
#define UNLOCK() pthread_mutex_unlock(&gIgbDeviceMutex)
-static pthread_mutex_t queueMutex[IGB_QUEUES] = {PTHREAD_MUTEX_INITIALIZER, PTHREAD_MUTEX_INITIALIZER};
-
-static struct {
- struct igb_dma_alloc a_page;
- struct igb_packet *free_packets;
-} queuePages[2];
+static struct igb_dma_alloc g_pages[IGB_PAGES];
+static struct igb_packet *g_free_packets;
static device_t *igb_dev = NULL;
static int igb_dev_users = 0; // time uses it
+static int g_totalBuffers = 0;
+static int g_usedBuffers = -1;
+
+static int count_packets(struct igb_packet *packet)
+{
+ int count=0;
+ while (packet) {
+ count++;
+ packet = packet->next;
+ }
+ return count;
+}
+
+static struct igb_packet* alloc_page(device_t* dev, struct igb_dma_alloc *a_page)
+{
+ int err = igb_dma_malloc_page(dev, a_page);
+ if (err) {
+ AVB_LOGF_ERROR("igb_dma_malloc_page failed: %s", strerror(err));
+ return NULL;
+ }
+
+ struct igb_packet *free_packets;
+ struct igb_packet a_packet;
+
+ a_packet.dmatime = a_packet.attime = a_packet.flags = 0;
+ a_packet.map.paddr = a_page->dma_paddr;
+ a_packet.map.mmap_size = a_page->mmap_size;
+ a_packet.offset = 0;
+ a_packet.vaddr = a_page->dma_vaddr + a_packet.offset;
+ a_packet.len = IGB_MTU;
+ a_packet.next = NULL;
+
+ free_packets = NULL;
+
+ /* divide the dma page into buffers for packets */
+ int i;
+ for (i = 0; i < a_page->mmap_size / IGB_MTU; i++) {
+ struct igb_packet *tmp_packet = malloc(sizeof(struct igb_packet));
+ if (!tmp_packet) {
+ AVB_LOG_ERROR("failed to allocate igb_packet memory!");
+ return false;
+ }
+ *tmp_packet = a_packet;
+ tmp_packet->offset = (i * IGB_MTU);
+ tmp_packet->vaddr += tmp_packet->offset;
+ tmp_packet->next = free_packets;
+ memset(tmp_packet->vaddr, 0, IGB_MTU);
+ free_packets = tmp_packet;
+ }
+ return free_packets;
+}
+
device_t *igbAcquireDevice()
{
AVB_TRACE_ENTRY(AVB_TRACE_HAL_ETHER);
@@ -78,43 +126,25 @@ device_t *igbAcquireDevice()
goto unlock;
}
- int queue;
- for (queue = 0; queue < IGB_QUEUES; queue++) {
- err = igb_dma_malloc_page(tmp_dev, &queuePages[queue].a_page);
- if (err) {
- AVB_LOGF_ERROR("igb_dma_malloc_page failed: %s", strerror(err));
- goto unlock;
- }
- struct igb_packet a_packet;
-
- a_packet.dmatime = a_packet.attime = a_packet.flags = 0;
- a_packet.map.paddr = queuePages[queue].a_page.dma_paddr;
- a_packet.map.mmap_size = queuePages[queue].a_page.mmap_size;
- a_packet.offset = 0;
- a_packet.vaddr = queuePages[queue].a_page.dma_vaddr + a_packet.offset;
- a_packet.len = IGB_MTU;
- a_packet.next = NULL;
-
- queuePages[queue].free_packets = NULL;
-
- /* divide the dma page into buffers for packets */
- int i;
- for (i = 1; i < ((queuePages[queue].a_page.mmap_size) / IGB_MTU); i++) {
- struct igb_packet *tmp_packet = malloc(sizeof(struct igb_packet));
- if (!tmp_packet) {
- AVB_LOG_ERROR("failed to allocate igb_packet memory!");
- goto unlock;
+ int i;
+ for (i = 0; i < IGB_PAGES; i++) {
+ struct igb_packet* free_packets = alloc_page(tmp_dev, &g_pages[i]);
+ if (!g_free_packets) {
+ g_free_packets = free_packets;
+ } else {
+ struct igb_packet* last_packet = g_free_packets;
+ while (last_packet->next) {
+ last_packet = last_packet->next;
}
- *tmp_packet = a_packet;
- tmp_packet->offset = (i * IGB_MTU);
- tmp_packet->vaddr += tmp_packet->offset;
- tmp_packet->next = queuePages[queue].free_packets;
- memset(tmp_packet->vaddr, 0, IGB_MTU);
- queuePages[queue].free_packets = tmp_packet;
+ last_packet->next = free_packets;
}
}
+ g_totalBuffers = count_packets(g_free_packets);
+
+ AVB_LOGF_INFO("TX buffers: %d", g_totalBuffers);
+
igbControlLaunchTime(tmp_dev, IGB_LAUNCHTIME_ENABLED);
AVB_LOGF_INFO("IGB launch time feature is %s", IGB_LAUNCHTIME_ENABLED ? "ENABLED" : "DISABLED");
@@ -145,10 +175,9 @@ void igbReleaseDevice(device_t* dev)
AVB_LOGF_DEBUG("igb_dev_users %d", igb_dev_users);
if (igb_dev && igb_dev_users <= 0) {
- int queue;
- for (queue = 0; queue < IGB_QUEUES; queue++) {
- igb_dma_free_page(igb_dev, &queuePages[queue].a_page);
- }
+ int i;
+ for (i = 0; i < IGB_PAGES; i++)
+ igb_dma_free_page(igb_dev, &g_pages[i]);
igb_detach(igb_dev);
free(igb_dev);
@@ -160,13 +189,13 @@ void igbReleaseDevice(device_t* dev)
AVB_TRACE_EXIT(AVB_TRACE_HAL_ETHER);
}
-struct igb_packet *igbGetTxPacket(device_t* dev, int queue)
+struct igb_packet *igbGetTxPacket(device_t* dev)
{
AVB_TRACE_ENTRY(AVB_TRACE_HAL_ETHER);
- pthread_mutex_lock(&queueMutex[queue]);
+ LOCK();
- struct igb_packet* tx_packet = queuePages[queue].free_packets;
+ struct igb_packet* tx_packet = g_free_packets;
if (!tx_packet) {
struct igb_packet *cleaned_packets;
@@ -174,17 +203,19 @@ struct igb_packet *igbGetTxPacket(device_t* dev, int queue)
while (cleaned_packets) {
struct igb_packet *tmp_packet = cleaned_packets;
cleaned_packets = cleaned_packets->next;
- tmp_packet->next = queuePages[queue].free_packets;
- queuePages[queue].free_packets = tmp_packet;
+ tmp_packet->next = g_free_packets;
+ g_free_packets = tmp_packet;
}
- tx_packet = queuePages[queue].free_packets;
+ tx_packet = g_free_packets;
+
+ g_usedBuffers = g_totalBuffers - count_packets(g_free_packets);
}
if (tx_packet) {
- queuePages[queue].free_packets = tx_packet->next;
+ g_free_packets = tx_packet->next;
}
- pthread_mutex_unlock(&queueMutex[queue]);
+ UNLOCK();
AVB_TRACE_EXIT(AVB_TRACE_HAL_ETHER);
return tx_packet;
@@ -194,16 +225,23 @@ void igbRelTxPacket(device_t* dev, int queue, struct igb_packet *tx_packet)
{
AVB_TRACE_ENTRY(AVB_TRACE_HAL_ETHER);
- pthread_mutex_lock(&queueMutex[queue]);
+ LOCK();
- tx_packet->next = queuePages[queue].free_packets;
- queuePages[queue].free_packets = tx_packet;
+ tx_packet->next = g_free_packets;
+ g_free_packets = tx_packet;
- pthread_mutex_unlock(&queueMutex[queue]);
+ UNLOCK();
AVB_TRACE_EXIT(AVB_TRACE_HAL_ETHER);
}
+int igbTxBufLevel(device_t *dev)
+{
+ AVB_TRACE_ENTRY(AVB_TRACE_HAL_ETHER);
+ AVB_TRACE_EXIT(AVB_TRACE_HAL_ETHER);
+ return g_usedBuffers;
+}
+
bool igbGetMacAddr(U8 mac_addr[ETH_ALEN])
{
int err = igb_get_mac_addr(igb_dev, mac_addr);
@@ -242,3 +280,4 @@ error:
AVB_TRACE_EXIT(AVB_TRACE_HAL_ETHER);
return !err;
}
+
diff --git a/lib/avtp_pipeline/platform/x86_i210/openavb_ether_hal.h b/lib/avtp_pipeline/platform/x86_i210/openavb_ether_hal.h
index 5d991c09..2ccc9db8 100644
--- a/lib/avtp_pipeline/platform/x86_i210/openavb_ether_hal.h
+++ b/lib/avtp_pipeline/platform/x86_i210/openavb_ether_hal.h
@@ -36,18 +36,23 @@ https://github.com/benhoyt/inih/commit/74d2ca064fb293bc60a77b0bd068075b293cf175.
#include "igb.h"
-#define IGB_MTU 256
-#define IGB_QUEUES 2
+#define IGB_MTU 1522
+
+// how many pages to alloc for tx buffers (2 frames fit in one page)
+#define IGB_PAGES 20
+
#define IGB_LAUNCHTIME_ENABLED 0
device_t *igbAcquireDevice();
void igbReleaseDevice(device_t *igb_dev);
-struct igb_packet *igbGetTxPacket(device_t* dev, int queue);
+struct igb_packet *igbGetTxPacket(device_t* dev);
void igbRelTxPacket(device_t* dev, int queue, struct igb_packet *tx_packet);
+int igbTxBufLevel(device_t *dev);
+
bool igbGetMacAddr(U8 mac_addr[ETH_ALEN]);
bool igbControlLaunchTime(device_t *dev, int enable);