drivers/net/can/spi/mcp251xfd/mcp251xfd-tef.c
Source file repositories/reference/linux-study-clean/drivers/net/can/spi/mcp251xfd/mcp251xfd-tef.c
File Facts
- System
- Linux kernel
- Corpus path
drivers/net/can/spi/mcp251xfd/mcp251xfd-tef.c- Extension
.c- Size
- 8105 bytes
- Lines
- 303
- Domain
- Driver Families
- Bucket
- drivers/net
- Inferred role
- Driver Families: implementation source
- Status
- source implementation candidate
Why This File Exists
Repeatable hardware-adapter layer. Deep compatibility for every driver is out of scope; this atlas records patterns, probe lifecycles, bus glue, IRQ/DMA usage, and links back to core abstractions.
- Repeatable hardware-adapter layer. Deep compatibility for every driver is out of scope; this atlas records patterns, probe lifecycles, bus glue, IRQ/DMA usage, and links back to core abstractions.
- Defines or uses C structs; map object ownership, embedded links, reference counts, and lock ownership.
Dependency Surface
linux/bitfield.hmcp251xfd.h
Detected Declarations
function mcp251xfd_tx_fifo_sta_emptyfunction mcp251xfd_tx_fifo_sta_less_than_half_fullfunction mcp251xfd_tef_tail_get_from_chipfunction mcp251xfd_check_tef_tailfunction mcp251xfd_handle_tefif_onefunction mcp251xfd_get_tef_lenfunction mcp251xfd_get_tx_freefunction mcp251xfd_tef_obj_readfunction mcp251xfd_ecc_tefif_successfulfunction mcp251xfd_handle_tefif
Annotated Snippet
mcp251xfd_get_tx_free(tx_ring) == 0) {
*len_p = tx_ring->obj_num;
return 0;
}
chip_tx_tail = FIELD_GET(MCP251XFD_REG_FIFOSTA_FIFOCI_MASK, fifo_sta);
err = mcp251xfd_check_tef_tail(priv);
if (err)
return err;
tail = mcp251xfd_get_tef_tail(priv);
/* First shift to full u8. The subtraction works on signed
* values, that keeps the difference steady around the u8
* overflow. The right shift acts on len, which is an u8.
*/
BUILD_BUG_ON(sizeof(tx_ring->obj_num) != sizeof(chip_tx_tail));
BUILD_BUG_ON(sizeof(tx_ring->obj_num) != sizeof(tail));
BUILD_BUG_ON(sizeof(tx_ring->obj_num) != sizeof(len));
len = (chip_tx_tail << shift) - (tail << shift);
len >>= shift;
/* According to mcp2518fd erratum DS80000789E 6. the FIFOCI
* bits of a FIFOSTA register, here the TX-FIFO tail index
* might be corrupted.
*
* However here it seems the bit indicating that the TX-FIFO
* is empty (MCP251XFD_REG_FIFOSTA_TFERFFIF) is not correct
* while the TX-FIFO tail index is.
*
* We assume the TX-FIFO is empty, i.e. all pending CAN frames
* haven been send, if:
* - Chip's head and tail index are equal (len == 0).
* - The TX-FIFO is less than half full.
* (The TX-FIFO empty case has already been checked at the
* beginning of this function.)
* - No free buffers in the TX ring.
*/
if (len == 0 && mcp251xfd_tx_fifo_sta_less_than_half_full(fifo_sta) &&
mcp251xfd_get_tx_free(tx_ring) == 0)
len = tx_ring->obj_num;
*len_p = len;
return 0;
}
static inline int
mcp251xfd_tef_obj_read(const struct mcp251xfd_priv *priv,
struct mcp251xfd_hw_tef_obj *hw_tef_obj,
const u8 offset, const u8 len)
{
const struct mcp251xfd_tx_ring *tx_ring = priv->tx;
const int val_bytes = regmap_get_val_bytes(priv->map_rx);
if (IS_ENABLED(CONFIG_CAN_MCP251XFD_SANITY) &&
(offset > tx_ring->obj_num ||
len > tx_ring->obj_num ||
offset + len > tx_ring->obj_num)) {
netdev_err(priv->ndev,
"Trying to read too many TEF objects (max=%d, offset=%d, len=%d).\n",
tx_ring->obj_num, offset, len);
return -ERANGE;
}
return regmap_bulk_read(priv->map_rx,
mcp251xfd_get_tef_obj_addr(offset),
hw_tef_obj,
sizeof(*hw_tef_obj) / val_bytes * len);
}
static inline void mcp251xfd_ecc_tefif_successful(struct mcp251xfd_priv *priv)
{
struct mcp251xfd_ecc *ecc = &priv->ecc;
ecc->ecc_stat = 0;
}
int mcp251xfd_handle_tefif(struct mcp251xfd_priv *priv)
{
struct mcp251xfd_hw_tef_obj hw_tef_obj[MCP251XFD_TX_OBJ_NUM_MAX];
unsigned int total_frame_len = 0;
u8 tef_tail, len, l;
int err, i;
err = mcp251xfd_get_tef_len(priv, &len);
if (err)
return err;
Annotation
- Immediate include surface: `linux/bitfield.h`, `mcp251xfd.h`.
- Detected declarations: `function mcp251xfd_tx_fifo_sta_empty`, `function mcp251xfd_tx_fifo_sta_less_than_half_full`, `function mcp251xfd_tef_tail_get_from_chip`, `function mcp251xfd_check_tef_tail`, `function mcp251xfd_handle_tefif_one`, `function mcp251xfd_get_tef_len`, `function mcp251xfd_get_tx_free`, `function mcp251xfd_tef_obj_read`, `function mcp251xfd_ecc_tefif_successful`, `function mcp251xfd_handle_tefif`.
- Atlas domain: Driver Families / drivers/net.
- Implementation status: source implementation candidate.
Implementation Notes
- This generated page is the file-by-file coverage layer; curated subsystem chapters should link here when they synthesize a multi-file control flow.
- Core OS pages should be promoted from atlas-only to deep-reviewed when they explain data structures, invariants, locking, lifecycle, and C implementation snippets.
- Driver-family pages are intentionally pattern-oriented unless they are part of the selected PCIe/NVMe representative device path.