get:
Show a patch.

patch:
Update a patch.

put:
Update a patch.

GET /api/patches/60318/?format=api
HTTP 200 OK
Allow: GET, PUT, PATCH, HEAD, OPTIONS
Content-Type: application/json
Vary: Accept

{
    "id": 60318,
    "url": "http://patches.dpdk.org/api/patches/60318/?format=api",
    "web_url": "http://patches.dpdk.org/project/dpdk/patch/20191001110209.6047-8-g.singh@nxp.com/",
    "project": {
        "id": 1,
        "url": "http://patches.dpdk.org/api/projects/1/?format=api",
        "name": "DPDK",
        "link_name": "dpdk",
        "list_id": "dev.dpdk.org",
        "list_email": "dev@dpdk.org",
        "web_url": "http://core.dpdk.org",
        "scm_url": "git://dpdk.org/dpdk",
        "webscm_url": "http://git.dpdk.org/dpdk",
        "list_archive_url": "https://inbox.dpdk.org/dev",
        "list_archive_url_format": "https://inbox.dpdk.org/dev/{}",
        "commit_url_format": ""
    },
    "msgid": "<20191001110209.6047-8-g.singh@nxp.com>",
    "list_archive_url": "https://inbox.dpdk.org/dev/20191001110209.6047-8-g.singh@nxp.com",
    "date": "2019-10-01T11:02:02",
    "name": "[v3,07/14] net/ppfe: add device start stop operations",
    "commit_ref": null,
    "pull_url": null,
    "state": "superseded",
    "archived": true,
    "hash": "54fb2a667a9f1aaf0b5a2ab45070994b3ab6c851",
    "submitter": {
        "id": 1068,
        "url": "http://patches.dpdk.org/api/people/1068/?format=api",
        "name": "Gagandeep Singh",
        "email": "g.singh@nxp.com"
    },
    "delegate": {
        "id": 319,
        "url": "http://patches.dpdk.org/api/users/319/?format=api",
        "username": "fyigit",
        "first_name": "Ferruh",
        "last_name": "Yigit",
        "email": "ferruh.yigit@amd.com"
    },
    "mbox": "http://patches.dpdk.org/project/dpdk/patch/20191001110209.6047-8-g.singh@nxp.com/mbox/",
    "series": [
        {
            "id": 6647,
            "url": "http://patches.dpdk.org/api/series/6647/?format=api",
            "web_url": "http://patches.dpdk.org/project/dpdk/list/?series=6647",
            "date": "2019-10-01T11:01:55",
            "name": "introduces ppfe network PMD",
            "version": 3,
            "mbox": "http://patches.dpdk.org/series/6647/mbox/"
        }
    ],
    "comments": "http://patches.dpdk.org/api/patches/60318/comments/",
    "check": "success",
    "checks": "http://patches.dpdk.org/api/patches/60318/checks/",
    "tags": {},
    "related": [],
    "headers": {
        "Return-Path": "<dev-bounces@dpdk.org>",
        "X-Original-To": "patchwork@dpdk.org",
        "Delivered-To": "patchwork@dpdk.org",
        "Received": [
            "from [92.243.14.124] (localhost [127.0.0.1])\n\tby dpdk.org (Postfix) with ESMTP id 5EB241BEAA;\n\tTue,  1 Oct 2019 13:17:41 +0200 (CEST)",
            "from inva020.nxp.com (inva020.nxp.com [92.121.34.13])\n\tby dpdk.org (Postfix) with ESMTP id 1E8C98F96\n\tfor <dev@dpdk.org>; Tue,  1 Oct 2019 13:17:34 +0200 (CEST)",
            "from inva020.nxp.com (localhost [127.0.0.1])\n\tby inva020.eu-rdc02.nxp.com (Postfix) with ESMTP id D44EF1A053F;\n\tTue,  1 Oct 2019 13:17:33 +0200 (CEST)",
            "from invc005.ap-rdc01.nxp.com (invc005.ap-rdc01.nxp.com\n\t[165.114.16.14])\n\tby inva020.eu-rdc02.nxp.com (Postfix) with ESMTP id DB85B1A02BC;\n\tTue,  1 Oct 2019 13:17:30 +0200 (CEST)",
            "from GDB1.ap.freescale.net (GDB1.ap.freescale.net [10.232.132.179])\n\tby invc005.ap-rdc01.nxp.com (Postfix) with ESMTP id D840F402DA;\n\tTue,  1 Oct 2019 19:17:26 +0800 (SGT)"
        ],
        "From": "Gagandeep Singh <g.singh@nxp.com>",
        "To": "dev@dpdk.org,\n\tferruh.yigit@intel.com",
        "Cc": "thomas@monjalon.net, Gagandeep Singh <g.singh@nxp.com>,\n\tAkhil Goyal <akhil.goyal@nxp.com>",
        "Date": "Tue,  1 Oct 2019 16:32:02 +0530",
        "Message-Id": "<20191001110209.6047-8-g.singh@nxp.com>",
        "X-Mailer": "git-send-email 2.17.1",
        "In-Reply-To": "<20191001110209.6047-1-g.singh@nxp.com>",
        "References": "<20190826130246.30485-1-g.singh@nxp.com>\n\t<20191001110209.6047-1-g.singh@nxp.com>",
        "X-Virus-Scanned": "ClamAV using ClamSMTP",
        "Subject": "[dpdk-dev] [PATCH v3 07/14] net/ppfe: add device start stop\n\toperations",
        "X-BeenThere": "dev@dpdk.org",
        "X-Mailman-Version": "2.1.15",
        "Precedence": "list",
        "List-Id": "DPDK patches and discussions <dev.dpdk.org>",
        "List-Unsubscribe": "<https://mails.dpdk.org/options/dev>,\n\t<mailto:dev-request@dpdk.org?subject=unsubscribe>",
        "List-Archive": "<http://mails.dpdk.org/archives/dev/>",
        "List-Post": "<mailto:dev@dpdk.org>",
        "List-Help": "<mailto:dev-request@dpdk.org?subject=help>",
        "List-Subscribe": "<https://mails.dpdk.org/listinfo/dev>,\n\t<mailto:dev-request@dpdk.org?subject=subscribe>",
        "Errors-To": "dev-bounces@dpdk.org",
        "Sender": "\"dev\" <dev-bounces@dpdk.org>"
    },
    "content": "This patch adds device start, stop and close\noperations.\n\nSigned-off-by: Gagandeep Singh <g.singh@nxp.com>\nSigned-off-by: Akhil Goyal <akhil.goyal@nxp.com>\nAcked-by: Nipun Gupta <nipun.gupta@nxp.com>\n---\n drivers/net/ppfe/Makefile      |   2 +-\n drivers/net/ppfe/pfe_eth.h     |   1 +\n drivers/net/ppfe/pfe_hif.c     | 139 +++++++++++++\n drivers/net/ppfe/pfe_hif.h     |  41 ++++\n drivers/net/ppfe/pfe_hif_lib.c | 362 ++++++++++++++++++++++++++++++++-\n drivers/net/ppfe/pfe_hif_lib.h |  11 +\n drivers/net/ppfe/pfe_mod.h     |   1 +\n drivers/net/ppfe/ppfe_ethdev.c | 181 +++++++++++++++++\n 8 files changed, 736 insertions(+), 2 deletions(-)",
    "diff": "diff --git a/drivers/net/ppfe/Makefile b/drivers/net/ppfe/Makefile\nindex 0f1dba188..151d24dc7 100644\n--- a/drivers/net/ppfe/Makefile\n+++ b/drivers/net/ppfe/Makefile\n@@ -32,7 +32,7 @@ SRCS-$(CONFIG_RTE_LIBRTE_PPFE_PMD) += pfe_hif.c\n LDLIBS += -lrte_bus_vdev\n LDLIBS += -lrte_bus_dpaa\n LDLIBS += -lrte_common_dpaax\n-LDLIBS += -lrte_eal\n+LDLIBS += -lrte_eal -lrte_mbuf -lrte_mempool\n LDLIBS += -lrte_ethdev -lrte_kvargs\n \n include $(RTE_SDK)/mk/rte.lib.mk\ndiff --git a/drivers/net/ppfe/pfe_eth.h b/drivers/net/ppfe/pfe_eth.h\nindex 5811b54eb..5dedc9eb9 100644\n--- a/drivers/net/ppfe/pfe_eth.h\n+++ b/drivers/net/ppfe/pfe_eth.h\n@@ -53,6 +53,7 @@ struct ls1012a_pfe_platform_data {\n \n struct  pfe_eth_priv_s {\n \tstruct pfe\t\t*pfe;\n+\tstruct hif_client_s\tclient;\n \tint\t\t\tlow_tmu_q;\n \tint\t\t\thigh_tmu_q;\n \tstruct rte_eth_dev\t*ndev;\ndiff --git a/drivers/net/ppfe/pfe_hif.c b/drivers/net/ppfe/pfe_hif.c\nindex 3a861b420..940f7419f 100644\n--- a/drivers/net/ppfe/pfe_hif.c\n+++ b/drivers/net/ppfe/pfe_hif.c\n@@ -43,6 +43,145 @@ pfe_hif_free_descr(struct pfe_hif *hif)\n \trte_free(hif->descr_baseaddr_v);\n }\n \n+/*\n+ * pfe_hif_client_register\n+ *\n+ * This function used to register a client driver with the HIF driver.\n+ *\n+ * Return value:\n+ * 0 - on Successful registration\n+ */\n+static int\n+pfe_hif_client_register(struct pfe_hif *hif, u32 client_id,\n+\t\t\tstruct hif_client_shm *client_shm)\n+{\n+\tstruct hif_client *client = &hif->client[client_id];\n+\tu32 i, cnt;\n+\tstruct rx_queue_desc *rx_qbase;\n+\tstruct tx_queue_desc *tx_qbase;\n+\tstruct hif_rx_queue *rx_queue;\n+\tstruct hif_tx_queue *tx_queue;\n+\tint err = 0;\n+\n+\tPMD_INIT_FUNC_TRACE();\n+\n+\trte_spinlock_lock(&hif->tx_lock);\n+\n+\tif (test_bit(client_id, &hif->shm->g_client_status[0])) {\n+\t\tPFE_PMD_ERR(\"client %d already registered\", client_id);\n+\t\terr = -1;\n+\t\tgoto unlock;\n+\t}\n+\n+\tmemset(client, 0, sizeof(struct hif_client));\n+\n+\t/* Initialize client Rx queues baseaddr, size */\n+\n+\tcnt = CLIENT_CTRL_RX_Q_CNT(client_shm->ctrl);\n+\t/* Check if client is requesting for more queues than supported */\n+\tif (cnt > HIF_CLIENT_QUEUES_MAX)\n+\t\tcnt = HIF_CLIENT_QUEUES_MAX;\n+\n+\tclient->rx_qn = cnt;\n+\trx_qbase = (struct rx_queue_desc *)client_shm->rx_qbase;\n+\tfor (i = 0; i < cnt; i++) {\n+\t\trx_queue = &client->rx_q[i];\n+\t\trx_queue->base = rx_qbase + i * client_shm->rx_qsize;\n+\t\trx_queue->size = client_shm->rx_qsize;\n+\t\trx_queue->write_idx = 0;\n+\t}\n+\n+\t/* Initialize client Tx queues baseaddr, size */\n+\tcnt = CLIENT_CTRL_TX_Q_CNT(client_shm->ctrl);\n+\n+\t/* Check if client is requesting for more queues than supported */\n+\tif (cnt > HIF_CLIENT_QUEUES_MAX)\n+\t\tcnt = HIF_CLIENT_QUEUES_MAX;\n+\n+\tclient->tx_qn = cnt;\n+\ttx_qbase = (struct tx_queue_desc *)client_shm->tx_qbase;\n+\tfor (i = 0; i < cnt; i++) {\n+\t\ttx_queue = &client->tx_q[i];\n+\t\ttx_queue->base = tx_qbase + i * client_shm->tx_qsize;\n+\t\ttx_queue->size = client_shm->tx_qsize;\n+\t\ttx_queue->ack_idx = 0;\n+\t}\n+\n+\tset_bit(client_id, &hif->shm->g_client_status[0]);\n+\n+unlock:\n+\trte_spinlock_unlock(&hif->tx_lock);\n+\n+\treturn err;\n+}\n+\n+/*\n+ * pfe_hif_client_unregister\n+ *\n+ * This function used to unregister a client  from the HIF driver.\n+ *\n+ */\n+static void\n+pfe_hif_client_unregister(struct pfe_hif *hif, u32 client_id)\n+{\n+\tPMD_INIT_FUNC_TRACE();\n+\n+\t/*\n+\t * Mark client as no longer available (which prevents further packet\n+\t * receive for this client)\n+\t */\n+\trte_spinlock_lock(&hif->tx_lock);\n+\n+\tif (!test_bit(client_id, &hif->shm->g_client_status[0])) {\n+\t\tPFE_PMD_ERR(\"client %d not registered\", client_id);\n+\n+\t\trte_spinlock_unlock(&hif->tx_lock);\n+\t\treturn;\n+\t}\n+\n+\tclear_bit(client_id, &hif->shm->g_client_status[0]);\n+\n+\trte_spinlock_unlock(&hif->tx_lock);\n+}\n+\n+void\n+hif_process_client_req(struct pfe_hif *hif, int req,\n+\t\t       int data1, __rte_unused int data2)\n+{\n+\tunsigned int client_id = data1;\n+\n+\tif (client_id >= HIF_CLIENTS_MAX) {\n+\t\tPFE_PMD_ERR(\"client id %d out of bounds\", client_id);\n+\t\treturn;\n+\t}\n+\n+\tswitch (req) {\n+\tcase REQUEST_CL_REGISTER:\n+\t\t\t/* Request for register a client */\n+\t\t\tPFE_PMD_INFO(\"register client_id %d\", client_id);\n+\t\t\tpfe_hif_client_register(hif, client_id, (struct\n+\t\t\t\thif_client_shm *)&hif->shm->client[client_id]);\n+\t\t\tbreak;\n+\n+\tcase REQUEST_CL_UNREGISTER:\n+\t\t\tPFE_PMD_INFO(\"unregister client_id %d\", client_id);\n+\n+\t\t\t/* Request for unregister a client */\n+\t\t\tpfe_hif_client_unregister(hif, client_id);\n+\n+\t\t\tbreak;\n+\n+\tdefault:\n+\t\t\tPFE_PMD_ERR(\"unsupported request %d\", req);\n+\t\t\tbreak;\n+\t}\n+\n+\t/*\n+\t * Process client Tx queues\n+\t * Currently we don't have checking for tx pending\n+\t */\n+}\n+\n #if defined(LS1012A_PFE_RESET_WA)\n static void\n pfe_hif_disable_rx_desc(struct pfe_hif *hif)\ndiff --git a/drivers/net/ppfe/pfe_hif.h b/drivers/net/ppfe/pfe_hif.h\nindex fa3c08cc7..483db75da 100644\n--- a/drivers/net/ppfe/pfe_hif.h\n+++ b/drivers/net/ppfe/pfe_hif.h\n@@ -14,6 +14,12 @@\n #define HIF_RX_DESC_NT\t\t64\n #define HIF_TX_DESC_NT\t\t2048\n \n+#define HIF_FIRST_BUFFER\tBIT(0)\n+#define HIF_LAST_BUFFER\t\tBIT(1)\n+#define HIF_DONT_DMA_MAP\tBIT(2)\n+#define HIF_DATA_VALID\t\tBIT(3)\n+#define HIF_TSO\t\t\tBIT(4)\n+\n enum {\n \tPFE_CL_GEM0 = 0,\n \tPFE_CL_GEM1,\n@@ -63,6 +69,39 @@ struct hif_desc_sw {\n \tu16 flags;\n };\n \n+struct hif_hdr {\n+\tu8 client_id;\n+\tu8 q_num;\n+\tu16 client_ctrl;\n+\tu16 client_ctrl1;\n+};\n+\n+struct __hif_hdr {\n+\tunion {\n+\t\tstruct hif_hdr hdr;\n+\t\tu32 word[2];\n+\t};\n+};\n+\n+struct hif_ipsec_hdr {\n+\tu16\tsa_handle[2];\n+} __packed;\n+\n+struct ppfe_parse {\n+\tunsigned int packet_type;\n+\tuint16_t hash;\n+\tuint16_t parse_incomplete;\n+\tunsigned long long ol_flags;\n+};\n+\n+/*  HIF_CTRL_TX... defines */\n+#define HIF_CTRL_TX_CHECKSUM\t\tBIT(2)\n+\n+/*  HIF_CTRL_RX... defines */\n+#define HIF_CTRL_RX_OFFSET_OFST         (24)\n+#define HIF_CTRL_RX_CHECKSUMMED\t\tBIT(2)\n+#define HIF_CTRL_RX_CONTINUED\t\tBIT(1)\n+\n struct pfe_hif {\n \t/* To store registered clients in hif layer */\n \tstruct hif_client client[HIF_CLIENTS_MAX];\n@@ -99,6 +138,8 @@ struct pfe_hif {\n \tstruct rte_device *dev;\n };\n \n+void hif_process_client_req(struct pfe_hif *hif, int req, int data1, int\n+\t\t\t\tdata2);\n int pfe_hif_init(struct pfe *pfe);\n void pfe_hif_exit(struct pfe *pfe);\n void pfe_hif_rx_idle(struct pfe_hif *hif);\ndiff --git a/drivers/net/ppfe/pfe_hif_lib.c b/drivers/net/ppfe/pfe_hif_lib.c\nindex 8f8121be1..2012d896a 100644\n--- a/drivers/net/ppfe/pfe_hif_lib.c\n+++ b/drivers/net/ppfe/pfe_hif_lib.c\n@@ -5,11 +5,371 @@\n #include \"pfe_logs.h\"\n #include \"pfe_mod.h\"\n \n+unsigned int emac_txq_cnt;\n+\n+/*\n+ * @pfe_hal_lib.c\n+ * Common functions used by HIF client drivers\n+ */\n+\n+/*HIF shared memory Global variable */\n+struct hif_shm ghif_shm;\n+\n+/*This function sends indication to HIF driver\n+ *\n+ * @param[in] hif\thif context\n+ */\n+static void\n+hif_lib_indicate_hif(struct pfe_hif *hif, int req, int data1, int\n+\t\t     data2)\n+{\n+\thif_process_client_req(hif, req, data1, data2);\n+}\n+\n+void\n+hif_lib_indicate_client(struct hif_client_s *client, int event_type,\n+\t\t\tint qno)\n+{\n+\tif (!client || event_type >= HIF_EVENT_MAX ||\n+\t    qno >= HIF_CLIENT_QUEUES_MAX)\n+\t\treturn;\n+\n+\tif (!test_and_set_bit(qno, &client->queue_mask[event_type]))\n+\t\tclient->event_handler(client->priv, event_type, qno);\n+}\n+\n+/*This function releases Rx queue descriptors memory and pre-filled buffers\n+ *\n+ * @param[in] client\thif_client context\n+ */\n+static void\n+hif_lib_client_release_rx_buffers(struct hif_client_s *client)\n+{\n+\tstruct rte_mempool *pool;\n+\tstruct rte_pktmbuf_pool_private *mb_priv;\n+\tstruct rx_queue_desc *desc;\n+\tunsigned int qno, ii;\n+\tvoid *buf;\n+\n+\tpool = client->pfe->hif.shm->pool;\n+\tmb_priv = rte_mempool_get_priv(pool);\n+\tfor (qno = 0; qno < client->rx_qn; qno++) {\n+\t\tdesc = client->rx_q[qno].base;\n+\n+\t\tfor (ii = 0; ii < client->rx_q[qno].size; ii++) {\n+\t\t\tbuf = (void *)desc->data;\n+\t\t\tif (buf) {\n+\t\t\t/* Data pointor to mbuf pointor calculation:\n+\t\t\t * \"Data - User private data - headroom - mbufsize\"\n+\t\t\t * Actual data pointor given to HIF BDs was\n+\t\t\t * \"mbuf->data_offset - PFE_PKT_HEADER_SZ\"\n+\t\t\t */\n+\t\t\t\tbuf = buf + PFE_PKT_HEADER_SZ\n+\t\t\t\t\t- sizeof(struct rte_mbuf)\n+\t\t\t\t\t- RTE_PKTMBUF_HEADROOM\n+\t\t\t\t\t- mb_priv->mbuf_priv_size;\n+\t\t\t\trte_pktmbuf_free((struct rte_mbuf *)buf);\n+\t\t\t\tdesc->ctrl = 0;\n+\t\t\t}\n+\t\t\tdesc++;\n+\t\t}\n+\t}\n+\trte_free(client->rx_qbase);\n+}\n+\n+/*This function allocates memory for the rxq descriptors and pre-fill rx queues\n+ * with buffers.\n+ * @param[in] client\tclient context\n+ * @param[in] q_size\tsize of the rxQ, all queues are of same size\n+ */\n+static int\n+hif_lib_client_init_rx_buffers(struct hif_client_s *client,\n+\t\t\t\t\t  int q_size)\n+{\n+\tstruct rx_queue_desc *desc;\n+\tstruct hif_client_rx_queue *queue;\n+\tunsigned int ii, qno;\n+\n+\t/*Allocate memory for the client queues */\n+\tclient->rx_qbase = rte_malloc(NULL, client->rx_qn * q_size *\n+\t\t\tsizeof(struct rx_queue_desc), RTE_CACHE_LINE_SIZE);\n+\tif (!client->rx_qbase)\n+\t\tgoto err;\n+\n+\tfor (qno = 0; qno < client->rx_qn; qno++) {\n+\t\tqueue = &client->rx_q[qno];\n+\n+\t\tqueue->base = client->rx_qbase + qno * q_size * sizeof(struct\n+\t\t\t\trx_queue_desc);\n+\t\tqueue->size = q_size;\n+\t\tqueue->read_idx = 0;\n+\t\tqueue->write_idx = 0;\n+\t\tqueue->queue_id = 0;\n+\t\tqueue->port_id = client->port_id;\n+\t\tqueue->priv = client->priv;\n+\t\tPFE_PMD_DEBUG(\"rx queue: %d, base: %p, size: %d\\n\", qno,\n+\t\t\t      queue->base, queue->size);\n+\t}\n+\n+\tfor (qno = 0; qno < client->rx_qn; qno++) {\n+\t\tqueue = &client->rx_q[qno];\n+\t\tdesc = queue->base;\n+\n+\t\tfor (ii = 0; ii < queue->size; ii++) {\n+\t\t\tdesc->ctrl = CL_DESC_OWN;\n+\t\t\tdesc++;\n+\t\t}\n+\t}\n+\n+\treturn 0;\n+\n+err:\n+\treturn 1;\n+}\n+\n+\n+static void\n+hif_lib_client_cleanup_tx_queue(struct hif_client_tx_queue *queue)\n+{\n+\t/*\n+\t * Check if there are any pending packets. Client must flush the tx\n+\t * queues before unregistering, by calling by calling\n+\t * hif_lib_tx_get_next_complete()\n+\t *\n+\t * Hif no longer calls since we are no longer registered\n+\t */\n+\tif (queue->tx_pending)\n+\t\tPFE_PMD_ERR(\"pending transmit packet\");\n+}\n+\n+static void\n+hif_lib_client_release_tx_buffers(struct hif_client_s *client)\n+{\n+\tunsigned int qno;\n+\n+\tfor (qno = 0; qno < client->tx_qn; qno++)\n+\t\thif_lib_client_cleanup_tx_queue(&client->tx_q[qno]);\n+\n+\trte_free(client->tx_qbase);\n+}\n+\n+static int\n+hif_lib_client_init_tx_buffers(struct hif_client_s *client, int\n+\t\t\t\t\t\tq_size)\n+{\n+\tstruct hif_client_tx_queue *queue;\n+\tunsigned int qno;\n+\n+\tclient->tx_qbase = rte_malloc(NULL, client->tx_qn * q_size *\n+\t\t\tsizeof(struct tx_queue_desc), RTE_CACHE_LINE_SIZE);\n+\tif (!client->tx_qbase)\n+\t\treturn 1;\n+\n+\tfor (qno = 0; qno < client->tx_qn; qno++) {\n+\t\tqueue = &client->tx_q[qno];\n+\n+\t\tqueue->base = client->tx_qbase + qno * q_size * sizeof(struct\n+\t\t\t\ttx_queue_desc);\n+\t\tqueue->size = q_size;\n+\t\tqueue->read_idx = 0;\n+\t\tqueue->write_idx = 0;\n+\t\tqueue->tx_pending = 0;\n+\t\tqueue->nocpy_flag = 0;\n+\t\tqueue->prev_tmu_tx_pkts = 0;\n+\t\tqueue->done_tmu_tx_pkts = 0;\n+\t\tqueue->priv = client->priv;\n+\t\tqueue->queue_id = 0;\n+\t\tqueue->port_id = client->port_id;\n+\n+\t\tPFE_PMD_DEBUG(\"tx queue: %d, base: %p, size: %d\", qno,\n+\t\t\t queue->base, queue->size);\n+\t}\n+\n+\treturn 0;\n+}\n+\n+static int\n+hif_lib_event_dummy(__rte_unused void *priv,\n+\t\t__rte_unused int event_type, __rte_unused int qno)\n+{\n+\treturn 0;\n+}\n+\n int\n-pfe_hif_lib_init(__rte_unused struct pfe *pfe)\n+hif_lib_client_register(struct hif_client_s *client)\n {\n+\tstruct hif_shm *hif_shm;\n+\tstruct hif_client_shm *client_shm;\n+\tint err, i;\n+\n \tPMD_INIT_FUNC_TRACE();\n \n+\t/*Allocate memory before spin_lock*/\n+\tif (hif_lib_client_init_rx_buffers(client, client->rx_qsize)) {\n+\t\terr = -ENOMEM;\n+\t\tgoto err_rx;\n+\t}\n+\n+\tif (hif_lib_client_init_tx_buffers(client, client->tx_qsize)) {\n+\t\terr = -ENOMEM;\n+\t\tgoto err_tx;\n+\t}\n+\n+\trte_spinlock_lock(&client->pfe->hif.lock);\n+\tif (!(client->pfe) || client->id >= HIF_CLIENTS_MAX ||\n+\t    client->pfe->hif_client[client->id]) {\n+\t\terr = -EINVAL;\n+\t\tgoto err;\n+\t}\n+\n+\thif_shm = client->pfe->hif.shm;\n+\n+\tif (!client->event_handler)\n+\t\tclient->event_handler = hif_lib_event_dummy;\n+\n+\t/*Initialize client specific shared memory */\n+\tclient_shm = (struct hif_client_shm *)&hif_shm->client[client->id];\n+\tclient_shm->rx_qbase = (unsigned long)client->rx_qbase;\n+\tclient_shm->rx_qsize = client->rx_qsize;\n+\tclient_shm->tx_qbase = (unsigned long)client->tx_qbase;\n+\tclient_shm->tx_qsize = client->tx_qsize;\n+\tclient_shm->ctrl = (client->tx_qn << CLIENT_CTRL_TX_Q_CNT_OFST) |\n+\t\t\t\t(client->rx_qn << CLIENT_CTRL_RX_Q_CNT_OFST);\n+\n+\tfor (i = 0; i < HIF_EVENT_MAX; i++) {\n+\t\tclient->queue_mask[i] = 0;  /*\n+\t\t\t\t\t     * By default all events are\n+\t\t\t\t\t     * unmasked\n+\t\t\t\t\t     */\n+\t}\n+\n+\t/*Indicate to HIF driver*/\n+\thif_lib_indicate_hif(&client->pfe->hif, REQUEST_CL_REGISTER,\n+\t\t\tclient->id, 0);\n+\n+\tPFE_PMD_DEBUG(\"client: %p, client_id: %d, tx_qsize: %d, rx_qsize: %d\",\n+\t\t      client, client->id, client->tx_qsize, client->rx_qsize);\n+\n+\tclient->cpu_id = -1;\n+\n+\tclient->pfe->hif_client[client->id] = client;\n+\trte_spinlock_unlock(&client->pfe->hif.lock);\n+\n+\treturn 0;\n+\n+err:\n+\trte_spinlock_unlock(&client->pfe->hif.lock);\n+\thif_lib_client_release_tx_buffers(client);\n+\n+err_tx:\n+\thif_lib_client_release_rx_buffers(client);\n+\n+err_rx:\n+\treturn err;\n+}\n+\n+int\n+hif_lib_client_unregister(struct hif_client_s *client)\n+{\n+\tstruct pfe *pfe = client->pfe;\n+\tu32 client_id = client->id;\n+\n+\tPFE_PMD_INFO(\"client: %p, client_id: %d, txQ_depth: %d, rxQ_depth: %d\",\n+\t\t     client, client->id, client->tx_qsize, client->rx_qsize);\n+\n+\trte_spinlock_lock(&pfe->hif.lock);\n+\thif_lib_indicate_hif(&pfe->hif, REQUEST_CL_UNREGISTER, client->id, 0);\n+\n+\thif_lib_client_release_tx_buffers(client);\n+\thif_lib_client_release_rx_buffers(client);\n+\tpfe->hif_client[client_id] = NULL;\n+\trte_spinlock_unlock(&pfe->hif.lock);\n+\n+\treturn 0;\n+}\n+\n+int\n+hif_lib_event_handler_start(struct hif_client_s *client, int event,\n+\t\t\t\tint qno)\n+{\n+\tstruct hif_client_rx_queue *queue = &client->rx_q[qno];\n+\tstruct rx_queue_desc *desc = queue->base + queue->read_idx;\n+\n+\tif (event >= HIF_EVENT_MAX || qno >= HIF_CLIENT_QUEUES_MAX) {\n+\t\tPFE_PMD_WARN(\"Unsupported event : %d  queue number : %d\",\n+\t\t\t\tevent, qno);\n+\t\treturn -1;\n+\t}\n+\n+\ttest_and_clear_bit(qno, &client->queue_mask[event]);\n+\n+\tswitch (event) {\n+\tcase EVENT_RX_PKT_IND:\n+\t\tif (!(desc->ctrl & CL_DESC_OWN))\n+\t\t\thif_lib_indicate_client(client,\n+\t\t\t\t\t\tEVENT_RX_PKT_IND, qno);\n+\t\tbreak;\n+\n+\tcase EVENT_HIGH_RX_WM:\n+\tcase EVENT_TXDONE_IND:\n+\tdefault:\n+\t\tbreak;\n+\t}\n+\n+\treturn 0;\n+}\n+\n+void *\n+hif_lib_tx_get_next_complete(struct hif_client_s *client, int qno,\n+\t\t\t\t   unsigned int *flags, __rte_unused  int count)\n+{\n+\tstruct hif_client_tx_queue *queue = &client->tx_q[qno];\n+\tstruct tx_queue_desc *desc = queue->base + queue->read_idx;\n+\n+\tPFE_DP_LOG(DEBUG, \"qno : %d rd_indx: %d pending:%d\",\n+\t\t   qno, queue->read_idx, queue->tx_pending);\n+\n+\tif (!queue->tx_pending)\n+\t\treturn NULL;\n+\n+\tif (queue->nocpy_flag && !queue->done_tmu_tx_pkts) {\n+\t\tu32 tmu_tx_pkts = 0;\n+\n+\t\tif (queue->prev_tmu_tx_pkts > tmu_tx_pkts)\n+\t\t\tqueue->done_tmu_tx_pkts = UINT_MAX -\n+\t\t\t\tqueue->prev_tmu_tx_pkts + tmu_tx_pkts;\n+\t\telse\n+\t\t\tqueue->done_tmu_tx_pkts = tmu_tx_pkts -\n+\t\t\t\t\t\tqueue->prev_tmu_tx_pkts;\n+\n+\t\tqueue->prev_tmu_tx_pkts  = tmu_tx_pkts;\n+\n+\t\tif (!queue->done_tmu_tx_pkts)\n+\t\t\treturn NULL;\n+\t}\n+\n+\tif (desc->ctrl & CL_DESC_OWN)\n+\t\treturn NULL;\n+\n+\tqueue->read_idx = (queue->read_idx + 1) & (queue->size - 1);\n+\tqueue->tx_pending--;\n+\n+\t*flags = CL_DESC_GET_FLAGS(desc->ctrl);\n+\n+\tif (queue->done_tmu_tx_pkts && (*flags & HIF_LAST_BUFFER))\n+\t\tqueue->done_tmu_tx_pkts--;\n+\n+\treturn desc->data;\n+}\n+\n+int\n+pfe_hif_lib_init(struct pfe *pfe)\n+{\n+\tPMD_INIT_FUNC_TRACE();\n+\n+\temac_txq_cnt = EMAC_TXQ_CNT;\n+\tpfe->hif.shm = &ghif_shm;\n+\n \treturn 0;\n }\n \ndiff --git a/drivers/net/ppfe/pfe_hif_lib.h b/drivers/net/ppfe/pfe_hif_lib.h\nindex 2db7338c2..03e492559 100644\n--- a/drivers/net/ppfe/pfe_hif_lib.h\n+++ b/drivers/net/ppfe/pfe_hif_lib.h\n@@ -5,6 +5,8 @@\n #ifndef _PFE_HIF_LIB_H_\n #define _PFE_HIF_LIB_H_\n \n+#include \"pfe_hif.h\"\n+\n #define HIF_CL_REQ_TIMEOUT\t10\n #define GFP_DMA_PFE 0\n \n@@ -158,5 +160,14 @@ extern unsigned int emac_txq_cnt;\n \n int pfe_hif_lib_init(struct pfe *pfe);\n void pfe_hif_lib_exit(struct pfe *pfe);\n+int hif_lib_client_register(struct hif_client_s *client);\n+int hif_lib_client_unregister(struct  hif_client_s *client);\n+void hif_lib_indicate_client(struct hif_client_s *client, int event, int data);\n+int hif_lib_event_handler_start(struct hif_client_s *client, int event, int\n+\t\t\t\t\tdata);\n+void *hif_lib_tx_get_next_complete(struct hif_client_s *client, int qno,\n+\t\t\t\t   unsigned int *flags, int count);\n+int pfe_hif_shm_init(struct hif_shm *hif_shm, struct rte_mempool *mb_pool);\n+void pfe_hif_shm_clean(struct hif_shm *hif_shm);\n \n #endif /* _PFE_HIF_LIB_H_ */\ndiff --git a/drivers/net/ppfe/pfe_mod.h b/drivers/net/ppfe/pfe_mod.h\nindex f3382f3a7..24b9ebd1e 100644\n--- a/drivers/net/ppfe/pfe_mod.h\n+++ b/drivers/net/ppfe/pfe_mod.h\n@@ -48,6 +48,7 @@ struct pfe {\n \tstruct ls1012a_pfe_platform_data platform_data;\n \tstruct pfe_hif hif;\n \tstruct pfe_eth eth;\n+\tstruct hif_client_s *hif_client[HIF_CLIENTS_MAX];\n \tint mdio_muxval[PHYID_MAX_VAL];\n \tuint8_t nb_devs;\n \tuint8_t max_intf;\ndiff --git a/drivers/net/ppfe/ppfe_ethdev.c b/drivers/net/ppfe/ppfe_ethdev.c\nindex 6e8db20b8..19467b90d 100644\n--- a/drivers/net/ppfe/ppfe_ethdev.c\n+++ b/drivers/net/ppfe/ppfe_ethdev.c\n@@ -71,6 +71,126 @@ pfe_soc_version_get(void)\n \tfclose(svr_file);\n }\n \n+static int pfe_eth_start(struct pfe_eth_priv_s *priv)\n+{\n+\tgpi_enable(priv->GPI_baseaddr);\n+\tgemac_enable(priv->EMAC_baseaddr);\n+\n+\treturn 0;\n+}\n+\n+static void\n+pfe_eth_flush_txQ(struct pfe_eth_priv_s *priv, int tx_q_num, int\n+\t\t  __rte_unused from_tx, __rte_unused int n_desc)\n+{\n+\tstruct rte_mbuf *mbuf;\n+\tunsigned int flags;\n+\n+\t/* Clean HIF and client queue */\n+\twhile ((mbuf = hif_lib_tx_get_next_complete(&priv->client,\n+\t\t\t\t\t\t   tx_q_num, &flags,\n+\t\t\t\t\t\t   HIF_TX_DESC_NT))) {\n+\t\tif (mbuf) {\n+\t\t\tmbuf->next = NULL;\n+\t\t\tmbuf->nb_segs = 1;\n+\t\t\trte_pktmbuf_free(mbuf);\n+\t\t}\n+\t}\n+}\n+\n+\n+static void\n+pfe_eth_flush_tx(struct pfe_eth_priv_s *priv)\n+{\n+\tunsigned int ii;\n+\n+\tfor (ii = 0; ii < emac_txq_cnt; ii++)\n+\t\tpfe_eth_flush_txQ(priv, ii, 0, 0);\n+}\n+\n+static int\n+pfe_eth_event_handler(void *data, int event, __rte_unused int qno)\n+{\n+\tstruct pfe_eth_priv_s *priv = data;\n+\n+\tswitch (event) {\n+\tcase EVENT_TXDONE_IND:\n+\t\tpfe_eth_flush_tx(priv);\n+\t\thif_lib_event_handler_start(&priv->client, EVENT_TXDONE_IND, 0);\n+\t\tbreak;\n+\tcase EVENT_HIGH_RX_WM:\n+\tdefault:\n+\t\tbreak;\n+\t}\n+\n+\treturn 0;\n+}\n+\n+static int\n+pfe_eth_open(struct rte_eth_dev *dev)\n+{\n+\tstruct pfe_eth_priv_s *priv = dev->data->dev_private;\n+\tstruct hif_client_s *client;\n+\tstruct hif_shm *hif_shm;\n+\tint rc;\n+\n+\t/* Register client driver with HIF */\n+\tclient = &priv->client;\n+\n+\tif (client->pfe) {\n+\t\thif_shm = client->pfe->hif.shm;\n+\t\t/* TODO please remove the below code of if block, once we add\n+\t\t * the proper cleanup in eth_close\n+\t\t */\n+\t\tif (!test_bit(PFE_CL_GEM0 + priv->id,\n+\t\t\t      &hif_shm->g_client_status[0])) {\n+\t\t\t/* Register client driver with HIF */\n+\t\t\tmemset(client, 0, sizeof(*client));\n+\t\t\tclient->id = PFE_CL_GEM0 + priv->id;\n+\t\t\tclient->tx_qn = emac_txq_cnt;\n+\t\t\tclient->rx_qn = EMAC_RXQ_CNT;\n+\t\t\tclient->priv = priv;\n+\t\t\tclient->pfe = priv->pfe;\n+\t\t\tclient->port_id = dev->data->port_id;\n+\t\t\tclient->event_handler = pfe_eth_event_handler;\n+\n+\t\t\tclient->tx_qsize = EMAC_TXQ_DEPTH;\n+\t\t\tclient->rx_qsize = EMAC_RXQ_DEPTH;\n+\n+\t\t\trc = hif_lib_client_register(client);\n+\t\t\tif (rc) {\n+\t\t\t\tPFE_PMD_ERR(\"hif_lib_client_register(%d)\"\n+\t\t\t\t\t    \" failed\", client->id);\n+\t\t\t\tgoto err0;\n+\t\t\t}\n+\t\t}\n+\t} else {\n+\t\t/* Register client driver with HIF */\n+\t\tmemset(client, 0, sizeof(*client));\n+\t\tclient->id = PFE_CL_GEM0 + priv->id;\n+\t\tclient->tx_qn = emac_txq_cnt;\n+\t\tclient->rx_qn = EMAC_RXQ_CNT;\n+\t\tclient->priv = priv;\n+\t\tclient->pfe = priv->pfe;\n+\t\tclient->port_id = dev->data->port_id;\n+\t\tclient->event_handler = pfe_eth_event_handler;\n+\n+\t\tclient->tx_qsize = EMAC_TXQ_DEPTH;\n+\t\tclient->rx_qsize = EMAC_RXQ_DEPTH;\n+\n+\t\trc = hif_lib_client_register(client);\n+\t\tif (rc) {\n+\t\t\tPFE_PMD_ERR(\"hif_lib_client_register(%d) failed\",\n+\t\t\t\t    client->id);\n+\t\t\tgoto err0;\n+\t\t}\n+\t}\n+\trc = pfe_eth_start(priv);\n+\n+err0:\n+\treturn rc;\n+}\n+\n static int\n pfe_eth_open_cdev(struct pfe_eth_priv_s *priv)\n {\n@@ -105,11 +225,21 @@ pfe_eth_close_cdev(struct pfe_eth_priv_s *priv)\n \t}\n }\n \n+static void\n+pfe_eth_stop(struct rte_eth_dev *dev/*, int wake*/)\n+{\n+\tstruct pfe_eth_priv_s *priv = dev->data->dev_private;\n+\n+\tgemac_disable(priv->EMAC_baseaddr);\n+\tgpi_disable(priv->GPI_baseaddr);\n+}\n+\n static void\n pfe_eth_exit(struct rte_eth_dev *dev, struct pfe *pfe)\n {\n \tPMD_INIT_FUNC_TRACE();\n \n+\tpfe_eth_stop(dev);\n \t/* Close the device file for link status */\n \tpfe_eth_close_cdev(dev->data->dev_private);\n \n@@ -118,6 +248,55 @@ pfe_eth_exit(struct rte_eth_dev *dev, struct pfe *pfe)\n \tpfe->nb_devs--;\n }\n \n+static void\n+pfe_eth_close(struct rte_eth_dev *dev)\n+{\n+\tif (!dev)\n+\t\treturn;\n+\n+\tif (!g_pfe)\n+\t\treturn;\n+\n+\tpfe_eth_exit(dev, g_pfe);\n+\n+\tif (g_pfe->nb_devs == 0) {\n+\t\tpfe_hif_exit(g_pfe);\n+\t\tpfe_hif_lib_exit(g_pfe);\n+\t\trte_free(g_pfe);\n+\t\tg_pfe = NULL;\n+\t}\n+}\n+\n+static int\n+pfe_eth_configure(struct rte_eth_dev *dev __rte_unused)\n+{\n+\treturn 0;\n+}\n+\n+static int\n+pfe_eth_info(struct rte_eth_dev *dev,\n+\t\tstruct rte_eth_dev_info *dev_info)\n+{\n+\tstruct pfe_eth_priv_s *internals = dev->data->dev_private;\n+\n+\tdev_info->if_index = internals->id;\n+\tdev_info->max_mac_addrs = PPFE_MAX_MACS;\n+\tdev_info->max_rx_pktlen = JUMBO_FRAME_SIZE;\n+\tdev_info->max_rx_queues = dev->data->nb_rx_queues;\n+\tdev_info->max_tx_queues = dev->data->nb_tx_queues;\n+\tdev_info->min_rx_bufsize = HIF_RX_PKT_MIN_SIZE;\n+\n+\treturn 0;\n+}\n+\n+static const struct eth_dev_ops ops = {\n+\t.dev_start = pfe_eth_open,\n+\t.dev_stop = pfe_eth_stop,\n+\t.dev_close = pfe_eth_close,\n+\t.dev_configure = pfe_eth_configure,\n+\t.dev_infos_get = pfe_eth_info,\n+};\n+\n static int\n pfe_eth_init(struct rte_vdev_device *vdev, struct pfe *pfe, int id)\n {\n@@ -178,6 +357,8 @@ pfe_eth_init(struct rte_vdev_device *vdev, struct pfe *pfe, int id)\n \t}\n \n \teth_dev->data->mtu = 1500;\n+\teth_dev->dev_ops = &ops;\n+\tpfe_eth_stop(eth_dev);\n \tpfe_gemac_init(priv);\n \n \teth_dev->data->nb_rx_queues = 1;\n",
    "prefixes": [
        "v3",
        "07/14"
    ]
}