Skip to content

Commit

Permalink
net/ark: provide API for hardware modules MPU RQP and pktdir
Browse files Browse the repository at this point in the history
Provide C-level interface for Arkville's internal HW resources
MPU, (Memory Prefetch Unit) pktdir (Packet director), and RQP
(Request Pacer) modules

Signed-off-by: Ed Czeck <ed.czeck@atomicrules.com>
  • Loading branch information
czeck authored and Ferruh Yigit committed Apr 19, 2017
1 parent 1131cbf commit b33ccdb
Show file tree
Hide file tree
Showing 7 changed files with 663 additions and 0 deletions.
3 changes: 3 additions & 0 deletions drivers/net/ark/Makefile
Expand Up @@ -47,6 +47,9 @@ LIBABIVER := 1
# all source are stored in SRCS-y
#
SRCS-$(CONFIG_RTE_LIBRTE_ARK_PMD) += ark_ethdev.c
SRCS-$(CONFIG_RTE_LIBRTE_ARK_PMD) += ark_mpu.c
SRCS-$(CONFIG_RTE_LIBRTE_ARK_PMD) += ark_pktdir.c
SRCS-$(CONFIG_RTE_LIBRTE_ARK_PMD) += ark_rqp.c

# this lib depends upon:
LDLIBS += -lpthread
Expand Down
181 changes: 181 additions & 0 deletions drivers/net/ark/ark_mpu.c
@@ -0,0 +1,181 @@
/*-
* BSD LICENSE
*
* Copyright (c) 2015-2017 Atomic Rules LLC
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* * Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in
* the documentation and/or other materials provided with the
* distribution.
* * Neither the name of copyright holder nor the names of its
* contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/

#include <unistd.h>

#include "ark_logs.h"
#include "ark_mpu.h"

uint16_t
ark_api_num_queues(struct ark_mpu_t *mpu)
{
return mpu->hw.num_queues;
}

uint16_t
ark_api_num_queues_per_port(struct ark_mpu_t *mpu, uint16_t ark_ports)
{
return mpu->hw.num_queues / ark_ports;
}

int
ark_mpu_verify(struct ark_mpu_t *mpu, uint32_t obj_size)
{
uint32_t version;

version = mpu->id.vernum & 0x0000fF00;
if ((mpu->id.idnum != 0x2055504d) ||
(mpu->hw.obj_size != obj_size) ||
(version != 0x00003100)) {
PMD_DRV_LOG(ERR,
" MPU module not found as expected %08x"
" \"%c%c%c%c %c%c%c%c\"\n",
mpu->id.idnum,
mpu->id.id[0], mpu->id.id[1],
mpu->id.id[2], mpu->id.id[3],
mpu->id.ver[0], mpu->id.ver[1],
mpu->id.ver[2], mpu->id.ver[3]);
PMD_DRV_LOG(ERR,
" MPU HW num_queues: %u hw_depth %u,"
" obj_size: %u, obj_per_mrr: %u"
" Expected size %u\n",
mpu->hw.num_queues,
mpu->hw.hw_depth,
mpu->hw.obj_size,
mpu->hw.obj_per_mrr,
obj_size);
return -1;
}
return 0;
}

void
ark_mpu_stop(struct ark_mpu_t *mpu)
{
mpu->cfg.command = MPU_CMD_STOP;
}

void
ark_mpu_start(struct ark_mpu_t *mpu)
{
mpu->cfg.command = MPU_CMD_RUN;
}

int
ark_mpu_reset(struct ark_mpu_t *mpu)
{
int cnt = 0;

mpu->cfg.command = MPU_CMD_RESET;

while (mpu->cfg.command != MPU_CMD_IDLE) {
if (cnt++ > 1000)
break;
usleep(10);
}
if (mpu->cfg.command != MPU_CMD_IDLE) {
mpu->cfg.command = MPU_CMD_FORCE_RESET;
usleep(10);
}
ark_mpu_reset_stats(mpu);
return mpu->cfg.command != MPU_CMD_IDLE;
}

void
ark_mpu_reset_stats(struct ark_mpu_t *mpu)
{
mpu->stats.pci_request = 1; /* reset stats */
}

int
ark_mpu_configure(struct ark_mpu_t *mpu, phys_addr_t ring, uint32_t ring_size,
int is_tx)
{
ark_mpu_reset(mpu);

if (!rte_is_power_of_2(ring_size)) {
PMD_DRV_LOG(ERR, "ARK: Invalid ring size for MPU %d\n",
ring_size);
return -1;
}

mpu->cfg.ring_base = ring;
mpu->cfg.ring_size = ring_size;
mpu->cfg.ring_mask = ring_size - 1;
mpu->cfg.min_host_move = is_tx ? 1 : mpu->hw.obj_per_mrr;
mpu->cfg.min_hw_move = mpu->hw.obj_per_mrr;
mpu->cfg.sw_prod_index = 0;
mpu->cfg.hw_cons_index = 0;
return 0;
}

