15253fe37SGagandeep Singh /* SPDX-License-Identifier: BSD-3-Clause 2f513f620SSachin Saxena * Copyright 2018-2019 NXP 35253fe37SGagandeep Singh */ 45253fe37SGagandeep Singh 55253fe37SGagandeep Singh #include "pfe_logs.h" 65253fe37SGagandeep Singh #include "pfe_mod.h" 75253fe37SGagandeep Singh 8fe38ad9bSGagandeep Singh unsigned int emac_txq_cnt; 9fe38ad9bSGagandeep Singh 10fe38ad9bSGagandeep Singh /* 11fe38ad9bSGagandeep Singh * @pfe_hal_lib.c 12fe38ad9bSGagandeep Singh * Common functions used by HIF client drivers 13fe38ad9bSGagandeep Singh */ 14fe38ad9bSGagandeep Singh 15fe38ad9bSGagandeep Singh /*HIF shared memory Global variable */ 16fe38ad9bSGagandeep Singh struct hif_shm ghif_shm; 17fe38ad9bSGagandeep Singh 18592041a0SGagandeep Singh /* Cleanup the HIF shared memory, release HIF rx_buffer_pool. 19592041a0SGagandeep Singh * This function should be called after pfe_hif_exit 20592041a0SGagandeep Singh * 21592041a0SGagandeep Singh * @param[in] hif_shm Shared memory address location in DDR 22592041a0SGagandeep Singh */ 23592041a0SGagandeep Singh void 24592041a0SGagandeep Singh pfe_hif_shm_clean(struct hif_shm *hif_shm) 25592041a0SGagandeep Singh { 26592041a0SGagandeep Singh unsigned int i; 27592041a0SGagandeep Singh void *pkt; 28592041a0SGagandeep Singh 29592041a0SGagandeep Singh for (i = 0; i < hif_shm->rx_buf_pool_cnt; i++) { 30592041a0SGagandeep Singh pkt = hif_shm->rx_buf_pool[i]; 31592041a0SGagandeep Singh if (pkt) 32592041a0SGagandeep Singh rte_pktmbuf_free((struct rte_mbuf *)pkt); 33592041a0SGagandeep Singh } 34592041a0SGagandeep Singh } 35592041a0SGagandeep Singh 36592041a0SGagandeep Singh /* Initialize shared memory used between HIF driver and clients, 37592041a0SGagandeep Singh * allocate rx_buffer_pool required for HIF Rx descriptors. 38592041a0SGagandeep Singh * This function should be called before initializing HIF driver. 39592041a0SGagandeep Singh * 40592041a0SGagandeep Singh * @param[in] hif_shm Shared memory address location in DDR 417be78d02SJosh Soref * @return 0 - on succes, <0 on fail to initialize 42592041a0SGagandeep Singh */ 43592041a0SGagandeep Singh int 44592041a0SGagandeep Singh pfe_hif_shm_init(struct hif_shm *hif_shm, struct rte_mempool *mb_pool) 45592041a0SGagandeep Singh { 46592041a0SGagandeep Singh unsigned int i; 47592041a0SGagandeep Singh struct rte_mbuf *mbuf; 48592041a0SGagandeep Singh 49592041a0SGagandeep Singh memset(hif_shm, 0, sizeof(struct hif_shm)); 50592041a0SGagandeep Singh hif_shm->rx_buf_pool_cnt = HIF_RX_DESC_NT; 51592041a0SGagandeep Singh 52592041a0SGagandeep Singh for (i = 0; i < hif_shm->rx_buf_pool_cnt; i++) { 53592041a0SGagandeep Singh mbuf = rte_cpu_to_le_64(rte_pktmbuf_alloc(mb_pool)); 54592041a0SGagandeep Singh if (mbuf) 55592041a0SGagandeep Singh hif_shm->rx_buf_pool[i] = mbuf; 56592041a0SGagandeep Singh else 57592041a0SGagandeep Singh goto err0; 58592041a0SGagandeep Singh } 59592041a0SGagandeep Singh 60592041a0SGagandeep Singh return 0; 61592041a0SGagandeep Singh 62592041a0SGagandeep Singh err0: 63592041a0SGagandeep Singh PFE_PMD_ERR("Low memory"); 64592041a0SGagandeep Singh pfe_hif_shm_clean(hif_shm); 65592041a0SGagandeep Singh return -ENOMEM; 66592041a0SGagandeep Singh } 67592041a0SGagandeep Singh 68fe38ad9bSGagandeep Singh /*This function sends indication to HIF driver 69fe38ad9bSGagandeep Singh * 70fe38ad9bSGagandeep Singh * @param[in] hif hif context 71fe38ad9bSGagandeep Singh */ 72fe38ad9bSGagandeep Singh static void 73fe38ad9bSGagandeep Singh hif_lib_indicate_hif(struct pfe_hif *hif, int req, int data1, int 74fe38ad9bSGagandeep Singh data2) 75fe38ad9bSGagandeep Singh { 76fe38ad9bSGagandeep Singh hif_process_client_req(hif, req, data1, data2); 77fe38ad9bSGagandeep Singh } 78fe38ad9bSGagandeep Singh 79fe38ad9bSGagandeep Singh void 80fe38ad9bSGagandeep Singh hif_lib_indicate_client(struct hif_client_s *client, int event_type, 81fe38ad9bSGagandeep Singh int qno) 82fe38ad9bSGagandeep Singh { 83fe38ad9bSGagandeep Singh if (!client || event_type >= HIF_EVENT_MAX || 84fe38ad9bSGagandeep Singh qno >= HIF_CLIENT_QUEUES_MAX) 85fe38ad9bSGagandeep Singh return; 86fe38ad9bSGagandeep Singh 87fe38ad9bSGagandeep Singh if (!test_and_set_bit(qno, &client->queue_mask[event_type])) 88fe38ad9bSGagandeep Singh client->event_handler(client->priv, event_type, qno); 89fe38ad9bSGagandeep Singh } 90fe38ad9bSGagandeep Singh 91fe38ad9bSGagandeep Singh /*This function releases Rx queue descriptors memory and pre-filled buffers 92fe38ad9bSGagandeep Singh * 93fe38ad9bSGagandeep Singh * @param[in] client hif_client context 94fe38ad9bSGagandeep Singh */ 95fe38ad9bSGagandeep Singh static void 96fe38ad9bSGagandeep Singh hif_lib_client_release_rx_buffers(struct hif_client_s *client) 97fe38ad9bSGagandeep Singh { 98fe38ad9bSGagandeep Singh struct rte_mempool *pool; 99fe38ad9bSGagandeep Singh struct rte_pktmbuf_pool_private *mb_priv; 100fe38ad9bSGagandeep Singh struct rx_queue_desc *desc; 101fe38ad9bSGagandeep Singh unsigned int qno, ii; 102fe38ad9bSGagandeep Singh void *buf; 103fe38ad9bSGagandeep Singh 104fe38ad9bSGagandeep Singh pool = client->pfe->hif.shm->pool; 105fe38ad9bSGagandeep Singh mb_priv = rte_mempool_get_priv(pool); 106fe38ad9bSGagandeep Singh for (qno = 0; qno < client->rx_qn; qno++) { 107fe38ad9bSGagandeep Singh desc = client->rx_q[qno].base; 108fe38ad9bSGagandeep Singh 109fe38ad9bSGagandeep Singh for (ii = 0; ii < client->rx_q[qno].size; ii++) { 110fe38ad9bSGagandeep Singh buf = (void *)desc->data; 111fe38ad9bSGagandeep Singh if (buf) { 1127be78d02SJosh Soref /* Data pointer to mbuf pointer calculation: 113fe38ad9bSGagandeep Singh * "Data - User private data - headroom - mbufsize" 1147be78d02SJosh Soref * Actual data pointer given to HIF BDs was 115fe38ad9bSGagandeep Singh * "mbuf->data_offset - PFE_PKT_HEADER_SZ" 116fe38ad9bSGagandeep Singh */ 117fe38ad9bSGagandeep Singh buf = buf + PFE_PKT_HEADER_SZ 118fe38ad9bSGagandeep Singh - sizeof(struct rte_mbuf) 119fe38ad9bSGagandeep Singh - RTE_PKTMBUF_HEADROOM 120fe38ad9bSGagandeep Singh - mb_priv->mbuf_priv_size; 121fe38ad9bSGagandeep Singh rte_pktmbuf_free((struct rte_mbuf *)buf); 122fe38ad9bSGagandeep Singh desc->ctrl = 0; 123fe38ad9bSGagandeep Singh } 124fe38ad9bSGagandeep Singh desc++; 125fe38ad9bSGagandeep Singh } 126fe38ad9bSGagandeep Singh } 127fe38ad9bSGagandeep Singh rte_free(client->rx_qbase); 128fe38ad9bSGagandeep Singh } 129fe38ad9bSGagandeep Singh 130fe38ad9bSGagandeep Singh /*This function allocates memory for the rxq descriptors and pre-fill rx queues 131fe38ad9bSGagandeep Singh * with buffers. 132fe38ad9bSGagandeep Singh * @param[in] client client context 133fe38ad9bSGagandeep Singh * @param[in] q_size size of the rxQ, all queues are of same size 134fe38ad9bSGagandeep Singh */ 135fe38ad9bSGagandeep Singh static int 136fe38ad9bSGagandeep Singh hif_lib_client_init_rx_buffers(struct hif_client_s *client, 137fe38ad9bSGagandeep Singh int q_size) 138fe38ad9bSGagandeep Singh { 139fe38ad9bSGagandeep Singh struct rx_queue_desc *desc; 140fe38ad9bSGagandeep Singh struct hif_client_rx_queue *queue; 141fe38ad9bSGagandeep Singh unsigned int ii, qno; 142fe38ad9bSGagandeep Singh 143fe38ad9bSGagandeep Singh /*Allocate memory for the client queues */ 144fe38ad9bSGagandeep Singh client->rx_qbase = rte_malloc(NULL, client->rx_qn * q_size * 145fe38ad9bSGagandeep Singh sizeof(struct rx_queue_desc), RTE_CACHE_LINE_SIZE); 146fe38ad9bSGagandeep Singh if (!client->rx_qbase) 147fe38ad9bSGagandeep Singh goto err; 148fe38ad9bSGagandeep Singh 149fe38ad9bSGagandeep Singh for (qno = 0; qno < client->rx_qn; qno++) { 150fe38ad9bSGagandeep Singh queue = &client->rx_q[qno]; 151fe38ad9bSGagandeep Singh 152fe38ad9bSGagandeep Singh queue->base = client->rx_qbase + qno * q_size * sizeof(struct 153fe38ad9bSGagandeep Singh rx_queue_desc); 154fe38ad9bSGagandeep Singh queue->size = q_size; 155fe38ad9bSGagandeep Singh queue->read_idx = 0; 156fe38ad9bSGagandeep Singh queue->write_idx = 0; 157fe38ad9bSGagandeep Singh queue->queue_id = 0; 158fe38ad9bSGagandeep Singh queue->port_id = client->port_id; 159fe38ad9bSGagandeep Singh queue->priv = client->priv; 160*f665790aSDavid Marchand PFE_PMD_DEBUG("rx queue: %d, base: %p, size: %d", qno, 161fe38ad9bSGagandeep Singh queue->base, queue->size); 162fe38ad9bSGagandeep Singh } 163fe38ad9bSGagandeep Singh 164fe38ad9bSGagandeep Singh for (qno = 0; qno < client->rx_qn; qno++) { 165fe38ad9bSGagandeep Singh queue = &client->rx_q[qno]; 166fe38ad9bSGagandeep Singh desc = queue->base; 167fe38ad9bSGagandeep Singh 168fe38ad9bSGagandeep Singh for (ii = 0; ii < queue->size; ii++) { 169fe38ad9bSGagandeep Singh desc->ctrl = CL_DESC_OWN; 170fe38ad9bSGagandeep Singh desc++; 171fe38ad9bSGagandeep Singh } 172fe38ad9bSGagandeep Singh } 173fe38ad9bSGagandeep Singh 174fe38ad9bSGagandeep Singh return 0; 175fe38ad9bSGagandeep Singh 176fe38ad9bSGagandeep Singh err: 177fe38ad9bSGagandeep Singh return 1; 178fe38ad9bSGagandeep Singh } 179fe38ad9bSGagandeep Singh 180fe38ad9bSGagandeep Singh 181fe38ad9bSGagandeep Singh static void 182fe38ad9bSGagandeep Singh hif_lib_client_cleanup_tx_queue(struct hif_client_tx_queue *queue) 183fe38ad9bSGagandeep Singh { 184fe38ad9bSGagandeep Singh /* 185fe38ad9bSGagandeep Singh * Check if there are any pending packets. Client must flush the tx 186fe38ad9bSGagandeep Singh * queues before unregistering, by calling by calling 187fe38ad9bSGagandeep Singh * hif_lib_tx_get_next_complete() 188fe38ad9bSGagandeep Singh * 189fe38ad9bSGagandeep Singh * Hif no longer calls since we are no longer registered 190fe38ad9bSGagandeep Singh */ 191fe38ad9bSGagandeep Singh if (queue->tx_pending) 192fe38ad9bSGagandeep Singh PFE_PMD_ERR("pending transmit packet"); 193fe38ad9bSGagandeep Singh } 194fe38ad9bSGagandeep Singh 195fe38ad9bSGagandeep Singh static void 196fe38ad9bSGagandeep Singh hif_lib_client_release_tx_buffers(struct hif_client_s *client) 197fe38ad9bSGagandeep Singh { 198fe38ad9bSGagandeep Singh unsigned int qno; 199fe38ad9bSGagandeep Singh 200fe38ad9bSGagandeep Singh for (qno = 0; qno < client->tx_qn; qno++) 201fe38ad9bSGagandeep Singh hif_lib_client_cleanup_tx_queue(&client->tx_q[qno]); 202fe38ad9bSGagandeep Singh 203fe38ad9bSGagandeep Singh rte_free(client->tx_qbase); 204fe38ad9bSGagandeep Singh } 205fe38ad9bSGagandeep Singh 206fe38ad9bSGagandeep Singh static int 207fe38ad9bSGagandeep Singh hif_lib_client_init_tx_buffers(struct hif_client_s *client, int 208fe38ad9bSGagandeep Singh q_size) 209fe38ad9bSGagandeep Singh { 210fe38ad9bSGagandeep Singh struct hif_client_tx_queue *queue; 211fe38ad9bSGagandeep Singh unsigned int qno; 212fe38ad9bSGagandeep Singh 213fe38ad9bSGagandeep Singh client->tx_qbase = rte_malloc(NULL, client->tx_qn * q_size * 214fe38ad9bSGagandeep Singh sizeof(struct tx_queue_desc), RTE_CACHE_LINE_SIZE); 215fe38ad9bSGagandeep Singh if (!client->tx_qbase) 216fe38ad9bSGagandeep Singh return 1; 217fe38ad9bSGagandeep Singh 218fe38ad9bSGagandeep Singh for (qno = 0; qno < client->tx_qn; qno++) { 219fe38ad9bSGagandeep Singh queue = &client->tx_q[qno]; 220fe38ad9bSGagandeep Singh 221fe38ad9bSGagandeep Singh queue->base = client->tx_qbase + qno * q_size * sizeof(struct 222fe38ad9bSGagandeep Singh tx_queue_desc); 223fe38ad9bSGagandeep Singh queue->size = q_size; 224fe38ad9bSGagandeep Singh queue->read_idx = 0; 225fe38ad9bSGagandeep Singh queue->write_idx = 0; 226fe38ad9bSGagandeep Singh queue->tx_pending = 0; 227fe38ad9bSGagandeep Singh queue->nocpy_flag = 0; 228fe38ad9bSGagandeep Singh queue->prev_tmu_tx_pkts = 0; 229fe38ad9bSGagandeep Singh queue->done_tmu_tx_pkts = 0; 230fe38ad9bSGagandeep Singh queue->priv = client->priv; 231fe38ad9bSGagandeep Singh queue->queue_id = 0; 232fe38ad9bSGagandeep Singh queue->port_id = client->port_id; 233fe38ad9bSGagandeep Singh 234fe38ad9bSGagandeep Singh PFE_PMD_DEBUG("tx queue: %d, base: %p, size: %d", qno, 235fe38ad9bSGagandeep Singh queue->base, queue->size); 236fe38ad9bSGagandeep Singh } 237fe38ad9bSGagandeep Singh 238fe38ad9bSGagandeep Singh return 0; 239fe38ad9bSGagandeep Singh } 240fe38ad9bSGagandeep Singh 241fe38ad9bSGagandeep Singh static int 242fe38ad9bSGagandeep Singh hif_lib_event_dummy(__rte_unused void *priv, 243fe38ad9bSGagandeep Singh __rte_unused int event_type, __rte_unused int qno) 244fe38ad9bSGagandeep Singh { 245fe38ad9bSGagandeep Singh return 0; 246fe38ad9bSGagandeep Singh } 247fe38ad9bSGagandeep Singh 2485253fe37SGagandeep Singh int 249fe38ad9bSGagandeep Singh hif_lib_client_register(struct hif_client_s *client) 250fe38ad9bSGagandeep Singh { 251fe38ad9bSGagandeep Singh struct hif_shm *hif_shm; 252fe38ad9bSGagandeep Singh struct hif_client_shm *client_shm; 253fe38ad9bSGagandeep Singh int err, i; 254fe38ad9bSGagandeep Singh 255fe38ad9bSGagandeep Singh PMD_INIT_FUNC_TRACE(); 256fe38ad9bSGagandeep Singh 257fe38ad9bSGagandeep Singh /*Allocate memory before spin_lock*/ 258fe38ad9bSGagandeep Singh if (hif_lib_client_init_rx_buffers(client, client->rx_qsize)) { 259fe38ad9bSGagandeep Singh err = -ENOMEM; 260fe38ad9bSGagandeep Singh goto err_rx; 261fe38ad9bSGagandeep Singh } 262fe38ad9bSGagandeep Singh 263fe38ad9bSGagandeep Singh if (hif_lib_client_init_tx_buffers(client, client->tx_qsize)) { 264fe38ad9bSGagandeep Singh err = -ENOMEM; 265fe38ad9bSGagandeep Singh goto err_tx; 266fe38ad9bSGagandeep Singh } 267fe38ad9bSGagandeep Singh 268fe38ad9bSGagandeep Singh rte_spinlock_lock(&client->pfe->hif.lock); 269fe38ad9bSGagandeep Singh if (!(client->pfe) || client->id >= HIF_CLIENTS_MAX || 270fe38ad9bSGagandeep Singh client->pfe->hif_client[client->id]) { 271fe38ad9bSGagandeep Singh err = -EINVAL; 272fe38ad9bSGagandeep Singh goto err; 273fe38ad9bSGagandeep Singh } 274fe38ad9bSGagandeep Singh 275fe38ad9bSGagandeep Singh hif_shm = client->pfe->hif.shm; 276fe38ad9bSGagandeep Singh 277fe38ad9bSGagandeep Singh if (!client->event_handler) 278fe38ad9bSGagandeep Singh client->event_handler = hif_lib_event_dummy; 279fe38ad9bSGagandeep Singh 280fe38ad9bSGagandeep Singh /*Initialize client specific shared memory */ 281fe38ad9bSGagandeep Singh client_shm = (struct hif_client_shm *)&hif_shm->client[client->id]; 282fe38ad9bSGagandeep Singh client_shm->rx_qbase = (unsigned long)client->rx_qbase; 283fe38ad9bSGagandeep Singh client_shm->rx_qsize = client->rx_qsize; 284fe38ad9bSGagandeep Singh client_shm->tx_qbase = (unsigned long)client->tx_qbase; 285fe38ad9bSGagandeep Singh client_shm->tx_qsize = client->tx_qsize; 286fe38ad9bSGagandeep Singh client_shm->ctrl = (client->tx_qn << CLIENT_CTRL_TX_Q_CNT_OFST) | 287fe38ad9bSGagandeep Singh (client->rx_qn << CLIENT_CTRL_RX_Q_CNT_OFST); 288fe38ad9bSGagandeep Singh 289fe38ad9bSGagandeep Singh for (i = 0; i < HIF_EVENT_MAX; i++) { 290fe38ad9bSGagandeep Singh client->queue_mask[i] = 0; /* 291fe38ad9bSGagandeep Singh * By default all events are 292fe38ad9bSGagandeep Singh * unmasked 293fe38ad9bSGagandeep Singh */ 294fe38ad9bSGagandeep Singh } 295fe38ad9bSGagandeep Singh 296fe38ad9bSGagandeep Singh /*Indicate to HIF driver*/ 297fe38ad9bSGagandeep Singh hif_lib_indicate_hif(&client->pfe->hif, REQUEST_CL_REGISTER, 298fe38ad9bSGagandeep Singh client->id, 0); 299fe38ad9bSGagandeep Singh 300fe38ad9bSGagandeep Singh PFE_PMD_DEBUG("client: %p, client_id: %d, tx_qsize: %d, rx_qsize: %d", 301fe38ad9bSGagandeep Singh client, client->id, client->tx_qsize, client->rx_qsize); 302fe38ad9bSGagandeep Singh 303fe38ad9bSGagandeep Singh client->cpu_id = -1; 304fe38ad9bSGagandeep Singh 305fe38ad9bSGagandeep Singh client->pfe->hif_client[client->id] = client; 306fe38ad9bSGagandeep Singh rte_spinlock_unlock(&client->pfe->hif.lock); 307fe38ad9bSGagandeep Singh 308fe38ad9bSGagandeep Singh return 0; 309fe38ad9bSGagandeep Singh 310fe38ad9bSGagandeep Singh err: 311fe38ad9bSGagandeep Singh rte_spinlock_unlock(&client->pfe->hif.lock); 312fe38ad9bSGagandeep Singh hif_lib_client_release_tx_buffers(client); 313fe38ad9bSGagandeep Singh 314fe38ad9bSGagandeep Singh err_tx: 315fe38ad9bSGagandeep Singh hif_lib_client_release_rx_buffers(client); 316fe38ad9bSGagandeep Singh 317fe38ad9bSGagandeep Singh err_rx: 318fe38ad9bSGagandeep Singh return err; 319fe38ad9bSGagandeep Singh } 320fe38ad9bSGagandeep Singh 321fe38ad9bSGagandeep Singh int 322fe38ad9bSGagandeep Singh hif_lib_client_unregister(struct hif_client_s *client) 323fe38ad9bSGagandeep Singh { 324fe38ad9bSGagandeep Singh struct pfe *pfe = client->pfe; 325fe38ad9bSGagandeep Singh u32 client_id = client->id; 326fe38ad9bSGagandeep Singh 327fe38ad9bSGagandeep Singh PFE_PMD_INFO("client: %p, client_id: %d, txQ_depth: %d, rxQ_depth: %d", 328fe38ad9bSGagandeep Singh client, client->id, client->tx_qsize, client->rx_qsize); 329fe38ad9bSGagandeep Singh 330fe38ad9bSGagandeep Singh rte_spinlock_lock(&pfe->hif.lock); 331fe38ad9bSGagandeep Singh hif_lib_indicate_hif(&pfe->hif, REQUEST_CL_UNREGISTER, client->id, 0); 332fe38ad9bSGagandeep Singh 333fe38ad9bSGagandeep Singh hif_lib_client_release_tx_buffers(client); 334fe38ad9bSGagandeep Singh hif_lib_client_release_rx_buffers(client); 335fe38ad9bSGagandeep Singh pfe->hif_client[client_id] = NULL; 336fe38ad9bSGagandeep Singh rte_spinlock_unlock(&pfe->hif.lock); 337fe38ad9bSGagandeep Singh 338fe38ad9bSGagandeep Singh return 0; 339fe38ad9bSGagandeep Singh } 340fe38ad9bSGagandeep Singh 341fe38ad9bSGagandeep Singh int 342fe38ad9bSGagandeep Singh hif_lib_event_handler_start(struct hif_client_s *client, int event, 343fe38ad9bSGagandeep Singh int qno) 344fe38ad9bSGagandeep Singh { 345fe38ad9bSGagandeep Singh struct hif_client_rx_queue *queue = &client->rx_q[qno]; 346fe38ad9bSGagandeep Singh struct rx_queue_desc *desc = queue->base + queue->read_idx; 347fe38ad9bSGagandeep Singh 348fe38ad9bSGagandeep Singh if (event >= HIF_EVENT_MAX || qno >= HIF_CLIENT_QUEUES_MAX) { 349fe38ad9bSGagandeep Singh PFE_PMD_WARN("Unsupported event : %d queue number : %d", 350fe38ad9bSGagandeep Singh event, qno); 351fe38ad9bSGagandeep Singh return -1; 352fe38ad9bSGagandeep Singh } 353fe38ad9bSGagandeep Singh 354fe38ad9bSGagandeep Singh test_and_clear_bit(qno, &client->queue_mask[event]); 355fe38ad9bSGagandeep Singh 356fe38ad9bSGagandeep Singh switch (event) { 357fe38ad9bSGagandeep Singh case EVENT_RX_PKT_IND: 358fe38ad9bSGagandeep Singh if (!(desc->ctrl & CL_DESC_OWN)) 359fe38ad9bSGagandeep Singh hif_lib_indicate_client(client, 360fe38ad9bSGagandeep Singh EVENT_RX_PKT_IND, qno); 361fe38ad9bSGagandeep Singh break; 362fe38ad9bSGagandeep Singh 363fe38ad9bSGagandeep Singh case EVENT_HIGH_RX_WM: 364fe38ad9bSGagandeep Singh case EVENT_TXDONE_IND: 365fe38ad9bSGagandeep Singh default: 366fe38ad9bSGagandeep Singh break; 367fe38ad9bSGagandeep Singh } 368fe38ad9bSGagandeep Singh 369fe38ad9bSGagandeep Singh return 0; 370fe38ad9bSGagandeep Singh } 371fe38ad9bSGagandeep Singh 37236220514SGagandeep Singh #ifdef RTE_LIBRTE_PFE_SW_PARSE 37336220514SGagandeep Singh static inline void 37436220514SGagandeep Singh pfe_sw_parse_pkt(struct rte_mbuf *mbuf) 37536220514SGagandeep Singh { 37636220514SGagandeep Singh struct rte_net_hdr_lens hdr_lens; 37736220514SGagandeep Singh 37836220514SGagandeep Singh mbuf->packet_type = rte_net_get_ptype(mbuf, &hdr_lens, 37936220514SGagandeep Singh RTE_PTYPE_L2_MASK | RTE_PTYPE_L3_MASK 38036220514SGagandeep Singh | RTE_PTYPE_L4_MASK); 38136220514SGagandeep Singh mbuf->l2_len = hdr_lens.l2_len; 38236220514SGagandeep Singh mbuf->l3_len = hdr_lens.l3_len; 38336220514SGagandeep Singh } 38436220514SGagandeep Singh #endif 38536220514SGagandeep Singh 38636220514SGagandeep Singh /* 38736220514SGagandeep Singh * This function gets one packet from the specified client queue 38836220514SGagandeep Singh * It also refill the rx buffer 38936220514SGagandeep Singh */ 39036220514SGagandeep Singh int 39136220514SGagandeep Singh hif_lib_receive_pkt(struct hif_client_rx_queue *queue, 39236220514SGagandeep Singh struct rte_mempool *pool, struct rte_mbuf **rx_pkts, 39336220514SGagandeep Singh uint16_t nb_pkts) 39436220514SGagandeep Singh { 39536220514SGagandeep Singh struct rx_queue_desc *desc; 39636220514SGagandeep Singh struct pfe_eth_priv_s *priv = queue->priv; 39736220514SGagandeep Singh struct rte_pktmbuf_pool_private *mb_priv; 39836220514SGagandeep Singh struct rte_mbuf *mbuf, *p_mbuf = NULL, *first_mbuf = NULL; 39936220514SGagandeep Singh struct rte_eth_stats *stats = &priv->stats; 40036220514SGagandeep Singh int i, wait_for_last = 0; 40136220514SGagandeep Singh #ifndef RTE_LIBRTE_PFE_SW_PARSE 40236220514SGagandeep Singh struct pfe_parse *parse_res; 40336220514SGagandeep Singh #endif 40436220514SGagandeep Singh 40536220514SGagandeep Singh for (i = 0; i < nb_pkts;) { 40636220514SGagandeep Singh do { 40736220514SGagandeep Singh desc = queue->base + queue->read_idx; 40836220514SGagandeep Singh if ((desc->ctrl & CL_DESC_OWN)) { 40936220514SGagandeep Singh stats->ipackets += i; 41036220514SGagandeep Singh return i; 41136220514SGagandeep Singh } 41236220514SGagandeep Singh 41336220514SGagandeep Singh mb_priv = rte_mempool_get_priv(pool); 41436220514SGagandeep Singh 41536220514SGagandeep Singh mbuf = desc->data + PFE_PKT_HEADER_SZ 41636220514SGagandeep Singh - sizeof(struct rte_mbuf) 41736220514SGagandeep Singh - RTE_PKTMBUF_HEADROOM 41836220514SGagandeep Singh - mb_priv->mbuf_priv_size; 41936220514SGagandeep Singh mbuf->next = NULL; 42036220514SGagandeep Singh if (desc->ctrl & CL_DESC_FIRST) { 42136220514SGagandeep Singh /* TODO size of priv data if present in 42236220514SGagandeep Singh * descriptor 42336220514SGagandeep Singh */ 42436220514SGagandeep Singh u16 size = 0; 42536220514SGagandeep Singh mbuf->pkt_len = CL_DESC_BUF_LEN(desc->ctrl) 42636220514SGagandeep Singh - PFE_PKT_HEADER_SZ - size; 42736220514SGagandeep Singh mbuf->data_len = mbuf->pkt_len; 42836220514SGagandeep Singh mbuf->port = queue->port_id; 42936220514SGagandeep Singh #ifdef RTE_LIBRTE_PFE_SW_PARSE 43036220514SGagandeep Singh pfe_sw_parse_pkt(mbuf); 43136220514SGagandeep Singh #else 43236220514SGagandeep Singh parse_res = (struct pfe_parse *)(desc->data + 43336220514SGagandeep Singh PFE_HIF_SIZE); 43436220514SGagandeep Singh mbuf->packet_type = parse_res->packet_type; 43536220514SGagandeep Singh #endif 43636220514SGagandeep Singh mbuf->nb_segs = 1; 43736220514SGagandeep Singh first_mbuf = mbuf; 43836220514SGagandeep Singh rx_pkts[i++] = first_mbuf; 43936220514SGagandeep Singh } else { 44036220514SGagandeep Singh mbuf->data_len = CL_DESC_BUF_LEN(desc->ctrl); 44136220514SGagandeep Singh mbuf->data_off = mbuf->data_off - 44236220514SGagandeep Singh PFE_PKT_HEADER_SZ; 44336220514SGagandeep Singh first_mbuf->pkt_len += mbuf->data_len; 44436220514SGagandeep Singh first_mbuf->nb_segs++; 44536220514SGagandeep Singh p_mbuf->next = mbuf; 44636220514SGagandeep Singh } 44736220514SGagandeep Singh stats->ibytes += mbuf->data_len; 44836220514SGagandeep Singh p_mbuf = mbuf; 44936220514SGagandeep Singh 45036220514SGagandeep Singh if (desc->ctrl & CL_DESC_LAST) 45136220514SGagandeep Singh wait_for_last = 0; 45236220514SGagandeep Singh else 45336220514SGagandeep Singh wait_for_last = 1; 45436220514SGagandeep Singh /* 45536220514SGagandeep Singh * Needed so we don't free a buffer/page 45636220514SGagandeep Singh * twice on module_exit 45736220514SGagandeep Singh */ 45836220514SGagandeep Singh desc->data = NULL; 45936220514SGagandeep Singh 46036220514SGagandeep Singh /* 46136220514SGagandeep Singh * Ensure everything else is written to DDR before 46236220514SGagandeep Singh * writing bd->ctrl 46336220514SGagandeep Singh */ 46436220514SGagandeep Singh rte_wmb(); 46536220514SGagandeep Singh 46636220514SGagandeep Singh desc->ctrl = CL_DESC_OWN; 46736220514SGagandeep Singh queue->read_idx = (queue->read_idx + 1) & 46836220514SGagandeep Singh (queue->size - 1); 46936220514SGagandeep Singh } while (wait_for_last); 47036220514SGagandeep Singh } 47136220514SGagandeep Singh stats->ipackets += i; 47236220514SGagandeep Singh return i; 47336220514SGagandeep Singh } 47436220514SGagandeep Singh 47536220514SGagandeep Singh static inline void 47636220514SGagandeep Singh hif_hdr_write(struct hif_hdr *pkt_hdr, unsigned int 47736220514SGagandeep Singh client_id, unsigned int qno, 47836220514SGagandeep Singh u32 client_ctrl) 47936220514SGagandeep Singh { 4807be78d02SJosh Soref /* Optimize the write since the destination may be non-cacheable */ 48136220514SGagandeep Singh if (!((unsigned long)pkt_hdr & 0x3)) { 48236220514SGagandeep Singh ((u32 *)pkt_hdr)[0] = (client_ctrl << 16) | (qno << 8) | 48336220514SGagandeep Singh client_id; 48436220514SGagandeep Singh } else { 48536220514SGagandeep Singh ((u16 *)pkt_hdr)[0] = (qno << 8) | (client_id & 0xFF); 48636220514SGagandeep Singh ((u16 *)pkt_hdr)[1] = (client_ctrl & 0xFFFF); 48736220514SGagandeep Singh } 48836220514SGagandeep Singh } 48936220514SGagandeep Singh 49036220514SGagandeep Singh /*This function puts the given packet in the specific client queue */ 49136220514SGagandeep Singh void 49236220514SGagandeep Singh hif_lib_xmit_pkt(struct hif_client_s *client, unsigned int qno, 49336220514SGagandeep Singh void *data, void *data1, unsigned int len, 49436220514SGagandeep Singh u32 client_ctrl, unsigned int flags, void *client_data) 49536220514SGagandeep Singh { 49636220514SGagandeep Singh struct hif_client_tx_queue *queue = &client->tx_q[qno]; 49736220514SGagandeep Singh struct tx_queue_desc *desc = queue->base + queue->write_idx; 49836220514SGagandeep Singh 49936220514SGagandeep Singh /* First buffer */ 50036220514SGagandeep Singh if (flags & HIF_FIRST_BUFFER) { 50136220514SGagandeep Singh data1 -= PFE_HIF_SIZE; 50236220514SGagandeep Singh data -= PFE_HIF_SIZE; 50336220514SGagandeep Singh len += PFE_HIF_SIZE; 50436220514SGagandeep Singh 50536220514SGagandeep Singh hif_hdr_write(data1, client->id, qno, client_ctrl); 50636220514SGagandeep Singh } 50736220514SGagandeep Singh 50836220514SGagandeep Singh desc->data = client_data; 50936220514SGagandeep Singh desc->ctrl = CL_DESC_OWN | CL_DESC_FLAGS(flags); 51036220514SGagandeep Singh 51136220514SGagandeep Singh hif_xmit_pkt(&client->pfe->hif, client->id, qno, data, len, flags); 51236220514SGagandeep Singh 51336220514SGagandeep Singh queue->write_idx = (queue->write_idx + 1) & (queue->size - 1); 51436220514SGagandeep Singh 51536220514SGagandeep Singh queue->tx_pending++; 51636220514SGagandeep Singh } 51736220514SGagandeep Singh 518fe38ad9bSGagandeep Singh void * 519fe38ad9bSGagandeep Singh hif_lib_tx_get_next_complete(struct hif_client_s *client, int qno, 520fe38ad9bSGagandeep Singh unsigned int *flags, __rte_unused int count) 521fe38ad9bSGagandeep Singh { 522fe38ad9bSGagandeep Singh struct hif_client_tx_queue *queue = &client->tx_q[qno]; 523fe38ad9bSGagandeep Singh struct tx_queue_desc *desc = queue->base + queue->read_idx; 524fe38ad9bSGagandeep Singh 525fe38ad9bSGagandeep Singh PFE_DP_LOG(DEBUG, "qno : %d rd_indx: %d pending:%d", 526fe38ad9bSGagandeep Singh qno, queue->read_idx, queue->tx_pending); 527fe38ad9bSGagandeep Singh 528fe38ad9bSGagandeep Singh if (!queue->tx_pending) 529fe38ad9bSGagandeep Singh return NULL; 530fe38ad9bSGagandeep Singh 531fe38ad9bSGagandeep Singh if (queue->nocpy_flag && !queue->done_tmu_tx_pkts) { 532fe38ad9bSGagandeep Singh u32 tmu_tx_pkts = 0; 533fe38ad9bSGagandeep Singh 534fe38ad9bSGagandeep Singh if (queue->prev_tmu_tx_pkts > tmu_tx_pkts) 535fe38ad9bSGagandeep Singh queue->done_tmu_tx_pkts = UINT_MAX - 536fe38ad9bSGagandeep Singh queue->prev_tmu_tx_pkts + tmu_tx_pkts; 537fe38ad9bSGagandeep Singh else 538fe38ad9bSGagandeep Singh queue->done_tmu_tx_pkts = tmu_tx_pkts - 539fe38ad9bSGagandeep Singh queue->prev_tmu_tx_pkts; 540fe38ad9bSGagandeep Singh 541fe38ad9bSGagandeep Singh queue->prev_tmu_tx_pkts = tmu_tx_pkts; 542fe38ad9bSGagandeep Singh 543fe38ad9bSGagandeep Singh if (!queue->done_tmu_tx_pkts) 544fe38ad9bSGagandeep Singh return NULL; 545fe38ad9bSGagandeep Singh } 546fe38ad9bSGagandeep Singh 547fe38ad9bSGagandeep Singh if (desc->ctrl & CL_DESC_OWN) 548fe38ad9bSGagandeep Singh return NULL; 549fe38ad9bSGagandeep Singh 550fe38ad9bSGagandeep Singh queue->read_idx = (queue->read_idx + 1) & (queue->size - 1); 551fe38ad9bSGagandeep Singh queue->tx_pending--; 552fe38ad9bSGagandeep Singh 553fe38ad9bSGagandeep Singh *flags = CL_DESC_GET_FLAGS(desc->ctrl); 554fe38ad9bSGagandeep Singh 555fe38ad9bSGagandeep Singh if (queue->done_tmu_tx_pkts && (*flags & HIF_LAST_BUFFER)) 556fe38ad9bSGagandeep Singh queue->done_tmu_tx_pkts--; 557fe38ad9bSGagandeep Singh 558fe38ad9bSGagandeep Singh return desc->data; 559fe38ad9bSGagandeep Singh } 560fe38ad9bSGagandeep Singh 561fe38ad9bSGagandeep Singh int 562fe38ad9bSGagandeep Singh pfe_hif_lib_init(struct pfe *pfe) 5635253fe37SGagandeep Singh { 5645253fe37SGagandeep Singh PMD_INIT_FUNC_TRACE(); 5655253fe37SGagandeep Singh 566fe38ad9bSGagandeep Singh emac_txq_cnt = EMAC_TXQ_CNT; 567fe38ad9bSGagandeep Singh pfe->hif.shm = &ghif_shm; 568fe38ad9bSGagandeep Singh 5695253fe37SGagandeep Singh return 0; 5705253fe37SGagandeep Singh } 5715253fe37SGagandeep Singh 5725253fe37SGagandeep Singh void 5735253fe37SGagandeep Singh pfe_hif_lib_exit(__rte_unused struct pfe *pfe) 5745253fe37SGagandeep Singh { 5755253fe37SGagandeep Singh PMD_INIT_FUNC_TRACE(); 5765253fe37SGagandeep Singh } 577