| .. | .. |
|---|
| 1 | | -/* SPDX-License-Identifier: GPL-2.0 */ |
|---|
| 2 | | -#ifndef __bcm_ring_included__ |
|---|
| 3 | | -#define __bcm_ring_included__ |
|---|
| 4 | | - |
|---|
| 5 | 1 | /* |
|---|
| 6 | | - * +---------------------------------------------------------------------------- |
|---|
| 7 | | - * |
|---|
| 8 | 2 | * bcm_ring.h : Ring context abstraction |
|---|
| 9 | | - * |
|---|
| 10 | 3 | * The ring context tracks the WRITE and READ indices where elements may be |
|---|
| 11 | 4 | * produced and consumed respectively. All elements in the ring need to be |
|---|
| 12 | 5 | * fixed size. |
|---|
| 13 | 6 | * |
|---|
| 14 | 7 | * NOTE: A ring of size N, may only hold N-1 elements. |
|---|
| 15 | 8 | * |
|---|
| 16 | | - * +---------------------------------------------------------------------------- |
|---|
| 9 | + * Portions of this code are copyright (c) 2022 Cypress Semiconductor Corporation |
|---|
| 17 | 10 | * |
|---|
| 11 | + * Copyright (C) 1999-2017, Broadcom Corporation |
|---|
| 12 | + * |
|---|
| 13 | + * Unless you and Broadcom execute a separate written software license |
|---|
| 14 | + * agreement governing use of this software, this software is licensed to you |
|---|
| 15 | + * under the terms of the GNU General Public License version 2 (the "GPL"), |
|---|
| 16 | + * available at http://www.broadcom.com/licenses/GPLv2.php, with the |
|---|
| 17 | + * following added to such license: |
|---|
| 18 | + * |
|---|
| 19 | + * As a special exception, the copyright holders of this software give you |
|---|
| 20 | + * permission to link this software with independent modules, and to copy and |
|---|
| 21 | + * distribute the resulting executable under terms of your choice, provided that |
|---|
| 22 | + * you also meet, for each linked independent module, the terms and conditions of |
|---|
| 23 | + * the license of that module. An independent module is a module which is not |
|---|
| 24 | + * derived from this software. The special exception does not apply to any |
|---|
| 25 | + * modifications of the software. |
|---|
| 26 | + * |
|---|
| 27 | + * Notwithstanding the above, under no circumstances may you combine this |
|---|
| 28 | + * software in any way with any other Broadcom software provided under a license |
|---|
| 29 | + * other than the GPL, without Broadcom's express prior written consent. |
|---|
| 30 | + * |
|---|
| 31 | + * |
|---|
| 32 | + * <<Broadcom-WL-IPTag/Open:>> |
|---|
| 33 | + * |
|---|
| 34 | + * $Id: bcm_ring.h 700321 2017-05-18 16:09:07Z $ |
|---|
| 35 | + */ |
|---|
| 36 | +#ifndef __bcm_ring_included__ |
|---|
| 37 | +#define __bcm_ring_included__ |
|---|
| 38 | +/* |
|---|
| 18 | 39 | * API Notes: |
|---|
| 19 | 40 | * |
|---|
| 20 | 41 | * Ring manipulation API allows for: |
|---|
| .. | .. |
|---|
| 82 | 103 | * private L1 data cache. |
|---|
| 83 | 104 | * +---------------------------------------------------------------------------- |
|---|
| 84 | 105 | * |
|---|
| 85 | | - * Copyright (C) 1999-2019, Broadcom Corporation |
|---|
| 86 | | - * |
|---|
| 106 | + * Portions of this code are copyright (c) 2022 Cypress Semiconductor Corporation |
|---|
| 107 | + * |
|---|
| 108 | + * Copyright (C) 1999-2017, Broadcom Corporation |
|---|
| 109 | + * |
|---|
| 87 | 110 | * Unless you and Broadcom execute a separate written software license |
|---|
| 88 | 111 | * agreement governing use of this software, this software is licensed to you |
|---|
| 89 | 112 | * under the terms of the GNU General Public License version 2 (the "GPL"), |
|---|
| 90 | 113 | * available at http://www.broadcom.com/licenses/GPLv2.php, with the |
|---|
| 91 | 114 | * following added to such license: |
|---|
| 92 | | - * |
|---|
| 115 | + * |
|---|
| 93 | 116 | * As a special exception, the copyright holders of this software give you |
|---|
| 94 | 117 | * permission to link this software with independent modules, and to copy and |
|---|
| 95 | 118 | * distribute the resulting executable under terms of your choice, provided that |
|---|
| .. | .. |
|---|
| 97 | 120 | * the license of that module. An independent module is a module which is not |
|---|
| 98 | 121 | * derived from this software. The special exception does not apply to any |
|---|
| 99 | 122 | * modifications of the software. |
|---|
| 100 | | - * |
|---|
| 123 | + * |
|---|
| 101 | 124 | * Notwithstanding the above, under no circumstances may you combine this |
|---|
| 102 | 125 | * software in any way with any other Broadcom software provided under a license |
|---|
| 103 | 126 | * other than the GPL, without Broadcom's express prior written consent. |
|---|
| 104 | 127 | * |
|---|
| 105 | | - * $Id$ |
|---|
| 128 | + * $Id: bcm_ring.h 700321 2017-05-18 16:09:07Z $ |
|---|
| 106 | 129 | * |
|---|
| 107 | 130 | * -*- Mode: C; tab-width: 4; indent-tabs-mode: t; c-basic-offset: 4 -*- |
|---|
| 108 | 131 | * vim: set ts=4 noet sw=4 tw=80: |
|---|
| .. | .. |
|---|
| 114 | 137 | #define __ring_aligned ____cacheline_aligned |
|---|
| 115 | 138 | #else |
|---|
| 116 | 139 | #define __ring_aligned |
|---|
| 117 | | -#endif |
|---|
| 140 | +#endif // endif |
|---|
| 118 | 141 | |
|---|
| 119 | 142 | /* Conditional compile for debug */ |
|---|
| 120 | 143 | /* #define BCM_RING_DEBUG */ |
|---|
| .. | .. |
|---|
| 147 | 170 | int read __ring_aligned; /* READ index in a circular ring */ |
|---|
| 148 | 171 | } bcm_ring_t; |
|---|
| 149 | 172 | |
|---|
| 150 | | - |
|---|
| 151 | 173 | static INLINE void bcm_ring_init(bcm_ring_t *ring); |
|---|
| 152 | 174 | static INLINE void bcm_ring_copy(bcm_ring_t *to, bcm_ring_t *from); |
|---|
| 153 | 175 | static INLINE bool bcm_ring_is_empty(bcm_ring_t *ring); |
|---|
| .. | .. |
|---|
| 175 | 197 | static INLINE int bcm_ring_cons_avail(const bcm_ring_t *ring, |
|---|
| 176 | 198 | const int ring_size); |
|---|
| 177 | 199 | static INLINE void bcm_ring_cons_all(bcm_ring_t *ring); |
|---|
| 178 | | - |
|---|
| 179 | 200 | |
|---|
| 180 | 201 | /** |
|---|
| 181 | 202 | * bcm_ring_init - initialize a ring context. |
|---|
| .. | .. |
|---|
| 219 | 240 | return (ring->read == ring->write); |
|---|
| 220 | 241 | } |
|---|
| 221 | 242 | |
|---|
| 222 | | - |
|---|
| 223 | 243 | /** |
|---|
| 224 | 244 | * __bcm_ring_next_write - determine the index where the next write may occur |
|---|
| 225 | 245 | * (with wrap-around). |
|---|
| .. | .. |
|---|
| 235 | 255 | return ((ring->write + 1) % ring_size); |
|---|
| 236 | 256 | } |
|---|
| 237 | 257 | |
|---|
| 238 | | - |
|---|
| 239 | 258 | /** |
|---|
| 240 | 259 | * __bcm_ring_full - support function for ring full test. |
|---|
| 241 | 260 | * @ring: pointer to a ring context |
|---|
| .. | .. |
|---|
| 248 | 267 | { |
|---|
| 249 | 268 | return (next_write == ring->read); |
|---|
| 250 | 269 | } |
|---|
| 251 | | - |
|---|
| 252 | 270 | |
|---|
| 253 | 271 | /** |
|---|
| 254 | 272 | * bcm_ring_is_full - "Boolean" test whether a ring is full. |
|---|
| .. | .. |
|---|
| 266 | 284 | return __bcm_ring_full(ring, next_write); |
|---|
| 267 | 285 | } |
|---|
| 268 | 286 | |
|---|
| 269 | | - |
|---|
| 270 | 287 | /** |
|---|
| 271 | 288 | * bcm_ring_prod_done - commit a previously pending index where production |
|---|
| 272 | 289 | * was requested. |
|---|
| .. | .. |
|---|
| 280 | 297 | RING_ASSERT(BCM_RING_IS_VALID(ring)); |
|---|
| 281 | 298 | ring->write = write; |
|---|
| 282 | 299 | } |
|---|
| 283 | | - |
|---|
| 284 | 300 | |
|---|
| 285 | 301 | /** |
|---|
| 286 | 302 | * bcm_ring_prod_pend - Fetch in "pend" mode, the index where an element may be |
|---|
| .. | .. |
|---|
| 305 | 321 | return rtn; |
|---|
| 306 | 322 | } |
|---|
| 307 | 323 | |
|---|
| 308 | | - |
|---|
| 309 | 324 | /** |
|---|
| 310 | 325 | * bcm_ring_prod - Fetch and "commit" the next index where a ring element may |
|---|
| 311 | 326 | * be produced. |
|---|
| .. | .. |
|---|
| 328 | 343 | return prod_write; |
|---|
| 329 | 344 | } |
|---|
| 330 | 345 | |
|---|
| 331 | | - |
|---|
| 332 | 346 | /** |
|---|
| 333 | 347 | * bcm_ring_cons_done - commit a previously pending read |
|---|
| 334 | 348 | * @ring: pointer to a ring context |
|---|
| .. | .. |
|---|
| 340 | 354 | RING_ASSERT(BCM_RING_IS_VALID(ring)); |
|---|
| 341 | 355 | ring->read = read; |
|---|
| 342 | 356 | } |
|---|
| 343 | | - |
|---|
| 344 | 357 | |
|---|
| 345 | 358 | /** |
|---|
| 346 | 359 | * bcm_ring_cons_pend - fetch in "pend" mode, the next index where a ring |
|---|
| .. | .. |
|---|
| 365 | 378 | return rtn; |
|---|
| 366 | 379 | } |
|---|
| 367 | 380 | |
|---|
| 368 | | - |
|---|
| 369 | 381 | /** |
|---|
| 370 | 382 | * bcm_ring_cons - fetch and "commit" the next index where a ring element may |
|---|
| 371 | 383 | * be consumed. |
|---|
| .. | .. |
|---|
| 386 | 398 | return cons_read; |
|---|
| 387 | 399 | } |
|---|
| 388 | 400 | |
|---|
| 389 | | - |
|---|
| 390 | 401 | /** |
|---|
| 391 | 402 | * bcm_ring_sync_read - on consumption, update peer's read index. |
|---|
| 392 | 403 | * @peer: pointer to peer's producer ring context |
|---|
| .. | .. |
|---|
| 400 | 411 | peer->read = self->read; /* flush read update to peer producer */ |
|---|
| 401 | 412 | } |
|---|
| 402 | 413 | |
|---|
| 403 | | - |
|---|
| 404 | 414 | /** |
|---|
| 405 | 415 | * bcm_ring_sync_write - on consumption, update peer's write index. |
|---|
| 406 | 416 | * @peer: pointer to peer's consumer ring context |
|---|
| .. | .. |
|---|
| 413 | 423 | RING_ASSERT(BCM_RING_IS_VALID(self)); |
|---|
| 414 | 424 | peer->write = self->write; /* flush write update to peer consumer */ |
|---|
| 415 | 425 | } |
|---|
| 416 | | - |
|---|
| 417 | 426 | |
|---|
| 418 | 427 | /** |
|---|
| 419 | 428 | * bcm_ring_prod_avail - fetch total number of available empty slots in the |
|---|
| .. | .. |
|---|
| 434 | 443 | ASSERT(prod_avail < ring_size); |
|---|
| 435 | 444 | return prod_avail; |
|---|
| 436 | 445 | } |
|---|
| 437 | | - |
|---|
| 438 | 446 | |
|---|
| 439 | 447 | /** |
|---|
| 440 | 448 | * bcm_ring_cons_avail - fetch total number of available elements for consumption. |
|---|
| .. | .. |
|---|
| 457 | 465 | return cons_avail; |
|---|
| 458 | 466 | } |
|---|
| 459 | 467 | |
|---|
| 460 | | - |
|---|
| 461 | 468 | /** |
|---|
| 462 | 469 | * bcm_ring_cons_all - set ring in state where all elements are consumed. |
|---|
| 463 | 470 | * @ring: pointer to a ring context |
|---|
| .. | .. |
|---|
| 467 | 474 | { |
|---|
| 468 | 475 | ring->read = ring->write; |
|---|
| 469 | 476 | } |
|---|
| 470 | | - |
|---|
| 471 | 477 | |
|---|
| 472 | 478 | /** |
|---|
| 473 | 479 | * Work Queue |
|---|
| .. | .. |
|---|
| 484 | 490 | } __ring_aligned; |
|---|
| 485 | 491 | |
|---|
| 486 | 492 | typedef struct bcm_workq bcm_workq_t; |
|---|
| 487 | | - |
|---|
| 488 | 493 | |
|---|
| 489 | 494 | /* #define BCM_WORKQ_DEBUG */ |
|---|
| 490 | 495 | #if defined(BCM_WORKQ_DEBUG) |
|---|
| .. | .. |
|---|
| 510 | 515 | WORKQ_ASSERT((__index) < ((__workq)->ring_size)); \ |
|---|
| 511 | 516 | ((__elem_type *)((__workq)->buffer)) + (__index); \ |
|---|
| 512 | 517 | }) |
|---|
| 513 | | - |
|---|
| 514 | 518 | |
|---|
| 515 | 519 | static INLINE void bcm_workq_init(bcm_workq_t *workq, bcm_workq_t *workq_peer, |
|---|
| 516 | 520 | void *buffer, int ring_size); |
|---|
| .. | .. |
|---|
| 584 | 588 | bcm_ring_sync_read(WORKQ_PEER_RING(workq_cons), WORKQ_RING(workq_cons)); |
|---|
| 585 | 589 | } |
|---|
| 586 | 590 | |
|---|
| 587 | | - |
|---|
| 588 | 591 | /** |
|---|
| 589 | 592 | * bcm_workq_prod_refresh - Fetch the updated consumer's read index |
|---|
| 590 | 593 | * @workq_prod: producer's workq whose read index must be refreshed from peer |
|---|
| .. | .. |
|---|
| 610 | 613 | /* cons::write <--- prod::write */ |
|---|
| 611 | 614 | bcm_ring_sync_write(WORKQ_RING(workq_cons), WORKQ_PEER_RING(workq_cons)); |
|---|
| 612 | 615 | } |
|---|
| 613 | | - |
|---|
| 614 | 616 | |
|---|
| 615 | 617 | #endif /* ! __bcm_ring_h_included__ */ |
|---|