diff options
Diffstat (limited to 'drivers/net/ethernet/stmicro')
| -rw-r--r-- | drivers/net/ethernet/stmicro/stmmac/descs_com.h | 22 | ||||
| -rw-r--r-- | drivers/net/ethernet/stmicro/stmmac/dwmac4_descs.c | 2 | ||||
| -rw-r--r-- | drivers/net/ethernet/stmicro/stmmac/dwxgmac2_descs.c | 2 | ||||
| -rw-r--r-- | drivers/net/ethernet/stmicro/stmmac/enh_desc.c | 22 | ||||
| -rw-r--r-- | drivers/net/ethernet/stmicro/stmmac/hwif.h | 2 | ||||
| -rw-r--r-- | drivers/net/ethernet/stmicro/stmmac/norm_desc.c | 12 | ||||
| -rw-r--r-- | drivers/net/ethernet/stmicro/stmmac/stmmac_main.c | 34 |
7 files changed, 59 insertions, 37 deletions
diff --git a/drivers/net/ethernet/stmicro/stmmac/descs_com.h b/drivers/net/ethernet/stmicro/stmmac/descs_com.h index 40d6356a7e73..3dfb07a78952 100644 --- a/drivers/net/ethernet/stmicro/stmmac/descs_com.h +++ b/drivers/net/ethernet/stmicro/stmmac/descs_com.h | |||
| @@ -29,11 +29,13 @@ | |||
| 29 | /* Specific functions used for Ring mode */ | 29 | /* Specific functions used for Ring mode */ |
| 30 | 30 | ||
| 31 | /* Enhanced descriptors */ | 31 | /* Enhanced descriptors */ |
| 32 | static inline void ehn_desc_rx_set_on_ring(struct dma_desc *p, int end) | 32 | static inline void ehn_desc_rx_set_on_ring(struct dma_desc *p, int end, |
| 33 | int bfsize) | ||
| 33 | { | 34 | { |
| 34 | p->des1 |= cpu_to_le32((BUF_SIZE_8KiB | 35 | if (bfsize == BUF_SIZE_16KiB) |
| 35 | << ERDES1_BUFFER2_SIZE_SHIFT) | 36 | p->des1 |= cpu_to_le32((BUF_SIZE_8KiB |
| 36 | & ERDES1_BUFFER2_SIZE_MASK); | 37 | << ERDES1_BUFFER2_SIZE_SHIFT) |
| 38 | & ERDES1_BUFFER2_SIZE_MASK); | ||
| 37 | 39 | ||
| 38 | if (end) | 40 | if (end) |
| 39 | p->des1 |= cpu_to_le32(ERDES1_END_RING); | 41 | p->des1 |= cpu_to_le32(ERDES1_END_RING); |
| @@ -59,11 +61,15 @@ static inline void enh_set_tx_desc_len_on_ring(struct dma_desc *p, int len) | |||
| 59 | } | 61 | } |
| 60 | 62 | ||
| 61 | /* Normal descriptors */ | 63 | /* Normal descriptors */ |
| 62 | static inline void ndesc_rx_set_on_ring(struct dma_desc *p, int end) | 64 | static inline void ndesc_rx_set_on_ring(struct dma_desc *p, int end, int bfsize) |
| 63 | { | 65 | { |
| 64 | p->des1 |= cpu_to_le32(((BUF_SIZE_2KiB - 1) | 66 | if (bfsize >= BUF_SIZE_2KiB) { |
| 65 | << RDES1_BUFFER2_SIZE_SHIFT) | 67 | int bfsize2; |
| 66 | & RDES1_BUFFER2_SIZE_MASK); | 68 | |
| 69 | bfsize2 = min(bfsize - BUF_SIZE_2KiB + 1, BUF_SIZE_2KiB - 1); | ||
| 70 | p->des1 |= cpu_to_le32((bfsize2 << RDES1_BUFFER2_SIZE_SHIFT) | ||
| 71 | & RDES1_BUFFER2_SIZE_MASK); | ||
| 72 | } | ||
| 67 | 73 | ||
| 68 | if (end) | 74 | if (end) |
| 69 | p->des1 |= cpu_to_le32(RDES1_END_RING); | 75 | p->des1 |= cpu_to_le32(RDES1_END_RING); |
diff --git a/drivers/net/ethernet/stmicro/stmmac/dwmac4_descs.c b/drivers/net/ethernet/stmicro/stmmac/dwmac4_descs.c index 7fbb6a4dbf51..e061e9f5fad7 100644 --- a/drivers/net/ethernet/stmicro/stmmac/dwmac4_descs.c +++ b/drivers/net/ethernet/stmicro/stmmac/dwmac4_descs.c | |||
| @@ -296,7 +296,7 @@ exit: | |||
| 296 | } | 296 | } |
| 297 | 297 | ||
| 298 | static void dwmac4_rd_init_rx_desc(struct dma_desc *p, int disable_rx_ic, | 298 | static void dwmac4_rd_init_rx_desc(struct dma_desc *p, int disable_rx_ic, |
| 299 | int mode, int end) | 299 | int mode, int end, int bfsize) |
| 300 | { | 300 | { |
| 301 | dwmac4_set_rx_owner(p, disable_rx_ic); | 301 | dwmac4_set_rx_owner(p, disable_rx_ic); |
| 302 | } | 302 | } |
diff --git a/drivers/net/ethernet/stmicro/stmmac/dwxgmac2_descs.c b/drivers/net/ethernet/stmicro/stmmac/dwxgmac2_descs.c index 1d858fdec997..98fa471da7c0 100644 --- a/drivers/net/ethernet/stmicro/stmmac/dwxgmac2_descs.c +++ b/drivers/net/ethernet/stmicro/stmmac/dwxgmac2_descs.c | |||
| @@ -123,7 +123,7 @@ static int dwxgmac2_get_rx_timestamp_status(void *desc, void *next_desc, | |||
| 123 | } | 123 | } |
| 124 | 124 | ||
| 125 | static void dwxgmac2_init_rx_desc(struct dma_desc *p, int disable_rx_ic, | 125 | static void dwxgmac2_init_rx_desc(struct dma_desc *p, int disable_rx_ic, |
| 126 | int mode, int end) | 126 | int mode, int end, int bfsize) |
| 127 | { | 127 | { |
| 128 | dwxgmac2_set_rx_owner(p, disable_rx_ic); | 128 | dwxgmac2_set_rx_owner(p, disable_rx_ic); |
| 129 | } | 129 | } |
diff --git a/drivers/net/ethernet/stmicro/stmmac/enh_desc.c b/drivers/net/ethernet/stmicro/stmmac/enh_desc.c index 5ef91a790f9d..5202d6ad7919 100644 --- a/drivers/net/ethernet/stmicro/stmmac/enh_desc.c +++ b/drivers/net/ethernet/stmicro/stmmac/enh_desc.c | |||
| @@ -201,6 +201,11 @@ static int enh_desc_get_rx_status(void *data, struct stmmac_extra_stats *x, | |||
| 201 | if (unlikely(rdes0 & RDES0_OWN)) | 201 | if (unlikely(rdes0 & RDES0_OWN)) |
| 202 | return dma_own; | 202 | return dma_own; |
| 203 | 203 | ||
| 204 | if (unlikely(!(rdes0 & RDES0_LAST_DESCRIPTOR))) { | ||
| 205 | stats->rx_length_errors++; | ||
| 206 | return discard_frame; | ||
| 207 | } | ||
| 208 | |||
| 204 | if (unlikely(rdes0 & RDES0_ERROR_SUMMARY)) { | 209 | if (unlikely(rdes0 & RDES0_ERROR_SUMMARY)) { |
| 205 | if (unlikely(rdes0 & RDES0_DESCRIPTOR_ERROR)) { | 210 | if (unlikely(rdes0 & RDES0_DESCRIPTOR_ERROR)) { |
| 206 | x->rx_desc++; | 211 | x->rx_desc++; |
| @@ -231,9 +236,10 @@ static int enh_desc_get_rx_status(void *data, struct stmmac_extra_stats *x, | |||
| 231 | * It doesn't match with the information reported into the databook. | 236 | * It doesn't match with the information reported into the databook. |
| 232 | * At any rate, we need to understand if the CSUM hw computation is ok | 237 | * At any rate, we need to understand if the CSUM hw computation is ok |
| 233 | * and report this info to the upper layers. */ | 238 | * and report this info to the upper layers. */ |
| 234 | ret = enh_desc_coe_rdes0(!!(rdes0 & RDES0_IPC_CSUM_ERROR), | 239 | if (likely(ret == good_frame)) |
| 235 | !!(rdes0 & RDES0_FRAME_TYPE), | 240 | ret = enh_desc_coe_rdes0(!!(rdes0 & RDES0_IPC_CSUM_ERROR), |
| 236 | !!(rdes0 & ERDES0_RX_MAC_ADDR)); | 241 | !!(rdes0 & RDES0_FRAME_TYPE), |
| 242 | !!(rdes0 & ERDES0_RX_MAC_ADDR)); | ||
| 237 | 243 | ||
| 238 | if (unlikely(rdes0 & RDES0_DRIBBLING)) | 244 | if (unlikely(rdes0 & RDES0_DRIBBLING)) |
| 239 | x->dribbling_bit++; | 245 | x->dribbling_bit++; |
| @@ -259,15 +265,19 @@ static int enh_desc_get_rx_status(void *data, struct stmmac_extra_stats *x, | |||
| 259 | } | 265 | } |
| 260 | 266 | ||
| 261 | static void enh_desc_init_rx_desc(struct dma_desc *p, int disable_rx_ic, | 267 | static void enh_desc_init_rx_desc(struct dma_desc *p, int disable_rx_ic, |
| 262 | int mode, int end) | 268 | int mode, int end, int bfsize) |
| 263 | { | 269 | { |
| 270 | int bfsize1; | ||
| 271 | |||
| 264 | p->des0 |= cpu_to_le32(RDES0_OWN); | 272 | p->des0 |= cpu_to_le32(RDES0_OWN); |
| 265 | p->des1 |= cpu_to_le32(BUF_SIZE_8KiB & ERDES1_BUFFER1_SIZE_MASK); | 273 | |
| 274 | bfsize1 = min(bfsize, BUF_SIZE_8KiB); | ||
| 275 | p->des1 |= cpu_to_le32(bfsize1 & ERDES1_BUFFER1_SIZE_MASK); | ||
| 266 | 276 | ||
| 267 | if (mode == STMMAC_CHAIN_MODE) | 277 | if (mode == STMMAC_CHAIN_MODE) |
| 268 | ehn_desc_rx_set_on_chain(p); | 278 | ehn_desc_rx_set_on_chain(p); |
| 269 | else | 279 | else |
| 270 | ehn_desc_rx_set_on_ring(p, end); | 280 | ehn_desc_rx_set_on_ring(p, end, bfsize); |
| 271 | 281 | ||
| 272 | if (disable_rx_ic) | 282 | if (disable_rx_ic) |
| 273 | p->des1 |= cpu_to_le32(ERDES1_DISABLE_IC); | 283 | p->des1 |= cpu_to_le32(ERDES1_DISABLE_IC); |
diff --git a/drivers/net/ethernet/stmicro/stmmac/hwif.h b/drivers/net/ethernet/stmicro/stmmac/hwif.h index 92b8944f26e3..5bb00234d961 100644 --- a/drivers/net/ethernet/stmicro/stmmac/hwif.h +++ b/drivers/net/ethernet/stmicro/stmmac/hwif.h | |||
| @@ -33,7 +33,7 @@ struct dma_extended_desc; | |||
| 33 | struct stmmac_desc_ops { | 33 | struct stmmac_desc_ops { |
| 34 | /* DMA RX descriptor ring initialization */ | 34 | /* DMA RX descriptor ring initialization */ |
| 35 | void (*init_rx_desc)(struct dma_desc *p, int disable_rx_ic, int mode, | 35 | void (*init_rx_desc)(struct dma_desc *p, int disable_rx_ic, int mode, |
| 36 | int end); | 36 | int end, int bfsize); |
| 37 | /* DMA TX descriptor ring initialization */ | 37 | /* DMA TX descriptor ring initialization */ |
| 38 | void (*init_tx_desc)(struct dma_desc *p, int mode, int end); | 38 | void (*init_tx_desc)(struct dma_desc *p, int mode, int end); |
| 39 | /* Invoked by the xmit function to prepare the tx descriptor */ | 39 | /* Invoked by the xmit function to prepare the tx descriptor */ |
diff --git a/drivers/net/ethernet/stmicro/stmmac/norm_desc.c b/drivers/net/ethernet/stmicro/stmmac/norm_desc.c index de65bb29feba..b7dd4e3c760d 100644 --- a/drivers/net/ethernet/stmicro/stmmac/norm_desc.c +++ b/drivers/net/ethernet/stmicro/stmmac/norm_desc.c | |||
| @@ -91,8 +91,6 @@ static int ndesc_get_rx_status(void *data, struct stmmac_extra_stats *x, | |||
| 91 | return dma_own; | 91 | return dma_own; |
| 92 | 92 | ||
| 93 | if (unlikely(!(rdes0 & RDES0_LAST_DESCRIPTOR))) { | 93 | if (unlikely(!(rdes0 & RDES0_LAST_DESCRIPTOR))) { |
| 94 | pr_warn("%s: Oversized frame spanned multiple buffers\n", | ||
| 95 | __func__); | ||
| 96 | stats->rx_length_errors++; | 94 | stats->rx_length_errors++; |
| 97 | return discard_frame; | 95 | return discard_frame; |
| 98 | } | 96 | } |
| @@ -135,15 +133,19 @@ static int ndesc_get_rx_status(void *data, struct stmmac_extra_stats *x, | |||
| 135 | } | 133 | } |
| 136 | 134 | ||
| 137 | static void ndesc_init_rx_desc(struct dma_desc *p, int disable_rx_ic, int mode, | 135 | static void ndesc_init_rx_desc(struct dma_desc *p, int disable_rx_ic, int mode, |
| 138 | int end) | 136 | int end, int bfsize) |
| 139 | { | 137 | { |
| 138 | int bfsize1; | ||
| 139 | |||
| 140 | p->des0 |= cpu_to_le32(RDES0_OWN); | 140 | p->des0 |= cpu_to_le32(RDES0_OWN); |
| 141 | p->des1 |= cpu_to_le32((BUF_SIZE_2KiB - 1) & RDES1_BUFFER1_SIZE_MASK); | 141 | |
| 142 | bfsize1 = min(bfsize, BUF_SIZE_2KiB - 1); | ||
| 143 | p->des1 |= cpu_to_le32(bfsize & RDES1_BUFFER1_SIZE_MASK); | ||
| 142 | 144 | ||
| 143 | if (mode == STMMAC_CHAIN_MODE) | 145 | if (mode == STMMAC_CHAIN_MODE) |
| 144 | ndesc_rx_set_on_chain(p, end); | 146 | ndesc_rx_set_on_chain(p, end); |
| 145 | else | 147 | else |
| 146 | ndesc_rx_set_on_ring(p, end); | 148 | ndesc_rx_set_on_ring(p, end, bfsize); |
| 147 | 149 | ||
| 148 | if (disable_rx_ic) | 150 | if (disable_rx_ic) |
| 149 | p->des1 |= cpu_to_le32(RDES1_DISABLE_IC); | 151 | p->des1 |= cpu_to_le32(RDES1_DISABLE_IC); |
diff --git a/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c b/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c index 6a2e1031a62a..a26e36dbb5df 100644 --- a/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c +++ b/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c | |||
| @@ -1136,11 +1136,13 @@ static void stmmac_clear_rx_descriptors(struct stmmac_priv *priv, u32 queue) | |||
| 1136 | if (priv->extend_desc) | 1136 | if (priv->extend_desc) |
| 1137 | stmmac_init_rx_desc(priv, &rx_q->dma_erx[i].basic, | 1137 | stmmac_init_rx_desc(priv, &rx_q->dma_erx[i].basic, |
| 1138 | priv->use_riwt, priv->mode, | 1138 | priv->use_riwt, priv->mode, |
| 1139 | (i == DMA_RX_SIZE - 1)); | 1139 | (i == DMA_RX_SIZE - 1), |
| 1140 | priv->dma_buf_sz); | ||
| 1140 | else | 1141 | else |
| 1141 | stmmac_init_rx_desc(priv, &rx_q->dma_rx[i], | 1142 | stmmac_init_rx_desc(priv, &rx_q->dma_rx[i], |
| 1142 | priv->use_riwt, priv->mode, | 1143 | priv->use_riwt, priv->mode, |
| 1143 | (i == DMA_RX_SIZE - 1)); | 1144 | (i == DMA_RX_SIZE - 1), |
| 1145 | priv->dma_buf_sz); | ||
| 1144 | } | 1146 | } |
| 1145 | 1147 | ||
| 1146 | /** | 1148 | /** |
| @@ -3352,9 +3354,8 @@ static int stmmac_rx(struct stmmac_priv *priv, int limit, u32 queue) | |||
| 3352 | { | 3354 | { |
| 3353 | struct stmmac_rx_queue *rx_q = &priv->rx_queue[queue]; | 3355 | struct stmmac_rx_queue *rx_q = &priv->rx_queue[queue]; |
| 3354 | struct stmmac_channel *ch = &priv->channel[queue]; | 3356 | struct stmmac_channel *ch = &priv->channel[queue]; |
| 3355 | unsigned int entry = rx_q->cur_rx; | 3357 | unsigned int next_entry = rx_q->cur_rx; |
| 3356 | int coe = priv->hw->rx_csum; | 3358 | int coe = priv->hw->rx_csum; |
| 3357 | unsigned int next_entry; | ||
| 3358 | unsigned int count = 0; | 3359 | unsigned int count = 0; |
| 3359 | bool xmac; | 3360 | bool xmac; |
| 3360 | 3361 | ||
| @@ -3372,10 +3373,12 @@ static int stmmac_rx(struct stmmac_priv *priv, int limit, u32 queue) | |||
| 3372 | stmmac_display_ring(priv, rx_head, DMA_RX_SIZE, true); | 3373 | stmmac_display_ring(priv, rx_head, DMA_RX_SIZE, true); |
| 3373 | } | 3374 | } |
| 3374 | while (count < limit) { | 3375 | while (count < limit) { |
| 3375 | int status; | 3376 | int entry, status; |
| 3376 | struct dma_desc *p; | 3377 | struct dma_desc *p; |
| 3377 | struct dma_desc *np; | 3378 | struct dma_desc *np; |
| 3378 | 3379 | ||
| 3380 | entry = next_entry; | ||
| 3381 | |||
| 3379 | if (priv->extend_desc) | 3382 | if (priv->extend_desc) |
| 3380 | p = (struct dma_desc *)(rx_q->dma_erx + entry); | 3383 | p = (struct dma_desc *)(rx_q->dma_erx + entry); |
| 3381 | else | 3384 | else |
| @@ -3431,11 +3434,12 @@ static int stmmac_rx(struct stmmac_priv *priv, int limit, u32 queue) | |||
| 3431 | * ignored | 3434 | * ignored |
| 3432 | */ | 3435 | */ |
| 3433 | if (frame_len > priv->dma_buf_sz) { | 3436 | if (frame_len > priv->dma_buf_sz) { |
| 3434 | netdev_err(priv->dev, | 3437 | if (net_ratelimit()) |
| 3435 | "len %d larger than size (%d)\n", | 3438 | netdev_err(priv->dev, |
| 3436 | frame_len, priv->dma_buf_sz); | 3439 | "len %d larger than size (%d)\n", |
| 3440 | frame_len, priv->dma_buf_sz); | ||
| 3437 | priv->dev->stats.rx_length_errors++; | 3441 | priv->dev->stats.rx_length_errors++; |
| 3438 | break; | 3442 | continue; |
| 3439 | } | 3443 | } |
| 3440 | 3444 | ||
| 3441 | /* ACS is set; GMAC core strips PAD/FCS for IEEE 802.3 | 3445 | /* ACS is set; GMAC core strips PAD/FCS for IEEE 802.3 |
| @@ -3470,7 +3474,7 @@ static int stmmac_rx(struct stmmac_priv *priv, int limit, u32 queue) | |||
| 3470 | dev_warn(priv->device, | 3474 | dev_warn(priv->device, |
| 3471 | "packet dropped\n"); | 3475 | "packet dropped\n"); |
| 3472 | priv->dev->stats.rx_dropped++; | 3476 | priv->dev->stats.rx_dropped++; |
| 3473 | break; | 3477 | continue; |
| 3474 | } | 3478 | } |
| 3475 | 3479 | ||
| 3476 | dma_sync_single_for_cpu(priv->device, | 3480 | dma_sync_single_for_cpu(priv->device, |
| @@ -3490,11 +3494,12 @@ static int stmmac_rx(struct stmmac_priv *priv, int limit, u32 queue) | |||
| 3490 | } else { | 3494 | } else { |
| 3491 | skb = rx_q->rx_skbuff[entry]; | 3495 | skb = rx_q->rx_skbuff[entry]; |
| 3492 | if (unlikely(!skb)) { | 3496 | if (unlikely(!skb)) { |
| 3493 | netdev_err(priv->dev, | 3497 | if (net_ratelimit()) |
| 3494 | "%s: Inconsistent Rx chain\n", | 3498 | netdev_err(priv->dev, |
| 3495 | priv->dev->name); | 3499 | "%s: Inconsistent Rx chain\n", |
| 3500 | priv->dev->name); | ||
| 3496 | priv->dev->stats.rx_dropped++; | 3501 | priv->dev->stats.rx_dropped++; |
| 3497 | break; | 3502 | continue; |
| 3498 | } | 3503 | } |
| 3499 | prefetch(skb->data - NET_IP_ALIGN); | 3504 | prefetch(skb->data - NET_IP_ALIGN); |
| 3500 | rx_q->rx_skbuff[entry] = NULL; | 3505 | rx_q->rx_skbuff[entry] = NULL; |
| @@ -3529,7 +3534,6 @@ static int stmmac_rx(struct stmmac_priv *priv, int limit, u32 queue) | |||
| 3529 | priv->dev->stats.rx_packets++; | 3534 | priv->dev->stats.rx_packets++; |
| 3530 | priv->dev->stats.rx_bytes += frame_len; | 3535 | priv->dev->stats.rx_bytes += frame_len; |
| 3531 | } | 3536 | } |
| 3532 | entry = next_entry; | ||
| 3533 | } | 3537 | } |
| 3534 | 3538 | ||
| 3535 | stmmac_rx_refill(priv, queue); | 3539 | stmmac_rx_refill(priv, queue); |