void
ark_mpu_dump(struct ark_mpu_t *mpu, const char *code, uint16_t qid)
{
/* DUMP to see that we have started */
PMD_DEBUG_LOG(DEBUG, "MPU: %s Q: %3u sw_prod %u, hw_cons: %u\n",
code, qid,
mpu->cfg.sw_prod_index, mpu->cfg.hw_cons_index);
PMD_DEBUG_LOG(DEBUG, "MPU: %s state: %d count %d, reserved %d"
" data 0x%08x_%08x 0x%08x_%08x\n",
code,
mpu->debug.state, mpu->debug.count,
mpu->debug.reserved,
mpu->debug.peek[1],
mpu->debug.peek[0],
mpu->debug.peek[3],
mpu->debug.peek[2]
);
PMD_STATS_LOG(INFO, "MPU: %s Q: %3u"
ARK_SU64 ARK_SU64 ARK_SU64 ARK_SU64
ARK_SU64 ARK_SU64 ARK_SU64 "\n",
code, qid,
"PCI Request:", mpu->stats.pci_request,
"Queue_empty", mpu->stats.q_empty,
"Queue_q1", mpu->stats.q_q1,
"Queue_q2", mpu->stats.q_q2,
"Queue_q3", mpu->stats.q_q3,
"Queue_q4", mpu->stats.q_q4,
"Queue_full", mpu->stats.q_full
);
}

void
ark_mpu_dump_setup(struct ark_mpu_t *mpu, uint16_t q_id)
{
PMD_DEBUG_LOG(DEBUG, "MPU Setup Q: %u"
ARK_SU64X "\n",
q_id,
"ring_base", mpu->cfg.ring_base
);
}
154 changes: 154 additions & 0 deletions drivers/net/ark/ark_mpu.h
@@ -0,0 +1,154 @@
/*-
* BSD LICENSE
*
* Copyright (c) 2015-2017 Atomic Rules LLC
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* * Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in
* the documentation and/or other materials provided with the
* distribution.
* * Neither the name of copyright holder nor the names of its
* contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/

#ifndef _ARK_MPU_H_
#define _ARK_MPU_H_

#include <stdint.h>

#include <rte_memory.h>

/* The MPU or Memory Prefetch Unit is an internal Arkville hardware
* module for moving data between host memory and the hardware FPGA.
* This module is *not* intended for end-user manipulation, hence
* there is minimal documentation.
*/

/*
* MPU hardware structures
* These are overlay structures to a memory mapped FPGA device. These
* structs will never be instantiated in ram memory
*/

#define ARK_MPU_ID 0x00
struct ark_mpu_id_t {
union {
char id[4];
uint32_t idnum;
};
union {
char ver[4];
uint32_t vernum;
};
uint32_t phys_id;
uint32_t mrr_code;
};

#define ARK_MPU_HW 0x010
struct ark_mpu_hw_t {
uint16_t num_queues;
uint16_t reserved;
uint32_t hw_depth;
uint32_t obj_size;
uint32_t obj_per_mrr;
};

#define ARK_MPU_CFG 0x040
struct ark_mpu_cfg_t {
phys_addr_t ring_base; /* phys_addr_t is a uint64_t */
uint32_t ring_size;
uint32_t ring_mask;
uint32_t min_host_move;
uint32_t min_hw_move;
volatile uint32_t sw_prod_index;
volatile uint32_t hw_cons_index;
volatile uint32_t command;
};
enum ARK_MPU_COMMAND {
MPU_CMD_IDLE = 1,
MPU_CMD_RUN = 2,
MPU_CMD_STOP = 4,
MPU_CMD_RESET = 8,
MPU_CMD_FORCE_RESET = 16,
MPU_COMMAND_LIMIT = 0xfFFFFFFF
};

#define ARK_MPU_STATS 0x080
struct ark_mpu_stats_t {
volatile uint64_t pci_request;
volatile uint64_t q_empty;
volatile uint64_t q_q1;
volatile uint64_t q_q2;
volatile uint64_t q_q3;
volatile uint64_t q_q4;
volatile uint64_t q_full;
};

#define ARK_MPU_DEBUG 0x0C0
struct ark_mpu_debug_t {
volatile uint32_t state;
uint32_t reserved;
volatile uint32_t count;
volatile uint32_t take;
volatile uint32_t peek[4];
};

/* Consolidated structure */
struct ark_mpu_t {
struct ark_mpu_id_t id;
uint8_t reserved0[(ARK_MPU_HW - ARK_MPU_ID)
- sizeof(struct ark_mpu_id_t)];
struct ark_mpu_hw_t hw;
uint8_t reserved1[(ARK_MPU_CFG - ARK_MPU_HW) -
sizeof(struct ark_mpu_hw_t)];
struct ark_mpu_cfg_t cfg;
uint8_t reserved2[(ARK_MPU_STATS - ARK_MPU_CFG) -
sizeof(struct ark_mpu_cfg_t)];
struct ark_mpu_stats_t stats;
uint8_t reserved3[(ARK_MPU_DEBUG - ARK_MPU_STATS) -
sizeof(struct ark_mpu_stats_t)];
struct ark_mpu_debug_t debug;
};

uint16_t ark_api_num_queues(struct ark_mpu_t *mpu);
uint16_t ark_api_num_queues_per_port(struct ark_mpu_t *mpu,
uint16_t ark_ports);
int ark_mpu_verify(struct ark_mpu_t *mpu, uint32_t obj_size);
void ark_mpu_stop(struct ark_mpu_t *mpu);
void ark_mpu_start(struct ark_mpu_t *mpu);
int ark_mpu_reset(struct ark_mpu_t *mpu);
int ark_mpu_configure(struct ark_mpu_t *mpu, phys_addr_t ring,
uint32_t ring_size, int is_tx);

void ark_mpu_dump(struct ark_mpu_t *mpu, const char *msg, uint16_t idx);
void ark_mpu_dump_setup(struct ark_mpu_t *mpu, uint16_t qid);
void ark_mpu_reset_stats(struct ark_mpu_t *mpu);

/* this action is in a performance critical path */
static inline void
ark_mpu_set_producer(struct ark_mpu_t *mpu, uint32_t idx)
{
mpu->cfg.sw_prod_index = idx;
}

#endif

0 comments on commit b33ccdb

Please sign in to comment.