Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 6 additions & 0 deletions drivers/net/ethernet/freescale/fec.h
Original file line number Diff line number Diff line change
Expand Up @@ -514,6 +514,12 @@ struct bufdesc_ex {
*/
#define FEC_QUIRK_HAS_MDIO_C45 BIT(24)

/* i.MX8MM FEC hardware RX checksum offload incorrectly validates certain UDP
* packets, causing them to be silently dropped by the kernel UDP stack.
* Force software re-validation for UDP by downgrading CHECKSUM_UNNECESSARY.
*/
#define FEC_QUIRK_ERR_UDP_CSUM BIT(25)
Comment on lines +517 to +521

struct bufdesc_prop {
int qid;
/* Address of Rx and Tx buffers */
Expand Down
27 changes: 26 additions & 1 deletion drivers/net/ethernet/freescale/fec_main.c
Original file line number Diff line number Diff line change
Expand Up @@ -154,6 +154,17 @@ static const struct fec_devinfo fec_imx6ul_info = {
FEC_QUIRK_HAS_MDIO_C45,
};

static const struct fec_devinfo fec_imx8mm_info = {
.quirks = FEC_QUIRK_ENET_MAC | FEC_QUIRK_HAS_GBIT |
FEC_QUIRK_HAS_BUFDESC_EX | FEC_QUIRK_HAS_CSUM |
FEC_QUIRK_HAS_VLAN | FEC_QUIRK_HAS_AVB |
FEC_QUIRK_ERR007885 | FEC_QUIRK_BUG_CAPTURE |
FEC_QUIRK_HAS_RACC | FEC_QUIRK_HAS_COALESCE |
FEC_QUIRK_CLEAR_SETUP_MII | FEC_QUIRK_HAS_MULTI_QUEUES |
FEC_QUIRK_HAS_EEE | FEC_QUIRK_WAKEUP_FROM_INT2 |
FEC_QUIRK_HAS_MDIO_C45 | FEC_QUIRK_ERR_UDP_CSUM,
};

static const struct fec_devinfo fec_imx8mq_info = {
.quirks = FEC_QUIRK_ENET_MAC | FEC_QUIRK_HAS_GBIT |
FEC_QUIRK_HAS_BUFDESC_EX | FEC_QUIRK_HAS_CSUM |
Expand Down Expand Up @@ -209,6 +220,9 @@ static struct platform_device_id fec_devtype[] = {
}, {
.name = "imx6ul-fec",
.driver_data = (kernel_ulong_t)&fec_imx6ul_info,
}, {
.name = "imx8mm-fec",
.driver_data = (kernel_ulong_t)&fec_imx8mm_info,
}, {
.name = "imx8mq-fec",
.driver_data = (kernel_ulong_t)&fec_imx8mq_info,
Expand All @@ -232,6 +246,7 @@ enum imx_fec_type {
MVF600_FEC,
IMX6SX_FEC,
IMX6UL_FEC,
IMX8MM_FEC,
IMX8MQ_FEC,
IMX8QM_FEC,
S32V234_FEC,
Expand All @@ -245,6 +260,7 @@ static const struct of_device_id fec_dt_ids[] = {
{ .compatible = "fsl,mvf600-fec", .data = &fec_devtype[MVF600_FEC], },
{ .compatible = "fsl,imx6sx-fec", .data = &fec_devtype[IMX6SX_FEC], },
{ .compatible = "fsl,imx6ul-fec", .data = &fec_devtype[IMX6UL_FEC], },
{ .compatible = "fsl,imx8mm-fec", .data = &fec_devtype[IMX8MM_FEC], },
{ .compatible = "fsl,imx8mq-fec", .data = &fec_devtype[IMX8MQ_FEC], },
{ .compatible = "fsl,imx8qm-fec", .data = &fec_devtype[IMX8QM_FEC], },
{ .compatible = "fsl,s32v234-fec", .data = &fec_devtype[S32V234_FEC], },
Expand Down Expand Up @@ -1786,8 +1802,17 @@ fec_enet_rx_queue(struct net_device *ndev, int budget, u16 queue_id)
if (fep->bufdesc_ex &&
(fep->csum_flags & FLAG_RX_CSUM_ENABLED)) {
if (!(ebdp->cbd_esc & cpu_to_fec32(FLAG_RX_CSUM_ERROR))) {
/* don't check it */
skb->ip_summed = CHECKSUM_UNNECESSARY;
/* i.MX8MM FEC HW checksum offload incorrectly
* validates certain UDP packets (FEC_QUIRK_ERR_UDP_CSUM).
* Force software re-validation for UDP only.
*/
if (fep->quirks & FEC_QUIRK_ERR_UDP_CSUM) {
struct iphdr *iph = (struct iphdr *)skb_network_header(skb);

if (iph && iph->protocol == IPPROTO_UDP)
skb->ip_summed = CHECKSUM_NONE;
}
Comment on lines +1806 to +1815
} else {
skb_checksum_none_assert(skb);
}
Expand Down