Skip to content

Commit 1c35874

Browse files
committed
drivers: eth_nxp_enet_qos: Don't drop unfinished packets
Instead of dropping packets for which we did not yet receive all the frames by the end of the work run, just store the pointer to the packet which is still in progress and finish it on the next work run, once the remaining frames come in. Ther doesn't seem to be any valid reason to drop the packet just because the frames didn't finish coming in by the time we are processing them. The MTL fifos will keep everything in order. Signed-off-by: Declan Snyder <declan.snyder@nxp.com>
1 parent 50ca2bf commit 1c35874

File tree

2 files changed

+32
-36
lines changed

2 files changed

+32
-36
lines changed

drivers/ethernet/eth_nxp_enet_qos/eth_nxp_enet_qos_mac.c

Lines changed: 31 additions & 36 deletions
Original file line numberDiff line numberDiff line change
@@ -221,8 +221,8 @@ static void enet_qos_dma_rx_resume(const struct device *dev)
221221
/* treats the frame as a potential start of a new packet.
222222
* returns new net_pkt pointer if successfully received or null otherwise.
223223
*/
224-
static struct net_pkt *enet_qos_start_new_packet(const struct device *dev,
225-
volatile union nxp_enet_qos_rx_desc *desc)
224+
static void enet_qos_start_new_rx_packet(const struct device *dev,
225+
volatile union nxp_enet_qos_rx_desc *desc)
226226
{
227227
struct nxp_enet_qos_mac_data *data = dev->data;
228228
struct nxp_enet_qos_rx_data *rx_data = &data->rx;
@@ -234,42 +234,46 @@ static struct net_pkt *enet_qos_start_new_packet(const struct device *dev,
234234
* drop error, since the starting frame must have been dropped and logged
235235
* earlier. ie. we only log dropping first descriptor flag frames.
236236
*/
237-
goto skip;
237+
return;
238238
}
239239

240240
pkt = net_pkt_rx_alloc(K_NO_WAIT);
241241

242242
if (!pkt) {
243243
LOG_ERR("Could not alloc new RX pkt");
244-
goto skip;
244+
} else {
245+
LOG_DBG("New RX pkt %p", pkt);
245246
}
246247

247248
rx_data->processed_pkt_len = 0;
249+
rx_data->pkt = pkt;
250+
}
248251

249-
LOG_DBG("New RX pkt %p", pkt);
252+
static void enet_qos_finish_rx_packet(const struct device *dev)
253+
{
254+
struct nxp_enet_qos_mac_data *data = dev->data;
255+
struct nxp_enet_qos_rx_data *rx_data = &data->rx;
250256

251-
return pkt;
252-
skip:
253-
return NULL;
257+
rx_data->pkt = NULL;
258+
rx_data->processed_pkt_len = 0;
254259
}
255260

256-
static void enet_qos_drop_rx_packet(const struct device *dev,
257-
struct net_pkt *pkt)
261+
static void enet_qos_drop_rx_packet(const struct device *dev)
258262
{
259263
struct nxp_enet_qos_mac_data *data = dev->data;
260264
struct nxp_enet_qos_rx_data *rx_data = &data->rx;
265+
struct net_pkt *pkt = rx_data->pkt;
261266

262267
eth_stats_update_errors_rx(data->iface);
263268
if (pkt != NULL) {
264269
LOG_WRN("Dropped packet %p", pkt);
265270
net_pkt_unref(pkt);
266271
}
267272

268-
rx_data->processed_pkt_len = 0;
273+
enet_qos_finish_rx_packet(dev);
269274
}
270275

