1 /* SPDX-License-Identifier: BSD-3-Clause
9 #include <sys/eventfd.h>
12 pfe_hif_alloc_descr(struct pfe_hif *hif)
17 PMD_INIT_FUNC_TRACE();
19 addr = rte_zmalloc(NULL, HIF_RX_DESC_NT * sizeof(struct hif_desc) +
20 HIF_TX_DESC_NT * sizeof(struct hif_desc), RTE_CACHE_LINE_SIZE);
22 PFE_PMD_ERR("Could not allocate buffer descriptors!");
27 hif->descr_baseaddr_p = pfe_mem_vtop((uintptr_t)addr);
28 hif->descr_baseaddr_v = addr;
29 hif->rx_ring_size = HIF_RX_DESC_NT;
30 hif->tx_ring_size = HIF_TX_DESC_NT;
39 pfe_hif_free_descr(struct pfe_hif *hif)
41 PMD_INIT_FUNC_TRACE();
43 rte_free(hif->descr_baseaddr_v);
47 * pfe_hif_client_register
49 * This function used to register a client driver with the HIF driver.
52 * 0 - on Successful registration
55 pfe_hif_client_register(struct pfe_hif *hif, u32 client_id,
56 struct hif_client_shm *client_shm)
58 struct hif_client *client = &hif->client[client_id];
60 struct rx_queue_desc *rx_qbase;
61 struct tx_queue_desc *tx_qbase;
62 struct hif_rx_queue *rx_queue;
63 struct hif_tx_queue *tx_queue;
66 PMD_INIT_FUNC_TRACE();
68 rte_spinlock_lock(&hif->tx_lock);
70 if (test_bit(client_id, &hif->shm->g_client_status[0])) {
71 PFE_PMD_ERR("client %d already registered", client_id);
76 memset(client, 0, sizeof(struct hif_client));
78 /* Initialize client Rx queues baseaddr, size */
80 cnt = CLIENT_CTRL_RX_Q_CNT(client_shm->ctrl);
81 /* Check if client is requesting for more queues than supported */
82 if (cnt > HIF_CLIENT_QUEUES_MAX)
83 cnt = HIF_CLIENT_QUEUES_MAX;
86 rx_qbase = (struct rx_queue_desc *)client_shm->rx_qbase;
87 for (i = 0; i < cnt; i++) {
88 rx_queue = &client->rx_q[i];
89 rx_queue->base = rx_qbase + i * client_shm->rx_qsize;
90 rx_queue->size = client_shm->rx_qsize;
91 rx_queue->write_idx = 0;
94 /* Initialize client Tx queues baseaddr, size */
95 cnt = CLIENT_CTRL_TX_Q_CNT(client_shm->ctrl);
97 /* Check if client is requesting for more queues than supported */
98 if (cnt > HIF_CLIENT_QUEUES_MAX)
99 cnt = HIF_CLIENT_QUEUES_MAX;
102 tx_qbase = (struct tx_queue_desc *)client_shm->tx_qbase;
103 for (i = 0; i < cnt; i++) {
104 tx_queue = &client->tx_q[i];
105 tx_queue->base = tx_qbase + i * client_shm->tx_qsize;
106 tx_queue->size = client_shm->tx_qsize;
107 tx_queue->ack_idx = 0;
110 set_bit(client_id, &hif->shm->g_client_status[0]);
113 rte_spinlock_unlock(&hif->tx_lock);
119 * pfe_hif_client_unregister
121 * This function used to unregister a client from the HIF driver.
125 pfe_hif_client_unregister(struct pfe_hif *hif, u32 client_id)
127 PMD_INIT_FUNC_TRACE();
130 * Mark client as no longer available (which prevents further packet
131 * receive for this client)
133 rte_spinlock_lock(&hif->tx_lock);
135 if (!test_bit(client_id, &hif->shm->g_client_status[0])) {
136 PFE_PMD_ERR("client %d not registered", client_id);
138 rte_spinlock_unlock(&hif->tx_lock);
142 clear_bit(client_id, &hif->shm->g_client_status[0]);
144 rte_spinlock_unlock(&hif->tx_lock);
148 hif_process_client_req(struct pfe_hif *hif, int req,
149 int data1, __rte_unused int data2)
151 unsigned int client_id = data1;
153 if (client_id >= HIF_CLIENTS_MAX) {
154 PFE_PMD_ERR("client id %d out of bounds", client_id);
159 case REQUEST_CL_REGISTER:
160 /* Request for register a client */
161 PFE_PMD_INFO("register client_id %d", client_id);
162 pfe_hif_client_register(hif, client_id, (struct
163 hif_client_shm *)&hif->shm->client[client_id]);
166 case REQUEST_CL_UNREGISTER:
167 PFE_PMD_INFO("unregister client_id %d", client_id);
169 /* Request for unregister a client */
170 pfe_hif_client_unregister(hif, client_id);
175 PFE_PMD_ERR("unsupported request %d", req);
180 * Process client Tx queues
181 * Currently we don't have checking for tx pending
185 #if defined(LS1012A_PFE_RESET_WA)
187 pfe_hif_disable_rx_desc(struct pfe_hif *hif)
190 struct hif_desc *desc = hif->rx_base;
192 /*Mark all descriptors as LAST_BD */
193 for (ii = 0; ii < hif->rx_ring_size; ii++) {
194 desc->ctrl |= BD_CTRL_LAST_BD;
199 struct class_rx_hdr_t {
200 u32 next_ptr; /* ptr to the start of the first DDR buffer */
201 u16 length; /* total packet length */
202 u16 phyno; /* input physical port number */
203 u32 status; /* gemac status bits */
204 u32 status2; /* reserved for software usage */
207 /* STATUS_BAD_FRAME_ERR is set for all errors (including checksums if enabled)
210 #define STATUS_BAD_FRAME_ERR BIT(16)
211 #define STATUS_LENGTH_ERR BIT(17)
212 #define STATUS_CRC_ERR BIT(18)
213 #define STATUS_TOO_SHORT_ERR BIT(19)
214 #define STATUS_TOO_LONG_ERR BIT(20)
215 #define STATUS_CODE_ERR BIT(21)
216 #define STATUS_MC_HASH_MATCH BIT(22)
217 #define STATUS_CUMULATIVE_ARC_HIT BIT(23)
218 #define STATUS_UNICAST_HASH_MATCH BIT(24)
219 #define STATUS_IP_CHECKSUM_CORRECT BIT(25)
220 #define STATUS_TCP_CHECKSUM_CORRECT BIT(26)
221 #define STATUS_UDP_CHECKSUM_CORRECT BIT(27)
222 #define STATUS_OVERFLOW_ERR BIT(28) /* GPI error */
223 #define MIN_PKT_SIZE 64
224 #define DUMMY_PKT_COUNT 128
227 copy_to_lmem(u32 *dst, u32 *src, int len)
231 for (i = 0; i < len; i += sizeof(u32)) {
236 #if defined(RTE_TOOLCHAIN_GCC)
237 __attribute__ ((optimize(1)))
240 send_dummy_pkt_to_hif(void)
242 void *lmem_ptr, *ddr_ptr, *lmem_virt_addr;
244 struct class_rx_hdr_t local_hdr;
245 static u32 dummy_pkt[] = {
246 0x33221100, 0x2b785544, 0xd73093cb, 0x01000608,
247 0x04060008, 0x2b780200, 0xd73093cb, 0x0a01a8c0,
248 0x33221100, 0xa8c05544, 0x00000301, 0x00000000,
249 0x00000000, 0x00000000, 0x00000000, 0xbe86c51f };
251 ddr_ptr = (void *)(size_t)readl(BMU2_BASE_ADDR + BMU_ALLOC_CTRL);
255 lmem_ptr = (void *)(size_t)readl(BMU1_BASE_ADDR + BMU_ALLOC_CTRL);
259 PFE_PMD_INFO("Sending a dummy pkt to HIF %p %p", ddr_ptr, lmem_ptr);
260 physaddr = DDR_VIRT_TO_PFE(ddr_ptr);
262 lmem_virt_addr = (void *)CBUS_PFE_TO_VIRT((unsigned long)lmem_ptr);
264 local_hdr.phyno = htons(0); /* RX_PHY_0 */
265 local_hdr.length = htons(MIN_PKT_SIZE);
267 local_hdr.next_ptr = htonl((u32)physaddr);
268 /*Mark checksum is correct */
269 local_hdr.status = htonl((STATUS_IP_CHECKSUM_CORRECT |
270 STATUS_UDP_CHECKSUM_CORRECT |
271 STATUS_TCP_CHECKSUM_CORRECT |
272 STATUS_UNICAST_HASH_MATCH |
273 STATUS_CUMULATIVE_ARC_HIT));
274 copy_to_lmem((u32 *)lmem_virt_addr, (u32 *)&local_hdr,
277 copy_to_lmem((u32 *)(lmem_virt_addr + LMEM_HDR_SIZE), (u32 *)dummy_pkt,
280 writel((unsigned long)lmem_ptr, CLASS_INQ_PKTPTR);
284 pfe_hif_rx_idle(struct pfe_hif *hif)
286 int hif_stop_loop = DUMMY_PKT_COUNT;
289 pfe_hif_disable_rx_desc(hif);
290 PFE_PMD_INFO("Bringing hif to idle state...");
291 writel(0, HIF_INT_ENABLE);
292 /*If HIF Rx BDP is busy send a dummy packet */
294 rx_status = readl(HIF_RX_STATUS);
295 if (rx_status & BDP_CSR_RX_DMA_ACTV)
296 send_dummy_pkt_to_hif();
299 } while (--hif_stop_loop);
301 if (readl(HIF_RX_STATUS) & BDP_CSR_RX_DMA_ACTV)
302 PFE_PMD_ERR("Failed\n");
304 PFE_PMD_INFO("Done\n");
310 * This function initializes the baseaddresses and irq, etc.
313 pfe_hif_init(struct pfe *pfe)
315 struct pfe_hif *hif = &pfe->hif;
318 PMD_INIT_FUNC_TRACE();
320 #if defined(LS1012A_PFE_RESET_WA)
321 pfe_hif_rx_idle(hif);
324 err = pfe_hif_alloc_descr(hif);
328 rte_spinlock_init(&hif->tx_lock);
329 rte_spinlock_init(&hif->lock);
331 gpi_enable(HGPI_BASE_ADDR);
332 if (getenv("PFE_INTR_SUPPORT")) {
333 struct epoll_event epoll_ev;
334 int event_fd = -1, epoll_fd, pfe_cdev_fd;
336 pfe_cdev_fd = open(PFE_CDEV_PATH, O_RDWR);
337 if (pfe_cdev_fd < 0) {
338 PFE_PMD_WARN("Unable to open PFE device file (%s).\n",
340 pfe->cdev_fd = PFE_CDEV_INVALID_FD;
343 pfe->cdev_fd = pfe_cdev_fd;
345 event_fd = eventfd(0, EFD_NONBLOCK);
346 /* hif interrupt enable */
347 err = ioctl(pfe->cdev_fd, PFE_CDEV_HIF_INTR_EN, &event_fd);
349 PFE_PMD_ERR("\nioctl failed for intr enable err: %d\n",
353 epoll_fd = epoll_create(1);
354 epoll_ev.events = EPOLLIN | EPOLLPRI | EPOLLET;
355 epoll_ev.data.fd = event_fd;
356 err = epoll_ctl(epoll_fd, EPOLL_CTL_ADD, event_fd, &epoll_ev);
358 PFE_PMD_ERR("epoll_ctl failed with err = %d\n", errno);
361 pfe->hif.epoll_fd = epoll_fd;
370 pfe_hif_exit(struct pfe *pfe)
372 struct pfe_hif *hif = &pfe->hif;
374 PMD_INIT_FUNC_TRACE();
376 rte_spinlock_lock(&hif->lock);
377 hif->shm->g_client_status[0] = 0;
378 /* Make sure all clients are disabled*/
379 hif->shm->g_client_status[1] = 0;
381 rte_spinlock_unlock(&hif->lock);
384 #if defined(LS1012A_PFE_RESET_WA)
385 pfe_hif_rx_idle(hif);
391 pfe_hif_free_descr(hif);
392 pfe->hif.setuped = 0;
394 gpi_disable(HGPI_BASE_ADDR);