t7xx_hif_dpmaif_rx.c (34191B)
1// SPDX-License-Identifier: GPL-2.0-only 2/* 3 * Copyright (c) 2021, MediaTek Inc. 4 * Copyright (c) 2021-2022, Intel Corporation. 5 * 6 * Authors: 7 * Amir Hanania <amir.hanania@intel.com> 8 * Haijun Liu <haijun.liu@mediatek.com> 9 * Eliot Lee <eliot.lee@intel.com> 10 * Moises Veleta <moises.veleta@intel.com> 11 * Ricardo Martinez <ricardo.martinez@linux.intel.com> 12 * 13 * Contributors: 14 * Andy Shevchenko <andriy.shevchenko@linux.intel.com> 15 * Chiranjeevi Rapolu <chiranjeevi.rapolu@intel.com> 16 * Sreehari Kancharla <sreehari.kancharla@intel.com> 17 */ 18 19#include <linux/atomic.h> 20#include <linux/bitfield.h> 21#include <linux/bitops.h> 22#include <linux/device.h> 23#include <linux/dma-direction.h> 24#include <linux/dma-mapping.h> 25#include <linux/gfp.h> 26#include <linux/err.h> 27#include <linux/iopoll.h> 28#include <linux/jiffies.h> 29#include <linux/kernel.h> 30#include <linux/kthread.h> 31#include <linux/list.h> 32#include <linux/minmax.h> 33#include <linux/mm.h> 34#include <linux/netdevice.h> 35#include <linux/pm_runtime.h> 36#include <linux/sched.h> 37#include <linux/skbuff.h> 38#include <linux/slab.h> 39#include <linux/spinlock.h> 40#include <linux/string.h> 41#include <linux/types.h> 42#include <linux/wait.h> 43#include <linux/workqueue.h> 44 45#include "t7xx_dpmaif.h" 46#include "t7xx_hif_dpmaif.h" 47#include "t7xx_hif_dpmaif_rx.h" 48#include "t7xx_pci.h" 49 50#define DPMAIF_BAT_COUNT 8192 51#define DPMAIF_FRG_COUNT 4814 52#define DPMAIF_PIT_COUNT (DPMAIF_BAT_COUNT * 2) 53 54#define DPMAIF_BAT_CNT_THRESHOLD 30 55#define DPMAIF_PIT_CNT_THRESHOLD 60 56#define DPMAIF_RX_PUSH_THRESHOLD_MASK GENMASK(2, 0) 57#define DPMAIF_NOTIFY_RELEASE_COUNT 128 58#define DPMAIF_POLL_PIT_TIME_US 20 59#define DPMAIF_POLL_PIT_MAX_TIME_US 2000 60#define DPMAIF_WQ_TIME_LIMIT_MS 2 61#define DPMAIF_CS_RESULT_PASS 0 62 63/* Packet type */ 64#define DES_PT_PD 0 65#define DES_PT_MSG 1 66/* Buffer type */ 67#define PKT_BUF_FRAG 1 68 69static unsigned int t7xx_normal_pit_bid(const struct dpmaif_pit *pit_info) 70{ 71 u32 value; 72 73 value = FIELD_GET(PD_PIT_H_BID, le32_to_cpu(pit_info->pd.footer)); 74 value <<= 13; 75 value += FIELD_GET(PD_PIT_BUFFER_ID, le32_to_cpu(pit_info->header)); 76 return value; 77} 78 79static int t7xx_dpmaif_net_rx_push_thread(void *arg) 80{ 81 struct dpmaif_rx_queue *q = arg; 82 struct dpmaif_ctrl *hif_ctrl; 83 struct dpmaif_callbacks *cb; 84 85 hif_ctrl = q->dpmaif_ctrl; 86 cb = hif_ctrl->callbacks; 87 88 while (!kthread_should_stop()) { 89 struct sk_buff *skb; 90 unsigned long flags; 91 92 if (skb_queue_empty(&q->skb_list)) { 93 if (wait_event_interruptible(q->rx_wq, 94 !skb_queue_empty(&q->skb_list) || 95 kthread_should_stop())) 96 continue; 97 98 if (kthread_should_stop()) 99 break; 100 } 101 102 spin_lock_irqsave(&q->skb_list.lock, flags); 103 skb = __skb_dequeue(&q->skb_list); 104 spin_unlock_irqrestore(&q->skb_list.lock, flags); 105 106 if (!skb) 107 continue; 108 109 cb->recv_skb(hif_ctrl->t7xx_dev, skb); 110 cond_resched(); 111 } 112 113 return 0; 114} 115 116static int t7xx_dpmaif_update_bat_wr_idx(struct dpmaif_ctrl *dpmaif_ctrl, 117 const unsigned int q_num, const unsigned int bat_cnt) 118{ 119 struct dpmaif_rx_queue *rxq = &dpmaif_ctrl->rxq[q_num]; 120 struct dpmaif_bat_request *bat_req = rxq->bat_req; 121 unsigned int old_rl_idx, new_wr_idx, old_wr_idx; 122 123 if (!rxq->que_started) { 124 dev_err(dpmaif_ctrl->dev, "RX queue %d has not been started\n", rxq->index); 125 return -EINVAL; 126 } 127 128 old_rl_idx = bat_req->bat_release_rd_idx; 129 old_wr_idx = bat_req->bat_wr_idx; 130 new_wr_idx = old_wr_idx + bat_cnt; 131 132 if (old_rl_idx > old_wr_idx && new_wr_idx >= old_rl_idx) 133 goto err_flow; 134 135 if (new_wr_idx >= bat_req->bat_size_cnt) { 136 new_wr_idx -= bat_req->bat_size_cnt; 137 if (new_wr_idx >= old_rl_idx) 138 goto err_flow; 139 } 140 141 bat_req->bat_wr_idx = new_wr_idx; 142 return 0; 143 144err_flow: 145 dev_err(dpmaif_ctrl->dev, "RX BAT flow check fail\n"); 146 return -EINVAL; 147} 148 149static bool t7xx_alloc_and_map_skb_info(const struct dpmaif_ctrl *dpmaif_ctrl, 150 const unsigned int size, struct dpmaif_bat_skb *cur_skb) 151{ 152 dma_addr_t data_bus_addr; 153 struct sk_buff *skb; 154 155 skb = __dev_alloc_skb(size, GFP_KERNEL); 156 if (!skb) 157 return false; 158 159 data_bus_addr = dma_map_single(dpmaif_ctrl->dev, skb->data, size, DMA_FROM_DEVICE); 160 if (dma_mapping_error(dpmaif_ctrl->dev, data_bus_addr)) { 161 dev_err_ratelimited(dpmaif_ctrl->dev, "DMA mapping error\n"); 162 dev_kfree_skb_any(skb); 163 return false; 164 } 165 166 cur_skb->skb = skb; 167 cur_skb->data_bus_addr = data_bus_addr; 168 cur_skb->data_len = size; 169 170 return true; 171} 172 173static void t7xx_unmap_bat_skb(struct device *dev, struct dpmaif_bat_skb *bat_skb_base, 174 unsigned int index) 175{ 176 struct dpmaif_bat_skb *bat_skb = bat_skb_base + index; 177 178 if (bat_skb->skb) { 179 dma_unmap_single(dev, bat_skb->data_bus_addr, bat_skb->data_len, DMA_FROM_DEVICE); 180 dev_kfree_skb(bat_skb->skb); 181 bat_skb->skb = NULL; 182 } 183} 184 185/** 186 * t7xx_dpmaif_rx_buf_alloc() - Allocate buffers for the BAT ring. 187 * @dpmaif_ctrl: Pointer to DPMAIF context structure. 188 * @bat_req: Pointer to BAT request structure. 189 * @q_num: Queue number. 190 * @buf_cnt: Number of buffers to allocate. 191 * @initial: Indicates if the ring is being populated for the first time. 192 * 193 * Allocate skb and store the start address of the data buffer into the BAT ring. 194 * If this is not the initial call, notify the HW about the new entries. 195 * 196 * Return: 197 * * 0 - Success. 198 * * -ERROR - Error code. 199 */ 200int t7xx_dpmaif_rx_buf_alloc(struct dpmaif_ctrl *dpmaif_ctrl, 201 const struct dpmaif_bat_request *bat_req, 202 const unsigned int q_num, const unsigned int buf_cnt, 203 const bool initial) 204{ 205 unsigned int i, bat_cnt, bat_max_cnt, bat_start_idx; 206 int ret; 207 208 if (!buf_cnt || buf_cnt > bat_req->bat_size_cnt) 209 return -EINVAL; 210 211 /* Check BAT buffer space */ 212 bat_max_cnt = bat_req->bat_size_cnt; 213 214 bat_cnt = t7xx_ring_buf_rd_wr_count(bat_max_cnt, bat_req->bat_release_rd_idx, 215 bat_req->bat_wr_idx, DPMAIF_WRITE); 216 if (buf_cnt > bat_cnt) 217 return -ENOMEM; 218 219 bat_start_idx = bat_req->bat_wr_idx; 220 221 for (i = 0; i < buf_cnt; i++) { 222 unsigned int cur_bat_idx = bat_start_idx + i; 223 struct dpmaif_bat_skb *cur_skb; 224 struct dpmaif_bat *cur_bat; 225 226 if (cur_bat_idx >= bat_max_cnt) 227 cur_bat_idx -= bat_max_cnt; 228 229 cur_skb = (struct dpmaif_bat_skb *)bat_req->bat_skb + cur_bat_idx; 230 if (!cur_skb->skb && 231 !t7xx_alloc_and_map_skb_info(dpmaif_ctrl, bat_req->pkt_buf_sz, cur_skb)) 232 break; 233 234 cur_bat = (struct dpmaif_bat *)bat_req->bat_base + cur_bat_idx; 235 cur_bat->buffer_addr_ext = upper_32_bits(cur_skb->data_bus_addr); 236 cur_bat->p_buffer_addr = lower_32_bits(cur_skb->data_bus_addr); 237 } 238 239 if (!i) 240 return -ENOMEM; 241 242 ret = t7xx_dpmaif_update_bat_wr_idx(dpmaif_ctrl, q_num, i); 243 if (ret) 244 goto err_unmap_skbs; 245 246 if (!initial) { 247 unsigned int hw_wr_idx; 248 249 ret = t7xx_dpmaif_dl_snd_hw_bat_cnt(&dpmaif_ctrl->hw_info, i); 250 if (ret) 251 goto err_unmap_skbs; 252 253 hw_wr_idx = t7xx_dpmaif_dl_get_bat_wr_idx(&dpmaif_ctrl->hw_info, 254 DPF_RX_QNO_DFT); 255 if (hw_wr_idx != bat_req->bat_wr_idx) { 256 ret = -EFAULT; 257 dev_err(dpmaif_ctrl->dev, "Write index mismatch in RX ring\n"); 258 goto err_unmap_skbs; 259 } 260 } 261 262 return 0; 263 264err_unmap_skbs: 265 while (--i > 0) 266 t7xx_unmap_bat_skb(dpmaif_ctrl->dev, bat_req->bat_skb, i); 267 268 return ret; 269} 270 271static int t7xx_dpmaifq_release_pit_entry(struct dpmaif_rx_queue *rxq, 272 const unsigned int rel_entry_num) 273{ 274 struct dpmaif_hw_info *hw_info = &rxq->dpmaif_ctrl->hw_info; 275 unsigned int old_rel_idx, new_rel_idx, hw_wr_idx; 276 int ret; 277 278 if (!rxq->que_started) 279 return 0; 280 281 if (rel_entry_num >= rxq->pit_size_cnt) { 282 dev_err(rxq->dpmaif_ctrl->dev, "Invalid PIT release index\n"); 283 return -EINVAL; 284 } 285 286 old_rel_idx = rxq->pit_release_rd_idx; 287 new_rel_idx = old_rel_idx + rel_entry_num; 288 hw_wr_idx = rxq->pit_wr_idx; 289 if (hw_wr_idx < old_rel_idx && new_rel_idx >= rxq->pit_size_cnt) 290 new_rel_idx -= rxq->pit_size_cnt; 291 292 ret = t7xx_dpmaif_dlq_add_pit_remain_cnt(hw_info, rxq->index, rel_entry_num); 293 if (ret) { 294 dev_err(rxq->dpmaif_ctrl->dev, "PIT release failure: %d\n", ret); 295 return ret; 296 } 297 298 rxq->pit_release_rd_idx = new_rel_idx; 299 return 0; 300} 301 302static void t7xx_dpmaif_set_bat_mask(struct dpmaif_bat_request *bat_req, unsigned int idx) 303{ 304 unsigned long flags; 305 306 spin_lock_irqsave(&bat_req->mask_lock, flags); 307 set_bit(idx, bat_req->bat_bitmap); 308 spin_unlock_irqrestore(&bat_req->mask_lock, flags); 309} 310 311static int t7xx_frag_bat_cur_bid_check(struct dpmaif_rx_queue *rxq, 312 const unsigned int cur_bid) 313{ 314 struct dpmaif_bat_request *bat_frag = rxq->bat_frag; 315 struct dpmaif_bat_page *bat_page; 316 317 if (cur_bid >= DPMAIF_FRG_COUNT) 318 return -EINVAL; 319 320 bat_page = bat_frag->bat_skb + cur_bid; 321 if (!bat_page->page) 322 return -EINVAL; 323 324 return 0; 325} 326 327static void t7xx_unmap_bat_page(struct device *dev, struct dpmaif_bat_page *bat_page_base, 328 unsigned int index) 329{ 330 struct dpmaif_bat_page *bat_page = bat_page_base + index; 331 332 if (bat_page->page) { 333 dma_unmap_page(dev, bat_page->data_bus_addr, bat_page->data_len, DMA_FROM_DEVICE); 334 put_page(bat_page->page); 335 bat_page->page = NULL; 336 } 337} 338 339/** 340 * t7xx_dpmaif_rx_frag_alloc() - Allocates buffers for the Fragment BAT ring. 341 * @dpmaif_ctrl: Pointer to DPMAIF context structure. 342 * @bat_req: Pointer to BAT request structure. 343 * @buf_cnt: Number of buffers to allocate. 344 * @initial: Indicates if the ring is being populated for the first time. 345 * 346 * Fragment BAT is used when the received packet does not fit in a normal BAT entry. 347 * This function allocates a page fragment and stores the start address of the page 348 * into the Fragment BAT ring. 349 * If this is not the initial call, notify the HW about the new entries. 350 * 351 * Return: 352 * * 0 - Success. 353 * * -ERROR - Error code. 354 */ 355int t7xx_dpmaif_rx_frag_alloc(struct dpmaif_ctrl *dpmaif_ctrl, struct dpmaif_bat_request *bat_req, 356 const unsigned int buf_cnt, const bool initial) 357{ 358 unsigned int buf_space, cur_bat_idx = bat_req->bat_wr_idx; 359 struct dpmaif_bat_page *bat_skb = bat_req->bat_skb; 360 int ret = 0, i; 361 362 if (!buf_cnt || buf_cnt > bat_req->bat_size_cnt) 363 return -EINVAL; 364 365 buf_space = t7xx_ring_buf_rd_wr_count(bat_req->bat_size_cnt, 366 bat_req->bat_release_rd_idx, bat_req->bat_wr_idx, 367 DPMAIF_WRITE); 368 if (buf_cnt > buf_space) { 369 dev_err(dpmaif_ctrl->dev, 370 "Requested more buffers than the space available in RX frag ring\n"); 371 return -EINVAL; 372 } 373 374 for (i = 0; i < buf_cnt; i++) { 375 struct dpmaif_bat_page *cur_page = bat_skb + cur_bat_idx; 376 struct dpmaif_bat *cur_bat; 377 dma_addr_t data_base_addr; 378 379 if (!cur_page->page) { 380 unsigned long offset; 381 struct page *page; 382 void *data; 383 384 data = netdev_alloc_frag(bat_req->pkt_buf_sz); 385 if (!data) 386 break; 387 388 page = virt_to_head_page(data); 389 offset = data - page_address(page); 390 391 data_base_addr = dma_map_page(dpmaif_ctrl->dev, page, offset, 392 bat_req->pkt_buf_sz, DMA_FROM_DEVICE); 393 if (dma_mapping_error(dpmaif_ctrl->dev, data_base_addr)) { 394 put_page(virt_to_head_page(data)); 395 dev_err(dpmaif_ctrl->dev, "DMA mapping fail\n"); 396 break; 397 } 398 399 cur_page->page = page; 400 cur_page->data_bus_addr = data_base_addr; 401 cur_page->offset = offset; 402 cur_page->data_len = bat_req->pkt_buf_sz; 403 } 404 405 data_base_addr = cur_page->data_bus_addr; 406 cur_bat = (struct dpmaif_bat *)bat_req->bat_base + cur_bat_idx; 407 cur_bat->buffer_addr_ext = upper_32_bits(data_base_addr); 408 cur_bat->p_buffer_addr = lower_32_bits(data_base_addr); 409 cur_bat_idx = t7xx_ring_buf_get_next_wr_idx(bat_req->bat_size_cnt, cur_bat_idx); 410 } 411 412 bat_req->bat_wr_idx = cur_bat_idx; 413 414 if (!initial) 415 t7xx_dpmaif_dl_snd_hw_frg_cnt(&dpmaif_ctrl->hw_info, i); 416 417 if (i < buf_cnt) { 418 ret = -ENOMEM; 419 if (initial) { 420 while (--i > 0) 421 t7xx_unmap_bat_page(dpmaif_ctrl->dev, bat_req->bat_skb, i); 422 } 423 } 424 425 return ret; 426} 427 428static int t7xx_dpmaif_set_frag_to_skb(const struct dpmaif_rx_queue *rxq, 429 const struct dpmaif_pit *pkt_info, 430 struct sk_buff *skb) 431{ 432 unsigned long long data_bus_addr, data_base_addr; 433 struct device *dev = rxq->dpmaif_ctrl->dev; 434 struct dpmaif_bat_page *page_info; 435 unsigned int data_len; 436 int data_offset; 437 438 page_info = rxq->bat_frag->bat_skb; 439 page_info += t7xx_normal_pit_bid(pkt_info); 440 dma_unmap_page(dev, page_info->data_bus_addr, page_info->data_len, DMA_FROM_DEVICE); 441 442 if (!page_info->page) 443 return -EINVAL; 444 445 data_bus_addr = le32_to_cpu(pkt_info->pd.data_addr_h); 446 data_bus_addr = (data_bus_addr << 32) + le32_to_cpu(pkt_info->pd.data_addr_l); 447 data_base_addr = page_info->data_bus_addr; 448 data_offset = data_bus_addr - data_base_addr; 449 data_offset += page_info->offset; 450 data_len = FIELD_GET(PD_PIT_DATA_LEN, le32_to_cpu(pkt_info->header)); 451 skb_add_rx_frag(skb, skb_shinfo(skb)->nr_frags, page_info->page, 452 data_offset, data_len, page_info->data_len); 453 454 page_info->page = NULL; 455 page_info->offset = 0; 456 page_info->data_len = 0; 457 return 0; 458} 459 460static int t7xx_dpmaif_get_frag(struct dpmaif_rx_queue *rxq, 461 const struct dpmaif_pit *pkt_info, 462 const struct dpmaif_cur_rx_skb_info *skb_info) 463{ 464 unsigned int cur_bid = t7xx_normal_pit_bid(pkt_info); 465 int ret; 466 467 ret = t7xx_frag_bat_cur_bid_check(rxq, cur_bid); 468 if (ret < 0) 469 return ret; 470 471 ret = t7xx_dpmaif_set_frag_to_skb(rxq, pkt_info, skb_info->cur_skb); 472 if (ret < 0) { 473 dev_err(rxq->dpmaif_ctrl->dev, "Failed to set frag data to skb: %d\n", ret); 474 return ret; 475 } 476 477 t7xx_dpmaif_set_bat_mask(rxq->bat_frag, cur_bid); 478 return 0; 479} 480 481static int t7xx_bat_cur_bid_check(struct dpmaif_rx_queue *rxq, const unsigned int cur_bid) 482{ 483 struct dpmaif_bat_skb *bat_skb = rxq->bat_req->bat_skb; 484 485 bat_skb += cur_bid; 486 if (cur_bid >= DPMAIF_BAT_COUNT || !bat_skb->skb) 487 return -EINVAL; 488 489 return 0; 490} 491 492static int t7xx_dpmaif_read_pit_seq(const struct dpmaif_pit *pit) 493{ 494 return FIELD_GET(PD_PIT_PIT_SEQ, le32_to_cpu(pit->pd.footer)); 495} 496 497static int t7xx_dpmaif_check_pit_seq(struct dpmaif_rx_queue *rxq, 498 const struct dpmaif_pit *pit) 499{ 500 unsigned int cur_pit_seq, expect_pit_seq = rxq->expect_pit_seq; 501 502 if (read_poll_timeout_atomic(t7xx_dpmaif_read_pit_seq, cur_pit_seq, 503 cur_pit_seq == expect_pit_seq, DPMAIF_POLL_PIT_TIME_US, 504 DPMAIF_POLL_PIT_MAX_TIME_US, false, pit)) 505 return -EFAULT; 506 507 rxq->expect_pit_seq++; 508 if (rxq->expect_pit_seq >= DPMAIF_DL_PIT_SEQ_VALUE) 509 rxq->expect_pit_seq = 0; 510 511 return 0; 512} 513 514static unsigned int t7xx_dpmaif_avail_pkt_bat_cnt(struct dpmaif_bat_request *bat_req) 515{ 516 unsigned int zero_index; 517 unsigned long flags; 518 519 spin_lock_irqsave(&bat_req->mask_lock, flags); 520 521 zero_index = find_next_zero_bit(bat_req->bat_bitmap, bat_req->bat_size_cnt, 522 bat_req->bat_release_rd_idx); 523 524 if (zero_index < bat_req->bat_size_cnt) { 525 spin_unlock_irqrestore(&bat_req->mask_lock, flags); 526 return zero_index - bat_req->bat_release_rd_idx; 527 } 528 529 /* limiting the search till bat_release_rd_idx */ 530 zero_index = find_first_zero_bit(bat_req->bat_bitmap, bat_req->bat_release_rd_idx); 531 spin_unlock_irqrestore(&bat_req->mask_lock, flags); 532 return bat_req->bat_size_cnt - bat_req->bat_release_rd_idx + zero_index; 533} 534 535static int t7xx_dpmaif_release_bat_entry(const struct dpmaif_rx_queue *rxq, 536 const unsigned int rel_entry_num, 537 const enum bat_type buf_type) 538{ 539 struct dpmaif_hw_info *hw_info = &rxq->dpmaif_ctrl->hw_info; 540 unsigned int old_rel_idx, new_rel_idx, hw_rd_idx, i; 541 struct dpmaif_bat_request *bat; 542 unsigned long flags; 543 544 if (!rxq->que_started || !rel_entry_num) 545 return -EINVAL; 546 547 if (buf_type == BAT_TYPE_FRAG) { 548 bat = rxq->bat_frag; 549 hw_rd_idx = t7xx_dpmaif_dl_get_frg_rd_idx(hw_info, rxq->index); 550 } else { 551 bat = rxq->bat_req; 552 hw_rd_idx = t7xx_dpmaif_dl_get_bat_rd_idx(hw_info, rxq->index); 553 } 554 555 if (rel_entry_num >= bat->bat_size_cnt) 556 return -EINVAL; 557 558 old_rel_idx = bat->bat_release_rd_idx; 559 new_rel_idx = old_rel_idx + rel_entry_num; 560 561 /* Do not need to release if the queue is empty */ 562 if (bat->bat_wr_idx == old_rel_idx) 563 return 0; 564 565 if (hw_rd_idx >= old_rel_idx) { 566 if (new_rel_idx > hw_rd_idx) 567 return -EINVAL; 568 } 569 570 if (new_rel_idx >= bat->bat_size_cnt) { 571 new_rel_idx -= bat->bat_size_cnt; 572 if (new_rel_idx > hw_rd_idx) 573 return -EINVAL; 574 } 575 576 spin_lock_irqsave(&bat->mask_lock, flags); 577 for (i = 0; i < rel_entry_num; i++) { 578 unsigned int index = bat->bat_release_rd_idx + i; 579 580 if (index >= bat->bat_size_cnt) 581 index -= bat->bat_size_cnt; 582 583 clear_bit(index, bat->bat_bitmap); 584 } 585 spin_unlock_irqrestore(&bat->mask_lock, flags); 586 587 bat->bat_release_rd_idx = new_rel_idx; 588 return rel_entry_num; 589} 590 591static int t7xx_dpmaif_pit_release_and_add(struct dpmaif_rx_queue *rxq) 592{ 593 int ret; 594 595 if (rxq->pit_remain_release_cnt < DPMAIF_PIT_CNT_THRESHOLD) 596 return 0; 597 598 ret = t7xx_dpmaifq_release_pit_entry(rxq, rxq->pit_remain_release_cnt); 599 if (ret) 600 return ret; 601 602 rxq->pit_remain_release_cnt = 0; 603 return 0; 604} 605 606static int t7xx_dpmaif_bat_release_and_add(const struct dpmaif_rx_queue *rxq) 607{ 608 unsigned int bid_cnt; 609 int ret; 610 611 bid_cnt = t7xx_dpmaif_avail_pkt_bat_cnt(rxq->bat_req); 612 if (bid_cnt < DPMAIF_BAT_CNT_THRESHOLD) 613 return 0; 614 615 ret = t7xx_dpmaif_release_bat_entry(rxq, bid_cnt, BAT_TYPE_NORMAL); 616 if (ret <= 0) { 617 dev_err(rxq->dpmaif_ctrl->dev, "Release PKT BAT failed: %d\n", ret); 618 return ret; 619 } 620 621 ret = t7xx_dpmaif_rx_buf_alloc(rxq->dpmaif_ctrl, rxq->bat_req, rxq->index, bid_cnt, false); 622 if (ret < 0) 623 dev_err(rxq->dpmaif_ctrl->dev, "Allocate new RX buffer failed: %d\n", ret); 624 625 return ret; 626} 627 628static int t7xx_dpmaif_frag_bat_release_and_add(const struct dpmaif_rx_queue *rxq) 629{ 630 unsigned int bid_cnt; 631 int ret; 632 633 bid_cnt = t7xx_dpmaif_avail_pkt_bat_cnt(rxq->bat_frag); 634 if (bid_cnt < DPMAIF_BAT_CNT_THRESHOLD) 635 return 0; 636 637 ret = t7xx_dpmaif_release_bat_entry(rxq, bid_cnt, BAT_TYPE_FRAG); 638 if (ret <= 0) { 639 dev_err(rxq->dpmaif_ctrl->dev, "Release BAT entry failed: %d\n", ret); 640 return ret; 641 } 642 643 return t7xx_dpmaif_rx_frag_alloc(rxq->dpmaif_ctrl, rxq->bat_frag, bid_cnt, false); 644} 645 646static void t7xx_dpmaif_parse_msg_pit(const struct dpmaif_rx_queue *rxq, 647 const struct dpmaif_pit *msg_pit, 648 struct dpmaif_cur_rx_skb_info *skb_info) 649{ 650 int header = le32_to_cpu(msg_pit->header); 651 652 skb_info->cur_chn_idx = FIELD_GET(MSG_PIT_CHANNEL_ID, header); 653 skb_info->check_sum = FIELD_GET(MSG_PIT_CHECKSUM, header); 654 skb_info->pit_dp = FIELD_GET(MSG_PIT_DP, header); 655 skb_info->pkt_type = FIELD_GET(MSG_PIT_IP, le32_to_cpu(msg_pit->msg.params_3)); 656} 657 658static int t7xx_dpmaif_set_data_to_skb(const struct dpmaif_rx_queue *rxq, 659 const struct dpmaif_pit *pkt_info, 660 struct dpmaif_cur_rx_skb_info *skb_info) 661{ 662 unsigned long long data_bus_addr, data_base_addr; 663 struct device *dev = rxq->dpmaif_ctrl->dev; 664 struct dpmaif_bat_skb *bat_skb; 665 unsigned int data_len; 666 struct sk_buff *skb; 667 int data_offset; 668 669 bat_skb = rxq->bat_req->bat_skb; 670 bat_skb += t7xx_normal_pit_bid(pkt_info); 671 dma_unmap_single(dev, bat_skb->data_bus_addr, bat_skb->data_len, DMA_FROM_DEVICE); 672 673 data_bus_addr = le32_to_cpu(pkt_info->pd.data_addr_h); 674 data_bus_addr = (data_bus_addr << 32) + le32_to_cpu(pkt_info->pd.data_addr_l); 675 data_base_addr = bat_skb->data_bus_addr; 676 data_offset = data_bus_addr - data_base_addr; 677 data_len = FIELD_GET(PD_PIT_DATA_LEN, le32_to_cpu(pkt_info->header)); 678 skb = bat_skb->skb; 679 skb->len = 0; 680 skb_reset_tail_pointer(skb); 681 skb_reserve(skb, data_offset); 682 683 if (skb->tail + data_len > skb->end) { 684 dev_err(dev, "No buffer space available\n"); 685 return -ENOBUFS; 686 } 687 688 skb_put(skb, data_len); 689 skb_info->cur_skb = skb; 690 bat_skb->skb = NULL; 691 return 0; 692} 693 694static int t7xx_dpmaif_get_rx_pkt(struct dpmaif_rx_queue *rxq, 695 const struct dpmaif_pit *pkt_info, 696 struct dpmaif_cur_rx_skb_info *skb_info) 697{ 698 unsigned int cur_bid = t7xx_normal_pit_bid(pkt_info); 699 int ret; 700 701 ret = t7xx_bat_cur_bid_check(rxq, cur_bid); 702 if (ret < 0) 703 return ret; 704 705 ret = t7xx_dpmaif_set_data_to_skb(rxq, pkt_info, skb_info); 706 if (ret < 0) { 707 dev_err(rxq->dpmaif_ctrl->dev, "RX set data to skb failed: %d\n", ret); 708 return ret; 709 } 710 711 t7xx_dpmaif_set_bat_mask(rxq->bat_req, cur_bid); 712 return 0; 713} 714 715static int t7xx_dpmaifq_rx_notify_hw(struct dpmaif_rx_queue *rxq) 716{ 717 struct dpmaif_ctrl *dpmaif_ctrl = rxq->dpmaif_ctrl; 718 int ret; 719 720 queue_work(dpmaif_ctrl->bat_release_wq, &dpmaif_ctrl->bat_release_work); 721 722 ret = t7xx_dpmaif_pit_release_and_add(rxq); 723 if (ret < 0) 724 dev_err(dpmaif_ctrl->dev, "RXQ%u update PIT failed: %d\n", rxq->index, ret); 725 726 return ret; 727} 728 729static void t7xx_dpmaif_rx_skb_enqueue(struct dpmaif_rx_queue *rxq, struct sk_buff *skb) 730{ 731 unsigned long flags; 732 733 spin_lock_irqsave(&rxq->skb_list.lock, flags); 734 if (rxq->skb_list.qlen < rxq->skb_list_max_len) 735 __skb_queue_tail(&rxq->skb_list, skb); 736 else 737 dev_kfree_skb_any(skb); 738 spin_unlock_irqrestore(&rxq->skb_list.lock, flags); 739} 740 741static void t7xx_dpmaif_rx_skb(struct dpmaif_rx_queue *rxq, 742 struct dpmaif_cur_rx_skb_info *skb_info) 743{ 744 struct sk_buff *skb = skb_info->cur_skb; 745 struct t7xx_skb_cb *skb_cb; 746 u8 netif_id; 747 748 skb_info->cur_skb = NULL; 749 750 if (skb_info->pit_dp) { 751 dev_kfree_skb_any(skb); 752 return; 753 } 754 755 skb->ip_summed = skb_info->check_sum == DPMAIF_CS_RESULT_PASS ? CHECKSUM_UNNECESSARY : 756 CHECKSUM_NONE; 757 netif_id = FIELD_GET(NETIF_MASK, skb_info->cur_chn_idx); 758 skb_cb = T7XX_SKB_CB(skb); 759 skb_cb->netif_idx = netif_id; 760 skb_cb->rx_pkt_type = skb_info->pkt_type; 761 t7xx_dpmaif_rx_skb_enqueue(rxq, skb); 762} 763 764static int t7xx_dpmaif_rx_start(struct dpmaif_rx_queue *rxq, const unsigned int pit_cnt, 765 const unsigned long timeout) 766{ 767 unsigned int cur_pit, pit_len, rx_cnt, recv_skb_cnt = 0; 768 struct device *dev = rxq->dpmaif_ctrl->dev; 769 struct dpmaif_cur_rx_skb_info *skb_info; 770 int ret = 0; 771 772 pit_len = rxq->pit_size_cnt; 773 skb_info = &rxq->rx_data_info; 774 cur_pit = rxq->pit_rd_idx; 775 776 for (rx_cnt = 0; rx_cnt < pit_cnt; rx_cnt++) { 777 struct dpmaif_pit *pkt_info; 778 u32 val; 779 780 if (!skb_info->msg_pit_received && time_after_eq(jiffies, timeout)) 781 break; 782 783 pkt_info = (struct dpmaif_pit *)rxq->pit_base + cur_pit; 784 if (t7xx_dpmaif_check_pit_seq(rxq, pkt_info)) { 785 dev_err_ratelimited(dev, "RXQ%u checks PIT SEQ fail\n", rxq->index); 786 return -EAGAIN; 787 } 788 789 val = FIELD_GET(PD_PIT_PACKET_TYPE, le32_to_cpu(pkt_info->header)); 790 if (val == DES_PT_MSG) { 791 if (skb_info->msg_pit_received) 792 dev_err(dev, "RXQ%u received repeated PIT\n", rxq->index); 793 794 skb_info->msg_pit_received = true; 795 t7xx_dpmaif_parse_msg_pit(rxq, pkt_info, skb_info); 796 } else { /* DES_PT_PD */ 797 val = FIELD_GET(PD_PIT_BUFFER_TYPE, le32_to_cpu(pkt_info->header)); 798 if (val != PKT_BUF_FRAG) 799 ret = t7xx_dpmaif_get_rx_pkt(rxq, pkt_info, skb_info); 800 else if (!skb_info->cur_skb) 801 ret = -EINVAL; 802 else 803 ret = t7xx_dpmaif_get_frag(rxq, pkt_info, skb_info); 804 805 if (ret < 0) { 806 skb_info->err_payload = 1; 807 dev_err_ratelimited(dev, "RXQ%u error payload\n", rxq->index); 808 } 809 810 val = FIELD_GET(PD_PIT_CONT, le32_to_cpu(pkt_info->header)); 811 if (!val) { 812 if (!skb_info->err_payload) { 813 t7xx_dpmaif_rx_skb(rxq, skb_info); 814 } else if (skb_info->cur_skb) { 815 dev_kfree_skb_any(skb_info->cur_skb); 816 skb_info->cur_skb = NULL; 817 } 818 819 memset(skb_info, 0, sizeof(*skb_info)); 820 821 recv_skb_cnt++; 822 if (!(recv_skb_cnt & DPMAIF_RX_PUSH_THRESHOLD_MASK)) { 823 wake_up_all(&rxq->rx_wq); 824 recv_skb_cnt = 0; 825 } 826 } 827 } 828 829 cur_pit = t7xx_ring_buf_get_next_wr_idx(pit_len, cur_pit); 830 rxq->pit_rd_idx = cur_pit; 831 rxq->pit_remain_release_cnt++; 832 833 if (rx_cnt > 0 && !(rx_cnt % DPMAIF_NOTIFY_RELEASE_COUNT)) { 834 ret = t7xx_dpmaifq_rx_notify_hw(rxq); 835 if (ret < 0) 836 break; 837 } 838 } 839 840 if (recv_skb_cnt) 841 wake_up_all(&rxq->rx_wq); 842 843 if (!ret) 844 ret = t7xx_dpmaifq_rx_notify_hw(rxq); 845 846 if (ret) 847 return ret; 848 849 return rx_cnt; 850} 851 852static unsigned int t7xx_dpmaifq_poll_pit(struct dpmaif_rx_queue *rxq) 853{ 854 unsigned int hw_wr_idx, pit_cnt; 855 856 if (!rxq->que_started) 857 return 0; 858 859 hw_wr_idx = t7xx_dpmaif_dl_dlq_pit_get_wr_idx(&rxq->dpmaif_ctrl->hw_info, rxq->index); 860 pit_cnt = t7xx_ring_buf_rd_wr_count(rxq->pit_size_cnt, rxq->pit_rd_idx, hw_wr_idx, 861 DPMAIF_READ); 862 rxq->pit_wr_idx = hw_wr_idx; 863 return pit_cnt; 864} 865 866static int t7xx_dpmaif_rx_data_collect(struct dpmaif_ctrl *dpmaif_ctrl, 867 const unsigned int q_num, const unsigned int budget) 868{ 869 struct dpmaif_rx_queue *rxq = &dpmaif_ctrl->rxq[q_num]; 870 unsigned long time_limit; 871 unsigned int cnt; 872 873 time_limit = jiffies + msecs_to_jiffies(DPMAIF_WQ_TIME_LIMIT_MS); 874 875 while ((cnt = t7xx_dpmaifq_poll_pit(rxq))) { 876 unsigned int rd_cnt; 877 int real_cnt; 878 879 rd_cnt = min(cnt, budget); 880 881 real_cnt = t7xx_dpmaif_rx_start(rxq, rd_cnt, time_limit); 882 if (real_cnt < 0) 883 return real_cnt; 884 885 if (real_cnt < cnt) 886 return -EAGAIN; 887 } 888 889 return 0; 890} 891 892static void t7xx_dpmaif_do_rx(struct dpmaif_ctrl *dpmaif_ctrl, struct dpmaif_rx_queue *rxq) 893{ 894 struct dpmaif_hw_info *hw_info = &dpmaif_ctrl->hw_info; 895 int ret; 896 897 ret = t7xx_dpmaif_rx_data_collect(dpmaif_ctrl, rxq->index, rxq->budget); 898 if (ret < 0) { 899 /* Try one more time */ 900 queue_work(rxq->worker, &rxq->dpmaif_rxq_work); 901 t7xx_dpmaif_clr_ip_busy_sts(hw_info); 902 } else { 903 t7xx_dpmaif_clr_ip_busy_sts(hw_info); 904 t7xx_dpmaif_dlq_unmask_rx_done(hw_info, rxq->index); 905 } 906} 907 908static void t7xx_dpmaif_rxq_work(struct work_struct *work) 909{ 910 struct dpmaif_rx_queue *rxq = container_of(work, struct dpmaif_rx_queue, dpmaif_rxq_work); 911 struct dpmaif_ctrl *dpmaif_ctrl = rxq->dpmaif_ctrl; 912 int ret; 913 914 atomic_set(&rxq->rx_processing, 1); 915 /* Ensure rx_processing is changed to 1 before actually begin RX flow */ 916 smp_mb(); 917 918 if (!rxq->que_started) { 919 atomic_set(&rxq->rx_processing, 0); 920 dev_err(dpmaif_ctrl->dev, "Work RXQ: %d has not been started\n", rxq->index); 921 return; 922 } 923 924 ret = pm_runtime_resume_and_get(dpmaif_ctrl->dev); 925 if (ret < 0 && ret != -EACCES) 926 return; 927 928 t7xx_pci_disable_sleep(dpmaif_ctrl->t7xx_dev); 929 if (t7xx_pci_sleep_disable_complete(dpmaif_ctrl->t7xx_dev)) 930 t7xx_dpmaif_do_rx(dpmaif_ctrl, rxq); 931 932 t7xx_pci_enable_sleep(dpmaif_ctrl->t7xx_dev); 933 pm_runtime_mark_last_busy(dpmaif_ctrl->dev); 934 pm_runtime_put_autosuspend(dpmaif_ctrl->dev); 935 atomic_set(&rxq->rx_processing, 0); 936} 937 938void t7xx_dpmaif_irq_rx_done(struct dpmaif_ctrl *dpmaif_ctrl, const unsigned int que_mask) 939{ 940 struct dpmaif_rx_queue *rxq; 941 int qno; 942 943 qno = ffs(que_mask) - 1; 944 if (qno < 0 || qno > DPMAIF_RXQ_NUM - 1) { 945 dev_err(dpmaif_ctrl->dev, "Invalid RXQ number: %u\n", qno); 946 return; 947 } 948 949 rxq = &dpmaif_ctrl->rxq[qno]; 950 queue_work(rxq->worker, &rxq->dpmaif_rxq_work); 951} 952 953static void t7xx_dpmaif_base_free(const struct dpmaif_ctrl *dpmaif_ctrl, 954 const struct dpmaif_bat_request *bat_req) 955{ 956 if (bat_req->bat_base) 957 dma_free_coherent(dpmaif_ctrl->dev, 958 bat_req->bat_size_cnt * sizeof(struct dpmaif_bat), 959 bat_req->bat_base, bat_req->bat_bus_addr); 960} 961 962/** 963 * t7xx_dpmaif_bat_alloc() - Allocate the BAT ring buffer. 964 * @dpmaif_ctrl: Pointer to DPMAIF context structure. 965 * @bat_req: Pointer to BAT request structure. 966 * @buf_type: BAT ring type. 967 * 968 * This function allocates the BAT ring buffer shared with the HW device, also allocates 969 * a buffer used to store information about the BAT skbs for further release. 970 * 971 * Return: 972 * * 0 - Success. 973 * * -ERROR - Error code. 974 */ 975int t7xx_dpmaif_bat_alloc(const struct dpmaif_ctrl *dpmaif_ctrl, struct dpmaif_bat_request *bat_req, 976 const enum bat_type buf_type) 977{ 978 int sw_buf_size; 979 980 if (buf_type == BAT_TYPE_FRAG) { 981 sw_buf_size = sizeof(struct dpmaif_bat_page); 982 bat_req->bat_size_cnt = DPMAIF_FRG_COUNT; 983 bat_req->pkt_buf_sz = DPMAIF_HW_FRG_PKTBUF; 984 } else { 985 sw_buf_size = sizeof(struct dpmaif_bat_skb); 986 bat_req->bat_size_cnt = DPMAIF_BAT_COUNT; 987 bat_req->pkt_buf_sz = DPMAIF_HW_BAT_PKTBUF; 988 } 989 990 bat_req->type = buf_type; 991 bat_req->bat_wr_idx = 0; 992 bat_req->bat_release_rd_idx = 0; 993 994 bat_req->bat_base = dma_alloc_coherent(dpmaif_ctrl->dev, 995 bat_req->bat_size_cnt * sizeof(struct dpmaif_bat), 996 &bat_req->bat_bus_addr, GFP_KERNEL | __GFP_ZERO); 997 if (!bat_req->bat_base) 998 return -ENOMEM; 999 1000 /* For AP SW to record skb information */ 1001 bat_req->bat_skb = devm_kzalloc(dpmaif_ctrl->dev, bat_req->bat_size_cnt * sw_buf_size, 1002 GFP_KERNEL); 1003 if (!bat_req->bat_skb) 1004 goto err_free_dma_mem; 1005 1006 bat_req->bat_bitmap = bitmap_zalloc(bat_req->bat_size_cnt, GFP_KERNEL); 1007 if (!bat_req->bat_bitmap) 1008 goto err_free_dma_mem; 1009 1010 spin_lock_init(&bat_req->mask_lock); 1011 atomic_set(&bat_req->refcnt, 0); 1012 return 0; 1013 1014err_free_dma_mem: 1015 t7xx_dpmaif_base_free(dpmaif_ctrl, bat_req); 1016 1017 return -ENOMEM; 1018} 1019 1020void t7xx_dpmaif_bat_free(const struct dpmaif_ctrl *dpmaif_ctrl, struct dpmaif_bat_request *bat_req) 1021{ 1022 if (!bat_req || !atomic_dec_and_test(&bat_req->refcnt)) 1023 return; 1024 1025 bitmap_free(bat_req->bat_bitmap); 1026 bat_req->bat_bitmap = NULL; 1027 1028 if (bat_req->bat_skb) { 1029 unsigned int i; 1030 1031 for (i = 0; i < bat_req->bat_size_cnt; i++) { 1032 if (bat_req->type == BAT_TYPE_FRAG) 1033 t7xx_unmap_bat_page(dpmaif_ctrl->dev, bat_req->bat_skb, i); 1034 else 1035 t7xx_unmap_bat_skb(dpmaif_ctrl->dev, bat_req->bat_skb, i); 1036 } 1037 } 1038 1039 t7xx_dpmaif_base_free(dpmaif_ctrl, bat_req); 1040} 1041 1042static int t7xx_dpmaif_rx_alloc(struct dpmaif_rx_queue *rxq) 1043{ 1044 rxq->pit_size_cnt = DPMAIF_PIT_COUNT; 1045 rxq->pit_rd_idx = 0; 1046 rxq->pit_wr_idx = 0; 1047 rxq->pit_release_rd_idx = 0; 1048 rxq->expect_pit_seq = 0; 1049 rxq->pit_remain_release_cnt = 0; 1050 memset(&rxq->rx_data_info, 0, sizeof(rxq->rx_data_info)); 1051 1052 rxq->pit_base = dma_alloc_coherent(rxq->dpmaif_ctrl->dev, 1053 rxq->pit_size_cnt * sizeof(struct dpmaif_pit), 1054 &rxq->pit_bus_addr, GFP_KERNEL | __GFP_ZERO); 1055 if (!rxq->pit_base) 1056 return -ENOMEM; 1057 1058 rxq->bat_req = &rxq->dpmaif_ctrl->bat_req; 1059 atomic_inc(&rxq->bat_req->refcnt); 1060 1061 rxq->bat_frag = &rxq->dpmaif_ctrl->bat_frag; 1062 atomic_inc(&rxq->bat_frag->refcnt); 1063 return 0; 1064} 1065 1066static void t7xx_dpmaif_rx_buf_free(const struct dpmaif_rx_queue *rxq) 1067{ 1068 if (!rxq->dpmaif_ctrl) 1069 return; 1070 1071 t7xx_dpmaif_bat_free(rxq->dpmaif_ctrl, rxq->bat_req); 1072 t7xx_dpmaif_bat_free(rxq->dpmaif_ctrl, rxq->bat_frag); 1073 1074 if (rxq->pit_base) 1075 dma_free_coherent(rxq->dpmaif_ctrl->dev, 1076 rxq->pit_size_cnt * sizeof(struct dpmaif_pit), 1077 rxq->pit_base, rxq->pit_bus_addr); 1078} 1079 1080int t7xx_dpmaif_rxq_init(struct dpmaif_rx_queue *queue) 1081{ 1082 int ret; 1083 1084 ret = t7xx_dpmaif_rx_alloc(queue); 1085 if (ret < 0) { 1086 dev_err(queue->dpmaif_ctrl->dev, "Failed to allocate RX buffers: %d\n", ret); 1087 return ret; 1088 } 1089 1090 INIT_WORK(&queue->dpmaif_rxq_work, t7xx_dpmaif_rxq_work); 1091 1092 queue->worker = alloc_workqueue("dpmaif_rx%d_worker", 1093 WQ_UNBOUND | WQ_MEM_RECLAIM | WQ_HIGHPRI, 1, queue->index); 1094 if (!queue->worker) { 1095 ret = -ENOMEM; 1096 goto err_free_rx_buffer; 1097 } 1098 1099 init_waitqueue_head(&queue->rx_wq); 1100 skb_queue_head_init(&queue->skb_list); 1101 queue->skb_list_max_len = queue->bat_req->pkt_buf_sz; 1102 queue->rx_thread = kthread_run(t7xx_dpmaif_net_rx_push_thread, 1103 queue, "dpmaif_rx%d_push", queue->index); 1104 1105 ret = PTR_ERR_OR_ZERO(queue->rx_thread); 1106 if (ret) 1107 goto err_free_workqueue; 1108 1109 return 0; 1110 1111err_free_workqueue: 1112 destroy_workqueue(queue->worker); 1113 1114err_free_rx_buffer: 1115 t7xx_dpmaif_rx_buf_free(queue); 1116 1117 return ret; 1118} 1119 1120void t7xx_dpmaif_rxq_free(struct dpmaif_rx_queue *queue) 1121{ 1122 if (queue->worker) 1123 destroy_workqueue(queue->worker); 1124 1125 if (queue->rx_thread) 1126 kthread_stop(queue->rx_thread); 1127 1128 skb_queue_purge(&queue->skb_list); 1129 t7xx_dpmaif_rx_buf_free(queue); 1130} 1131 1132static void t7xx_dpmaif_bat_release_work(struct work_struct *work) 1133{ 1134 struct dpmaif_ctrl *dpmaif_ctrl = container_of(work, struct dpmaif_ctrl, bat_release_work); 1135 struct dpmaif_rx_queue *rxq; 1136 int ret; 1137 1138 ret = pm_runtime_resume_and_get(dpmaif_ctrl->dev); 1139 if (ret < 0 && ret != -EACCES) 1140 return; 1141 1142 t7xx_pci_disable_sleep(dpmaif_ctrl->t7xx_dev); 1143 1144 /* ALL RXQ use one BAT table, so choose DPF_RX_QNO_DFT */ 1145 rxq = &dpmaif_ctrl->rxq[DPF_RX_QNO_DFT]; 1146 if (t7xx_pci_sleep_disable_complete(dpmaif_ctrl->t7xx_dev)) { 1147 t7xx_dpmaif_bat_release_and_add(rxq); 1148 t7xx_dpmaif_frag_bat_release_and_add(rxq); 1149 } 1150 1151 t7xx_pci_enable_sleep(dpmaif_ctrl->t7xx_dev); 1152 pm_runtime_mark_last_busy(dpmaif_ctrl->dev); 1153 pm_runtime_put_autosuspend(dpmaif_ctrl->dev); 1154} 1155 1156int t7xx_dpmaif_bat_rel_wq_alloc(struct dpmaif_ctrl *dpmaif_ctrl) 1157{ 1158 dpmaif_ctrl->bat_release_wq = alloc_workqueue("dpmaif_bat_release_work_queue", 1159 WQ_MEM_RECLAIM, 1); 1160 if (!dpmaif_ctrl->bat_release_wq) 1161 return -ENOMEM; 1162 1163 INIT_WORK(&dpmaif_ctrl->bat_release_work, t7xx_dpmaif_bat_release_work); 1164 return 0; 1165} 1166 1167void t7xx_dpmaif_bat_wq_rel(struct dpmaif_ctrl *dpmaif_ctrl) 1168{ 1169 flush_work(&dpmaif_ctrl->bat_release_work); 1170 1171 if (dpmaif_ctrl->bat_release_wq) { 1172 destroy_workqueue(dpmaif_ctrl->bat_release_wq); 1173 dpmaif_ctrl->bat_release_wq = NULL; 1174 } 1175} 1176 1177/** 1178 * t7xx_dpmaif_rx_stop() - Suspend RX flow. 1179 * @dpmaif_ctrl: Pointer to data path control struct dpmaif_ctrl. 1180 * 1181 * Wait for all the RX work to finish executing and mark the RX queue as paused. 1182 */ 1183void t7xx_dpmaif_rx_stop(struct dpmaif_ctrl *dpmaif_ctrl) 1184{ 1185 unsigned int i; 1186 1187 for (i = 0; i < DPMAIF_RXQ_NUM; i++) { 1188 struct dpmaif_rx_queue *rxq = &dpmaif_ctrl->rxq[i]; 1189 int timeout, value; 1190 1191 flush_work(&rxq->dpmaif_rxq_work); 1192 1193 timeout = readx_poll_timeout_atomic(atomic_read, &rxq->rx_processing, value, 1194 !value, 0, DPMAIF_CHECK_INIT_TIMEOUT_US); 1195 if (timeout) 1196 dev_err(dpmaif_ctrl->dev, "Stop RX SW failed\n"); 1197 1198 /* Ensure RX processing has stopped before we set rxq->que_started to false */ 1199 smp_mb(); 1200 rxq->que_started = false; 1201 } 1202} 1203 1204static void t7xx_dpmaif_stop_rxq(struct dpmaif_rx_queue *rxq) 1205{ 1206 int cnt, j = 0; 1207 1208 flush_work(&rxq->dpmaif_rxq_work); 1209 rxq->que_started = false; 1210 1211 do { 1212 cnt = t7xx_ring_buf_rd_wr_count(rxq->pit_size_cnt, rxq->pit_rd_idx, 1213 rxq->pit_wr_idx, DPMAIF_READ); 1214 1215 if (++j >= DPMAIF_MAX_CHECK_COUNT) { 1216 dev_err(rxq->dpmaif_ctrl->dev, "Stop RX SW failed, %d\n", cnt); 1217 break; 1218 } 1219 } while (cnt); 1220 1221 memset(rxq->pit_base, 0, rxq->pit_size_cnt * sizeof(struct dpmaif_pit)); 1222 memset(rxq->bat_req->bat_base, 0, rxq->bat_req->bat_size_cnt * sizeof(struct dpmaif_bat)); 1223 bitmap_zero(rxq->bat_req->bat_bitmap, rxq->bat_req->bat_size_cnt); 1224 memset(&rxq->rx_data_info, 0, sizeof(rxq->rx_data_info)); 1225 1226 rxq->pit_rd_idx = 0; 1227 rxq->pit_wr_idx = 0; 1228 rxq->pit_release_rd_idx = 0; 1229 rxq->expect_pit_seq = 0; 1230 rxq->pit_remain_release_cnt = 0; 1231 rxq->bat_req->bat_release_rd_idx = 0; 1232 rxq->bat_req->bat_wr_idx = 0; 1233 rxq->bat_frag->bat_release_rd_idx = 0; 1234 rxq->bat_frag->bat_wr_idx = 0; 1235} 1236 1237void t7xx_dpmaif_rx_clear(struct dpmaif_ctrl *dpmaif_ctrl) 1238{ 1239 int i; 1240 1241 for (i = 0; i < DPMAIF_RXQ_NUM; i++) 1242 t7xx_dpmaif_stop_rxq(&dpmaif_ctrl->rxq[i]); 1243}