271276
static void enet_qos_drop_rx_frame(const struct device *dev,
272-
struct net_pkt *pkt,
273277
volatile union nxp_enet_qos_rx_desc *desc)
274278
{
275279
struct nxp_enet_qos_mac_data *data = dev->data;
@@ -312,7 +316,6 @@ static int enet_qos_get_frame_len(const struct device *dev,
312316
}
313317

314318
static int enet_qos_append_frame_to_packet(const struct device *dev,
315-
struct net_pkt *pkt,
316319
volatile union nxp_enet_qos_rx_desc *desc,
317320
size_t frame_len)
318321
{
@@ -321,33 +324,33 @@ static int enet_qos_append_frame_to_packet(const struct device *dev,
321324
volatile union nxp_enet_qos_rx_desc *desc_arr = rx_data->descriptors;
322325
int desc_idx = ARRAY_INDEX(desc_arr, desc);
323326
struct net_buf *frame_buf = data->rx.reserved_bufs[desc_idx];
327+
struct net_pkt *pkt = rx_data->pkt;
324328

325329
net_buf_add(frame_buf, frame_len);
326330
net_pkt_frag_add(pkt, frame_buf);
327331

328332
return 0;
329333
}
330334

331-
static int enet_qos_pass_up_rx(const struct device *dev, struct net_pkt **pkt)
335+
static int enet_qos_pass_up_rx(const struct device *dev)
332336
{
333337
struct nxp_enet_qos_mac_data *data = dev->data;
334338
struct nxp_enet_qos_rx_data *rx_data = &data->rx;
335339
int ret = 0;
336340

337341
LOG_DBG("Receiving RX packet");
338342

339-
ret = net_recv_data(data->iface, *pkt);
343+
ret = net_recv_data(data->iface, rx_data->pkt);
340344
if (ret != 0) {
341-
LOG_ERR("RECV failed for pkt %p", *pkt);
342-
enet_qos_drop_rx_packet(dev, *pkt);
345+
LOG_ERR("RECV failed for pkt %p", rx_data->pkt);
346+
enet_qos_drop_rx_packet(dev);
343347
goto done;
344348
}
345349

346350
eth_stats_update_pkts_rx(data->iface);
347351

348352
done:
349-
rx_data->processed_pkt_len = 0;
350-
*pkt = NULL;
353+
enet_qos_finish_rx_packet(dev);
351354
return ret;
352355
}
353356

@@ -374,19 +377,18 @@ static void enet_qos_swap_rx_desc_buf(const struct device *dev,
374377
}
375378

376379
static void eth_nxp_enet_qos_process_rx_frame(const struct device *dev,
377-
struct net_pkt **pkt,
378380
volatile union nxp_enet_qos_rx_desc *desc)
379381
{
380382
struct nxp_enet_qos_mac_data *data = dev->data;
381383
struct nxp_enet_qos_rx_data *rx_data = &data->rx;
382384
int frame_len = 0;
383385
int ret = 0;
384386

385-
if (*pkt == NULL) {
387+
if (rx_data->pkt == NULL) {
386388
/* Trying to start a new packet if none is provided */
387-
*pkt = enet_qos_start_new_packet(dev, desc);
389+
enet_qos_start_new_rx_packet(dev, desc);
388390
}
389-
if (*pkt == NULL) {
391+
if (rx_data->pkt == NULL) {
390392
/* Still no packet so drop the frame */
391393
goto drop;
392394
}
@@ -397,23 +399,22 @@ static void eth_nxp_enet_qos_process_rx_frame(const struct device *dev,
397399
}
398400

399401
/* Take the received data and add to the packet */
400-
enet_qos_append_frame_to_packet(dev, *pkt, desc, frame_len);
402+
enet_qos_append_frame_to_packet(dev, desc, frame_len);
401403
rx_data->processed_pkt_len += frame_len;
402404

403405
if (!frame_is_last(desc)) {
404406
goto done;
405407
}
406408

407409
/* If this is the last frame of the packet, send it up the stack */
408-
ret = enet_qos_pass_up_rx(dev, pkt);
410+
ret = enet_qos_pass_up_rx(dev);
409411
if (ret != 0) {
410412
goto drop;
411413
}
412414

413415
goto done;
414416
drop:
415-
enet_qos_drop_rx_frame(dev, *pkt, desc);
416-
*pkt = NULL;
417+
enet_qos_drop_rx_frame(dev, desc);
417418
return;
418419
done:
419420
/* last thing to do is switch the buf so the DMA doesn't overwrite
@@ -432,7 +433,7 @@ static void eth_nxp_enet_qos_rx(struct k_work *work)
432433
volatile union nxp_enet_qos_rx_desc *desc_arr = data->rx.descriptors;
433434
uint32_t desc_idx = rx_data->next_desc_idx;
434435
volatile union nxp_enet_qos_rx_desc *desc = &desc_arr[desc_idx];
435-
struct net_pkt *pkt = NULL;
436+
struct net_pkt *pkt = rx_data->pkt;
436437

437438
LOG_DBG("RX work start: %p", work);
438439

@@ -442,19 +443,13 @@ static void eth_nxp_enet_qos_rx(struct k_work *work)
442443
while (software_owns_descriptor(desc)) {
443444
rx_data->next_desc_idx = (desc_idx + 1U) % NUM_RX_BUFDESC;
444445

445-
eth_nxp_enet_qos_process_rx_frame(dev, &pkt, desc);
446+
eth_nxp_enet_qos_process_rx_frame(dev, desc);
446447

447448
desc_idx = rx_data->next_desc_idx;
448449
desc = &desc_arr[desc_idx];
449450
}
450451

451-
if (pkt != NULL) {
452-
/* Looped through descriptors without reaching the final
453-
* fragment of the packet, deallocate the incomplete one
454-
*/
455-
LOG_DBG("Incomplete packet received, cleaning up");
456-
enet_qos_drop_rx_packet(dev, pkt);
457-
}
452+
rx_data->pkt = pkt;
458453

459454
/* now that we updated the descriptors, resume in case we are suspended */
460455
enet_qos_dma_rx_resume(dev);

drivers/ethernet/eth_nxp_enet_qos/nxp_enet_qos_priv.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -117,6 +117,7 @@ struct nxp_enet_qos_rx_data {
117117
volatile union nxp_enet_qos_rx_desc descriptors[NUM_RX_BUFDESC];
118118
struct net_buf *reserved_bufs[NUM_RX_BUFDESC];
119119
size_t processed_pkt_len;
120+
struct net_pkt *pkt;
120121
};
121122

122123
struct nxp_enet_qos_mac_data {

0 commit comments

Comments
 (0)