Lines Matching +full:tx +full:- +full:ts +full:- +full:mask
1 // SPDX-License-Identifier: GPL-2.0
4 // Marc Kleine-Budde <kernel@pengutronix.de>
16 canid_t mask = CAN_EFF_FLAG; in rkcanfd_can_frame_header_equal() local
18 if (canfd_sanitize_len(cfd1->len) != canfd_sanitize_len(cfd2->len)) in rkcanfd_can_frame_header_equal()
22 mask |= CAN_RTR_FLAG; in rkcanfd_can_frame_header_equal()
24 if (cfd1->can_id & CAN_EFF_FLAG) in rkcanfd_can_frame_header_equal()
25 mask |= CAN_EFF_MASK; in rkcanfd_can_frame_header_equal()
27 mask |= CAN_SFF_MASK; in rkcanfd_can_frame_header_equal()
29 if ((cfd1->can_id & mask) != (cfd2->can_id & mask)) in rkcanfd_can_frame_header_equal()
33 (cfd1->flags & mask_flags) != (cfd2->flags & mask_flags)) in rkcanfd_can_frame_header_equal()
45 if (!is_canfd && (cfd1->can_id & CAN_RTR_FLAG)) in rkcanfd_can_frame_data_equal()
48 len = canfd_sanitize_len(cfd1->len); in rkcanfd_can_frame_data_equal()
50 return !memcmp(cfd1->data, cfd2->data, len); in rkcanfd_can_frame_data_equal()
58 unsigned int len = sizeof(*cfd) - sizeof(cfd->data); in rkcanfd_fifo_header_to_cfd_header()
61 if (header->frameinfo & RKCANFD_REG_FD_FRAMEINFO_FRAME_FORMAT) in rkcanfd_fifo_header_to_cfd_header()
62 cfd->can_id = FIELD_GET(RKCANFD_REG_FD_ID_EFF, header->id) | in rkcanfd_fifo_header_to_cfd_header()
65 cfd->can_id = FIELD_GET(RKCANFD_REG_FD_ID_SFF, header->id); in rkcanfd_fifo_header_to_cfd_header()
68 header->frameinfo); in rkcanfd_fifo_header_to_cfd_header()
70 /* CAN-FD */ in rkcanfd_fifo_header_to_cfd_header()
71 if (header->frameinfo & RKCANFD_REG_FD_FRAMEINFO_FDF) { in rkcanfd_fifo_header_to_cfd_header()
72 cfd->len = can_fd_dlc2len(dlc); in rkcanfd_fifo_header_to_cfd_header()
77 cfd->flags |= CANFD_FDF; in rkcanfd_fifo_header_to_cfd_header()
79 if (header->frameinfo & RKCANFD_REG_FD_FRAMEINFO_BRS) in rkcanfd_fifo_header_to_cfd_header()
80 cfd->flags |= CANFD_BRS; in rkcanfd_fifo_header_to_cfd_header()
82 cfd->len = can_cc_dlc2len(dlc); in rkcanfd_fifo_header_to_cfd_header()
84 if (header->frameinfo & RKCANFD_REG_FD_FRAMEINFO_RTR) { in rkcanfd_fifo_header_to_cfd_header()
85 cfd->can_id |= CAN_RTR_FLAG; in rkcanfd_fifo_header_to_cfd_header()
91 return len + cfd->len; in rkcanfd_fifo_header_to_cfd_header()
95 const struct canfd_frame *cfd_rx, const u32 ts, in rkcanfd_rxstx_filter() argument
98 struct net_device_stats *stats = &priv->ndev->stats; in rkcanfd_rxstx_filter()
99 struct rkcanfd_stats *rkcanfd_stats = &priv->stats; in rkcanfd_rxstx_filter()
105 skb = priv->can.echo_skb[tx_tail]; in rkcanfd_rxstx_filter()
107 netdev_err(priv->ndev, in rkcanfd_rxstx_filter()
110 priv->tx_head, priv->tx_tail); in rkcanfd_rxstx_filter()
112 return -ENOMSG; in rkcanfd_rxstx_filter()
114 cfd_nominal = (struct canfd_frame *)skb->data; in rkcanfd_rxstx_filter()
116 /* We RX'ed a frame identical to our pending TX frame. */ in rkcanfd_rxstx_filter()
118 cfd_rx->flags & CANFD_FDF) && in rkcanfd_rxstx_filter()
120 cfd_rx->flags & CANFD_FDF)) { in rkcanfd_rxstx_filter()
123 rkcanfd_handle_tx_done_one(priv, ts, &frame_len); in rkcanfd_rxstx_filter()
125 WRITE_ONCE(priv->tx_tail, priv->tx_tail + 1); in rkcanfd_rxstx_filter()
126 netif_subqueue_completed_wake(priv->ndev, 0, 1, frame_len, in rkcanfd_rxstx_filter()
135 if (!(priv->devtype_data.quirks & RKCANFD_QUIRK_RK3568_ERRATUM_6)) in rkcanfd_rxstx_filter()
141 * - TX'ed a standard frame -or- in rkcanfd_rxstx_filter()
142 * - RX'ed an extended frame in rkcanfd_rxstx_filter()
144 if (!(cfd_nominal->can_id & CAN_EFF_FLAG) || in rkcanfd_rxstx_filter()
145 (cfd_rx->can_id & CAN_EFF_FLAG)) in rkcanfd_rxstx_filter()
149 * - standard part and RTR flag of the TX'ed frame in rkcanfd_rxstx_filter()
150 * is not equal the CAN-ID and RTR flag of the RX'ed frame. in rkcanfd_rxstx_filter()
152 if ((cfd_nominal->can_id & (CAN_RTR_FLAG | CAN_SFF_MASK)) != in rkcanfd_rxstx_filter()
153 (cfd_rx->can_id & (CAN_RTR_FLAG | CAN_SFF_MASK))) in rkcanfd_rxstx_filter()
157 * - length is not the same in rkcanfd_rxstx_filter()
159 if (cfd_nominal->len != cfd_rx->len) in rkcanfd_rxstx_filter()
163 * - the data of non RTR frames is different in rkcanfd_rxstx_filter()
165 if (!(cfd_nominal->can_id & CAN_RTR_FLAG) && in rkcanfd_rxstx_filter()
166 memcmp(cfd_nominal->data, cfd_rx->data, cfd_nominal->len)) in rkcanfd_rxstx_filter()
170 u64_stats_update_begin(&rkcanfd_stats->syncp); in rkcanfd_rxstx_filter()
171 u64_stats_inc(&rkcanfd_stats->tx_extended_as_standard_errors); in rkcanfd_rxstx_filter()
172 u64_stats_update_end(&rkcanfd_stats->syncp); in rkcanfd_rxstx_filter()
178 if (priv->bec.txerr) in rkcanfd_rxstx_filter()
179 priv->bec.txerr--; in rkcanfd_rxstx_filter()
183 stats->tx_packets++; in rkcanfd_rxstx_filter()
184 stats->tx_errors++; in rkcanfd_rxstx_filter()
197 return header->frameinfo == header->id && in rkcanfd_fifo_header_empty()
198 header->frameinfo == header->ts; in rkcanfd_fifo_header_empty()
203 struct net_device_stats *stats = &priv->ndev->stats; in rkcanfd_handle_rx_int_one()
215 cfd->data, sizeof(cfd->data)); in rkcanfd_handle_rx_int_one()
219 struct rkcanfd_stats *rkcanfd_stats = &priv->stats; in rkcanfd_handle_rx_int_one()
221 u64_stats_update_begin(&rkcanfd_stats->syncp); in rkcanfd_handle_rx_int_one()
222 u64_stats_inc(&rkcanfd_stats->rx_fifo_empty_errors); in rkcanfd_handle_rx_int_one()
223 u64_stats_update_end(&rkcanfd_stats->syncp); in rkcanfd_handle_rx_int_one()
230 /* Drop any received CAN-FD frames if CAN-FD mode is not in rkcanfd_handle_rx_int_one()
233 if (header->frameinfo & RKCANFD_REG_FD_FRAMEINFO_FDF && in rkcanfd_handle_rx_int_one()
234 !(priv->can.ctrlmode & CAN_CTRLMODE_FD)) { in rkcanfd_handle_rx_int_one()
235 stats->rx_dropped++; in rkcanfd_handle_rx_int_one()
243 err = rkcanfd_rxstx_filter(priv, cfd, header->ts, &tx_done); in rkcanfd_handle_rx_int_one()
246 if (tx_done && !(priv->can.ctrlmode & CAN_CTRLMODE_LOOPBACK)) in rkcanfd_handle_rx_int_one()
254 if (priv->bec.rxerr) in rkcanfd_handle_rx_int_one()
255 priv->bec.rxerr = min(CAN_ERROR_PASSIVE_THRESHOLD, in rkcanfd_handle_rx_int_one()
256 priv->bec.rxerr) - 1; in rkcanfd_handle_rx_int_one()
258 if (header->frameinfo & RKCANFD_REG_FD_FRAMEINFO_FDF) in rkcanfd_handle_rx_int_one()
259 skb = alloc_canfd_skb(priv->ndev, &skb_cfd); in rkcanfd_handle_rx_int_one()
261 skb = alloc_can_skb(priv->ndev, (struct can_frame **)&skb_cfd); in rkcanfd_handle_rx_int_one()
264 stats->rx_dropped++; in rkcanfd_handle_rx_int_one()
270 rkcanfd_skb_set_timestamp(priv, skb, header->ts); in rkcanfd_handle_rx_int_one()
272 err = can_rx_offload_queue_timestamp(&priv->offload, skb, header->ts); in rkcanfd_handle_rx_int_one()
274 stats->rx_fifo_errors++; in rkcanfd_handle_rx_int_one()