diff options
Diffstat (limited to 'drivers/net')
71 files changed, 633 insertions, 354 deletions
diff --git a/drivers/net/can/dev.c b/drivers/net/can/dev.c index 49163570a63a..3b3f88ffab53 100644 --- a/drivers/net/can/dev.c +++ b/drivers/net/can/dev.c | |||
@@ -477,6 +477,34 @@ void can_put_echo_skb(struct sk_buff *skb, struct net_device *dev, | |||
477 | } | 477 | } |
478 | EXPORT_SYMBOL_GPL(can_put_echo_skb); | 478 | EXPORT_SYMBOL_GPL(can_put_echo_skb); |
479 | 479 | ||
480 | struct sk_buff *__can_get_echo_skb(struct net_device *dev, unsigned int idx, u8 *len_ptr) | ||
481 | { | ||
482 | struct can_priv *priv = netdev_priv(dev); | ||
483 | struct sk_buff *skb = priv->echo_skb[idx]; | ||
484 | struct canfd_frame *cf; | ||
485 | |||
486 | if (idx >= priv->echo_skb_max) { | ||
487 | netdev_err(dev, "%s: BUG! Trying to access can_priv::echo_skb out of bounds (%u/max %u)\n", | ||
488 | __func__, idx, priv->echo_skb_max); | ||
489 | return NULL; | ||
490 | } | ||
491 | |||
492 | if (!skb) { | ||
493 | netdev_err(dev, "%s: BUG! Trying to echo non existing skb: can_priv::echo_skb[%u]\n", | ||
494 | __func__, idx); | ||
495 | return NULL; | ||
496 | } | ||
497 | |||
498 | /* Using "struct canfd_frame::len" for the frame | ||
499 | * length is supported on both CAN and CANFD frames. | ||
500 | */ | ||
501 | cf = (struct canfd_frame *)skb->data; | ||
502 | *len_ptr = cf->len; | ||
503 | priv->echo_skb[idx] = NULL; | ||
504 | |||
505 | return skb; | ||
506 | } | ||
507 | |||
480 | /* | 508 | /* |
481 | * Get the skb from the stack and loop it back locally | 509 | * Get the skb from the stack and loop it back locally |
482 | * | 510 | * |
@@ -486,22 +514,16 @@ EXPORT_SYMBOL_GPL(can_put_echo_skb); | |||
486 | */ | 514 | */ |
487 | unsigned int can_get_echo_skb(struct net_device *dev, unsigned int idx) | 515 | unsigned int can_get_echo_skb(struct net_device *dev, unsigned int idx) |
488 | { | 516 | { |
489 | struct can_priv *priv = netdev_priv(dev); | 517 | struct sk_buff *skb; |
490 | 518 | u8 len; | |
491 | BUG_ON(idx >= priv->echo_skb_max); | ||
492 | |||
493 | if (priv->echo_skb[idx]) { | ||
494 | struct sk_buff *skb = priv->echo_skb[idx]; | ||
495 | struct can_frame *cf = (struct can_frame *)skb->data; | ||
496 | u8 dlc = cf->can_dlc; | ||
497 | 519 | ||
498 | netif_rx(priv->echo_skb[idx]); | 520 | skb = __can_get_echo_skb(dev, idx, &len); |
499 | priv->echo_skb[idx] = NULL; | 521 | if (!skb) |
522 | return 0; | ||
500 | 523 | ||
501 | return dlc; | 524 | netif_rx(skb); |
502 | } | ||
503 | 525 | ||
504 | return 0; | 526 | return len; |
505 | } | 527 | } |
506 | EXPORT_SYMBOL_GPL(can_get_echo_skb); | 528 | EXPORT_SYMBOL_GPL(can_get_echo_skb); |
507 | 529 | ||
diff --git a/drivers/net/can/flexcan.c b/drivers/net/can/flexcan.c index 8e972ef08637..75ce11395ee8 100644 --- a/drivers/net/can/flexcan.c +++ b/drivers/net/can/flexcan.c | |||
@@ -135,13 +135,12 @@ | |||
135 | 135 | ||
136 | /* FLEXCAN interrupt flag register (IFLAG) bits */ | 136 | /* FLEXCAN interrupt flag register (IFLAG) bits */ |
137 | /* Errata ERR005829 step7: Reserve first valid MB */ | 137 | /* Errata ERR005829 step7: Reserve first valid MB */ |
138 | #define FLEXCAN_TX_MB_RESERVED_OFF_FIFO 8 | 138 | #define FLEXCAN_TX_MB_RESERVED_OFF_FIFO 8 |
139 | #define FLEXCAN_TX_MB_OFF_FIFO 9 | ||
140 | #define FLEXCAN_TX_MB_RESERVED_OFF_TIMESTAMP 0 | 139 | #define FLEXCAN_TX_MB_RESERVED_OFF_TIMESTAMP 0 |
141 | #define FLEXCAN_TX_MB_OFF_TIMESTAMP 1 | 140 | #define FLEXCAN_TX_MB 63 |
142 | #define FLEXCAN_RX_MB_OFF_TIMESTAMP_FIRST (FLEXCAN_TX_MB_OFF_TIMESTAMP + 1) | 141 | #define FLEXCAN_RX_MB_OFF_TIMESTAMP_FIRST (FLEXCAN_TX_MB_RESERVED_OFF_TIMESTAMP + 1) |
143 | #define FLEXCAN_RX_MB_OFF_TIMESTAMP_LAST 63 | 142 | #define FLEXCAN_RX_MB_OFF_TIMESTAMP_LAST (FLEXCAN_TX_MB - 1) |
144 | #define FLEXCAN_IFLAG_MB(x) BIT(x) | 143 | #define FLEXCAN_IFLAG_MB(x) BIT(x & 0x1f) |
145 | #define FLEXCAN_IFLAG_RX_FIFO_OVERFLOW BIT(7) | 144 | #define FLEXCAN_IFLAG_RX_FIFO_OVERFLOW BIT(7) |
146 | #define FLEXCAN_IFLAG_RX_FIFO_WARN BIT(6) | 145 | #define FLEXCAN_IFLAG_RX_FIFO_WARN BIT(6) |
147 | #define FLEXCAN_IFLAG_RX_FIFO_AVAILABLE BIT(5) | 146 | #define FLEXCAN_IFLAG_RX_FIFO_AVAILABLE BIT(5) |
@@ -259,9 +258,7 @@ struct flexcan_priv { | |||
259 | struct can_rx_offload offload; | 258 | struct can_rx_offload offload; |
260 | 259 | ||
261 | struct flexcan_regs __iomem *regs; | 260 | struct flexcan_regs __iomem *regs; |
262 | struct flexcan_mb __iomem *tx_mb; | ||
263 | struct flexcan_mb __iomem *tx_mb_reserved; | 261 | struct flexcan_mb __iomem *tx_mb_reserved; |
264 | u8 tx_mb_idx; | ||
265 | u32 reg_ctrl_default; | 262 | u32 reg_ctrl_default; |
266 | u32 reg_imask1_default; | 263 | u32 reg_imask1_default; |
267 | u32 reg_imask2_default; | 264 | u32 reg_imask2_default; |
@@ -515,6 +512,7 @@ static int flexcan_get_berr_counter(const struct net_device *dev, | |||
515 | static netdev_tx_t flexcan_start_xmit(struct sk_buff *skb, struct net_device *dev) | 512 | static netdev_tx_t flexcan_start_xmit(struct sk_buff *skb, struct net_device *dev) |
516 | { | 513 | { |
517 | const struct flexcan_priv *priv = netdev_priv(dev); | 514 | const struct flexcan_priv *priv = netdev_priv(dev); |
515 | struct flexcan_regs __iomem *regs = priv->regs; | ||
518 | struct can_frame *cf = (struct can_frame *)skb->data; | 516 | struct can_frame *cf = (struct can_frame *)skb->data; |
519 | u32 can_id; | 517 | u32 can_id; |
520 | u32 data; | 518 | u32 data; |
@@ -537,17 +535,17 @@ static netdev_tx_t flexcan_start_xmit(struct sk_buff *skb, struct net_device *de | |||
537 | 535 | ||
538 | if (cf->can_dlc > 0) { | 536 | if (cf->can_dlc > 0) { |
539 | data = be32_to_cpup((__be32 *)&cf->data[0]); | 537 | data = be32_to_cpup((__be32 *)&cf->data[0]); |
540 | priv->write(data, &priv->tx_mb->data[0]); | 538 | priv->write(data, ®s->mb[FLEXCAN_TX_MB].data[0]); |
541 | } | 539 | } |
542 | if (cf->can_dlc > 4) { | 540 | if (cf->can_dlc > 4) { |
543 | data = be32_to_cpup((__be32 *)&cf->data[4]); | 541 | data = be32_to_cpup((__be32 *)&cf->data[4]); |
544 | priv->write(data, &priv->tx_mb->data[1]); | 542 | priv->write(data, ®s->mb[FLEXCAN_TX_MB].data[1]); |
545 | } | 543 | } |
546 | 544 | ||
547 | can_put_echo_skb(skb, dev, 0); | 545 | can_put_echo_skb(skb, dev, 0); |
548 | 546 | ||
549 | priv->write(can_id, &priv->tx_mb->can_id); | 547 | priv->write(can_id, ®s->mb[FLEXCAN_TX_MB].can_id); |
550 | priv->write(ctrl, &priv->tx_mb->can_ctrl); | 548 | priv->write(ctrl, ®s->mb[FLEXCAN_TX_MB].can_ctrl); |
551 | 549 | ||
552 | /* Errata ERR005829 step8: | 550 | /* Errata ERR005829 step8: |
553 | * Write twice INACTIVE(0x8) code to first MB. | 551 | * Write twice INACTIVE(0x8) code to first MB. |
@@ -563,9 +561,13 @@ static netdev_tx_t flexcan_start_xmit(struct sk_buff *skb, struct net_device *de | |||
563 | static void flexcan_irq_bus_err(struct net_device *dev, u32 reg_esr) | 561 | static void flexcan_irq_bus_err(struct net_device *dev, u32 reg_esr) |
564 | { | 562 | { |
565 | struct flexcan_priv *priv = netdev_priv(dev); | 563 | struct flexcan_priv *priv = netdev_priv(dev); |
564 | struct flexcan_regs __iomem *regs = priv->regs; | ||
566 | struct sk_buff *skb; | 565 | struct sk_buff *skb; |
567 | struct can_frame *cf; | 566 | struct can_frame *cf; |
568 | bool rx_errors = false, tx_errors = false; | 567 | bool rx_errors = false, tx_errors = false; |
568 | u32 timestamp; | ||
569 | |||
570 | timestamp = priv->read(®s->timer) << 16; | ||
569 | 571 | ||
570 | skb = alloc_can_err_skb(dev, &cf); | 572 | skb = alloc_can_err_skb(dev, &cf); |
571 | if (unlikely(!skb)) | 573 | if (unlikely(!skb)) |
@@ -612,17 +614,21 @@ static void flexcan_irq_bus_err(struct net_device *dev, u32 reg_esr) | |||
612 | if (tx_errors) | 614 | if (tx_errors) |
613 | dev->stats.tx_errors++; | 615 | dev->stats.tx_errors++; |
614 | 616 | ||
615 | can_rx_offload_irq_queue_err_skb(&priv->offload, skb); | 617 | can_rx_offload_queue_sorted(&priv->offload, skb, timestamp); |
616 | } | 618 | } |
617 | 619 | ||
618 | static void flexcan_irq_state(struct net_device *dev, u32 reg_esr) | 620 | static void flexcan_irq_state(struct net_device *dev, u32 reg_esr) |
619 | { | 621 | { |
620 | struct flexcan_priv *priv = netdev_priv(dev); | 622 | struct flexcan_priv *priv = netdev_priv(dev); |
623 | struct flexcan_regs __iomem *regs = priv->regs; | ||
621 | struct sk_buff *skb; | 624 | struct sk_buff *skb; |
622 | struct can_frame *cf; | 625 | struct can_frame *cf; |
623 | enum can_state new_state, rx_state, tx_state; | 626 | enum can_state new_state, rx_state, tx_state; |
624 | int flt; | 627 | int flt; |
625 | struct can_berr_counter bec; | 628 | struct can_berr_counter bec; |
629 | u32 timestamp; | ||
630 | |||
631 | timestamp = priv->read(®s->timer) << 16; | ||
626 | 632 | ||
627 | flt = reg_esr & FLEXCAN_ESR_FLT_CONF_MASK; | 633 | flt = reg_esr & FLEXCAN_ESR_FLT_CONF_MASK; |
628 | if (likely(flt == FLEXCAN_ESR_FLT_CONF_ACTIVE)) { | 634 | if (likely(flt == FLEXCAN_ESR_FLT_CONF_ACTIVE)) { |
@@ -652,7 +658,7 @@ static void flexcan_irq_state(struct net_device *dev, u32 reg_esr) | |||
652 | if (unlikely(new_state == CAN_STATE_BUS_OFF)) | 658 | if (unlikely(new_state == CAN_STATE_BUS_OFF)) |
653 | can_bus_off(dev); | 659 | can_bus_off(dev); |
654 | 660 | ||
655 | can_rx_offload_irq_queue_err_skb(&priv->offload, skb); | 661 | can_rx_offload_queue_sorted(&priv->offload, skb, timestamp); |
656 | } | 662 | } |
657 | 663 | ||
658 | static inline struct flexcan_priv *rx_offload_to_priv(struct can_rx_offload *offload) | 664 | static inline struct flexcan_priv *rx_offload_to_priv(struct can_rx_offload *offload) |
@@ -720,9 +726,14 @@ static unsigned int flexcan_mailbox_read(struct can_rx_offload *offload, | |||
720 | priv->write(BIT(n - 32), ®s->iflag2); | 726 | priv->write(BIT(n - 32), ®s->iflag2); |
721 | } else { | 727 | } else { |
722 | priv->write(FLEXCAN_IFLAG_RX_FIFO_AVAILABLE, ®s->iflag1); | 728 | priv->write(FLEXCAN_IFLAG_RX_FIFO_AVAILABLE, ®s->iflag1); |
723 | priv->read(®s->timer); | ||
724 | } | 729 | } |
725 | 730 | ||
731 | /* Read the Free Running Timer. It is optional but recommended | ||
732 | * to unlock Mailbox as soon as possible and make it available | ||
733 | * for reception. | ||
734 | */ | ||
735 | priv->read(®s->timer); | ||
736 | |||
726 | return 1; | 737 | return 1; |
727 | } | 738 | } |
728 | 739 | ||
@@ -732,9 +743,9 @@ static inline u64 flexcan_read_reg_iflag_rx(struct flexcan_priv *priv) | |||
732 | struct flexcan_regs __iomem *regs = priv->regs; | 743 | struct flexcan_regs __iomem *regs = priv->regs; |
733 | u32 iflag1, iflag2; | 744 | u32 iflag1, iflag2; |
734 | 745 | ||
735 | iflag2 = priv->read(®s->iflag2) & priv->reg_imask2_default; | 746 | iflag2 = priv->read(®s->iflag2) & priv->reg_imask2_default & |
736 | iflag1 = priv->read(®s->iflag1) & priv->reg_imask1_default & | 747 | ~FLEXCAN_IFLAG_MB(FLEXCAN_TX_MB); |
737 | ~FLEXCAN_IFLAG_MB(priv->tx_mb_idx); | 748 | iflag1 = priv->read(®s->iflag1) & priv->reg_imask1_default; |
738 | 749 | ||
739 | return (u64)iflag2 << 32 | iflag1; | 750 | return (u64)iflag2 << 32 | iflag1; |
740 | } | 751 | } |
@@ -746,11 +757,9 @@ static irqreturn_t flexcan_irq(int irq, void *dev_id) | |||
746 | struct flexcan_priv *priv = netdev_priv(dev); | 757 | struct flexcan_priv *priv = netdev_priv(dev); |
747 | struct flexcan_regs __iomem *regs = priv->regs; | 758 | struct flexcan_regs __iomem *regs = priv->regs; |
748 | irqreturn_t handled = IRQ_NONE; | 759 | irqreturn_t handled = IRQ_NONE; |
749 | u32 reg_iflag1, reg_esr; | 760 | u32 reg_iflag2, reg_esr; |
750 | enum can_state last_state = priv->can.state; | 761 | enum can_state last_state = priv->can.state; |
751 | 762 | ||
752 | reg_iflag1 = priv->read(®s->iflag1); | ||
753 | |||
754 | /* reception interrupt */ | 763 | /* reception interrupt */ |
755 | if (priv->devtype_data->quirks & FLEXCAN_QUIRK_USE_OFF_TIMESTAMP) { | 764 | if (priv->devtype_data->quirks & FLEXCAN_QUIRK_USE_OFF_TIMESTAMP) { |
756 | u64 reg_iflag; | 765 | u64 reg_iflag; |
@@ -764,6 +773,9 @@ static irqreturn_t flexcan_irq(int irq, void *dev_id) | |||
764 | break; | 773 | break; |
765 | } | 774 | } |
766 | } else { | 775 | } else { |
776 | u32 reg_iflag1; | ||
777 | |||
778 | reg_iflag1 = priv->read(®s->iflag1); | ||
767 | if (reg_iflag1 & FLEXCAN_IFLAG_RX_FIFO_AVAILABLE) { | 779 | if (reg_iflag1 & FLEXCAN_IFLAG_RX_FIFO_AVAILABLE) { |
768 | handled = IRQ_HANDLED; | 780 | handled = IRQ_HANDLED; |
769 | can_rx_offload_irq_offload_fifo(&priv->offload); | 781 | can_rx_offload_irq_offload_fifo(&priv->offload); |
@@ -779,17 +791,22 @@ static irqreturn_t flexcan_irq(int irq, void *dev_id) | |||
779 | } | 791 | } |
780 | } | 792 | } |
781 | 793 | ||
794 | reg_iflag2 = priv->read(®s->iflag2); | ||
795 | |||
782 | /* transmission complete interrupt */ | 796 | /* transmission complete interrupt */ |
783 | if (reg_iflag1 & FLEXCAN_IFLAG_MB(priv->tx_mb_idx)) { | 797 | if (reg_iflag2 & FLEXCAN_IFLAG_MB(FLEXCAN_TX_MB)) { |
798 | u32 reg_ctrl = priv->read(®s->mb[FLEXCAN_TX_MB].can_ctrl); | ||
799 | |||
784 | handled = IRQ_HANDLED; | 800 | handled = IRQ_HANDLED; |
785 | stats->tx_bytes += can_get_echo_skb(dev, 0); | 801 | stats->tx_bytes += can_rx_offload_get_echo_skb(&priv->offload, |
802 | 0, reg_ctrl << 16); | ||
786 | stats->tx_packets++; | 803 | stats->tx_packets++; |
787 | can_led_event(dev, CAN_LED_EVENT_TX); | 804 | can_led_event(dev, CAN_LED_EVENT_TX); |
788 | 805 | ||
789 | /* after sending a RTR frame MB is in RX mode */ | 806 | /* after sending a RTR frame MB is in RX mode */ |
790 | priv->write(FLEXCAN_MB_CODE_TX_INACTIVE, | 807 | priv->write(FLEXCAN_MB_CODE_TX_INACTIVE, |
791 | &priv->tx_mb->can_ctrl); | 808 | ®s->mb[FLEXCAN_TX_MB].can_ctrl); |
792 | priv->write(FLEXCAN_IFLAG_MB(priv->tx_mb_idx), ®s->iflag1); | 809 | priv->write(FLEXCAN_IFLAG_MB(FLEXCAN_TX_MB), ®s->iflag2); |
793 | netif_wake_queue(dev); | 810 | netif_wake_queue(dev); |
794 | } | 811 | } |
795 | 812 | ||
@@ -931,15 +948,13 @@ static int flexcan_chip_start(struct net_device *dev) | |||
931 | reg_mcr &= ~FLEXCAN_MCR_MAXMB(0xff); | 948 | reg_mcr &= ~FLEXCAN_MCR_MAXMB(0xff); |
932 | reg_mcr |= FLEXCAN_MCR_FRZ | FLEXCAN_MCR_HALT | FLEXCAN_MCR_SUPV | | 949 | reg_mcr |= FLEXCAN_MCR_FRZ | FLEXCAN_MCR_HALT | FLEXCAN_MCR_SUPV | |
933 | FLEXCAN_MCR_WRN_EN | FLEXCAN_MCR_SRX_DIS | FLEXCAN_MCR_IRMQ | | 950 | FLEXCAN_MCR_WRN_EN | FLEXCAN_MCR_SRX_DIS | FLEXCAN_MCR_IRMQ | |
934 | FLEXCAN_MCR_IDAM_C; | 951 | FLEXCAN_MCR_IDAM_C | FLEXCAN_MCR_MAXMB(FLEXCAN_TX_MB); |
935 | 952 | ||
936 | if (priv->devtype_data->quirks & FLEXCAN_QUIRK_USE_OFF_TIMESTAMP) { | 953 | if (priv->devtype_data->quirks & FLEXCAN_QUIRK_USE_OFF_TIMESTAMP) |
937 | reg_mcr &= ~FLEXCAN_MCR_FEN; | 954 | reg_mcr &= ~FLEXCAN_MCR_FEN; |
938 | reg_mcr |= FLEXCAN_MCR_MAXMB(priv->offload.mb_last); | 955 | else |
939 | } else { | 956 | reg_mcr |= FLEXCAN_MCR_FEN; |
940 | reg_mcr |= FLEXCAN_MCR_FEN | | 957 | |
941 | FLEXCAN_MCR_MAXMB(priv->tx_mb_idx); | ||
942 | } | ||
943 | netdev_dbg(dev, "%s: writing mcr=0x%08x", __func__, reg_mcr); | 958 | netdev_dbg(dev, "%s: writing mcr=0x%08x", __func__, reg_mcr); |
944 | priv->write(reg_mcr, ®s->mcr); | 959 | priv->write(reg_mcr, ®s->mcr); |
945 | 960 | ||
@@ -982,16 +997,17 @@ static int flexcan_chip_start(struct net_device *dev) | |||
982 | priv->write(reg_ctrl2, ®s->ctrl2); | 997 | priv->write(reg_ctrl2, ®s->ctrl2); |
983 | } | 998 | } |
984 | 999 | ||
985 | /* clear and invalidate all mailboxes first */ | ||
986 | for (i = priv->tx_mb_idx; i < ARRAY_SIZE(regs->mb); i++) { | ||
987 | priv->write(FLEXCAN_MB_CODE_RX_INACTIVE, | ||
988 | ®s->mb[i].can_ctrl); | ||
989 | } | ||
990 | |||
991 | if (priv->devtype_data->quirks & FLEXCAN_QUIRK_USE_OFF_TIMESTAMP) { | 1000 | if (priv->devtype_data->quirks & FLEXCAN_QUIRK_USE_OFF_TIMESTAMP) { |
992 | for (i = priv->offload.mb_first; i <= priv->offload.mb_last; i++) | 1001 | for (i = priv->offload.mb_first; i <= priv->offload.mb_last; i++) { |
993 | priv->write(FLEXCAN_MB_CODE_RX_EMPTY, | 1002 | priv->write(FLEXCAN_MB_CODE_RX_EMPTY, |
994 | ®s->mb[i].can_ctrl); | 1003 | ®s->mb[i].can_ctrl); |
1004 | } | ||
1005 | } else { | ||
1006 | /* clear and invalidate unused mailboxes first */ | ||
1007 | for (i = FLEXCAN_TX_MB_RESERVED_OFF_FIFO; i <= ARRAY_SIZE(regs->mb); i++) { | ||
1008 | priv->write(FLEXCAN_MB_CODE_RX_INACTIVE, | ||
1009 | ®s->mb[i].can_ctrl); | ||
1010 | } | ||
995 | } | 1011 | } |
996 | 1012 | ||
997 | /* Errata ERR005829: mark first TX mailbox as INACTIVE */ | 1013 | /* Errata ERR005829: mark first TX mailbox as INACTIVE */ |
@@ -1000,7 +1016,7 @@ static int flexcan_chip_start(struct net_device *dev) | |||
1000 | 1016 | ||
1001 | /* mark TX mailbox as INACTIVE */ | 1017 | /* mark TX mailbox as INACTIVE */ |
1002 | priv->write(FLEXCAN_MB_CODE_TX_INACTIVE, | 1018 | priv->write(FLEXCAN_MB_CODE_TX_INACTIVE, |
1003 | &priv->tx_mb->can_ctrl); | 1019 | ®s->mb[FLEXCAN_TX_MB].can_ctrl); |
1004 | 1020 | ||
1005 | /* acceptance mask/acceptance code (accept everything) */ | 1021 | /* acceptance mask/acceptance code (accept everything) */ |
1006 | priv->write(0x0, ®s->rxgmask); | 1022 | priv->write(0x0, ®s->rxgmask); |
@@ -1355,17 +1371,13 @@ static int flexcan_probe(struct platform_device *pdev) | |||
1355 | priv->devtype_data = devtype_data; | 1371 | priv->devtype_data = devtype_data; |
1356 | priv->reg_xceiver = reg_xceiver; | 1372 | priv->reg_xceiver = reg_xceiver; |
1357 | 1373 | ||
1358 | if (priv->devtype_data->quirks & FLEXCAN_QUIRK_USE_OFF_TIMESTAMP) { | 1374 | if (priv->devtype_data->quirks & FLEXCAN_QUIRK_USE_OFF_TIMESTAMP) |
1359 | priv->tx_mb_idx = FLEXCAN_TX_MB_OFF_TIMESTAMP; | ||
1360 | priv->tx_mb_reserved = ®s->mb[FLEXCAN_TX_MB_RESERVED_OFF_TIMESTAMP]; | 1375 | priv->tx_mb_reserved = ®s->mb[FLEXCAN_TX_MB_RESERVED_OFF_TIMESTAMP]; |
1361 | } else { | 1376 | else |
1362 | priv->tx_mb_idx = FLEXCAN_TX_MB_OFF_FIFO; | ||
1363 | priv->tx_mb_reserved = ®s->mb[FLEXCAN_TX_MB_RESERVED_OFF_FIFO]; | 1377 | priv->tx_mb_reserved = ®s->mb[FLEXCAN_TX_MB_RESERVED_OFF_FIFO]; |
1364 | } | ||
1365 | priv->tx_mb = ®s->mb[priv->tx_mb_idx]; | ||
1366 | 1378 | ||
1367 | priv->reg_imask1_default = FLEXCAN_IFLAG_MB(priv->tx_mb_idx); | 1379 | priv->reg_imask1_default = 0; |
1368 | priv->reg_imask2_default = 0; | 1380 | priv->reg_imask2_default = FLEXCAN_IFLAG_MB(FLEXCAN_TX_MB); |
1369 | 1381 | ||
1370 | priv->offload.mailbox_read = flexcan_mailbox_read; | 1382 | priv->offload.mailbox_read = flexcan_mailbox_read; |
1371 | 1383 | ||
diff --git a/drivers/net/can/rcar/rcar_can.c b/drivers/net/can/rcar/rcar_can.c index 11662f479e76..771a46083739 100644 --- a/drivers/net/can/rcar/rcar_can.c +++ b/drivers/net/can/rcar/rcar_can.c | |||
@@ -24,6 +24,9 @@ | |||
24 | 24 | ||
25 | #define RCAR_CAN_DRV_NAME "rcar_can" | 25 | #define RCAR_CAN_DRV_NAME "rcar_can" |
26 | 26 | ||
27 | #define RCAR_SUPPORTED_CLOCKS (BIT(CLKR_CLKP1) | BIT(CLKR_CLKP2) | \ | ||
28 | BIT(CLKR_CLKEXT)) | ||
29 | |||
27 | /* Mailbox configuration: | 30 | /* Mailbox configuration: |
28 | * mailbox 60 - 63 - Rx FIFO mailboxes | 31 | * mailbox 60 - 63 - Rx FIFO mailboxes |
29 | * mailbox 56 - 59 - Tx FIFO mailboxes | 32 | * mailbox 56 - 59 - Tx FIFO mailboxes |
@@ -789,7 +792,7 @@ static int rcar_can_probe(struct platform_device *pdev) | |||
789 | goto fail_clk; | 792 | goto fail_clk; |
790 | } | 793 | } |
791 | 794 | ||
792 | if (clock_select >= ARRAY_SIZE(clock_names)) { | 795 | if (!(BIT(clock_select) & RCAR_SUPPORTED_CLOCKS)) { |
793 | err = -EINVAL; | 796 | err = -EINVAL; |
794 | dev_err(&pdev->dev, "invalid CAN clock selected\n"); | 797 | dev_err(&pdev->dev, "invalid CAN clock selected\n"); |
795 | goto fail_clk; | 798 | goto fail_clk; |
diff --git a/drivers/net/can/rx-offload.c b/drivers/net/can/rx-offload.c index c7d05027a7a0..2ce4fa8698c7 100644 --- a/drivers/net/can/rx-offload.c +++ b/drivers/net/can/rx-offload.c | |||
@@ -211,7 +211,54 @@ int can_rx_offload_irq_offload_fifo(struct can_rx_offload *offload) | |||
211 | } | 211 | } |
212 | EXPORT_SYMBOL_GPL(can_rx_offload_irq_offload_fifo); | 212 | EXPORT_SYMBOL_GPL(can_rx_offload_irq_offload_fifo); |
213 | 213 | ||
214 | int can_rx_offload_irq_queue_err_skb(struct can_rx_offload *offload, struct sk_buff *skb) | 214 | int can_rx_offload_queue_sorted(struct can_rx_offload *offload, |
215 | struct sk_buff *skb, u32 timestamp) | ||
216 | { | ||
217 | struct can_rx_offload_cb *cb; | ||
218 | unsigned long flags; | ||
219 | |||
220 | if (skb_queue_len(&offload->skb_queue) > | ||
221 | offload->skb_queue_len_max) | ||
222 | return -ENOMEM; | ||
223 | |||
224 | cb = can_rx_offload_get_cb(skb); | ||
225 | cb->timestamp = timestamp; | ||
226 | |||
227 | spin_lock_irqsave(&offload->skb_queue.lock, flags); | ||
228 | __skb_queue_add_sort(&offload->skb_queue, skb, can_rx_offload_compare); | ||
229 | spin_unlock_irqrestore(&offload->skb_queue.lock, flags); | ||
230 | |||
231 | can_rx_offload_schedule(offload); | ||
232 | |||
233 | return 0; | ||
234 | } | ||
235 | EXPORT_SYMBOL_GPL(can_rx_offload_queue_sorted); | ||
236 | |||
237 | unsigned int can_rx_offload_get_echo_skb(struct can_rx_offload *offload, | ||
238 | unsigned int idx, u32 timestamp) | ||
239 | { | ||
240 | struct net_device *dev = offload->dev; | ||
241 | struct net_device_stats *stats = &dev->stats; | ||
242 | struct sk_buff *skb; | ||
243 | u8 len; | ||
244 | int err; | ||
245 | |||
246 | skb = __can_get_echo_skb(dev, idx, &len); | ||
247 | if (!skb) | ||
248 | return 0; | ||
249 | |||
250 | err = can_rx_offload_queue_sorted(offload, skb, timestamp); | ||
251 | if (err) { | ||
252 | stats->rx_errors++; | ||
253 | stats->tx_fifo_errors++; | ||
254 | } | ||
255 | |||
256 | return len; | ||
257 | } | ||
258 | EXPORT_SYMBOL_GPL(can_rx_offload_get_echo_skb); | ||
259 | |||
260 | int can_rx_offload_queue_tail(struct can_rx_offload *offload, | ||
261 | struct sk_buff *skb) | ||
215 | { | 262 | { |
216 | if (skb_queue_len(&offload->skb_queue) > | 263 | if (skb_queue_len(&offload->skb_queue) > |
217 | offload->skb_queue_len_max) | 264 | offload->skb_queue_len_max) |
@@ -222,7 +269,7 @@ int can_rx_offload_irq_queue_err_skb(struct can_rx_offload *offload, struct sk_b | |||
222 | 269 | ||
223 | return 0; | 270 | return 0; |
224 | } | 271 | } |
225 | EXPORT_SYMBOL_GPL(can_rx_offload_irq_queue_err_skb); | 272 | EXPORT_SYMBOL_GPL(can_rx_offload_queue_tail); |
226 | 273 | ||
227 | static int can_rx_offload_init_queue(struct net_device *dev, struct can_rx_offload *offload, unsigned int weight) | 274 | static int can_rx_offload_init_queue(struct net_device *dev, struct can_rx_offload *offload, unsigned int weight) |
228 | { | 275 | { |
diff --git a/drivers/net/can/spi/hi311x.c b/drivers/net/can/spi/hi311x.c index 53e320c92a8b..ddaf46239e39 100644 --- a/drivers/net/can/spi/hi311x.c +++ b/drivers/net/can/spi/hi311x.c | |||
@@ -760,7 +760,7 @@ static int hi3110_open(struct net_device *net) | |||
760 | { | 760 | { |
761 | struct hi3110_priv *priv = netdev_priv(net); | 761 | struct hi3110_priv *priv = netdev_priv(net); |
762 | struct spi_device *spi = priv->spi; | 762 | struct spi_device *spi = priv->spi; |
763 | unsigned long flags = IRQF_ONESHOT | IRQF_TRIGGER_RISING; | 763 | unsigned long flags = IRQF_ONESHOT | IRQF_TRIGGER_HIGH; |
764 | int ret; | 764 | int ret; |
765 | 765 | ||
766 | ret = open_candev(net); | 766 | ret = open_candev(net); |
diff --git a/drivers/net/can/usb/kvaser_usb/kvaser_usb_core.c b/drivers/net/can/usb/kvaser_usb/kvaser_usb_core.c index b939a4c10b84..c89c7d4900d7 100644 --- a/drivers/net/can/usb/kvaser_usb/kvaser_usb_core.c +++ b/drivers/net/can/usb/kvaser_usb/kvaser_usb_core.c | |||
@@ -528,7 +528,6 @@ static netdev_tx_t kvaser_usb_start_xmit(struct sk_buff *skb, | |||
528 | context = &priv->tx_contexts[i]; | 528 | context = &priv->tx_contexts[i]; |
529 | 529 | ||
530 | context->echo_index = i; | 530 | context->echo_index = i; |
531 | can_put_echo_skb(skb, netdev, context->echo_index); | ||
532 | ++priv->active_tx_contexts; | 531 | ++priv->active_tx_contexts; |
533 | if (priv->active_tx_contexts >= (int)dev->max_tx_urbs) | 532 | if (priv->active_tx_contexts >= (int)dev->max_tx_urbs) |
534 | netif_stop_queue(netdev); | 533 | netif_stop_queue(netdev); |
@@ -553,7 +552,6 @@ static netdev_tx_t kvaser_usb_start_xmit(struct sk_buff *skb, | |||
553 | dev_kfree_skb(skb); | 552 | dev_kfree_skb(skb); |
554 | spin_lock_irqsave(&priv->tx_contexts_lock, flags); | 553 | spin_lock_irqsave(&priv->tx_contexts_lock, flags); |
555 | 554 | ||
556 | can_free_echo_skb(netdev, context->echo_index); | ||
557 | context->echo_index = dev->max_tx_urbs; | 555 | context->echo_index = dev->max_tx_urbs; |
558 | --priv->active_tx_contexts; | 556 | --priv->active_tx_contexts; |
559 | netif_wake_queue(netdev); | 557 | netif_wake_queue(netdev); |
@@ -564,6 +562,8 @@ static netdev_tx_t kvaser_usb_start_xmit(struct sk_buff *skb, | |||
564 | 562 | ||
565 | context->priv = priv; | 563 | context->priv = priv; |
566 | 564 | ||
565 | can_put_echo_skb(skb, netdev, context->echo_index); | ||
566 | |||
567 | usb_fill_bulk_urb(urb, dev->udev, | 567 | usb_fill_bulk_urb(urb, dev->udev, |
568 | usb_sndbulkpipe(dev->udev, | 568 | usb_sndbulkpipe(dev->udev, |
569 | dev->bulk_out->bEndpointAddress), | 569 | dev->bulk_out->bEndpointAddress), |
diff --git a/drivers/net/can/usb/kvaser_usb/kvaser_usb_hydra.c b/drivers/net/can/usb/kvaser_usb/kvaser_usb_hydra.c index c084bae5ec0a..5fc0be564274 100644 --- a/drivers/net/can/usb/kvaser_usb/kvaser_usb_hydra.c +++ b/drivers/net/can/usb/kvaser_usb/kvaser_usb_hydra.c | |||
@@ -1019,6 +1019,11 @@ kvaser_usb_hydra_error_frame(struct kvaser_usb_net_priv *priv, | |||
1019 | new_state : CAN_STATE_ERROR_ACTIVE; | 1019 | new_state : CAN_STATE_ERROR_ACTIVE; |
1020 | 1020 | ||
1021 | can_change_state(netdev, cf, tx_state, rx_state); | 1021 | can_change_state(netdev, cf, tx_state, rx_state); |
1022 | |||
1023 | if (priv->can.restart_ms && | ||
1024 | old_state >= CAN_STATE_BUS_OFF && | ||
1025 | new_state < CAN_STATE_BUS_OFF) | ||
1026 | cf->can_id |= CAN_ERR_RESTARTED; | ||
1022 | } | 1027 | } |
1023 | 1028 | ||
1024 | if (new_state == CAN_STATE_BUS_OFF) { | 1029 | if (new_state == CAN_STATE_BUS_OFF) { |
@@ -1028,11 +1033,6 @@ kvaser_usb_hydra_error_frame(struct kvaser_usb_net_priv *priv, | |||
1028 | 1033 | ||
1029 | can_bus_off(netdev); | 1034 | can_bus_off(netdev); |
1030 | } | 1035 | } |
1031 | |||
1032 | if (priv->can.restart_ms && | ||
1033 | old_state >= CAN_STATE_BUS_OFF && | ||
1034 | new_state < CAN_STATE_BUS_OFF) | ||
1035 | cf->can_id |= CAN_ERR_RESTARTED; | ||
1036 | } | 1036 | } |
1037 | 1037 | ||
1038 | if (!skb) { | 1038 | if (!skb) { |
diff --git a/drivers/net/can/usb/ucan.c b/drivers/net/can/usb/ucan.c index 0678a38b1af4..f3d5bda012a1 100644 --- a/drivers/net/can/usb/ucan.c +++ b/drivers/net/can/usb/ucan.c | |||
@@ -35,10 +35,6 @@ | |||
35 | #include <linux/slab.h> | 35 | #include <linux/slab.h> |
36 | #include <linux/usb.h> | 36 | #include <linux/usb.h> |
37 | 37 | ||
38 | #include <linux/can.h> | ||
39 | #include <linux/can/dev.h> | ||
40 | #include <linux/can/error.h> | ||
41 | |||
42 | #define UCAN_DRIVER_NAME "ucan" | 38 | #define UCAN_DRIVER_NAME "ucan" |
43 | #define UCAN_MAX_RX_URBS 8 | 39 | #define UCAN_MAX_RX_URBS 8 |
44 | /* the CAN controller needs a while to enable/disable the bus */ | 40 | /* the CAN controller needs a while to enable/disable the bus */ |
@@ -1575,11 +1571,8 @@ err_firmware_needs_update: | |||
1575 | /* disconnect the device */ | 1571 | /* disconnect the device */ |
1576 | static void ucan_disconnect(struct usb_interface *intf) | 1572 | static void ucan_disconnect(struct usb_interface *intf) |
1577 | { | 1573 | { |
1578 | struct usb_device *udev; | ||
1579 | struct ucan_priv *up = usb_get_intfdata(intf); | 1574 | struct ucan_priv *up = usb_get_intfdata(intf); |
1580 | 1575 | ||
1581 | udev = interface_to_usbdev(intf); | ||
1582 | |||
1583 | usb_set_intfdata(intf, NULL); | 1576 | usb_set_intfdata(intf, NULL); |
1584 | 1577 | ||
1585 | if (up) { | 1578 | if (up) { |
diff --git a/drivers/net/ethernet/amazon/ena/ena_netdev.c b/drivers/net/ethernet/amazon/ena/ena_netdev.c index 18956e7604a3..a70bb1bb90e7 100644 --- a/drivers/net/ethernet/amazon/ena/ena_netdev.c +++ b/drivers/net/ethernet/amazon/ena/ena_netdev.c | |||
@@ -1848,6 +1848,8 @@ static void ena_down(struct ena_adapter *adapter) | |||
1848 | rc = ena_com_dev_reset(adapter->ena_dev, adapter->reset_reason); | 1848 | rc = ena_com_dev_reset(adapter->ena_dev, adapter->reset_reason); |
1849 | if (rc) | 1849 | if (rc) |
1850 | dev_err(&adapter->pdev->dev, "Device reset failed\n"); | 1850 | dev_err(&adapter->pdev->dev, "Device reset failed\n"); |
1851 | /* stop submitting admin commands on a device that was reset */ | ||
1852 | ena_com_set_admin_running_state(adapter->ena_dev, false); | ||
1851 | } | 1853 | } |
1852 | 1854 | ||
1853 | ena_destroy_all_io_queues(adapter); | 1855 | ena_destroy_all_io_queues(adapter); |
@@ -1914,6 +1916,9 @@ static int ena_close(struct net_device *netdev) | |||
1914 | 1916 | ||
1915 | netif_dbg(adapter, ifdown, netdev, "%s\n", __func__); | 1917 | netif_dbg(adapter, ifdown, netdev, "%s\n", __func__); |
1916 | 1918 | ||
1919 | if (!test_bit(ENA_FLAG_DEVICE_RUNNING, &adapter->flags)) | ||
1920 | return 0; | ||
1921 | |||
1917 | if (test_bit(ENA_FLAG_DEV_UP, &adapter->flags)) | 1922 | if (test_bit(ENA_FLAG_DEV_UP, &adapter->flags)) |
1918 | ena_down(adapter); | 1923 | ena_down(adapter); |
1919 | 1924 | ||
@@ -2613,9 +2618,7 @@ static void ena_destroy_device(struct ena_adapter *adapter, bool graceful) | |||
2613 | ena_down(adapter); | 2618 | ena_down(adapter); |
2614 | 2619 | ||
2615 | /* Stop the device from sending AENQ events (in case reset flag is set | 2620 | /* Stop the device from sending AENQ events (in case reset flag is set |
2616 | * and device is up, ena_close already reset the device | 2621 | * and device is up, ena_down() already reset the device. |
2617 | * In case the reset flag is set and the device is up, ena_down() | ||
2618 | * already perform the reset, so it can be skipped. | ||
2619 | */ | 2622 | */ |
2620 | if (!(test_bit(ENA_FLAG_TRIGGER_RESET, &adapter->flags) && dev_up)) | 2623 | if (!(test_bit(ENA_FLAG_TRIGGER_RESET, &adapter->flags) && dev_up)) |
2621 | ena_com_dev_reset(adapter->ena_dev, adapter->reset_reason); | 2624 | ena_com_dev_reset(adapter->ena_dev, adapter->reset_reason); |
@@ -2694,8 +2697,8 @@ err_device_destroy: | |||
2694 | ena_com_abort_admin_commands(ena_dev); | 2697 | ena_com_abort_admin_commands(ena_dev); |
2695 | ena_com_wait_for_abort_completion(ena_dev); | 2698 | ena_com_wait_for_abort_completion(ena_dev); |
2696 | ena_com_admin_destroy(ena_dev); | 2699 | ena_com_admin_destroy(ena_dev); |
2697 | ena_com_mmio_reg_read_request_destroy(ena_dev); | ||
2698 | ena_com_dev_reset(ena_dev, ENA_REGS_RESET_DRIVER_INVALID_STATE); | 2700 | ena_com_dev_reset(ena_dev, ENA_REGS_RESET_DRIVER_INVALID_STATE); |
2701 | ena_com_mmio_reg_read_request_destroy(ena_dev); | ||
2699 | err: | 2702 | err: |
2700 | clear_bit(ENA_FLAG_DEVICE_RUNNING, &adapter->flags); | 2703 | clear_bit(ENA_FLAG_DEVICE_RUNNING, &adapter->flags); |
2701 | clear_bit(ENA_FLAG_ONGOING_RESET, &adapter->flags); | 2704 | clear_bit(ENA_FLAG_ONGOING_RESET, &adapter->flags); |
@@ -3452,6 +3455,8 @@ err_rss: | |||
3452 | ena_com_rss_destroy(ena_dev); | 3455 | ena_com_rss_destroy(ena_dev); |
3453 | err_free_msix: | 3456 | err_free_msix: |
3454 | ena_com_dev_reset(ena_dev, ENA_REGS_RESET_INIT_ERR); | 3457 | ena_com_dev_reset(ena_dev, ENA_REGS_RESET_INIT_ERR); |
3458 | /* stop submitting admin commands on a device that was reset */ | ||
3459 | ena_com_set_admin_running_state(ena_dev, false); | ||
3455 | ena_free_mgmnt_irq(adapter); | 3460 | ena_free_mgmnt_irq(adapter); |
3456 | ena_disable_msix(adapter); | 3461 | ena_disable_msix(adapter); |
3457 | err_worker_destroy: | 3462 | err_worker_destroy: |
@@ -3498,18 +3503,12 @@ static void ena_remove(struct pci_dev *pdev) | |||
3498 | 3503 | ||
3499 | cancel_work_sync(&adapter->reset_task); | 3504 | cancel_work_sync(&adapter->reset_task); |
3500 | 3505 | ||
3501 | unregister_netdev(netdev); | ||
3502 | |||
3503 | /* If the device is running then we want to make sure the device will be | ||
3504 | * reset to make sure no more events will be issued by the device. | ||
3505 | */ | ||
3506 | if (test_bit(ENA_FLAG_DEVICE_RUNNING, &adapter->flags)) | ||
3507 | set_bit(ENA_FLAG_TRIGGER_RESET, &adapter->flags); | ||
3508 | |||
3509 | rtnl_lock(); | 3506 | rtnl_lock(); |
3510 | ena_destroy_device(adapter, true); | 3507 | ena_destroy_device(adapter, true); |
3511 | rtnl_unlock(); | 3508 | rtnl_unlock(); |
3512 | 3509 | ||
3510 | unregister_netdev(netdev); | ||
3511 | |||
3513 | free_netdev(netdev); | 3512 | free_netdev(netdev); |
3514 | 3513 | ||
3515 | ena_com_rss_destroy(ena_dev); | 3514 | ena_com_rss_destroy(ena_dev); |
diff --git a/drivers/net/ethernet/amazon/ena/ena_netdev.h b/drivers/net/ethernet/amazon/ena/ena_netdev.h index 521873642339..dc8b6173d8d8 100644 --- a/drivers/net/ethernet/amazon/ena/ena_netdev.h +++ b/drivers/net/ethernet/amazon/ena/ena_netdev.h | |||
@@ -45,7 +45,7 @@ | |||
45 | 45 | ||
46 | #define DRV_MODULE_VER_MAJOR 2 | 46 | #define DRV_MODULE_VER_MAJOR 2 |
47 | #define DRV_MODULE_VER_MINOR 0 | 47 | #define DRV_MODULE_VER_MINOR 0 |
48 | #define DRV_MODULE_VER_SUBMINOR 1 | 48 | #define DRV_MODULE_VER_SUBMINOR 2 |
49 | 49 | ||
50 | #define DRV_MODULE_NAME "ena" | 50 | #define DRV_MODULE_NAME "ena" |
51 | #ifndef DRV_MODULE_VERSION | 51 | #ifndef DRV_MODULE_VERSION |
diff --git a/drivers/net/ethernet/amd/sunlance.c b/drivers/net/ethernet/amd/sunlance.c index b4fc0ed5bce8..9d4899826823 100644 --- a/drivers/net/ethernet/amd/sunlance.c +++ b/drivers/net/ethernet/amd/sunlance.c | |||
@@ -1419,7 +1419,7 @@ static int sparc_lance_probe_one(struct platform_device *op, | |||
1419 | 1419 | ||
1420 | prop = of_get_property(nd, "tpe-link-test?", NULL); | 1420 | prop = of_get_property(nd, "tpe-link-test?", NULL); |
1421 | if (!prop) | 1421 | if (!prop) |
1422 | goto no_link_test; | 1422 | goto node_put; |
1423 | 1423 | ||
1424 | if (strcmp(prop, "true")) { | 1424 | if (strcmp(prop, "true")) { |
1425 | printk(KERN_NOTICE "SunLance: warning: overriding option " | 1425 | printk(KERN_NOTICE "SunLance: warning: overriding option " |
@@ -1428,6 +1428,8 @@ static int sparc_lance_probe_one(struct platform_device *op, | |||
1428 | "to ecd@skynet.be\n"); | 1428 | "to ecd@skynet.be\n"); |
1429 | auxio_set_lte(AUXIO_LTE_ON); | 1429 | auxio_set_lte(AUXIO_LTE_ON); |
1430 | } | 1430 | } |
1431 | node_put: | ||
1432 | of_node_put(nd); | ||
1431 | no_link_test: | 1433 | no_link_test: |
1432 | lp->auto_select = 1; | 1434 | lp->auto_select = 1; |
1433 | lp->tpe = 0; | 1435 | lp->tpe = 0; |
diff --git a/drivers/net/ethernet/broadcom/bnx2x/bnx2x.h b/drivers/net/ethernet/broadcom/bnx2x/bnx2x.h index be1506169076..0de487a8f0eb 100644 --- a/drivers/net/ethernet/broadcom/bnx2x/bnx2x.h +++ b/drivers/net/ethernet/broadcom/bnx2x/bnx2x.h | |||
@@ -2191,6 +2191,13 @@ void bnx2x_igu_clear_sb_gen(struct bnx2x *bp, u8 func, u8 idu_sb_id, | |||
2191 | #define PMF_DMAE_C(bp) (BP_PORT(bp) * MAX_DMAE_C_PER_PORT + \ | 2191 | #define PMF_DMAE_C(bp) (BP_PORT(bp) * MAX_DMAE_C_PER_PORT + \ |
2192 | E1HVN_MAX) | 2192 | E1HVN_MAX) |
2193 | 2193 | ||
2194 | /* Following is the DMAE channel number allocation for the clients. | ||
2195 | * MFW: OCBB/OCSD implementations use DMAE channels 14/15 respectively. | ||
2196 | * Driver: 0-3 and 8-11 (for PF dmae operations) | ||
2197 | * 4 and 12 (for stats requests) | ||
2198 | */ | ||
2199 | #define BNX2X_FW_DMAE_C 13 /* Channel for FW DMAE operations */ | ||
2200 | |||
2194 | /* PCIE link and speed */ | 2201 | /* PCIE link and speed */ |
2195 | #define PCICFG_LINK_WIDTH 0x1f00000 | 2202 | #define PCICFG_LINK_WIDTH 0x1f00000 |
2196 | #define PCICFG_LINK_WIDTH_SHIFT 20 | 2203 | #define PCICFG_LINK_WIDTH_SHIFT 20 |
diff --git a/drivers/net/ethernet/broadcom/bnx2x/bnx2x_sp.c b/drivers/net/ethernet/broadcom/bnx2x/bnx2x_sp.c index 3f4d2c8da21a..a9eaaf3e73a4 100644 --- a/drivers/net/ethernet/broadcom/bnx2x/bnx2x_sp.c +++ b/drivers/net/ethernet/broadcom/bnx2x/bnx2x_sp.c | |||
@@ -6149,6 +6149,7 @@ static inline int bnx2x_func_send_start(struct bnx2x *bp, | |||
6149 | rdata->sd_vlan_tag = cpu_to_le16(start_params->sd_vlan_tag); | 6149 | rdata->sd_vlan_tag = cpu_to_le16(start_params->sd_vlan_tag); |
6150 | rdata->path_id = BP_PATH(bp); | 6150 | rdata->path_id = BP_PATH(bp); |
6151 | rdata->network_cos_mode = start_params->network_cos_mode; | 6151 | rdata->network_cos_mode = start_params->network_cos_mode; |
6152 | rdata->dmae_cmd_id = BNX2X_FW_DMAE_C; | ||
6152 | 6153 | ||
6153 | rdata->vxlan_dst_port = cpu_to_le16(start_params->vxlan_dst_port); | 6154 | rdata->vxlan_dst_port = cpu_to_le16(start_params->vxlan_dst_port); |
6154 | rdata->geneve_dst_port = cpu_to_le16(start_params->geneve_dst_port); | 6155 | rdata->geneve_dst_port = cpu_to_le16(start_params->geneve_dst_port); |
diff --git a/drivers/net/ethernet/broadcom/bnxt/bnxt.c b/drivers/net/ethernet/broadcom/bnxt/bnxt.c index dd85d790f638..d4c300117529 100644 --- a/drivers/net/ethernet/broadcom/bnxt/bnxt.c +++ b/drivers/net/ethernet/broadcom/bnxt/bnxt.c | |||
@@ -1675,7 +1675,7 @@ static int bnxt_rx_pkt(struct bnxt *bp, struct bnxt_cp_ring_info *cpr, | |||
1675 | } else { | 1675 | } else { |
1676 | if (rxcmp1->rx_cmp_cfa_code_errors_v2 & RX_CMP_L4_CS_ERR_BITS) { | 1676 | if (rxcmp1->rx_cmp_cfa_code_errors_v2 & RX_CMP_L4_CS_ERR_BITS) { |
1677 | if (dev->features & NETIF_F_RXCSUM) | 1677 | if (dev->features & NETIF_F_RXCSUM) |
1678 | cpr->rx_l4_csum_errors++; | 1678 | bnapi->cp_ring.rx_l4_csum_errors++; |
1679 | } | 1679 | } |
1680 | } | 1680 | } |
1681 | 1681 | ||
@@ -8714,6 +8714,26 @@ static int bnxt_set_features(struct net_device *dev, netdev_features_t features) | |||
8714 | return rc; | 8714 | return rc; |
8715 | } | 8715 | } |
8716 | 8716 | ||
8717 | static int bnxt_dbg_hwrm_ring_info_get(struct bnxt *bp, u8 ring_type, | ||
8718 | u32 ring_id, u32 *prod, u32 *cons) | ||
8719 | { | ||
8720 | struct hwrm_dbg_ring_info_get_output *resp = bp->hwrm_cmd_resp_addr; | ||
8721 | struct hwrm_dbg_ring_info_get_input req = {0}; | ||
8722 | int rc; | ||
8723 | |||
8724 | bnxt_hwrm_cmd_hdr_init(bp, &req, HWRM_DBG_RING_INFO_GET, -1, -1); | ||
8725 | req.ring_type = ring_type; | ||
8726 | req.fw_ring_id = cpu_to_le32(ring_id); | ||
8727 | mutex_lock(&bp->hwrm_cmd_lock); | ||
8728 | rc = _hwrm_send_message(bp, &req, sizeof(req), HWRM_CMD_TIMEOUT); | ||
8729 | if (!rc) { | ||
8730 | *prod = le32_to_cpu(resp->producer_index); | ||
8731 | *cons = le32_to_cpu(resp->consumer_index); | ||
8732 | } | ||
8733 | mutex_unlock(&bp->hwrm_cmd_lock); | ||
8734 | return rc; | ||
8735 | } | ||
8736 | |||
8717 | static void bnxt_dump_tx_sw_state(struct bnxt_napi *bnapi) | 8737 | static void bnxt_dump_tx_sw_state(struct bnxt_napi *bnapi) |
8718 | { | 8738 | { |
8719 | struct bnxt_tx_ring_info *txr = bnapi->tx_ring; | 8739 | struct bnxt_tx_ring_info *txr = bnapi->tx_ring; |
@@ -8821,6 +8841,11 @@ static void bnxt_timer(struct timer_list *t) | |||
8821 | bnxt_queue_sp_work(bp); | 8841 | bnxt_queue_sp_work(bp); |
8822 | } | 8842 | } |
8823 | } | 8843 | } |
8844 | |||
8845 | if ((bp->flags & BNXT_FLAG_CHIP_P5) && netif_carrier_ok(dev)) { | ||
8846 | set_bit(BNXT_RING_COAL_NOW_SP_EVENT, &bp->sp_event); | ||
8847 | bnxt_queue_sp_work(bp); | ||
8848 | } | ||
8824 | bnxt_restart_timer: | 8849 | bnxt_restart_timer: |
8825 | mod_timer(&bp->timer, jiffies + bp->current_interval); | 8850 | mod_timer(&bp->timer, jiffies + bp->current_interval); |
8826 | } | 8851 | } |
@@ -8851,6 +8876,44 @@ static void bnxt_reset(struct bnxt *bp, bool silent) | |||
8851 | bnxt_rtnl_unlock_sp(bp); | 8876 | bnxt_rtnl_unlock_sp(bp); |
8852 | } | 8877 | } |
8853 | 8878 | ||
8879 | static void bnxt_chk_missed_irq(struct bnxt *bp) | ||
8880 | { | ||
8881 | int i; | ||
8882 | |||
8883 | if (!(bp->flags & BNXT_FLAG_CHIP_P5)) | ||
8884 | return; | ||
8885 | |||
8886 | for (i = 0; i < bp->cp_nr_rings; i++) { | ||
8887 | struct bnxt_napi *bnapi = bp->bnapi[i]; | ||
8888 | struct bnxt_cp_ring_info *cpr; | ||
8889 | u32 fw_ring_id; | ||
8890 | int j; | ||
8891 | |||
8892 | if (!bnapi) | ||
8893 | continue; | ||
8894 | |||
8895 | cpr = &bnapi->cp_ring; | ||
8896 | for (j = 0; j < 2; j++) { | ||
8897 | struct bnxt_cp_ring_info *cpr2 = cpr->cp_ring_arr[j]; | ||
8898 | u32 val[2]; | ||
8899 | |||
8900 | if (!cpr2 || cpr2->has_more_work || | ||
8901 | !bnxt_has_work(bp, cpr2)) | ||
8902 | continue; | ||
8903 | |||
8904 | if (cpr2->cp_raw_cons != cpr2->last_cp_raw_cons) { | ||
8905 | cpr2->last_cp_raw_cons = cpr2->cp_raw_cons; | ||
8906 | continue; | ||
8907 | } | ||
8908 | fw_ring_id = cpr2->cp_ring_struct.fw_ring_id; | ||
8909 | bnxt_dbg_hwrm_ring_info_get(bp, | ||
8910 | DBG_RING_INFO_GET_REQ_RING_TYPE_L2_CMPL, | ||
8911 | fw_ring_id, &val[0], &val[1]); | ||
8912 | cpr->missed_irqs++; | ||
8913 | } | ||
8914 | } | ||
8915 | } | ||
8916 | |||
8854 | static void bnxt_cfg_ntp_filters(struct bnxt *); | 8917 | static void bnxt_cfg_ntp_filters(struct bnxt *); |
8855 | 8918 | ||
8856 | static void bnxt_sp_task(struct work_struct *work) | 8919 | static void bnxt_sp_task(struct work_struct *work) |
@@ -8930,6 +8993,9 @@ static void bnxt_sp_task(struct work_struct *work) | |||
8930 | if (test_and_clear_bit(BNXT_FLOW_STATS_SP_EVENT, &bp->sp_event)) | 8993 | if (test_and_clear_bit(BNXT_FLOW_STATS_SP_EVENT, &bp->sp_event)) |
8931 | bnxt_tc_flow_stats_work(bp); | 8994 | bnxt_tc_flow_stats_work(bp); |
8932 | 8995 | ||
8996 | if (test_and_clear_bit(BNXT_RING_COAL_NOW_SP_EVENT, &bp->sp_event)) | ||
8997 | bnxt_chk_missed_irq(bp); | ||
8998 | |||
8933 | /* These functions below will clear BNXT_STATE_IN_SP_TASK. They | 8999 | /* These functions below will clear BNXT_STATE_IN_SP_TASK. They |
8934 | * must be the last functions to be called before exiting. | 9000 | * must be the last functions to be called before exiting. |
8935 | */ | 9001 | */ |
@@ -10087,6 +10153,7 @@ static int bnxt_init_one(struct pci_dev *pdev, const struct pci_device_id *ent) | |||
10087 | } | 10153 | } |
10088 | 10154 | ||
10089 | bnxt_hwrm_func_qcfg(bp); | 10155 | bnxt_hwrm_func_qcfg(bp); |
10156 | bnxt_hwrm_vnic_qcaps(bp); | ||
10090 | bnxt_hwrm_port_led_qcaps(bp); | 10157 | bnxt_hwrm_port_led_qcaps(bp); |
10091 | bnxt_ethtool_init(bp); | 10158 | bnxt_ethtool_init(bp); |
10092 | bnxt_dcb_init(bp); | 10159 | bnxt_dcb_init(bp); |
@@ -10120,7 +10187,6 @@ static int bnxt_init_one(struct pci_dev *pdev, const struct pci_device_id *ent) | |||
10120 | VNIC_RSS_CFG_REQ_HASH_TYPE_UDP_IPV6; | 10187 | VNIC_RSS_CFG_REQ_HASH_TYPE_UDP_IPV6; |
10121 | } | 10188 | } |
10122 | 10189 | ||
10123 | bnxt_hwrm_vnic_qcaps(bp); | ||
10124 | if (bnxt_rfs_supported(bp)) { | 10190 | if (bnxt_rfs_supported(bp)) { |
10125 | dev->hw_features |= NETIF_F_NTUPLE; | 10191 | dev->hw_features |= NETIF_F_NTUPLE; |
10126 | if (bnxt_rfs_capable(bp)) { | 10192 | if (bnxt_rfs_capable(bp)) { |
diff --git a/drivers/net/ethernet/broadcom/bnxt/bnxt.h b/drivers/net/ethernet/broadcom/bnxt/bnxt.h index 498b373c992d..9e99d4ab3e06 100644 --- a/drivers/net/ethernet/broadcom/bnxt/bnxt.h +++ b/drivers/net/ethernet/broadcom/bnxt/bnxt.h | |||
@@ -798,6 +798,8 @@ struct bnxt_cp_ring_info { | |||
798 | u8 had_work_done:1; | 798 | u8 had_work_done:1; |
799 | u8 has_more_work:1; | 799 | u8 has_more_work:1; |
800 | 800 | ||
801 | u32 last_cp_raw_cons; | ||
802 | |||
801 | struct bnxt_coal rx_ring_coal; | 803 | struct bnxt_coal rx_ring_coal; |
802 | u64 rx_packets; | 804 | u64 rx_packets; |
803 | u64 rx_bytes; | 805 | u64 rx_bytes; |
@@ -816,6 +818,7 @@ struct bnxt_cp_ring_info { | |||
816 | dma_addr_t hw_stats_map; | 818 | dma_addr_t hw_stats_map; |
817 | u32 hw_stats_ctx_id; | 819 | u32 hw_stats_ctx_id; |
818 | u64 rx_l4_csum_errors; | 820 | u64 rx_l4_csum_errors; |
821 | u64 missed_irqs; | ||
819 | 822 | ||
820 | struct bnxt_ring_struct cp_ring_struct; | 823 | struct bnxt_ring_struct cp_ring_struct; |
821 | 824 | ||
@@ -1527,6 +1530,7 @@ struct bnxt { | |||
1527 | #define BNXT_LINK_SPEED_CHNG_SP_EVENT 14 | 1530 | #define BNXT_LINK_SPEED_CHNG_SP_EVENT 14 |
1528 | #define BNXT_FLOW_STATS_SP_EVENT 15 | 1531 | #define BNXT_FLOW_STATS_SP_EVENT 15 |
1529 | #define BNXT_UPDATE_PHY_SP_EVENT 16 | 1532 | #define BNXT_UPDATE_PHY_SP_EVENT 16 |
1533 | #define BNXT_RING_COAL_NOW_SP_EVENT 17 | ||
1530 | 1534 | ||
1531 | struct bnxt_hw_resc hw_resc; | 1535 | struct bnxt_hw_resc hw_resc; |
1532 | struct bnxt_pf_info pf; | 1536 | struct bnxt_pf_info pf; |
diff --git a/drivers/net/ethernet/broadcom/bnxt/bnxt_ethtool.c b/drivers/net/ethernet/broadcom/bnxt/bnxt_ethtool.c index 48078564f025..6cc69a58478a 100644 --- a/drivers/net/ethernet/broadcom/bnxt/bnxt_ethtool.c +++ b/drivers/net/ethernet/broadcom/bnxt/bnxt_ethtool.c | |||
@@ -137,7 +137,7 @@ reset_coalesce: | |||
137 | return rc; | 137 | return rc; |
138 | } | 138 | } |
139 | 139 | ||
140 | #define BNXT_NUM_STATS 21 | 140 | #define BNXT_NUM_STATS 22 |
141 | 141 | ||
142 | #define BNXT_RX_STATS_ENTRY(counter) \ | 142 | #define BNXT_RX_STATS_ENTRY(counter) \ |
143 | { BNXT_RX_STATS_OFFSET(counter), __stringify(counter) } | 143 | { BNXT_RX_STATS_OFFSET(counter), __stringify(counter) } |
@@ -384,6 +384,7 @@ static void bnxt_get_ethtool_stats(struct net_device *dev, | |||
384 | for (k = 0; k < stat_fields; j++, k++) | 384 | for (k = 0; k < stat_fields; j++, k++) |
385 | buf[j] = le64_to_cpu(hw_stats[k]); | 385 | buf[j] = le64_to_cpu(hw_stats[k]); |
386 | buf[j++] = cpr->rx_l4_csum_errors; | 386 | buf[j++] = cpr->rx_l4_csum_errors; |
387 | buf[j++] = cpr->missed_irqs; | ||
387 | 388 | ||
388 | bnxt_sw_func_stats[RX_TOTAL_DISCARDS].counter += | 389 | bnxt_sw_func_stats[RX_TOTAL_DISCARDS].counter += |
389 | le64_to_cpu(cpr->hw_stats->rx_discard_pkts); | 390 | le64_to_cpu(cpr->hw_stats->rx_discard_pkts); |
@@ -468,6 +469,8 @@ static void bnxt_get_strings(struct net_device *dev, u32 stringset, u8 *buf) | |||
468 | buf += ETH_GSTRING_LEN; | 469 | buf += ETH_GSTRING_LEN; |
469 | sprintf(buf, "[%d]: rx_l4_csum_errors", i); | 470 | sprintf(buf, "[%d]: rx_l4_csum_errors", i); |
470 | buf += ETH_GSTRING_LEN; | 471 | buf += ETH_GSTRING_LEN; |
472 | sprintf(buf, "[%d]: missed_irqs", i); | ||
473 | buf += ETH_GSTRING_LEN; | ||
471 | } | 474 | } |
472 | for (i = 0; i < BNXT_NUM_SW_FUNC_STATS; i++) { | 475 | for (i = 0; i < BNXT_NUM_SW_FUNC_STATS; i++) { |
473 | strcpy(buf, bnxt_sw_func_stats[i].string); | 476 | strcpy(buf, bnxt_sw_func_stats[i].string); |
@@ -2942,8 +2945,8 @@ bnxt_fill_coredump_record(struct bnxt *bp, struct bnxt_coredump_record *record, | |||
2942 | record->asic_state = 0; | 2945 | record->asic_state = 0; |
2943 | strlcpy(record->system_name, utsname()->nodename, | 2946 | strlcpy(record->system_name, utsname()->nodename, |
2944 | sizeof(record->system_name)); | 2947 | sizeof(record->system_name)); |
2945 | record->year = cpu_to_le16(tm.tm_year); | 2948 | record->year = cpu_to_le16(tm.tm_year + 1900); |
2946 | record->month = cpu_to_le16(tm.tm_mon); | 2949 | record->month = cpu_to_le16(tm.tm_mon + 1); |
2947 | record->day = cpu_to_le16(tm.tm_mday); | 2950 | record->day = cpu_to_le16(tm.tm_mday); |
2948 | record->hour = cpu_to_le16(tm.tm_hour); | 2951 | record->hour = cpu_to_le16(tm.tm_hour); |
2949 | record->minute = cpu_to_le16(tm.tm_min); | 2952 | record->minute = cpu_to_le16(tm.tm_min); |
diff --git a/drivers/net/ethernet/broadcom/bnxt/bnxt_ulp.c b/drivers/net/ethernet/broadcom/bnxt/bnxt_ulp.c index beee61292d5e..b59b382d34f9 100644 --- a/drivers/net/ethernet/broadcom/bnxt/bnxt_ulp.c +++ b/drivers/net/ethernet/broadcom/bnxt/bnxt_ulp.c | |||
@@ -43,6 +43,9 @@ static int bnxt_register_dev(struct bnxt_en_dev *edev, int ulp_id, | |||
43 | if (ulp_id == BNXT_ROCE_ULP) { | 43 | if (ulp_id == BNXT_ROCE_ULP) { |
44 | unsigned int max_stat_ctxs; | 44 | unsigned int max_stat_ctxs; |
45 | 45 | ||
46 | if (bp->flags & BNXT_FLAG_CHIP_P5) | ||
47 | return -EOPNOTSUPP; | ||
48 | |||
46 | max_stat_ctxs = bnxt_get_max_func_stat_ctxs(bp); | 49 | max_stat_ctxs = bnxt_get_max_func_stat_ctxs(bp); |
47 | if (max_stat_ctxs <= BNXT_MIN_ROCE_STAT_CTXS || | 50 | if (max_stat_ctxs <= BNXT_MIN_ROCE_STAT_CTXS || |
48 | bp->num_stat_ctxs == max_stat_ctxs) | 51 | bp->num_stat_ctxs == max_stat_ctxs) |
diff --git a/drivers/net/ethernet/broadcom/tg3.c b/drivers/net/ethernet/broadcom/tg3.c index 89295306f161..432c3b867084 100644 --- a/drivers/net/ethernet/broadcom/tg3.c +++ b/drivers/net/ethernet/broadcom/tg3.c | |||
@@ -12422,6 +12422,7 @@ static int tg3_set_ringparam(struct net_device *dev, struct ethtool_ringparam *e | |||
12422 | { | 12422 | { |
12423 | struct tg3 *tp = netdev_priv(dev); | 12423 | struct tg3 *tp = netdev_priv(dev); |
12424 | int i, irq_sync = 0, err = 0; | 12424 | int i, irq_sync = 0, err = 0; |
12425 | bool reset_phy = false; | ||
12425 | 12426 | ||
12426 | if ((ering->rx_pending > tp->rx_std_ring_mask) || | 12427 | if ((ering->rx_pending > tp->rx_std_ring_mask) || |
12427 | (ering->rx_jumbo_pending > tp->rx_jmb_ring_mask) || | 12428 | (ering->rx_jumbo_pending > tp->rx_jmb_ring_mask) || |
@@ -12453,7 +12454,13 @@ static int tg3_set_ringparam(struct net_device *dev, struct ethtool_ringparam *e | |||
12453 | 12454 | ||
12454 | if (netif_running(dev)) { | 12455 | if (netif_running(dev)) { |
12455 | tg3_halt(tp, RESET_KIND_SHUTDOWN, 1); | 12456 | tg3_halt(tp, RESET_KIND_SHUTDOWN, 1); |
12456 | err = tg3_restart_hw(tp, false); | 12457 | /* Reset PHY to avoid PHY lock up */ |
12458 | if (tg3_asic_rev(tp) == ASIC_REV_5717 || | ||
12459 | tg3_asic_rev(tp) == ASIC_REV_5719 || | ||
12460 | tg3_asic_rev(tp) == ASIC_REV_5720) | ||
12461 | reset_phy = true; | ||
12462 | |||
12463 | err = tg3_restart_hw(tp, reset_phy); | ||
12457 | if (!err) | 12464 | if (!err) |
12458 | tg3_netif_start(tp); | 12465 | tg3_netif_start(tp); |
12459 | } | 12466 | } |
@@ -12487,6 +12494,7 @@ static int tg3_set_pauseparam(struct net_device *dev, struct ethtool_pauseparam | |||
12487 | { | 12494 | { |
12488 | struct tg3 *tp = netdev_priv(dev); | 12495 | struct tg3 *tp = netdev_priv(dev); |
12489 | int err = 0; | 12496 | int err = 0; |
12497 | bool reset_phy = false; | ||
12490 | 12498 | ||
12491 | if (tp->link_config.autoneg == AUTONEG_ENABLE) | 12499 | if (tp->link_config.autoneg == AUTONEG_ENABLE) |
12492 | tg3_warn_mgmt_link_flap(tp); | 12500 | tg3_warn_mgmt_link_flap(tp); |
@@ -12556,7 +12564,13 @@ static int tg3_set_pauseparam(struct net_device *dev, struct ethtool_pauseparam | |||
12556 | 12564 | ||
12557 | if (netif_running(dev)) { | 12565 | if (netif_running(dev)) { |
12558 | tg3_halt(tp, RESET_KIND_SHUTDOWN, 1); | 12566 | tg3_halt(tp, RESET_KIND_SHUTDOWN, 1); |
12559 | err = tg3_restart_hw(tp, false); | 12567 | /* Reset PHY to avoid PHY lock up */ |
12568 | if (tg3_asic_rev(tp) == ASIC_REV_5717 || | ||
12569 | tg3_asic_rev(tp) == ASIC_REV_5719 || | ||
12570 | tg3_asic_rev(tp) == ASIC_REV_5720) | ||
12571 | reset_phy = true; | ||
12572 | |||
12573 | err = tg3_restart_hw(tp, reset_phy); | ||
12560 | if (!err) | 12574 | if (!err) |
12561 | tg3_netif_start(tp); | 12575 | tg3_netif_start(tp); |
12562 | } | 12576 | } |
diff --git a/drivers/net/ethernet/cavium/thunder/nicvf_main.c b/drivers/net/ethernet/cavium/thunder/nicvf_main.c index 768f584f8392..88f8a8fa93cd 100644 --- a/drivers/net/ethernet/cavium/thunder/nicvf_main.c +++ b/drivers/net/ethernet/cavium/thunder/nicvf_main.c | |||
@@ -1784,6 +1784,7 @@ static int nicvf_xdp_setup(struct nicvf *nic, struct bpf_prog *prog) | |||
1784 | bool if_up = netif_running(nic->netdev); | 1784 | bool if_up = netif_running(nic->netdev); |
1785 | struct bpf_prog *old_prog; | 1785 | struct bpf_prog *old_prog; |
1786 | bool bpf_attached = false; | 1786 | bool bpf_attached = false; |
1787 | int ret = 0; | ||
1787 | 1788 | ||
1788 | /* For now just support only the usual MTU sized frames */ | 1789 | /* For now just support only the usual MTU sized frames */ |
1789 | if (prog && (dev->mtu > 1500)) { | 1790 | if (prog && (dev->mtu > 1500)) { |
@@ -1817,8 +1818,12 @@ static int nicvf_xdp_setup(struct nicvf *nic, struct bpf_prog *prog) | |||
1817 | if (nic->xdp_prog) { | 1818 | if (nic->xdp_prog) { |
1818 | /* Attach BPF program */ | 1819 | /* Attach BPF program */ |
1819 | nic->xdp_prog = bpf_prog_add(nic->xdp_prog, nic->rx_queues - 1); | 1820 | nic->xdp_prog = bpf_prog_add(nic->xdp_prog, nic->rx_queues - 1); |
1820 | if (!IS_ERR(nic->xdp_prog)) | 1821 | if (!IS_ERR(nic->xdp_prog)) { |
1821 | bpf_attached = true; | 1822 | bpf_attached = true; |
1823 | } else { | ||
1824 | ret = PTR_ERR(nic->xdp_prog); | ||
1825 | nic->xdp_prog = NULL; | ||
1826 | } | ||
1822 | } | 1827 | } |
1823 | 1828 | ||
1824 | /* Calculate Tx queues needed for XDP and network stack */ | 1829 | /* Calculate Tx queues needed for XDP and network stack */ |
@@ -1830,7 +1835,7 @@ static int nicvf_xdp_setup(struct nicvf *nic, struct bpf_prog *prog) | |||
1830 | netif_trans_update(nic->netdev); | 1835 | netif_trans_update(nic->netdev); |
1831 | } | 1836 | } |
1832 | 1837 | ||
1833 | return 0; | 1838 | return ret; |
1834 | } | 1839 | } |
1835 | 1840 | ||
1836 | static int nicvf_xdp(struct net_device *netdev, struct netdev_bpf *xdp) | 1841 | static int nicvf_xdp(struct net_device *netdev, struct netdev_bpf *xdp) |
diff --git a/drivers/net/ethernet/cavium/thunder/nicvf_queues.c b/drivers/net/ethernet/cavium/thunder/nicvf_queues.c index 187a249ff2d1..fcaf18fa3904 100644 --- a/drivers/net/ethernet/cavium/thunder/nicvf_queues.c +++ b/drivers/net/ethernet/cavium/thunder/nicvf_queues.c | |||
@@ -585,10 +585,12 @@ static void nicvf_free_snd_queue(struct nicvf *nic, struct snd_queue *sq) | |||
585 | if (!sq->dmem.base) | 585 | if (!sq->dmem.base) |
586 | return; | 586 | return; |
587 | 587 | ||
588 | if (sq->tso_hdrs) | 588 | if (sq->tso_hdrs) { |
589 | dma_free_coherent(&nic->pdev->dev, | 589 | dma_free_coherent(&nic->pdev->dev, |
590 | sq->dmem.q_len * TSO_HEADER_SIZE, | 590 | sq->dmem.q_len * TSO_HEADER_SIZE, |
591 | sq->tso_hdrs, sq->tso_hdrs_phys); | 591 | sq->tso_hdrs, sq->tso_hdrs_phys); |
592 | sq->tso_hdrs = NULL; | ||
593 | } | ||
592 | 594 | ||
593 | /* Free pending skbs in the queue */ | 595 | /* Free pending skbs in the queue */ |
594 | smp_rmb(); | 596 | smp_rmb(); |
diff --git a/drivers/net/ethernet/chelsio/Kconfig b/drivers/net/ethernet/chelsio/Kconfig index 75c1c5ed2387..e2cdfa75673f 100644 --- a/drivers/net/ethernet/chelsio/Kconfig +++ b/drivers/net/ethernet/chelsio/Kconfig | |||
@@ -67,7 +67,6 @@ config CHELSIO_T3 | |||
67 | config CHELSIO_T4 | 67 | config CHELSIO_T4 |
68 | tristate "Chelsio Communications T4/T5/T6 Ethernet support" | 68 | tristate "Chelsio Communications T4/T5/T6 Ethernet support" |
69 | depends on PCI && (IPV6 || IPV6=n) | 69 | depends on PCI && (IPV6 || IPV6=n) |
70 | depends on THERMAL || !THERMAL | ||
71 | select FW_LOADER | 70 | select FW_LOADER |
72 | select MDIO | 71 | select MDIO |
73 | select ZLIB_DEFLATE | 72 | select ZLIB_DEFLATE |
diff --git a/drivers/net/ethernet/chelsio/cxgb4/Makefile b/drivers/net/ethernet/chelsio/cxgb4/Makefile index 78e5d17a1d5f..91d8a885deba 100644 --- a/drivers/net/ethernet/chelsio/cxgb4/Makefile +++ b/drivers/net/ethernet/chelsio/cxgb4/Makefile | |||
@@ -12,6 +12,4 @@ cxgb4-objs := cxgb4_main.o l2t.o smt.o t4_hw.o sge.o clip_tbl.o cxgb4_ethtool.o | |||
12 | cxgb4-$(CONFIG_CHELSIO_T4_DCB) += cxgb4_dcb.o | 12 | cxgb4-$(CONFIG_CHELSIO_T4_DCB) += cxgb4_dcb.o |
13 | cxgb4-$(CONFIG_CHELSIO_T4_FCOE) += cxgb4_fcoe.o | 13 | cxgb4-$(CONFIG_CHELSIO_T4_FCOE) += cxgb4_fcoe.o |
14 | cxgb4-$(CONFIG_DEBUG_FS) += cxgb4_debugfs.o | 14 | cxgb4-$(CONFIG_DEBUG_FS) += cxgb4_debugfs.o |
15 | ifdef CONFIG_THERMAL | 15 | cxgb4-$(CONFIG_THERMAL) += cxgb4_thermal.o |
16 | cxgb4-objs += cxgb4_thermal.o | ||
17 | endif | ||
diff --git a/drivers/net/ethernet/chelsio/cxgb4/cxgb4_main.c b/drivers/net/ethernet/chelsio/cxgb4/cxgb4_main.c index 05a46926016a..d49db46254cd 100644 --- a/drivers/net/ethernet/chelsio/cxgb4/cxgb4_main.c +++ b/drivers/net/ethernet/chelsio/cxgb4/cxgb4_main.c | |||
@@ -5863,7 +5863,7 @@ fw_attach_fail: | |||
5863 | if (!is_t4(adapter->params.chip)) | 5863 | if (!is_t4(adapter->params.chip)) |
5864 | cxgb4_ptp_init(adapter); | 5864 | cxgb4_ptp_init(adapter); |
5865 | 5865 | ||
5866 | if (IS_ENABLED(CONFIG_THERMAL) && | 5866 | if (IS_REACHABLE(CONFIG_THERMAL) && |
5867 | !is_t4(adapter->params.chip) && (adapter->flags & FW_OK)) | 5867 | !is_t4(adapter->params.chip) && (adapter->flags & FW_OK)) |
5868 | cxgb4_thermal_init(adapter); | 5868 | cxgb4_thermal_init(adapter); |
5869 | 5869 | ||
@@ -5932,7 +5932,7 @@ static void remove_one(struct pci_dev *pdev) | |||
5932 | 5932 | ||
5933 | if (!is_t4(adapter->params.chip)) | 5933 | if (!is_t4(adapter->params.chip)) |
5934 | cxgb4_ptp_stop(adapter); | 5934 | cxgb4_ptp_stop(adapter); |
5935 | if (IS_ENABLED(CONFIG_THERMAL)) | 5935 | if (IS_REACHABLE(CONFIG_THERMAL)) |
5936 | cxgb4_thermal_remove(adapter); | 5936 | cxgb4_thermal_remove(adapter); |
5937 | 5937 | ||
5938 | /* If we allocated filters, free up state associated with any | 5938 | /* If we allocated filters, free up state associated with any |
diff --git a/drivers/net/ethernet/cortina/gemini.c b/drivers/net/ethernet/cortina/gemini.c index ceec467f590d..949103db8a8a 100644 --- a/drivers/net/ethernet/cortina/gemini.c +++ b/drivers/net/ethernet/cortina/gemini.c | |||
@@ -660,7 +660,7 @@ static void gmac_clean_txq(struct net_device *netdev, struct gmac_txq *txq, | |||
660 | 660 | ||
661 | u64_stats_update_begin(&port->tx_stats_syncp); | 661 | u64_stats_update_begin(&port->tx_stats_syncp); |
662 | port->tx_frag_stats[nfrags]++; | 662 | port->tx_frag_stats[nfrags]++; |
663 | u64_stats_update_end(&port->ir_stats_syncp); | 663 | u64_stats_update_end(&port->tx_stats_syncp); |
664 | } | 664 | } |
665 | } | 665 | } |
666 | 666 | ||
diff --git a/drivers/net/ethernet/faraday/ftmac100.c b/drivers/net/ethernet/faraday/ftmac100.c index 570caeb8ee9e..084f24daf2b5 100644 --- a/drivers/net/ethernet/faraday/ftmac100.c +++ b/drivers/net/ethernet/faraday/ftmac100.c | |||
@@ -872,11 +872,10 @@ static irqreturn_t ftmac100_interrupt(int irq, void *dev_id) | |||
872 | struct net_device *netdev = dev_id; | 872 | struct net_device *netdev = dev_id; |
873 | struct ftmac100 *priv = netdev_priv(netdev); | 873 | struct ftmac100 *priv = netdev_priv(netdev); |
874 | 874 | ||
875 | if (likely(netif_running(netdev))) { | 875 | /* Disable interrupts for polling */ |
876 | /* Disable interrupts for polling */ | 876 | ftmac100_disable_all_int(priv); |
877 | ftmac100_disable_all_int(priv); | 877 | if (likely(netif_running(netdev))) |
878 | napi_schedule(&priv->napi); | 878 | napi_schedule(&priv->napi); |
879 | } | ||
880 | 879 | ||
881 | return IRQ_HANDLED; | 880 | return IRQ_HANDLED; |
882 | } | 881 | } |
diff --git a/drivers/net/ethernet/ibm/ibmvnic.c b/drivers/net/ethernet/ibm/ibmvnic.c index c9d5d0a7fbf1..c0203a0d5e3b 100644 --- a/drivers/net/ethernet/ibm/ibmvnic.c +++ b/drivers/net/ethernet/ibm/ibmvnic.c | |||
@@ -485,8 +485,8 @@ static void release_rx_pools(struct ibmvnic_adapter *adapter) | |||
485 | 485 | ||
486 | for (j = 0; j < rx_pool->size; j++) { | 486 | for (j = 0; j < rx_pool->size; j++) { |
487 | if (rx_pool->rx_buff[j].skb) { | 487 | if (rx_pool->rx_buff[j].skb) { |
488 | dev_kfree_skb_any(rx_pool->rx_buff[i].skb); | 488 | dev_kfree_skb_any(rx_pool->rx_buff[j].skb); |
489 | rx_pool->rx_buff[i].skb = NULL; | 489 | rx_pool->rx_buff[j].skb = NULL; |
490 | } | 490 | } |
491 | } | 491 | } |
492 | 492 | ||
@@ -1103,20 +1103,15 @@ static int ibmvnic_open(struct net_device *netdev) | |||
1103 | return 0; | 1103 | return 0; |
1104 | } | 1104 | } |
1105 | 1105 | ||
1106 | mutex_lock(&adapter->reset_lock); | ||
1107 | |||
1108 | if (adapter->state != VNIC_CLOSED) { | 1106 | if (adapter->state != VNIC_CLOSED) { |
1109 | rc = ibmvnic_login(netdev); | 1107 | rc = ibmvnic_login(netdev); |
1110 | if (rc) { | 1108 | if (rc) |
1111 | mutex_unlock(&adapter->reset_lock); | ||
1112 | return rc; | 1109 | return rc; |
1113 | } | ||
1114 | 1110 | ||
1115 | rc = init_resources(adapter); | 1111 | rc = init_resources(adapter); |
1116 | if (rc) { | 1112 | if (rc) { |
1117 | netdev_err(netdev, "failed to initialize resources\n"); | 1113 | netdev_err(netdev, "failed to initialize resources\n"); |
1118 | release_resources(adapter); | 1114 | release_resources(adapter); |
1119 | mutex_unlock(&adapter->reset_lock); | ||
1120 | return rc; | 1115 | return rc; |
1121 | } | 1116 | } |
1122 | } | 1117 | } |
@@ -1124,8 +1119,6 @@ static int ibmvnic_open(struct net_device *netdev) | |||
1124 | rc = __ibmvnic_open(netdev); | 1119 | rc = __ibmvnic_open(netdev); |
1125 | netif_carrier_on(netdev); | 1120 | netif_carrier_on(netdev); |
1126 | 1121 | ||
1127 | mutex_unlock(&adapter->reset_lock); | ||
1128 | |||
1129 | return rc; | 1122 | return rc; |
1130 | } | 1123 | } |
1131 | 1124 | ||
@@ -1269,10 +1262,8 @@ static int ibmvnic_close(struct net_device *netdev) | |||
1269 | return 0; | 1262 | return 0; |
1270 | } | 1263 | } |
1271 | 1264 | ||
1272 | mutex_lock(&adapter->reset_lock); | ||
1273 | rc = __ibmvnic_close(netdev); | 1265 | rc = __ibmvnic_close(netdev); |
1274 | ibmvnic_cleanup(netdev); | 1266 | ibmvnic_cleanup(netdev); |
1275 | mutex_unlock(&adapter->reset_lock); | ||
1276 | 1267 | ||
1277 | return rc; | 1268 | return rc; |
1278 | } | 1269 | } |
@@ -1746,6 +1737,7 @@ static int do_reset(struct ibmvnic_adapter *adapter, | |||
1746 | struct ibmvnic_rwi *rwi, u32 reset_state) | 1737 | struct ibmvnic_rwi *rwi, u32 reset_state) |
1747 | { | 1738 | { |
1748 | u64 old_num_rx_queues, old_num_tx_queues; | 1739 | u64 old_num_rx_queues, old_num_tx_queues; |
1740 | u64 old_num_rx_slots, old_num_tx_slots; | ||
1749 | struct net_device *netdev = adapter->netdev; | 1741 | struct net_device *netdev = adapter->netdev; |
1750 | int i, rc; | 1742 | int i, rc; |
1751 | 1743 | ||
@@ -1757,6 +1749,8 @@ static int do_reset(struct ibmvnic_adapter *adapter, | |||
1757 | 1749 | ||
1758 | old_num_rx_queues = adapter->req_rx_queues; | 1750 | old_num_rx_queues = adapter->req_rx_queues; |
1759 | old_num_tx_queues = adapter->req_tx_queues; | 1751 | old_num_tx_queues = adapter->req_tx_queues; |
1752 | old_num_rx_slots = adapter->req_rx_add_entries_per_subcrq; | ||
1753 | old_num_tx_slots = adapter->req_tx_entries_per_subcrq; | ||
1760 | 1754 | ||
1761 | ibmvnic_cleanup(netdev); | 1755 | ibmvnic_cleanup(netdev); |
1762 | 1756 | ||
@@ -1819,21 +1813,20 @@ static int do_reset(struct ibmvnic_adapter *adapter, | |||
1819 | if (rc) | 1813 | if (rc) |
1820 | return rc; | 1814 | return rc; |
1821 | } else if (adapter->req_rx_queues != old_num_rx_queues || | 1815 | } else if (adapter->req_rx_queues != old_num_rx_queues || |
1822 | adapter->req_tx_queues != old_num_tx_queues) { | 1816 | adapter->req_tx_queues != old_num_tx_queues || |
1823 | adapter->map_id = 1; | 1817 | adapter->req_rx_add_entries_per_subcrq != |
1818 | old_num_rx_slots || | ||
1819 | adapter->req_tx_entries_per_subcrq != | ||
1820 | old_num_tx_slots) { | ||
1824 | release_rx_pools(adapter); | 1821 | release_rx_pools(adapter); |
1825 | release_tx_pools(adapter); | 1822 | release_tx_pools(adapter); |
1826 | rc = init_rx_pools(netdev); | ||
1827 | if (rc) | ||
1828 | return rc; | ||
1829 | rc = init_tx_pools(netdev); | ||
1830 | if (rc) | ||
1831 | return rc; | ||
1832 | |||
1833 | release_napi(adapter); | 1823 | release_napi(adapter); |
1834 | rc = init_napi(adapter); | 1824 | release_vpd_data(adapter); |
1825 | |||
1826 | rc = init_resources(adapter); | ||
1835 | if (rc) | 1827 | if (rc) |
1836 | return rc; | 1828 | return rc; |
1829 | |||
1837 | } else { | 1830 | } else { |
1838 | rc = reset_tx_pools(adapter); | 1831 | rc = reset_tx_pools(adapter); |
1839 | if (rc) | 1832 | if (rc) |
@@ -1917,17 +1910,8 @@ static int do_hard_reset(struct ibmvnic_adapter *adapter, | |||
1917 | adapter->state = VNIC_PROBED; | 1910 | adapter->state = VNIC_PROBED; |
1918 | return 0; | 1911 | return 0; |
1919 | } | 1912 | } |
1920 | /* netif_set_real_num_xx_queues needs to take rtnl lock here | 1913 | |
1921 | * unless wait_for_reset is set, in which case the rtnl lock | 1914 | rc = init_resources(adapter); |
1922 | * has already been taken before initializing the reset | ||
1923 | */ | ||
1924 | if (!adapter->wait_for_reset) { | ||
1925 | rtnl_lock(); | ||
1926 | rc = init_resources(adapter); | ||
1927 | rtnl_unlock(); | ||
1928 | } else { | ||
1929 | rc = init_resources(adapter); | ||
1930 | } | ||
1931 | if (rc) | 1915 | if (rc) |
1932 | return rc; | 1916 | return rc; |
1933 | 1917 | ||
@@ -1986,13 +1970,21 @@ static void __ibmvnic_reset(struct work_struct *work) | |||
1986 | struct ibmvnic_rwi *rwi; | 1970 | struct ibmvnic_rwi *rwi; |
1987 | struct ibmvnic_adapter *adapter; | 1971 | struct ibmvnic_adapter *adapter; |
1988 | struct net_device *netdev; | 1972 | struct net_device *netdev; |
1973 | bool we_lock_rtnl = false; | ||
1989 | u32 reset_state; | 1974 | u32 reset_state; |
1990 | int rc = 0; | 1975 | int rc = 0; |
1991 | 1976 | ||
1992 | adapter = container_of(work, struct ibmvnic_adapter, ibmvnic_reset); | 1977 | adapter = container_of(work, struct ibmvnic_adapter, ibmvnic_reset); |
1993 | netdev = adapter->netdev; | 1978 | netdev = adapter->netdev; |
1994 | 1979 | ||
1995 | mutex_lock(&adapter->reset_lock); | 1980 | /* netif_set_real_num_xx_queues needs to take rtnl lock here |
1981 | * unless wait_for_reset is set, in which case the rtnl lock | ||
1982 | * has already been taken before initializing the reset | ||
1983 | */ | ||
1984 | if (!adapter->wait_for_reset) { | ||
1985 | rtnl_lock(); | ||
1986 | we_lock_rtnl = true; | ||
1987 | } | ||
1996 | reset_state = adapter->state; | 1988 | reset_state = adapter->state; |
1997 | 1989 | ||
1998 | rwi = get_next_rwi(adapter); | 1990 | rwi = get_next_rwi(adapter); |
@@ -2020,12 +2012,11 @@ static void __ibmvnic_reset(struct work_struct *work) | |||
2020 | if (rc) { | 2012 | if (rc) { |
2021 | netdev_dbg(adapter->netdev, "Reset failed\n"); | 2013 | netdev_dbg(adapter->netdev, "Reset failed\n"); |
2022 | free_all_rwi(adapter); | 2014 | free_all_rwi(adapter); |
2023 | mutex_unlock(&adapter->reset_lock); | ||
2024 | return; | ||
2025 | } | 2015 | } |
2026 | 2016 | ||
2027 | adapter->resetting = false; | 2017 | adapter->resetting = false; |
2028 | mutex_unlock(&adapter->reset_lock); | 2018 | if (we_lock_rtnl) |
2019 | rtnl_unlock(); | ||
2029 | } | 2020 | } |
2030 | 2021 | ||
2031 | static int ibmvnic_reset(struct ibmvnic_adapter *adapter, | 2022 | static int ibmvnic_reset(struct ibmvnic_adapter *adapter, |
@@ -4768,7 +4759,6 @@ static int ibmvnic_probe(struct vio_dev *dev, const struct vio_device_id *id) | |||
4768 | 4759 | ||
4769 | INIT_WORK(&adapter->ibmvnic_reset, __ibmvnic_reset); | 4760 | INIT_WORK(&adapter->ibmvnic_reset, __ibmvnic_reset); |
4770 | INIT_LIST_HEAD(&adapter->rwi_list); | 4761 | INIT_LIST_HEAD(&adapter->rwi_list); |
4771 | mutex_init(&adapter->reset_lock); | ||
4772 | mutex_init(&adapter->rwi_lock); | 4762 | mutex_init(&adapter->rwi_lock); |
4773 | adapter->resetting = false; | 4763 | adapter->resetting = false; |
4774 | 4764 | ||
@@ -4840,8 +4830,8 @@ static int ibmvnic_remove(struct vio_dev *dev) | |||
4840 | struct ibmvnic_adapter *adapter = netdev_priv(netdev); | 4830 | struct ibmvnic_adapter *adapter = netdev_priv(netdev); |
4841 | 4831 | ||
4842 | adapter->state = VNIC_REMOVING; | 4832 | adapter->state = VNIC_REMOVING; |
4843 | unregister_netdev(netdev); | 4833 | rtnl_lock(); |
4844 | mutex_lock(&adapter->reset_lock); | 4834 | unregister_netdevice(netdev); |
4845 | 4835 | ||
4846 | release_resources(adapter); | 4836 | release_resources(adapter); |
4847 | release_sub_crqs(adapter, 1); | 4837 | release_sub_crqs(adapter, 1); |
@@ -4852,7 +4842,7 @@ static int ibmvnic_remove(struct vio_dev *dev) | |||
4852 | 4842 | ||
4853 | adapter->state = VNIC_REMOVED; | 4843 | adapter->state = VNIC_REMOVED; |
4854 | 4844 | ||
4855 | mutex_unlock(&adapter->reset_lock); | 4845 | rtnl_unlock(); |
4856 | device_remove_file(&dev->dev, &dev_attr_failover); | 4846 | device_remove_file(&dev->dev, &dev_attr_failover); |
4857 | free_netdev(netdev); | 4847 | free_netdev(netdev); |
4858 | dev_set_drvdata(&dev->dev, NULL); | 4848 | dev_set_drvdata(&dev->dev, NULL); |
diff --git a/drivers/net/ethernet/ibm/ibmvnic.h b/drivers/net/ethernet/ibm/ibmvnic.h index 18103b811d4d..99c4f8d331ce 100644 --- a/drivers/net/ethernet/ibm/ibmvnic.h +++ b/drivers/net/ethernet/ibm/ibmvnic.h | |||
@@ -1075,7 +1075,7 @@ struct ibmvnic_adapter { | |||
1075 | struct tasklet_struct tasklet; | 1075 | struct tasklet_struct tasklet; |
1076 | enum vnic_state state; | 1076 | enum vnic_state state; |
1077 | enum ibmvnic_reset_reason reset_reason; | 1077 | enum ibmvnic_reset_reason reset_reason; |
1078 | struct mutex reset_lock, rwi_lock; | 1078 | struct mutex rwi_lock; |
1079 | struct list_head rwi_list; | 1079 | struct list_head rwi_list; |
1080 | struct work_struct ibmvnic_reset; | 1080 | struct work_struct ibmvnic_reset; |
1081 | bool resetting; | 1081 | bool resetting; |
diff --git a/drivers/net/ethernet/lantiq_xrx200.c b/drivers/net/ethernet/lantiq_xrx200.c index 8c5ba4b81fb7..2d4d10a017e5 100644 --- a/drivers/net/ethernet/lantiq_xrx200.c +++ b/drivers/net/ethernet/lantiq_xrx200.c | |||
@@ -512,7 +512,8 @@ static int xrx200_probe(struct platform_device *pdev) | |||
512 | err = register_netdev(net_dev); | 512 | err = register_netdev(net_dev); |
513 | if (err) | 513 | if (err) |
514 | goto err_unprepare_clk; | 514 | goto err_unprepare_clk; |
515 | return err; | 515 | |
516 | return 0; | ||
516 | 517 | ||
517 | err_unprepare_clk: | 518 | err_unprepare_clk: |
518 | clk_disable_unprepare(priv->clk); | 519 | clk_disable_unprepare(priv->clk); |
@@ -520,7 +521,7 @@ err_unprepare_clk: | |||
520 | err_uninit_dma: | 521 | err_uninit_dma: |
521 | xrx200_hw_cleanup(priv); | 522 | xrx200_hw_cleanup(priv); |
522 | 523 | ||
523 | return 0; | 524 | return err; |
524 | } | 525 | } |
525 | 526 | ||
526 | static int xrx200_remove(struct platform_device *pdev) | 527 | static int xrx200_remove(struct platform_device *pdev) |
diff --git a/drivers/net/ethernet/marvell/mvneta.c b/drivers/net/ethernet/marvell/mvneta.c index 3ba672e9e353..e5397c8197b9 100644 --- a/drivers/net/ethernet/marvell/mvneta.c +++ b/drivers/net/ethernet/marvell/mvneta.c | |||
@@ -3343,7 +3343,6 @@ static void mvneta_validate(struct net_device *ndev, unsigned long *supported, | |||
3343 | if (state->interface != PHY_INTERFACE_MODE_NA && | 3343 | if (state->interface != PHY_INTERFACE_MODE_NA && |
3344 | state->interface != PHY_INTERFACE_MODE_QSGMII && | 3344 | state->interface != PHY_INTERFACE_MODE_QSGMII && |
3345 | state->interface != PHY_INTERFACE_MODE_SGMII && | 3345 | state->interface != PHY_INTERFACE_MODE_SGMII && |
3346 | state->interface != PHY_INTERFACE_MODE_2500BASEX && | ||
3347 | !phy_interface_mode_is_8023z(state->interface) && | 3346 | !phy_interface_mode_is_8023z(state->interface) && |
3348 | !phy_interface_mode_is_rgmii(state->interface)) { | 3347 | !phy_interface_mode_is_rgmii(state->interface)) { |
3349 | bitmap_zero(supported, __ETHTOOL_LINK_MODE_MASK_NBITS); | 3348 | bitmap_zero(supported, __ETHTOOL_LINK_MODE_MASK_NBITS); |
@@ -3357,14 +3356,9 @@ static void mvneta_validate(struct net_device *ndev, unsigned long *supported, | |||
3357 | /* Asymmetric pause is unsupported */ | 3356 | /* Asymmetric pause is unsupported */ |
3358 | phylink_set(mask, Pause); | 3357 | phylink_set(mask, Pause); |
3359 | 3358 | ||
3360 | /* We cannot use 1Gbps when using the 2.5G interface. */ | 3359 | /* Half-duplex at speeds higher than 100Mbit is unsupported */ |
3361 | if (state->interface == PHY_INTERFACE_MODE_2500BASEX) { | 3360 | phylink_set(mask, 1000baseT_Full); |
3362 | phylink_set(mask, 2500baseT_Full); | 3361 | phylink_set(mask, 1000baseX_Full); |
3363 | phylink_set(mask, 2500baseX_Full); | ||
3364 | } else { | ||
3365 | phylink_set(mask, 1000baseT_Full); | ||
3366 | phylink_set(mask, 1000baseX_Full); | ||
3367 | } | ||
3368 | 3362 | ||
3369 | if (!phy_interface_mode_is_8023z(state->interface)) { | 3363 | if (!phy_interface_mode_is_8023z(state->interface)) { |
3370 | /* 10M and 100M are only supported in non-802.3z mode */ | 3364 | /* 10M and 100M are only supported in non-802.3z mode */ |
diff --git a/drivers/net/ethernet/mellanox/mlx4/alloc.c b/drivers/net/ethernet/mellanox/mlx4/alloc.c index deef5a998985..9af34e03892c 100644 --- a/drivers/net/ethernet/mellanox/mlx4/alloc.c +++ b/drivers/net/ethernet/mellanox/mlx4/alloc.c | |||
@@ -337,7 +337,7 @@ void mlx4_zone_allocator_destroy(struct mlx4_zone_allocator *zone_alloc) | |||
337 | static u32 __mlx4_alloc_from_zone(struct mlx4_zone_entry *zone, int count, | 337 | static u32 __mlx4_alloc_from_zone(struct mlx4_zone_entry *zone, int count, |
338 | int align, u32 skip_mask, u32 *puid) | 338 | int align, u32 skip_mask, u32 *puid) |
339 | { | 339 | { |
340 | u32 uid; | 340 | u32 uid = 0; |
341 | u32 res; | 341 | u32 res; |
342 | struct mlx4_zone_allocator *zone_alloc = zone->allocator; | 342 | struct mlx4_zone_allocator *zone_alloc = zone->allocator; |
343 | struct mlx4_zone_entry *curr_node; | 343 | struct mlx4_zone_entry *curr_node; |
diff --git a/drivers/net/ethernet/mellanox/mlx4/mlx4.h b/drivers/net/ethernet/mellanox/mlx4/mlx4.h index ebcd2778eeb3..23f1b5b512c2 100644 --- a/drivers/net/ethernet/mellanox/mlx4/mlx4.h +++ b/drivers/net/ethernet/mellanox/mlx4/mlx4.h | |||
@@ -540,8 +540,8 @@ struct slave_list { | |||
540 | struct resource_allocator { | 540 | struct resource_allocator { |
541 | spinlock_t alloc_lock; /* protect quotas */ | 541 | spinlock_t alloc_lock; /* protect quotas */ |
542 | union { | 542 | union { |
543 | int res_reserved; | 543 | unsigned int res_reserved; |
544 | int res_port_rsvd[MLX4_MAX_PORTS]; | 544 | unsigned int res_port_rsvd[MLX4_MAX_PORTS]; |
545 | }; | 545 | }; |
546 | union { | 546 | union { |
547 | int res_free; | 547 | int res_free; |
diff --git a/drivers/net/ethernet/mellanox/mlx4/mr.c b/drivers/net/ethernet/mellanox/mlx4/mr.c index 2e84f10f59ba..1a11bc0e1612 100644 --- a/drivers/net/ethernet/mellanox/mlx4/mr.c +++ b/drivers/net/ethernet/mellanox/mlx4/mr.c | |||
@@ -363,6 +363,7 @@ int mlx4_mr_hw_write_mpt(struct mlx4_dev *dev, struct mlx4_mr *mmr, | |||
363 | container_of((void *)mpt_entry, struct mlx4_cmd_mailbox, | 363 | container_of((void *)mpt_entry, struct mlx4_cmd_mailbox, |
364 | buf); | 364 | buf); |
365 | 365 | ||
366 | (*mpt_entry)->lkey = 0; | ||
366 | err = mlx4_SW2HW_MPT(dev, mailbox, key); | 367 | err = mlx4_SW2HW_MPT(dev, mailbox, key); |
367 | } | 368 | } |
368 | 369 | ||
diff --git a/drivers/net/ethernet/mellanox/mlx5/core/en.h b/drivers/net/ethernet/mellanox/mlx5/core/en.h index d7fbd5b6ac95..118324802926 100644 --- a/drivers/net/ethernet/mellanox/mlx5/core/en.h +++ b/drivers/net/ethernet/mellanox/mlx5/core/en.h | |||
@@ -569,6 +569,7 @@ struct mlx5e_rq { | |||
569 | 569 | ||
570 | unsigned long state; | 570 | unsigned long state; |
571 | int ix; | 571 | int ix; |
572 | unsigned int hw_mtu; | ||
572 | 573 | ||
573 | struct net_dim dim; /* Dynamic Interrupt Moderation */ | 574 | struct net_dim dim; /* Dynamic Interrupt Moderation */ |
574 | 575 | ||
diff --git a/drivers/net/ethernet/mellanox/mlx5/core/en/port.c b/drivers/net/ethernet/mellanox/mlx5/core/en/port.c index 023dc4bccd28..4a37713023be 100644 --- a/drivers/net/ethernet/mellanox/mlx5/core/en/port.c +++ b/drivers/net/ethernet/mellanox/mlx5/core/en/port.c | |||
@@ -88,10 +88,8 @@ int mlx5e_port_linkspeed(struct mlx5_core_dev *mdev, u32 *speed) | |||
88 | 88 | ||
89 | eth_proto_oper = MLX5_GET(ptys_reg, out, eth_proto_oper); | 89 | eth_proto_oper = MLX5_GET(ptys_reg, out, eth_proto_oper); |
90 | *speed = mlx5e_port_ptys2speed(eth_proto_oper); | 90 | *speed = mlx5e_port_ptys2speed(eth_proto_oper); |
91 | if (!(*speed)) { | 91 | if (!(*speed)) |
92 | mlx5_core_warn(mdev, "cannot get port speed\n"); | ||
93 | err = -EINVAL; | 92 | err = -EINVAL; |
94 | } | ||
95 | 93 | ||
96 | return err; | 94 | return err; |
97 | } | 95 | } |
@@ -258,7 +256,7 @@ static int mlx5e_fec_admin_field(u32 *pplm, | |||
258 | case 40000: | 256 | case 40000: |
259 | if (!write) | 257 | if (!write) |
260 | *fec_policy = MLX5_GET(pplm_reg, pplm, | 258 | *fec_policy = MLX5_GET(pplm_reg, pplm, |
261 | fec_override_cap_10g_40g); | 259 | fec_override_admin_10g_40g); |
262 | else | 260 | else |
263 | MLX5_SET(pplm_reg, pplm, | 261 | MLX5_SET(pplm_reg, pplm, |
264 | fec_override_admin_10g_40g, *fec_policy); | 262 | fec_override_admin_10g_40g, *fec_policy); |
@@ -310,7 +308,7 @@ static int mlx5e_get_fec_cap_field(u32 *pplm, | |||
310 | case 10000: | 308 | case 10000: |
311 | case 40000: | 309 | case 40000: |
312 | *fec_cap = MLX5_GET(pplm_reg, pplm, | 310 | *fec_cap = MLX5_GET(pplm_reg, pplm, |
313 | fec_override_admin_10g_40g); | 311 | fec_override_cap_10g_40g); |
314 | break; | 312 | break; |
315 | case 25000: | 313 | case 25000: |
316 | *fec_cap = MLX5_GET(pplm_reg, pplm, | 314 | *fec_cap = MLX5_GET(pplm_reg, pplm, |
@@ -394,12 +392,12 @@ int mlx5e_get_fec_mode(struct mlx5_core_dev *dev, u32 *fec_mode_active, | |||
394 | 392 | ||
395 | int mlx5e_set_fec_mode(struct mlx5_core_dev *dev, u8 fec_policy) | 393 | int mlx5e_set_fec_mode(struct mlx5_core_dev *dev, u8 fec_policy) |
396 | { | 394 | { |
395 | u8 fec_policy_nofec = BIT(MLX5E_FEC_NOFEC); | ||
397 | bool fec_mode_not_supp_in_speed = false; | 396 | bool fec_mode_not_supp_in_speed = false; |
398 | u8 no_fec_policy = BIT(MLX5E_FEC_NOFEC); | ||
399 | u32 out[MLX5_ST_SZ_DW(pplm_reg)] = {}; | 397 | u32 out[MLX5_ST_SZ_DW(pplm_reg)] = {}; |
400 | u32 in[MLX5_ST_SZ_DW(pplm_reg)] = {}; | 398 | u32 in[MLX5_ST_SZ_DW(pplm_reg)] = {}; |
401 | int sz = MLX5_ST_SZ_BYTES(pplm_reg); | 399 | int sz = MLX5_ST_SZ_BYTES(pplm_reg); |
402 | u32 current_fec_speed; | 400 | u8 fec_policy_auto = 0; |
403 | u8 fec_caps = 0; | 401 | u8 fec_caps = 0; |
404 | int err; | 402 | int err; |
405 | int i; | 403 | int i; |
@@ -415,23 +413,19 @@ int mlx5e_set_fec_mode(struct mlx5_core_dev *dev, u8 fec_policy) | |||
415 | if (err) | 413 | if (err) |
416 | return err; | 414 | return err; |
417 | 415 | ||
418 | err = mlx5e_port_linkspeed(dev, ¤t_fec_speed); | 416 | MLX5_SET(pplm_reg, out, local_port, 1); |
419 | if (err) | ||
420 | return err; | ||
421 | 417 | ||
422 | memset(in, 0, sz); | 418 | for (i = 0; i < MLX5E_FEC_SUPPORTED_SPEEDS; i++) { |
423 | MLX5_SET(pplm_reg, in, local_port, 1); | ||
424 | for (i = 0; i < MLX5E_FEC_SUPPORTED_SPEEDS && !!fec_policy; i++) { | ||
425 | mlx5e_get_fec_cap_field(out, &fec_caps, fec_supported_speeds[i]); | 419 | mlx5e_get_fec_cap_field(out, &fec_caps, fec_supported_speeds[i]); |
426 | /* policy supported for link speed */ | 420 | /* policy supported for link speed, or policy is auto */ |
427 | if (!!(fec_caps & fec_policy)) { | 421 | if (fec_caps & fec_policy || fec_policy == fec_policy_auto) { |
428 | mlx5e_fec_admin_field(in, &fec_policy, 1, | 422 | mlx5e_fec_admin_field(out, &fec_policy, 1, |
429 | fec_supported_speeds[i]); | 423 | fec_supported_speeds[i]); |
430 | } else { | 424 | } else { |
431 | if (fec_supported_speeds[i] == current_fec_speed) | 425 | /* turn off FEC if supported. Else, leave it the same */ |
432 | return -EOPNOTSUPP; | 426 | if (fec_caps & fec_policy_nofec) |
433 | mlx5e_fec_admin_field(in, &no_fec_policy, 1, | 427 | mlx5e_fec_admin_field(out, &fec_policy_nofec, 1, |
434 | fec_supported_speeds[i]); | 428 | fec_supported_speeds[i]); |
435 | fec_mode_not_supp_in_speed = true; | 429 | fec_mode_not_supp_in_speed = true; |
436 | } | 430 | } |
437 | } | 431 | } |
@@ -441,5 +435,5 @@ int mlx5e_set_fec_mode(struct mlx5_core_dev *dev, u8 fec_policy) | |||
441 | "FEC policy 0x%x is not supported for some speeds", | 435 | "FEC policy 0x%x is not supported for some speeds", |
442 | fec_policy); | 436 | fec_policy); |
443 | 437 | ||
444 | return mlx5_core_access_reg(dev, in, sz, out, sz, MLX5_REG_PPLM, 0, 1); | 438 | return mlx5_core_access_reg(dev, out, sz, out, sz, MLX5_REG_PPLM, 0, 1); |
445 | } | 439 | } |
diff --git a/drivers/net/ethernet/mellanox/mlx5/core/en/port_buffer.c b/drivers/net/ethernet/mellanox/mlx5/core/en/port_buffer.c index c047da8752da..eac245a93f91 100644 --- a/drivers/net/ethernet/mellanox/mlx5/core/en/port_buffer.c +++ b/drivers/net/ethernet/mellanox/mlx5/core/en/port_buffer.c | |||
@@ -130,8 +130,10 @@ static u32 calculate_xoff(struct mlx5e_priv *priv, unsigned int mtu) | |||
130 | int err; | 130 | int err; |
131 | 131 | ||
132 | err = mlx5e_port_linkspeed(priv->mdev, &speed); | 132 | err = mlx5e_port_linkspeed(priv->mdev, &speed); |
133 | if (err) | 133 | if (err) { |
134 | mlx5_core_warn(priv->mdev, "cannot get port speed\n"); | ||
134 | return 0; | 135 | return 0; |
136 | } | ||
135 | 137 | ||
136 | xoff = (301 + 216 * priv->dcbx.cable_len / 100) * speed / 1000 + 272 * mtu / 100; | 138 | xoff = (301 + 216 * priv->dcbx.cable_len / 100) * speed / 1000 + 272 * mtu / 100; |
137 | 139 | ||
diff --git a/drivers/net/ethernet/mellanox/mlx5/core/en_ethtool.c b/drivers/net/ethernet/mellanox/mlx5/core/en_ethtool.c index 3e770abfd802..25c1c4f96841 100644 --- a/drivers/net/ethernet/mellanox/mlx5/core/en_ethtool.c +++ b/drivers/net/ethernet/mellanox/mlx5/core/en_ethtool.c | |||
@@ -843,8 +843,7 @@ static int mlx5e_get_link_ksettings(struct net_device *netdev, | |||
843 | ethtool_link_ksettings_add_link_mode(link_ksettings, supported, | 843 | ethtool_link_ksettings_add_link_mode(link_ksettings, supported, |
844 | Autoneg); | 844 | Autoneg); |
845 | 845 | ||
846 | err = get_fec_supported_advertised(mdev, link_ksettings); | 846 | if (get_fec_supported_advertised(mdev, link_ksettings)) |
847 | if (err) | ||
848 | netdev_dbg(netdev, "%s: FEC caps query failed: %d\n", | 847 | netdev_dbg(netdev, "%s: FEC caps query failed: %d\n", |
849 | __func__, err); | 848 | __func__, err); |
850 | 849 | ||
diff --git a/drivers/net/ethernet/mellanox/mlx5/core/en_main.c b/drivers/net/ethernet/mellanox/mlx5/core/en_main.c index 1243edbedc9e..871313d6b34d 100644 --- a/drivers/net/ethernet/mellanox/mlx5/core/en_main.c +++ b/drivers/net/ethernet/mellanox/mlx5/core/en_main.c | |||
@@ -502,6 +502,7 @@ static int mlx5e_alloc_rq(struct mlx5e_channel *c, | |||
502 | rq->channel = c; | 502 | rq->channel = c; |
503 | rq->ix = c->ix; | 503 | rq->ix = c->ix; |
504 | rq->mdev = mdev; | 504 | rq->mdev = mdev; |
505 | rq->hw_mtu = MLX5E_SW2HW_MTU(params, params->sw_mtu); | ||
505 | rq->stats = &c->priv->channel_stats[c->ix].rq; | 506 | rq->stats = &c->priv->channel_stats[c->ix].rq; |
506 | 507 | ||
507 | rq->xdp_prog = params->xdp_prog ? bpf_prog_inc(params->xdp_prog) : NULL; | 508 | rq->xdp_prog = params->xdp_prog ? bpf_prog_inc(params->xdp_prog) : NULL; |
@@ -1623,13 +1624,15 @@ static int mlx5e_alloc_cq_common(struct mlx5_core_dev *mdev, | |||
1623 | int err; | 1624 | int err; |
1624 | u32 i; | 1625 | u32 i; |
1625 | 1626 | ||
1627 | err = mlx5_vector2eqn(mdev, param->eq_ix, &eqn_not_used, &irqn); | ||
1628 | if (err) | ||
1629 | return err; | ||
1630 | |||
1626 | err = mlx5_cqwq_create(mdev, ¶m->wq, param->cqc, &cq->wq, | 1631 | err = mlx5_cqwq_create(mdev, ¶m->wq, param->cqc, &cq->wq, |
1627 | &cq->wq_ctrl); | 1632 | &cq->wq_ctrl); |
1628 | if (err) | 1633 | if (err) |
1629 | return err; | 1634 | return err; |
1630 | 1635 | ||
1631 | mlx5_vector2eqn(mdev, param->eq_ix, &eqn_not_used, &irqn); | ||
1632 | |||
1633 | mcq->cqe_sz = 64; | 1636 | mcq->cqe_sz = 64; |
1634 | mcq->set_ci_db = cq->wq_ctrl.db.db; | 1637 | mcq->set_ci_db = cq->wq_ctrl.db.db; |
1635 | mcq->arm_db = cq->wq_ctrl.db.db + 1; | 1638 | mcq->arm_db = cq->wq_ctrl.db.db + 1; |
@@ -1687,6 +1690,10 @@ static int mlx5e_create_cq(struct mlx5e_cq *cq, struct mlx5e_cq_param *param) | |||
1687 | int eqn; | 1690 | int eqn; |
1688 | int err; | 1691 | int err; |
1689 | 1692 | ||
1693 | err = mlx5_vector2eqn(mdev, param->eq_ix, &eqn, &irqn_not_used); | ||
1694 | if (err) | ||
1695 | return err; | ||
1696 | |||
1690 | inlen = MLX5_ST_SZ_BYTES(create_cq_in) + | 1697 | inlen = MLX5_ST_SZ_BYTES(create_cq_in) + |
1691 | sizeof(u64) * cq->wq_ctrl.buf.npages; | 1698 | sizeof(u64) * cq->wq_ctrl.buf.npages; |
1692 | in = kvzalloc(inlen, GFP_KERNEL); | 1699 | in = kvzalloc(inlen, GFP_KERNEL); |
@@ -1700,8 +1707,6 @@ static int mlx5e_create_cq(struct mlx5e_cq *cq, struct mlx5e_cq_param *param) | |||
1700 | mlx5_fill_page_frag_array(&cq->wq_ctrl.buf, | 1707 | mlx5_fill_page_frag_array(&cq->wq_ctrl.buf, |
1701 | (__be64 *)MLX5_ADDR_OF(create_cq_in, in, pas)); | 1708 | (__be64 *)MLX5_ADDR_OF(create_cq_in, in, pas)); |
1702 | 1709 | ||
1703 | mlx5_vector2eqn(mdev, param->eq_ix, &eqn, &irqn_not_used); | ||
1704 | |||
1705 | MLX5_SET(cqc, cqc, cq_period_mode, param->cq_period_mode); | 1710 | MLX5_SET(cqc, cqc, cq_period_mode, param->cq_period_mode); |
1706 | MLX5_SET(cqc, cqc, c_eqn, eqn); | 1711 | MLX5_SET(cqc, cqc, c_eqn, eqn); |
1707 | MLX5_SET(cqc, cqc, uar_page, mdev->priv.uar->index); | 1712 | MLX5_SET(cqc, cqc, uar_page, mdev->priv.uar->index); |
@@ -1921,6 +1926,10 @@ static int mlx5e_open_channel(struct mlx5e_priv *priv, int ix, | |||
1921 | int err; | 1926 | int err; |
1922 | int eqn; | 1927 | int eqn; |
1923 | 1928 | ||
1929 | err = mlx5_vector2eqn(priv->mdev, ix, &eqn, &irq); | ||
1930 | if (err) | ||
1931 | return err; | ||
1932 | |||
1924 | c = kvzalloc_node(sizeof(*c), GFP_KERNEL, cpu_to_node(cpu)); | 1933 | c = kvzalloc_node(sizeof(*c), GFP_KERNEL, cpu_to_node(cpu)); |
1925 | if (!c) | 1934 | if (!c) |
1926 | return -ENOMEM; | 1935 | return -ENOMEM; |
@@ -1937,7 +1946,6 @@ static int mlx5e_open_channel(struct mlx5e_priv *priv, int ix, | |||
1937 | c->xdp = !!params->xdp_prog; | 1946 | c->xdp = !!params->xdp_prog; |
1938 | c->stats = &priv->channel_stats[ix].ch; | 1947 | c->stats = &priv->channel_stats[ix].ch; |
1939 | 1948 | ||
1940 | mlx5_vector2eqn(priv->mdev, ix, &eqn, &irq); | ||
1941 | c->irq_desc = irq_to_desc(irq); | 1949 | c->irq_desc = irq_to_desc(irq); |
1942 | 1950 | ||
1943 | netif_napi_add(netdev, &c->napi, mlx5e_napi_poll, 64); | 1951 | netif_napi_add(netdev, &c->napi, mlx5e_napi_poll, 64); |
@@ -3574,6 +3582,7 @@ static int set_feature_cvlan_filter(struct net_device *netdev, bool enable) | |||
3574 | return 0; | 3582 | return 0; |
3575 | } | 3583 | } |
3576 | 3584 | ||
3585 | #ifdef CONFIG_MLX5_ESWITCH | ||
3577 | static int set_feature_tc_num_filters(struct net_device *netdev, bool enable) | 3586 | static int set_feature_tc_num_filters(struct net_device *netdev, bool enable) |
3578 | { | 3587 | { |
3579 | struct mlx5e_priv *priv = netdev_priv(netdev); | 3588 | struct mlx5e_priv *priv = netdev_priv(netdev); |
@@ -3586,6 +3595,7 @@ static int set_feature_tc_num_filters(struct net_device *netdev, bool enable) | |||
3586 | 3595 | ||
3587 | return 0; | 3596 | return 0; |
3588 | } | 3597 | } |
3598 | #endif | ||
3589 | 3599 | ||
3590 | static int set_feature_rx_all(struct net_device *netdev, bool enable) | 3600 | static int set_feature_rx_all(struct net_device *netdev, bool enable) |
3591 | { | 3601 | { |
@@ -3684,7 +3694,9 @@ static int mlx5e_set_features(struct net_device *netdev, | |||
3684 | err |= MLX5E_HANDLE_FEATURE(NETIF_F_LRO, set_feature_lro); | 3694 | err |= MLX5E_HANDLE_FEATURE(NETIF_F_LRO, set_feature_lro); |
3685 | err |= MLX5E_HANDLE_FEATURE(NETIF_F_HW_VLAN_CTAG_FILTER, | 3695 | err |= MLX5E_HANDLE_FEATURE(NETIF_F_HW_VLAN_CTAG_FILTER, |
3686 | set_feature_cvlan_filter); | 3696 | set_feature_cvlan_filter); |
3697 | #ifdef CONFIG_MLX5_ESWITCH | ||
3687 | err |= MLX5E_HANDLE_FEATURE(NETIF_F_HW_TC, set_feature_tc_num_filters); | 3698 | err |= MLX5E_HANDLE_FEATURE(NETIF_F_HW_TC, set_feature_tc_num_filters); |
3699 | #endif | ||
3688 | err |= MLX5E_HANDLE_FEATURE(NETIF_F_RXALL, set_feature_rx_all); | 3700 | err |= MLX5E_HANDLE_FEATURE(NETIF_F_RXALL, set_feature_rx_all); |
3689 | err |= MLX5E_HANDLE_FEATURE(NETIF_F_RXFCS, set_feature_rx_fcs); | 3701 | err |= MLX5E_HANDLE_FEATURE(NETIF_F_RXFCS, set_feature_rx_fcs); |
3690 | err |= MLX5E_HANDLE_FEATURE(NETIF_F_HW_VLAN_CTAG_RX, set_feature_rx_vlan); | 3702 | err |= MLX5E_HANDLE_FEATURE(NETIF_F_HW_VLAN_CTAG_RX, set_feature_rx_vlan); |
@@ -3755,10 +3767,11 @@ int mlx5e_change_mtu(struct net_device *netdev, int new_mtu, | |||
3755 | } | 3767 | } |
3756 | 3768 | ||
3757 | if (params->rq_wq_type == MLX5_WQ_TYPE_LINKED_LIST_STRIDING_RQ) { | 3769 | if (params->rq_wq_type == MLX5_WQ_TYPE_LINKED_LIST_STRIDING_RQ) { |
3770 | bool is_linear = mlx5e_rx_mpwqe_is_linear_skb(priv->mdev, &new_channels.params); | ||
3758 | u8 ppw_old = mlx5e_mpwqe_log_pkts_per_wqe(params); | 3771 | u8 ppw_old = mlx5e_mpwqe_log_pkts_per_wqe(params); |
3759 | u8 ppw_new = mlx5e_mpwqe_log_pkts_per_wqe(&new_channels.params); | 3772 | u8 ppw_new = mlx5e_mpwqe_log_pkts_per_wqe(&new_channels.params); |
3760 | 3773 | ||
3761 | reset = reset && (ppw_old != ppw_new); | 3774 | reset = reset && (is_linear || (ppw_old != ppw_new)); |
3762 | } | 3775 | } |
3763 | 3776 | ||
3764 | if (!reset) { | 3777 | if (!reset) { |
@@ -4678,7 +4691,9 @@ static void mlx5e_build_nic_netdev(struct net_device *netdev) | |||
4678 | FT_CAP(modify_root) && | 4691 | FT_CAP(modify_root) && |
4679 | FT_CAP(identified_miss_table_mode) && | 4692 | FT_CAP(identified_miss_table_mode) && |
4680 | FT_CAP(flow_table_modify)) { | 4693 | FT_CAP(flow_table_modify)) { |
4694 | #ifdef CONFIG_MLX5_ESWITCH | ||
4681 | netdev->hw_features |= NETIF_F_HW_TC; | 4695 | netdev->hw_features |= NETIF_F_HW_TC; |
4696 | #endif | ||
4682 | #ifdef CONFIG_MLX5_EN_ARFS | 4697 | #ifdef CONFIG_MLX5_EN_ARFS |
4683 | netdev->hw_features |= NETIF_F_NTUPLE; | 4698 | netdev->hw_features |= NETIF_F_NTUPLE; |
4684 | #endif | 4699 | #endif |
@@ -5004,11 +5019,21 @@ err_free_netdev: | |||
5004 | int mlx5e_attach_netdev(struct mlx5e_priv *priv) | 5019 | int mlx5e_attach_netdev(struct mlx5e_priv *priv) |
5005 | { | 5020 | { |
5006 | const struct mlx5e_profile *profile; | 5021 | const struct mlx5e_profile *profile; |
5022 | int max_nch; | ||
5007 | int err; | 5023 | int err; |
5008 | 5024 | ||
5009 | profile = priv->profile; | 5025 | profile = priv->profile; |
5010 | clear_bit(MLX5E_STATE_DESTROYING, &priv->state); | 5026 | clear_bit(MLX5E_STATE_DESTROYING, &priv->state); |
5011 | 5027 | ||
5028 | /* max number of channels may have changed */ | ||
5029 | max_nch = mlx5e_get_max_num_channels(priv->mdev); | ||
5030 | if (priv->channels.params.num_channels > max_nch) { | ||
5031 | mlx5_core_warn(priv->mdev, "MLX5E: Reducing number of channels to %d\n", max_nch); | ||
5032 | priv->channels.params.num_channels = max_nch; | ||
5033 | mlx5e_build_default_indir_rqt(priv->channels.params.indirection_rqt, | ||
5034 | MLX5E_INDIR_RQT_SIZE, max_nch); | ||
5035 | } | ||
5036 | |||
5012 | err = profile->init_tx(priv); | 5037 | err = profile->init_tx(priv); |
5013 | if (err) | 5038 | if (err) |
5014 | goto out; | 5039 | goto out; |
diff --git a/drivers/net/ethernet/mellanox/mlx5/core/en_rx.c b/drivers/net/ethernet/mellanox/mlx5/core/en_rx.c index 79638dcbae78..16985ca3248d 100644 --- a/drivers/net/ethernet/mellanox/mlx5/core/en_rx.c +++ b/drivers/net/ethernet/mellanox/mlx5/core/en_rx.c | |||
@@ -1104,6 +1104,12 @@ mlx5e_skb_from_cqe_mpwrq_linear(struct mlx5e_rq *rq, struct mlx5e_mpw_info *wi, | |||
1104 | u32 frag_size; | 1104 | u32 frag_size; |
1105 | bool consumed; | 1105 | bool consumed; |
1106 | 1106 | ||
1107 | /* Check packet size. Note LRO doesn't use linear SKB */ | ||
1108 | if (unlikely(cqe_bcnt > rq->hw_mtu)) { | ||
1109 | rq->stats->oversize_pkts_sw_drop++; | ||
1110 | return NULL; | ||
1111 | } | ||
1112 | |||
1107 | va = page_address(di->page) + head_offset; | 1113 | va = page_address(di->page) + head_offset; |
1108 | data = va + rx_headroom; | 1114 | data = va + rx_headroom; |
1109 | frag_size = MLX5_SKB_FRAG_SZ(rx_headroom + cqe_bcnt32); | 1115 | frag_size = MLX5_SKB_FRAG_SZ(rx_headroom + cqe_bcnt32); |
diff --git a/drivers/net/ethernet/mellanox/mlx5/core/en_selftest.c b/drivers/net/ethernet/mellanox/mlx5/core/en_selftest.c index 35ded91203f5..4382ef85488c 100644 --- a/drivers/net/ethernet/mellanox/mlx5/core/en_selftest.c +++ b/drivers/net/ethernet/mellanox/mlx5/core/en_selftest.c | |||
@@ -98,18 +98,17 @@ static int mlx5e_test_link_speed(struct mlx5e_priv *priv) | |||
98 | return 1; | 98 | return 1; |
99 | } | 99 | } |
100 | 100 | ||
101 | #ifdef CONFIG_INET | ||
102 | /* loopback test */ | ||
103 | #define MLX5E_TEST_PKT_SIZE (MLX5E_RX_MAX_HEAD - NET_IP_ALIGN) | ||
104 | static const char mlx5e_test_text[ETH_GSTRING_LEN] = "MLX5E SELF TEST"; | ||
105 | #define MLX5E_TEST_MAGIC 0x5AEED15C001ULL | ||
106 | |||
107 | struct mlx5ehdr { | 101 | struct mlx5ehdr { |
108 | __be32 version; | 102 | __be32 version; |
109 | __be64 magic; | 103 | __be64 magic; |
110 | char text[ETH_GSTRING_LEN]; | ||
111 | }; | 104 | }; |
112 | 105 | ||
106 | #ifdef CONFIG_INET | ||
107 | /* loopback test */ | ||
108 | #define MLX5E_TEST_PKT_SIZE (sizeof(struct ethhdr) + sizeof(struct iphdr) +\ | ||
109 | sizeof(struct udphdr) + sizeof(struct mlx5ehdr)) | ||
110 | #define MLX5E_TEST_MAGIC 0x5AEED15C001ULL | ||
111 | |||
113 | static struct sk_buff *mlx5e_test_get_udp_skb(struct mlx5e_priv *priv) | 112 | static struct sk_buff *mlx5e_test_get_udp_skb(struct mlx5e_priv *priv) |
114 | { | 113 | { |
115 | struct sk_buff *skb = NULL; | 114 | struct sk_buff *skb = NULL; |
@@ -117,10 +116,7 @@ static struct sk_buff *mlx5e_test_get_udp_skb(struct mlx5e_priv *priv) | |||
117 | struct ethhdr *ethh; | 116 | struct ethhdr *ethh; |
118 | struct udphdr *udph; | 117 | struct udphdr *udph; |
119 | struct iphdr *iph; | 118 | struct iphdr *iph; |
120 | int datalen, iplen; | 119 | int iplen; |
121 | |||
122 | datalen = MLX5E_TEST_PKT_SIZE - | ||
123 | (sizeof(*ethh) + sizeof(*iph) + sizeof(*udph)); | ||
124 | 120 | ||
125 | skb = netdev_alloc_skb(priv->netdev, MLX5E_TEST_PKT_SIZE); | 121 | skb = netdev_alloc_skb(priv->netdev, MLX5E_TEST_PKT_SIZE); |
126 | if (!skb) { | 122 | if (!skb) { |
@@ -149,7 +145,7 @@ static struct sk_buff *mlx5e_test_get_udp_skb(struct mlx5e_priv *priv) | |||
149 | /* Fill UDP header */ | 145 | /* Fill UDP header */ |
150 | udph->source = htons(9); | 146 | udph->source = htons(9); |
151 | udph->dest = htons(9); /* Discard Protocol */ | 147 | udph->dest = htons(9); /* Discard Protocol */ |
152 | udph->len = htons(datalen + sizeof(struct udphdr)); | 148 | udph->len = htons(sizeof(struct mlx5ehdr) + sizeof(struct udphdr)); |
153 | udph->check = 0; | 149 | udph->check = 0; |
154 | 150 | ||
155 | /* Fill IP header */ | 151 | /* Fill IP header */ |
@@ -157,7 +153,8 @@ static struct sk_buff *mlx5e_test_get_udp_skb(struct mlx5e_priv *priv) | |||
157 | iph->ttl = 32; | 153 | iph->ttl = 32; |
158 | iph->version = 4; | 154 | iph->version = 4; |
159 | iph->protocol = IPPROTO_UDP; | 155 | iph->protocol = IPPROTO_UDP; |
160 | iplen = sizeof(struct iphdr) + sizeof(struct udphdr) + datalen; | 156 | iplen = sizeof(struct iphdr) + sizeof(struct udphdr) + |
157 | sizeof(struct mlx5ehdr); | ||
161 | iph->tot_len = htons(iplen); | 158 | iph->tot_len = htons(iplen); |
162 | iph->frag_off = 0; | 159 | iph->frag_off = 0; |
163 | iph->saddr = 0; | 160 | iph->saddr = 0; |
@@ -170,9 +167,6 @@ static struct sk_buff *mlx5e_test_get_udp_skb(struct mlx5e_priv *priv) | |||
170 | mlxh = skb_put(skb, sizeof(*mlxh)); | 167 | mlxh = skb_put(skb, sizeof(*mlxh)); |
171 | mlxh->version = 0; | 168 | mlxh->version = 0; |
172 | mlxh->magic = cpu_to_be64(MLX5E_TEST_MAGIC); | 169 | mlxh->magic = cpu_to_be64(MLX5E_TEST_MAGIC); |
173 | strlcpy(mlxh->text, mlx5e_test_text, sizeof(mlxh->text)); | ||
174 | datalen -= sizeof(*mlxh); | ||
175 | skb_put_zero(skb, datalen); | ||
176 | 170 | ||
177 | skb->csum = 0; | 171 | skb->csum = 0; |
178 | skb->ip_summed = CHECKSUM_PARTIAL; | 172 | skb->ip_summed = CHECKSUM_PARTIAL; |
diff --git a/drivers/net/ethernet/mellanox/mlx5/core/en_stats.c b/drivers/net/ethernet/mellanox/mlx5/core/en_stats.c index 1e55b9c27ffc..3e99d0728b2f 100644 --- a/drivers/net/ethernet/mellanox/mlx5/core/en_stats.c +++ b/drivers/net/ethernet/mellanox/mlx5/core/en_stats.c | |||
@@ -83,6 +83,7 @@ static const struct counter_desc sw_stats_desc[] = { | |||
83 | { MLX5E_DECLARE_STAT(struct mlx5e_sw_stats, rx_wqe_err) }, | 83 | { MLX5E_DECLARE_STAT(struct mlx5e_sw_stats, rx_wqe_err) }, |
84 | { MLX5E_DECLARE_STAT(struct mlx5e_sw_stats, rx_mpwqe_filler_cqes) }, | 84 | { MLX5E_DECLARE_STAT(struct mlx5e_sw_stats, rx_mpwqe_filler_cqes) }, |
85 | { MLX5E_DECLARE_STAT(struct mlx5e_sw_stats, rx_mpwqe_filler_strides) }, | 85 | { MLX5E_DECLARE_STAT(struct mlx5e_sw_stats, rx_mpwqe_filler_strides) }, |
86 | { MLX5E_DECLARE_STAT(struct mlx5e_sw_stats, rx_oversize_pkts_sw_drop) }, | ||
86 | { MLX5E_DECLARE_STAT(struct mlx5e_sw_stats, rx_buff_alloc_err) }, | 87 | { MLX5E_DECLARE_STAT(struct mlx5e_sw_stats, rx_buff_alloc_err) }, |
87 | { MLX5E_DECLARE_STAT(struct mlx5e_sw_stats, rx_cqe_compress_blks) }, | 88 | { MLX5E_DECLARE_STAT(struct mlx5e_sw_stats, rx_cqe_compress_blks) }, |
88 | { MLX5E_DECLARE_STAT(struct mlx5e_sw_stats, rx_cqe_compress_pkts) }, | 89 | { MLX5E_DECLARE_STAT(struct mlx5e_sw_stats, rx_cqe_compress_pkts) }, |
@@ -161,6 +162,7 @@ void mlx5e_grp_sw_update_stats(struct mlx5e_priv *priv) | |||
161 | s->rx_wqe_err += rq_stats->wqe_err; | 162 | s->rx_wqe_err += rq_stats->wqe_err; |
162 | s->rx_mpwqe_filler_cqes += rq_stats->mpwqe_filler_cqes; | 163 | s->rx_mpwqe_filler_cqes += rq_stats->mpwqe_filler_cqes; |
163 | s->rx_mpwqe_filler_strides += rq_stats->mpwqe_filler_strides; | 164 | s->rx_mpwqe_filler_strides += rq_stats->mpwqe_filler_strides; |
165 | s->rx_oversize_pkts_sw_drop += rq_stats->oversize_pkts_sw_drop; | ||
164 | s->rx_buff_alloc_err += rq_stats->buff_alloc_err; | 166 | s->rx_buff_alloc_err += rq_stats->buff_alloc_err; |
165 | s->rx_cqe_compress_blks += rq_stats->cqe_compress_blks; | 167 | s->rx_cqe_compress_blks += rq_stats->cqe_compress_blks; |
166 | s->rx_cqe_compress_pkts += rq_stats->cqe_compress_pkts; | 168 | s->rx_cqe_compress_pkts += rq_stats->cqe_compress_pkts; |
@@ -1189,6 +1191,7 @@ static const struct counter_desc rq_stats_desc[] = { | |||
1189 | { MLX5E_DECLARE_RX_STAT(struct mlx5e_rq_stats, wqe_err) }, | 1191 | { MLX5E_DECLARE_RX_STAT(struct mlx5e_rq_stats, wqe_err) }, |
1190 | { MLX5E_DECLARE_RX_STAT(struct mlx5e_rq_stats, mpwqe_filler_cqes) }, | 1192 | { MLX5E_DECLARE_RX_STAT(struct mlx5e_rq_stats, mpwqe_filler_cqes) }, |
1191 | { MLX5E_DECLARE_RX_STAT(struct mlx5e_rq_stats, mpwqe_filler_strides) }, | 1193 | { MLX5E_DECLARE_RX_STAT(struct mlx5e_rq_stats, mpwqe_filler_strides) }, |
1194 | { MLX5E_DECLARE_RX_STAT(struct mlx5e_rq_stats, oversize_pkts_sw_drop) }, | ||
1192 | { MLX5E_DECLARE_RX_STAT(struct mlx5e_rq_stats, buff_alloc_err) }, | 1195 | { MLX5E_DECLARE_RX_STAT(struct mlx5e_rq_stats, buff_alloc_err) }, |
1193 | { MLX5E_DECLARE_RX_STAT(struct mlx5e_rq_stats, cqe_compress_blks) }, | 1196 | { MLX5E_DECLARE_RX_STAT(struct mlx5e_rq_stats, cqe_compress_blks) }, |
1194 | { MLX5E_DECLARE_RX_STAT(struct mlx5e_rq_stats, cqe_compress_pkts) }, | 1197 | { MLX5E_DECLARE_RX_STAT(struct mlx5e_rq_stats, cqe_compress_pkts) }, |
diff --git a/drivers/net/ethernet/mellanox/mlx5/core/en_stats.h b/drivers/net/ethernet/mellanox/mlx5/core/en_stats.h index 77f74ce11280..3f8e870ef4c9 100644 --- a/drivers/net/ethernet/mellanox/mlx5/core/en_stats.h +++ b/drivers/net/ethernet/mellanox/mlx5/core/en_stats.h | |||
@@ -96,6 +96,7 @@ struct mlx5e_sw_stats { | |||
96 | u64 rx_wqe_err; | 96 | u64 rx_wqe_err; |
97 | u64 rx_mpwqe_filler_cqes; | 97 | u64 rx_mpwqe_filler_cqes; |
98 | u64 rx_mpwqe_filler_strides; | 98 | u64 rx_mpwqe_filler_strides; |
99 | u64 rx_oversize_pkts_sw_drop; | ||
99 | u64 rx_buff_alloc_err; | 100 | u64 rx_buff_alloc_err; |
100 | u64 rx_cqe_compress_blks; | 101 | u64 rx_cqe_compress_blks; |
101 | u64 rx_cqe_compress_pkts; | 102 | u64 rx_cqe_compress_pkts; |
@@ -193,6 +194,7 @@ struct mlx5e_rq_stats { | |||
193 | u64 wqe_err; | 194 | u64 wqe_err; |
194 | u64 mpwqe_filler_cqes; | 195 | u64 mpwqe_filler_cqes; |
195 | u64 mpwqe_filler_strides; | 196 | u64 mpwqe_filler_strides; |
197 | u64 oversize_pkts_sw_drop; | ||
196 | u64 buff_alloc_err; | 198 | u64 buff_alloc_err; |
197 | u64 cqe_compress_blks; | 199 | u64 cqe_compress_blks; |
198 | u64 cqe_compress_pkts; | 200 | u64 cqe_compress_pkts; |
diff --git a/drivers/net/ethernet/mellanox/mlx5/core/en_tc.c b/drivers/net/ethernet/mellanox/mlx5/core/en_tc.c index 608025ca5c04..fca6f4132c91 100644 --- a/drivers/net/ethernet/mellanox/mlx5/core/en_tc.c +++ b/drivers/net/ethernet/mellanox/mlx5/core/en_tc.c | |||
@@ -1447,31 +1447,21 @@ static int __parse_cls_flower(struct mlx5e_priv *priv, | |||
1447 | inner_headers); | 1447 | inner_headers); |
1448 | } | 1448 | } |
1449 | 1449 | ||
1450 | if (dissector_uses_key(f->dissector, FLOW_DISSECTOR_KEY_ETH_ADDRS)) { | 1450 | if (dissector_uses_key(f->dissector, FLOW_DISSECTOR_KEY_BASIC)) { |
1451 | struct flow_dissector_key_eth_addrs *key = | 1451 | struct flow_dissector_key_basic *key = |
1452 | skb_flow_dissector_target(f->dissector, | 1452 | skb_flow_dissector_target(f->dissector, |
1453 | FLOW_DISSECTOR_KEY_ETH_ADDRS, | 1453 | FLOW_DISSECTOR_KEY_BASIC, |
1454 | f->key); | 1454 | f->key); |
1455 | struct flow_dissector_key_eth_addrs *mask = | 1455 | struct flow_dissector_key_basic *mask = |
1456 | skb_flow_dissector_target(f->dissector, | 1456 | skb_flow_dissector_target(f->dissector, |
1457 | FLOW_DISSECTOR_KEY_ETH_ADDRS, | 1457 | FLOW_DISSECTOR_KEY_BASIC, |
1458 | f->mask); | 1458 | f->mask); |
1459 | MLX5_SET(fte_match_set_lyr_2_4, headers_c, ethertype, | ||
1460 | ntohs(mask->n_proto)); | ||
1461 | MLX5_SET(fte_match_set_lyr_2_4, headers_v, ethertype, | ||
1462 | ntohs(key->n_proto)); | ||
1459 | 1463 | ||
1460 | ether_addr_copy(MLX5_ADDR_OF(fte_match_set_lyr_2_4, headers_c, | 1464 | if (mask->n_proto) |
1461 | dmac_47_16), | ||
1462 | mask->dst); | ||
1463 | ether_addr_copy(MLX5_ADDR_OF(fte_match_set_lyr_2_4, headers_v, | ||
1464 | dmac_47_16), | ||
1465 | key->dst); | ||
1466 | |||
1467 | ether_addr_copy(MLX5_ADDR_OF(fte_match_set_lyr_2_4, headers_c, | ||
1468 | smac_47_16), | ||
1469 | mask->src); | ||
1470 | ether_addr_copy(MLX5_ADDR_OF(fte_match_set_lyr_2_4, headers_v, | ||
1471 | smac_47_16), | ||
1472 | key->src); | ||
1473 | |||
1474 | if (!is_zero_ether_addr(mask->src) || !is_zero_ether_addr(mask->dst)) | ||
1475 | *match_level = MLX5_MATCH_L2; | 1465 | *match_level = MLX5_MATCH_L2; |
1476 | } | 1466 | } |
1477 | 1467 | ||
@@ -1505,9 +1495,10 @@ static int __parse_cls_flower(struct mlx5e_priv *priv, | |||
1505 | 1495 | ||
1506 | *match_level = MLX5_MATCH_L2; | 1496 | *match_level = MLX5_MATCH_L2; |
1507 | } | 1497 | } |
1508 | } else { | 1498 | } else if (*match_level != MLX5_MATCH_NONE) { |
1509 | MLX5_SET(fte_match_set_lyr_2_4, headers_c, svlan_tag, 1); | 1499 | MLX5_SET(fte_match_set_lyr_2_4, headers_c, svlan_tag, 1); |
1510 | MLX5_SET(fte_match_set_lyr_2_4, headers_c, cvlan_tag, 1); | 1500 | MLX5_SET(fte_match_set_lyr_2_4, headers_c, cvlan_tag, 1); |
1501 | *match_level = MLX5_MATCH_L2; | ||
1511 | } | 1502 | } |
1512 | 1503 | ||
1513 | if (dissector_uses_key(f->dissector, FLOW_DISSECTOR_KEY_CVLAN)) { | 1504 | if (dissector_uses_key(f->dissector, FLOW_DISSECTOR_KEY_CVLAN)) { |
@@ -1545,21 +1536,31 @@ static int __parse_cls_flower(struct mlx5e_priv *priv, | |||
1545 | } | 1536 | } |
1546 | } | 1537 | } |
1547 | 1538 | ||
1548 | if (dissector_uses_key(f->dissector, FLOW_DISSECTOR_KEY_BASIC)) { | 1539 | if (dissector_uses_key(f->dissector, FLOW_DISSECTOR_KEY_ETH_ADDRS)) { |
1549 | struct flow_dissector_key_basic *key = | 1540 | struct flow_dissector_key_eth_addrs *key = |
1550 | skb_flow_dissector_target(f->dissector, | 1541 | skb_flow_dissector_target(f->dissector, |
1551 | FLOW_DISSECTOR_KEY_BASIC, | 1542 | FLOW_DISSECTOR_KEY_ETH_ADDRS, |
1552 | f->key); | 1543 | f->key); |
1553 | struct flow_dissector_key_basic *mask = | 1544 | struct flow_dissector_key_eth_addrs *mask = |
1554 | skb_flow_dissector_target(f->dissector, | 1545 | skb_flow_dissector_target(f->dissector, |
1555 | FLOW_DISSECTOR_KEY_BASIC, | 1546 | FLOW_DISSECTOR_KEY_ETH_ADDRS, |
1556 | f->mask); | 1547 | f->mask); |
1557 | MLX5_SET(fte_match_set_lyr_2_4, headers_c, ethertype, | ||
1558 | ntohs(mask->n_proto)); | ||
1559 | MLX5_SET(fte_match_set_lyr_2_4, headers_v, ethertype, | ||
1560 | ntohs(key->n_proto)); | ||
1561 | 1548 | ||
1562 | if (mask->n_proto) | 1549 | ether_addr_copy(MLX5_ADDR_OF(fte_match_set_lyr_2_4, headers_c, |
1550 | dmac_47_16), | ||
1551 | mask->dst); | ||
1552 | ether_addr_copy(MLX5_ADDR_OF(fte_match_set_lyr_2_4, headers_v, | ||
1553 | dmac_47_16), | ||
1554 | key->dst); | ||
1555 | |||
1556 | ether_addr_copy(MLX5_ADDR_OF(fte_match_set_lyr_2_4, headers_c, | ||
1557 | smac_47_16), | ||
1558 | mask->src); | ||
1559 | ether_addr_copy(MLX5_ADDR_OF(fte_match_set_lyr_2_4, headers_v, | ||
1560 | smac_47_16), | ||
1561 | key->src); | ||
1562 | |||
1563 | if (!is_zero_ether_addr(mask->src) || !is_zero_ether_addr(mask->dst)) | ||
1563 | *match_level = MLX5_MATCH_L2; | 1564 | *match_level = MLX5_MATCH_L2; |
1564 | } | 1565 | } |
1565 | 1566 | ||
@@ -1586,10 +1587,10 @@ static int __parse_cls_flower(struct mlx5e_priv *priv, | |||
1586 | 1587 | ||
1587 | /* the HW doesn't need L3 inline to match on frag=no */ | 1588 | /* the HW doesn't need L3 inline to match on frag=no */ |
1588 | if (!(key->flags & FLOW_DIS_IS_FRAGMENT)) | 1589 | if (!(key->flags & FLOW_DIS_IS_FRAGMENT)) |
1589 | *match_level = MLX5_INLINE_MODE_L2; | 1590 | *match_level = MLX5_MATCH_L2; |
1590 | /* *** L2 attributes parsing up to here *** */ | 1591 | /* *** L2 attributes parsing up to here *** */ |
1591 | else | 1592 | else |
1592 | *match_level = MLX5_INLINE_MODE_IP; | 1593 | *match_level = MLX5_MATCH_L3; |
1593 | } | 1594 | } |
1594 | } | 1595 | } |
1595 | 1596 | ||
@@ -2979,7 +2980,7 @@ static int parse_tc_fdb_actions(struct mlx5e_priv *priv, struct tcf_exts *exts, | |||
2979 | if (!actions_match_supported(priv, exts, parse_attr, flow, extack)) | 2980 | if (!actions_match_supported(priv, exts, parse_attr, flow, extack)) |
2980 | return -EOPNOTSUPP; | 2981 | return -EOPNOTSUPP; |
2981 | 2982 | ||
2982 | if (attr->out_count > 1 && !mlx5_esw_has_fwd_fdb(priv->mdev)) { | 2983 | if (attr->mirror_count > 0 && !mlx5_esw_has_fwd_fdb(priv->mdev)) { |
2983 | NL_SET_ERR_MSG_MOD(extack, | 2984 | NL_SET_ERR_MSG_MOD(extack, |
2984 | "current firmware doesn't support split rule for port mirroring"); | 2985 | "current firmware doesn't support split rule for port mirroring"); |
2985 | netdev_warn_once(priv->netdev, "current firmware doesn't support split rule for port mirroring\n"); | 2986 | netdev_warn_once(priv->netdev, "current firmware doesn't support split rule for port mirroring\n"); |
diff --git a/drivers/net/ethernet/mellanox/mlx5/core/fpga/ipsec.c b/drivers/net/ethernet/mellanox/mlx5/core/fpga/ipsec.c index 515e3d6de051..5a22c5874f3b 100644 --- a/drivers/net/ethernet/mellanox/mlx5/core/fpga/ipsec.c +++ b/drivers/net/ethernet/mellanox/mlx5/core/fpga/ipsec.c | |||
@@ -83,8 +83,14 @@ struct mlx5_fpga_ipsec_rule { | |||
83 | }; | 83 | }; |
84 | 84 | ||
85 | static const struct rhashtable_params rhash_sa = { | 85 | static const struct rhashtable_params rhash_sa = { |
86 | .key_len = FIELD_SIZEOF(struct mlx5_fpga_ipsec_sa_ctx, hw_sa), | 86 | /* Keep out "cmd" field from the key as it's |
87 | .key_offset = offsetof(struct mlx5_fpga_ipsec_sa_ctx, hw_sa), | 87 | * value is not constant during the lifetime |
88 | * of the key object. | ||
89 | */ | ||
90 | .key_len = FIELD_SIZEOF(struct mlx5_fpga_ipsec_sa_ctx, hw_sa) - | ||
91 | FIELD_SIZEOF(struct mlx5_ifc_fpga_ipsec_sa_v1, cmd), | ||
92 | .key_offset = offsetof(struct mlx5_fpga_ipsec_sa_ctx, hw_sa) + | ||
93 | FIELD_SIZEOF(struct mlx5_ifc_fpga_ipsec_sa_v1, cmd), | ||
88 | .head_offset = offsetof(struct mlx5_fpga_ipsec_sa_ctx, hash), | 94 | .head_offset = offsetof(struct mlx5_fpga_ipsec_sa_ctx, hash), |
89 | .automatic_shrinking = true, | 95 | .automatic_shrinking = true, |
90 | .min_size = 1, | 96 | .min_size = 1, |
diff --git a/drivers/net/ethernet/mellanox/mlx5/core/ipoib/ipoib.c b/drivers/net/ethernet/mellanox/mlx5/core/ipoib/ipoib.c index b59953daf8b4..11dabd62e2c7 100644 --- a/drivers/net/ethernet/mellanox/mlx5/core/ipoib/ipoib.c +++ b/drivers/net/ethernet/mellanox/mlx5/core/ipoib/ipoib.c | |||
@@ -560,9 +560,9 @@ static int mlx5i_close(struct net_device *netdev) | |||
560 | 560 | ||
561 | netif_carrier_off(epriv->netdev); | 561 | netif_carrier_off(epriv->netdev); |
562 | mlx5_fs_remove_rx_underlay_qpn(mdev, ipriv->qp.qpn); | 562 | mlx5_fs_remove_rx_underlay_qpn(mdev, ipriv->qp.qpn); |
563 | mlx5i_uninit_underlay_qp(epriv); | ||
564 | mlx5e_deactivate_priv_channels(epriv); | 563 | mlx5e_deactivate_priv_channels(epriv); |
565 | mlx5e_close_channels(&epriv->channels); | 564 | mlx5e_close_channels(&epriv->channels); |
565 | mlx5i_uninit_underlay_qp(epriv); | ||
566 | unlock: | 566 | unlock: |
567 | mutex_unlock(&epriv->state_lock); | 567 | mutex_unlock(&epriv->state_lock); |
568 | return 0; | 568 | return 0; |
diff --git a/drivers/net/ethernet/qlogic/qed/qed_dcbx.c b/drivers/net/ethernet/qlogic/qed/qed_dcbx.c index 8e8fa823d611..69966dfc6e3d 100644 --- a/drivers/net/ethernet/qlogic/qed/qed_dcbx.c +++ b/drivers/net/ethernet/qlogic/qed/qed_dcbx.c | |||
@@ -191,7 +191,7 @@ qed_dcbx_dp_protocol(struct qed_hwfn *p_hwfn, struct qed_dcbx_results *p_data) | |||
191 | static void | 191 | static void |
192 | qed_dcbx_set_params(struct qed_dcbx_results *p_data, | 192 | qed_dcbx_set_params(struct qed_dcbx_results *p_data, |
193 | struct qed_hwfn *p_hwfn, struct qed_ptt *p_ptt, | 193 | struct qed_hwfn *p_hwfn, struct qed_ptt *p_ptt, |
194 | bool enable, u8 prio, u8 tc, | 194 | bool app_tlv, bool enable, u8 prio, u8 tc, |
195 | enum dcbx_protocol_type type, | 195 | enum dcbx_protocol_type type, |
196 | enum qed_pci_personality personality) | 196 | enum qed_pci_personality personality) |
197 | { | 197 | { |
@@ -210,7 +210,7 @@ qed_dcbx_set_params(struct qed_dcbx_results *p_data, | |||
210 | p_data->arr[type].dont_add_vlan0 = true; | 210 | p_data->arr[type].dont_add_vlan0 = true; |
211 | 211 | ||
212 | /* QM reconf data */ | 212 | /* QM reconf data */ |
213 | if (p_hwfn->hw_info.personality == personality) | 213 | if (app_tlv && p_hwfn->hw_info.personality == personality) |
214 | qed_hw_info_set_offload_tc(&p_hwfn->hw_info, tc); | 214 | qed_hw_info_set_offload_tc(&p_hwfn->hw_info, tc); |
215 | 215 | ||
216 | /* Configure dcbx vlan priority in doorbell block for roce EDPM */ | 216 | /* Configure dcbx vlan priority in doorbell block for roce EDPM */ |
@@ -225,7 +225,7 @@ qed_dcbx_set_params(struct qed_dcbx_results *p_data, | |||
225 | static void | 225 | static void |
226 | qed_dcbx_update_app_info(struct qed_dcbx_results *p_data, | 226 | qed_dcbx_update_app_info(struct qed_dcbx_results *p_data, |
227 | struct qed_hwfn *p_hwfn, struct qed_ptt *p_ptt, | 227 | struct qed_hwfn *p_hwfn, struct qed_ptt *p_ptt, |
228 | bool enable, u8 prio, u8 tc, | 228 | bool app_tlv, bool enable, u8 prio, u8 tc, |
229 | enum dcbx_protocol_type type) | 229 | enum dcbx_protocol_type type) |
230 | { | 230 | { |
231 | enum qed_pci_personality personality; | 231 | enum qed_pci_personality personality; |
@@ -240,7 +240,7 @@ qed_dcbx_update_app_info(struct qed_dcbx_results *p_data, | |||
240 | 240 | ||
241 | personality = qed_dcbx_app_update[i].personality; | 241 | personality = qed_dcbx_app_update[i].personality; |
242 | 242 | ||
243 | qed_dcbx_set_params(p_data, p_hwfn, p_ptt, enable, | 243 | qed_dcbx_set_params(p_data, p_hwfn, p_ptt, app_tlv, enable, |
244 | prio, tc, type, personality); | 244 | prio, tc, type, personality); |
245 | } | 245 | } |
246 | } | 246 | } |
@@ -319,8 +319,8 @@ qed_dcbx_process_tlv(struct qed_hwfn *p_hwfn, struct qed_ptt *p_ptt, | |||
319 | enable = true; | 319 | enable = true; |
320 | } | 320 | } |
321 | 321 | ||
322 | qed_dcbx_update_app_info(p_data, p_hwfn, p_ptt, enable, | 322 | qed_dcbx_update_app_info(p_data, p_hwfn, p_ptt, true, |
323 | priority, tc, type); | 323 | enable, priority, tc, type); |
324 | } | 324 | } |
325 | } | 325 | } |
326 | 326 | ||
@@ -341,7 +341,7 @@ qed_dcbx_process_tlv(struct qed_hwfn *p_hwfn, struct qed_ptt *p_ptt, | |||
341 | continue; | 341 | continue; |
342 | 342 | ||
343 | enable = (type == DCBX_PROTOCOL_ETH) ? false : !!dcbx_version; | 343 | enable = (type == DCBX_PROTOCOL_ETH) ? false : !!dcbx_version; |
344 | qed_dcbx_update_app_info(p_data, p_hwfn, p_ptt, enable, | 344 | qed_dcbx_update_app_info(p_data, p_hwfn, p_ptt, false, enable, |
345 | priority, tc, type); | 345 | priority, tc, type); |
346 | } | 346 | } |
347 | 347 | ||
diff --git a/drivers/net/ethernet/qlogic/qed/qed_dev.c b/drivers/net/ethernet/qlogic/qed/qed_dev.c index 7ceb2b97538d..88a8576ca9ce 100644 --- a/drivers/net/ethernet/qlogic/qed/qed_dev.c +++ b/drivers/net/ethernet/qlogic/qed/qed_dev.c | |||
@@ -185,6 +185,10 @@ void qed_resc_free(struct qed_dev *cdev) | |||
185 | qed_iscsi_free(p_hwfn); | 185 | qed_iscsi_free(p_hwfn); |
186 | qed_ooo_free(p_hwfn); | 186 | qed_ooo_free(p_hwfn); |
187 | } | 187 | } |
188 | |||
189 | if (QED_IS_RDMA_PERSONALITY(p_hwfn)) | ||
190 | qed_rdma_info_free(p_hwfn); | ||
191 | |||
188 | qed_iov_free(p_hwfn); | 192 | qed_iov_free(p_hwfn); |
189 | qed_l2_free(p_hwfn); | 193 | qed_l2_free(p_hwfn); |
190 | qed_dmae_info_free(p_hwfn); | 194 | qed_dmae_info_free(p_hwfn); |
@@ -481,8 +485,16 @@ static u16 *qed_init_qm_get_idx_from_flags(struct qed_hwfn *p_hwfn, | |||
481 | struct qed_qm_info *qm_info = &p_hwfn->qm_info; | 485 | struct qed_qm_info *qm_info = &p_hwfn->qm_info; |
482 | 486 | ||
483 | /* Can't have multiple flags set here */ | 487 | /* Can't have multiple flags set here */ |
484 | if (bitmap_weight((unsigned long *)&pq_flags, sizeof(pq_flags)) > 1) | 488 | if (bitmap_weight((unsigned long *)&pq_flags, |
489 | sizeof(pq_flags) * BITS_PER_BYTE) > 1) { | ||
490 | DP_ERR(p_hwfn, "requested multiple pq flags 0x%x\n", pq_flags); | ||
491 | goto err; | ||
492 | } | ||
493 | |||
494 | if (!(qed_get_pq_flags(p_hwfn) & pq_flags)) { | ||
495 | DP_ERR(p_hwfn, "pq flag 0x%x is not set\n", pq_flags); | ||
485 | goto err; | 496 | goto err; |
497 | } | ||
486 | 498 | ||
487 | switch (pq_flags) { | 499 | switch (pq_flags) { |
488 | case PQ_FLAGS_RLS: | 500 | case PQ_FLAGS_RLS: |
@@ -506,8 +518,7 @@ static u16 *qed_init_qm_get_idx_from_flags(struct qed_hwfn *p_hwfn, | |||
506 | } | 518 | } |
507 | 519 | ||
508 | err: | 520 | err: |
509 | DP_ERR(p_hwfn, "BAD pq flags %d\n", pq_flags); | 521 | return &qm_info->start_pq; |
510 | return NULL; | ||
511 | } | 522 | } |
512 | 523 | ||
513 | /* save pq index in qm info */ | 524 | /* save pq index in qm info */ |
@@ -531,20 +542,32 @@ u16 qed_get_cm_pq_idx_mcos(struct qed_hwfn *p_hwfn, u8 tc) | |||
531 | { | 542 | { |
532 | u8 max_tc = qed_init_qm_get_num_tcs(p_hwfn); | 543 | u8 max_tc = qed_init_qm_get_num_tcs(p_hwfn); |
533 | 544 | ||
545 | if (max_tc == 0) { | ||
546 | DP_ERR(p_hwfn, "pq with flag 0x%lx do not exist\n", | ||
547 | PQ_FLAGS_MCOS); | ||
548 | return p_hwfn->qm_info.start_pq; | ||
549 | } | ||
550 | |||
534 | if (tc > max_tc) | 551 | if (tc > max_tc) |
535 | DP_ERR(p_hwfn, "tc %d must be smaller than %d\n", tc, max_tc); | 552 | DP_ERR(p_hwfn, "tc %d must be smaller than %d\n", tc, max_tc); |
536 | 553 | ||
537 | return qed_get_cm_pq_idx(p_hwfn, PQ_FLAGS_MCOS) + tc; | 554 | return qed_get_cm_pq_idx(p_hwfn, PQ_FLAGS_MCOS) + (tc % max_tc); |
538 | } | 555 | } |
539 | 556 | ||
540 | u16 qed_get_cm_pq_idx_vf(struct qed_hwfn *p_hwfn, u16 vf) | 557 | u16 qed_get_cm_pq_idx_vf(struct qed_hwfn *p_hwfn, u16 vf) |
541 | { | 558 | { |
542 | u16 max_vf = qed_init_qm_get_num_vfs(p_hwfn); | 559 | u16 max_vf = qed_init_qm_get_num_vfs(p_hwfn); |
543 | 560 | ||
561 | if (max_vf == 0) { | ||
562 | DP_ERR(p_hwfn, "pq with flag 0x%lx do not exist\n", | ||
563 | PQ_FLAGS_VFS); | ||
564 | return p_hwfn->qm_info.start_pq; | ||
565 | } | ||
566 | |||
544 | if (vf > max_vf) | 567 | if (vf > max_vf) |
545 | DP_ERR(p_hwfn, "vf %d must be smaller than %d\n", vf, max_vf); | 568 | DP_ERR(p_hwfn, "vf %d must be smaller than %d\n", vf, max_vf); |
546 | 569 | ||
547 | return qed_get_cm_pq_idx(p_hwfn, PQ_FLAGS_VFS) + vf; | 570 | return qed_get_cm_pq_idx(p_hwfn, PQ_FLAGS_VFS) + (vf % max_vf); |
548 | } | 571 | } |
549 | 572 | ||
550 | u16 qed_get_cm_pq_idx_ofld_mtc(struct qed_hwfn *p_hwfn, u8 tc) | 573 | u16 qed_get_cm_pq_idx_ofld_mtc(struct qed_hwfn *p_hwfn, u8 tc) |
@@ -1081,6 +1104,12 @@ int qed_resc_alloc(struct qed_dev *cdev) | |||
1081 | goto alloc_err; | 1104 | goto alloc_err; |
1082 | } | 1105 | } |
1083 | 1106 | ||
1107 | if (QED_IS_RDMA_PERSONALITY(p_hwfn)) { | ||
1108 | rc = qed_rdma_info_alloc(p_hwfn); | ||
1109 | if (rc) | ||
1110 | goto alloc_err; | ||
1111 | } | ||
1112 | |||
1084 | /* DMA info initialization */ | 1113 | /* DMA info initialization */ |
1085 | rc = qed_dmae_info_alloc(p_hwfn); | 1114 | rc = qed_dmae_info_alloc(p_hwfn); |
1086 | if (rc) | 1115 | if (rc) |
@@ -2102,11 +2131,8 @@ int qed_hw_start_fastpath(struct qed_hwfn *p_hwfn) | |||
2102 | if (!p_ptt) | 2131 | if (!p_ptt) |
2103 | return -EAGAIN; | 2132 | return -EAGAIN; |
2104 | 2133 | ||
2105 | /* If roce info is allocated it means roce is initialized and should | ||
2106 | * be enabled in searcher. | ||
2107 | */ | ||
2108 | if (p_hwfn->p_rdma_info && | 2134 | if (p_hwfn->p_rdma_info && |
2109 | p_hwfn->b_rdma_enabled_in_prs) | 2135 | p_hwfn->p_rdma_info->active && p_hwfn->b_rdma_enabled_in_prs) |
2110 | qed_wr(p_hwfn, p_ptt, p_hwfn->rdma_prs_search_reg, 0x1); | 2136 | qed_wr(p_hwfn, p_ptt, p_hwfn->rdma_prs_search_reg, 0x1); |
2111 | 2137 | ||
2112 | /* Re-open incoming traffic */ | 2138 | /* Re-open incoming traffic */ |
diff --git a/drivers/net/ethernet/qlogic/qed/qed_int.c b/drivers/net/ethernet/qlogic/qed/qed_int.c index 0f0aba793352..b22f464ea3fa 100644 --- a/drivers/net/ethernet/qlogic/qed/qed_int.c +++ b/drivers/net/ethernet/qlogic/qed/qed_int.c | |||
@@ -992,6 +992,8 @@ static int qed_int_attentions(struct qed_hwfn *p_hwfn) | |||
992 | */ | 992 | */ |
993 | do { | 993 | do { |
994 | index = p_sb_attn->sb_index; | 994 | index = p_sb_attn->sb_index; |
995 | /* finish reading index before the loop condition */ | ||
996 | dma_rmb(); | ||
995 | attn_bits = le32_to_cpu(p_sb_attn->atten_bits); | 997 | attn_bits = le32_to_cpu(p_sb_attn->atten_bits); |
996 | attn_acks = le32_to_cpu(p_sb_attn->atten_ack); | 998 | attn_acks = le32_to_cpu(p_sb_attn->atten_ack); |
997 | } while (index != p_sb_attn->sb_index); | 999 | } while (index != p_sb_attn->sb_index); |
diff --git a/drivers/net/ethernet/qlogic/qed/qed_main.c b/drivers/net/ethernet/qlogic/qed/qed_main.c index 35fd0db6a677..fff7f04d4525 100644 --- a/drivers/net/ethernet/qlogic/qed/qed_main.c +++ b/drivers/net/ethernet/qlogic/qed/qed_main.c | |||
@@ -1782,9 +1782,9 @@ static int qed_drain(struct qed_dev *cdev) | |||
1782 | return -EBUSY; | 1782 | return -EBUSY; |
1783 | } | 1783 | } |
1784 | rc = qed_mcp_drain(hwfn, ptt); | 1784 | rc = qed_mcp_drain(hwfn, ptt); |
1785 | qed_ptt_release(hwfn, ptt); | ||
1785 | if (rc) | 1786 | if (rc) |
1786 | return rc; | 1787 | return rc; |
1787 | qed_ptt_release(hwfn, ptt); | ||
1788 | } | 1788 | } |
1789 | 1789 | ||
1790 | return 0; | 1790 | return 0; |
diff --git a/drivers/net/ethernet/qlogic/qed/qed_rdma.c b/drivers/net/ethernet/qlogic/qed/qed_rdma.c index 62113438c880..7873d6dfd91f 100644 --- a/drivers/net/ethernet/qlogic/qed/qed_rdma.c +++ b/drivers/net/ethernet/qlogic/qed/qed_rdma.c | |||
@@ -140,22 +140,34 @@ static u32 qed_rdma_get_sb_id(void *p_hwfn, u32 rel_sb_id) | |||
140 | return FEAT_NUM((struct qed_hwfn *)p_hwfn, QED_PF_L2_QUE) + rel_sb_id; | 140 | return FEAT_NUM((struct qed_hwfn *)p_hwfn, QED_PF_L2_QUE) + rel_sb_id; |
141 | } | 141 | } |
142 | 142 | ||
143 | static int qed_rdma_alloc(struct qed_hwfn *p_hwfn, | 143 | int qed_rdma_info_alloc(struct qed_hwfn *p_hwfn) |
144 | struct qed_ptt *p_ptt, | ||
145 | struct qed_rdma_start_in_params *params) | ||
146 | { | 144 | { |
147 | struct qed_rdma_info *p_rdma_info; | 145 | struct qed_rdma_info *p_rdma_info; |
148 | u32 num_cons, num_tasks; | ||
149 | int rc = -ENOMEM; | ||
150 | 146 | ||
151 | DP_VERBOSE(p_hwfn, QED_MSG_RDMA, "Allocating RDMA\n"); | ||
152 | |||
153 | /* Allocate a struct with current pf rdma info */ | ||
154 | p_rdma_info = kzalloc(sizeof(*p_rdma_info), GFP_KERNEL); | 147 | p_rdma_info = kzalloc(sizeof(*p_rdma_info), GFP_KERNEL); |
155 | if (!p_rdma_info) | 148 | if (!p_rdma_info) |
156 | return rc; | 149 | return -ENOMEM; |
150 | |||
151 | spin_lock_init(&p_rdma_info->lock); | ||
157 | 152 | ||
158 | p_hwfn->p_rdma_info = p_rdma_info; | 153 | p_hwfn->p_rdma_info = p_rdma_info; |
154 | return 0; | ||
155 | } | ||
156 | |||
157 | void qed_rdma_info_free(struct qed_hwfn *p_hwfn) | ||
158 | { | ||
159 | kfree(p_hwfn->p_rdma_info); | ||
160 | p_hwfn->p_rdma_info = NULL; | ||
161 | } | ||
162 | |||
163 | static int qed_rdma_alloc(struct qed_hwfn *p_hwfn) | ||
164 | { | ||
165 | struct qed_rdma_info *p_rdma_info = p_hwfn->p_rdma_info; | ||
166 | u32 num_cons, num_tasks; | ||
167 | int rc = -ENOMEM; | ||
168 | |||
169 | DP_VERBOSE(p_hwfn, QED_MSG_RDMA, "Allocating RDMA\n"); | ||
170 | |||
159 | if (QED_IS_IWARP_PERSONALITY(p_hwfn)) | 171 | if (QED_IS_IWARP_PERSONALITY(p_hwfn)) |
160 | p_rdma_info->proto = PROTOCOLID_IWARP; | 172 | p_rdma_info->proto = PROTOCOLID_IWARP; |
161 | else | 173 | else |
@@ -183,7 +195,7 @@ static int qed_rdma_alloc(struct qed_hwfn *p_hwfn, | |||
183 | /* Allocate a struct with device params and fill it */ | 195 | /* Allocate a struct with device params and fill it */ |
184 | p_rdma_info->dev = kzalloc(sizeof(*p_rdma_info->dev), GFP_KERNEL); | 196 | p_rdma_info->dev = kzalloc(sizeof(*p_rdma_info->dev), GFP_KERNEL); |
185 | if (!p_rdma_info->dev) | 197 | if (!p_rdma_info->dev) |
186 | goto free_rdma_info; | 198 | return rc; |
187 | 199 | ||
188 | /* Allocate a struct with port params and fill it */ | 200 | /* Allocate a struct with port params and fill it */ |
189 | p_rdma_info->port = kzalloc(sizeof(*p_rdma_info->port), GFP_KERNEL); | 201 | p_rdma_info->port = kzalloc(sizeof(*p_rdma_info->port), GFP_KERNEL); |
@@ -298,8 +310,6 @@ free_rdma_port: | |||
298 | kfree(p_rdma_info->port); | 310 | kfree(p_rdma_info->port); |
299 | free_rdma_dev: | 311 | free_rdma_dev: |
300 | kfree(p_rdma_info->dev); | 312 | kfree(p_rdma_info->dev); |
301 | free_rdma_info: | ||
302 | kfree(p_rdma_info); | ||
303 | 313 | ||
304 | return rc; | 314 | return rc; |
305 | } | 315 | } |
@@ -370,8 +380,6 @@ static void qed_rdma_resc_free(struct qed_hwfn *p_hwfn) | |||
370 | 380 | ||
371 | kfree(p_rdma_info->port); | 381 | kfree(p_rdma_info->port); |
372 | kfree(p_rdma_info->dev); | 382 | kfree(p_rdma_info->dev); |
373 | |||
374 | kfree(p_rdma_info); | ||
375 | } | 383 | } |
376 | 384 | ||
377 | static void qed_rdma_free_tid(void *rdma_cxt, u32 itid) | 385 | static void qed_rdma_free_tid(void *rdma_cxt, u32 itid) |
@@ -679,8 +687,6 @@ static int qed_rdma_setup(struct qed_hwfn *p_hwfn, | |||
679 | 687 | ||
680 | DP_VERBOSE(p_hwfn, QED_MSG_RDMA, "RDMA setup\n"); | 688 | DP_VERBOSE(p_hwfn, QED_MSG_RDMA, "RDMA setup\n"); |
681 | 689 | ||
682 | spin_lock_init(&p_hwfn->p_rdma_info->lock); | ||
683 | |||
684 | qed_rdma_init_devinfo(p_hwfn, params); | 690 | qed_rdma_init_devinfo(p_hwfn, params); |
685 | qed_rdma_init_port(p_hwfn); | 691 | qed_rdma_init_port(p_hwfn); |
686 | qed_rdma_init_events(p_hwfn, params); | 692 | qed_rdma_init_events(p_hwfn, params); |
@@ -727,7 +733,7 @@ static int qed_rdma_stop(void *rdma_cxt) | |||
727 | /* Disable RoCE search */ | 733 | /* Disable RoCE search */ |
728 | qed_wr(p_hwfn, p_ptt, p_hwfn->rdma_prs_search_reg, 0); | 734 | qed_wr(p_hwfn, p_ptt, p_hwfn->rdma_prs_search_reg, 0); |
729 | p_hwfn->b_rdma_enabled_in_prs = false; | 735 | p_hwfn->b_rdma_enabled_in_prs = false; |
730 | 736 | p_hwfn->p_rdma_info->active = 0; | |
731 | qed_wr(p_hwfn, p_ptt, PRS_REG_ROCE_DEST_QP_MAX_PF, 0); | 737 | qed_wr(p_hwfn, p_ptt, PRS_REG_ROCE_DEST_QP_MAX_PF, 0); |
732 | 738 | ||
733 | ll2_ethertype_en = qed_rd(p_hwfn, p_ptt, PRS_REG_LIGHT_L2_ETHERTYPE_EN); | 739 | ll2_ethertype_en = qed_rd(p_hwfn, p_ptt, PRS_REG_LIGHT_L2_ETHERTYPE_EN); |
@@ -1236,7 +1242,8 @@ qed_rdma_create_qp(void *rdma_cxt, | |||
1236 | u8 max_stats_queues; | 1242 | u8 max_stats_queues; |
1237 | int rc; | 1243 | int rc; |
1238 | 1244 | ||
1239 | if (!rdma_cxt || !in_params || !out_params || !p_hwfn->p_rdma_info) { | 1245 | if (!rdma_cxt || !in_params || !out_params || |
1246 | !p_hwfn->p_rdma_info->active) { | ||
1240 | DP_ERR(p_hwfn->cdev, | 1247 | DP_ERR(p_hwfn->cdev, |
1241 | "qed roce create qp failed due to NULL entry (rdma_cxt=%p, in=%p, out=%p, roce_info=?\n", | 1248 | "qed roce create qp failed due to NULL entry (rdma_cxt=%p, in=%p, out=%p, roce_info=?\n", |
1242 | rdma_cxt, in_params, out_params); | 1249 | rdma_cxt, in_params, out_params); |
@@ -1802,8 +1809,8 @@ bool qed_rdma_allocated_qps(struct qed_hwfn *p_hwfn) | |||
1802 | { | 1809 | { |
1803 | bool result; | 1810 | bool result; |
1804 | 1811 | ||
1805 | /* if rdma info has not been allocated, naturally there are no qps */ | 1812 | /* if rdma wasn't activated yet, naturally there are no qps */ |
1806 | if (!p_hwfn->p_rdma_info) | 1813 | if (!p_hwfn->p_rdma_info->active) |
1807 | return false; | 1814 | return false; |
1808 | 1815 | ||
1809 | spin_lock_bh(&p_hwfn->p_rdma_info->lock); | 1816 | spin_lock_bh(&p_hwfn->p_rdma_info->lock); |
@@ -1849,7 +1856,7 @@ static int qed_rdma_start(void *rdma_cxt, | |||
1849 | if (!p_ptt) | 1856 | if (!p_ptt) |
1850 | goto err; | 1857 | goto err; |
1851 | 1858 | ||
1852 | rc = qed_rdma_alloc(p_hwfn, p_ptt, params); | 1859 | rc = qed_rdma_alloc(p_hwfn); |
1853 | if (rc) | 1860 | if (rc) |
1854 | goto err1; | 1861 | goto err1; |
1855 | 1862 | ||
@@ -1858,6 +1865,7 @@ static int qed_rdma_start(void *rdma_cxt, | |||
1858 | goto err2; | 1865 | goto err2; |
1859 | 1866 | ||
1860 | qed_ptt_release(p_hwfn, p_ptt); | 1867 | qed_ptt_release(p_hwfn, p_ptt); |
1868 | p_hwfn->p_rdma_info->active = 1; | ||
1861 | 1869 | ||
1862 | return rc; | 1870 | return rc; |
1863 | 1871 | ||
diff --git a/drivers/net/ethernet/qlogic/qed/qed_rdma.h b/drivers/net/ethernet/qlogic/qed/qed_rdma.h index 6f722ee8ee94..3689fe3e5935 100644 --- a/drivers/net/ethernet/qlogic/qed/qed_rdma.h +++ b/drivers/net/ethernet/qlogic/qed/qed_rdma.h | |||
@@ -102,6 +102,7 @@ struct qed_rdma_info { | |||
102 | u16 max_queue_zones; | 102 | u16 max_queue_zones; |
103 | enum protocol_type proto; | 103 | enum protocol_type proto; |
104 | struct qed_iwarp_info iwarp; | 104 | struct qed_iwarp_info iwarp; |
105 | u8 active:1; | ||
105 | }; | 106 | }; |
106 | 107 | ||
107 | struct qed_rdma_qp { | 108 | struct qed_rdma_qp { |
@@ -176,10 +177,14 @@ struct qed_rdma_qp { | |||
176 | #if IS_ENABLED(CONFIG_QED_RDMA) | 177 | #if IS_ENABLED(CONFIG_QED_RDMA) |
177 | void qed_rdma_dpm_bar(struct qed_hwfn *p_hwfn, struct qed_ptt *p_ptt); | 178 | void qed_rdma_dpm_bar(struct qed_hwfn *p_hwfn, struct qed_ptt *p_ptt); |
178 | void qed_rdma_dpm_conf(struct qed_hwfn *p_hwfn, struct qed_ptt *p_ptt); | 179 | void qed_rdma_dpm_conf(struct qed_hwfn *p_hwfn, struct qed_ptt *p_ptt); |
180 | int qed_rdma_info_alloc(struct qed_hwfn *p_hwfn); | ||
181 | void qed_rdma_info_free(struct qed_hwfn *p_hwfn); | ||
179 | #else | 182 | #else |
180 | static inline void qed_rdma_dpm_conf(struct qed_hwfn *p_hwfn, struct qed_ptt *p_ptt) {} | 183 | static inline void qed_rdma_dpm_conf(struct qed_hwfn *p_hwfn, struct qed_ptt *p_ptt) {} |
181 | static inline void qed_rdma_dpm_bar(struct qed_hwfn *p_hwfn, | 184 | static inline void qed_rdma_dpm_bar(struct qed_hwfn *p_hwfn, |
182 | struct qed_ptt *p_ptt) {} | 185 | struct qed_ptt *p_ptt) {} |
186 | static inline int qed_rdma_info_alloc(struct qed_hwfn *p_hwfn) {return -EINVAL;} | ||
187 | static inline void qed_rdma_info_free(struct qed_hwfn *p_hwfn) {} | ||
183 | #endif | 188 | #endif |
184 | 189 | ||
185 | int | 190 | int |
diff --git a/drivers/net/phy/mdio-gpio.c b/drivers/net/phy/mdio-gpio.c index 33265747bf39..0fbcedcdf6e2 100644 --- a/drivers/net/phy/mdio-gpio.c +++ b/drivers/net/phy/mdio-gpio.c | |||
@@ -63,7 +63,7 @@ static void mdio_dir(struct mdiobb_ctrl *ctrl, int dir) | |||
63 | * assume the pin serves as pull-up. If direction is | 63 | * assume the pin serves as pull-up. If direction is |
64 | * output, the default value is high. | 64 | * output, the default value is high. |
65 | */ | 65 | */ |
66 | gpiod_set_value(bitbang->mdo, 1); | 66 | gpiod_set_value_cansleep(bitbang->mdo, 1); |
67 | return; | 67 | return; |
68 | } | 68 | } |
69 | 69 | ||
@@ -78,7 +78,7 @@ static int mdio_get(struct mdiobb_ctrl *ctrl) | |||
78 | struct mdio_gpio_info *bitbang = | 78 | struct mdio_gpio_info *bitbang = |
79 | container_of(ctrl, struct mdio_gpio_info, ctrl); | 79 | container_of(ctrl, struct mdio_gpio_info, ctrl); |
80 | 80 | ||
81 | return gpiod_get_value(bitbang->mdio); | 81 | return gpiod_get_value_cansleep(bitbang->mdio); |
82 | } | 82 | } |
83 | 83 | ||
84 | static void mdio_set(struct mdiobb_ctrl *ctrl, int what) | 84 | static void mdio_set(struct mdiobb_ctrl *ctrl, int what) |
@@ -87,9 +87,9 @@ static void mdio_set(struct mdiobb_ctrl *ctrl, int what) | |||
87 | container_of(ctrl, struct mdio_gpio_info, ctrl); | 87 | container_of(ctrl, struct mdio_gpio_info, ctrl); |
88 | 88 | ||
89 | if (bitbang->mdo) | 89 | if (bitbang->mdo) |
90 | gpiod_set_value(bitbang->mdo, what); | 90 | gpiod_set_value_cansleep(bitbang->mdo, what); |
91 | else | 91 | else |
92 | gpiod_set_value(bitbang->mdio, what); | 92 | gpiod_set_value_cansleep(bitbang->mdio, what); |
93 | } | 93 | } |
94 | 94 | ||
95 | static void mdc_set(struct mdiobb_ctrl *ctrl, int what) | 95 | static void mdc_set(struct mdiobb_ctrl *ctrl, int what) |
@@ -97,7 +97,7 @@ static void mdc_set(struct mdiobb_ctrl *ctrl, int what) | |||
97 | struct mdio_gpio_info *bitbang = | 97 | struct mdio_gpio_info *bitbang = |
98 | container_of(ctrl, struct mdio_gpio_info, ctrl); | 98 | container_of(ctrl, struct mdio_gpio_info, ctrl); |
99 | 99 | ||
100 | gpiod_set_value(bitbang->mdc, what); | 100 | gpiod_set_value_cansleep(bitbang->mdc, what); |
101 | } | 101 | } |
102 | 102 | ||
103 | static const struct mdiobb_ops mdio_gpio_ops = { | 103 | static const struct mdiobb_ops mdio_gpio_ops = { |
diff --git a/drivers/net/phy/mscc.c b/drivers/net/phy/mscc.c index a2e59f4f6f01..7cae17517744 100644 --- a/drivers/net/phy/mscc.c +++ b/drivers/net/phy/mscc.c | |||
@@ -810,17 +810,13 @@ static int vsc85xx_default_config(struct phy_device *phydev) | |||
810 | 810 | ||
811 | phydev->mdix_ctrl = ETH_TP_MDI_AUTO; | 811 | phydev->mdix_ctrl = ETH_TP_MDI_AUTO; |
812 | mutex_lock(&phydev->lock); | 812 | mutex_lock(&phydev->lock); |
813 | rc = phy_select_page(phydev, MSCC_PHY_PAGE_EXTENDED_2); | ||
814 | if (rc < 0) | ||
815 | goto out_unlock; | ||
816 | 813 | ||
817 | reg_val = phy_read(phydev, MSCC_PHY_RGMII_CNTL); | 814 | reg_val = RGMII_RX_CLK_DELAY_1_1_NS << RGMII_RX_CLK_DELAY_POS; |
818 | reg_val &= ~(RGMII_RX_CLK_DELAY_MASK); | 815 | |
819 | reg_val |= (RGMII_RX_CLK_DELAY_1_1_NS << RGMII_RX_CLK_DELAY_POS); | 816 | rc = phy_modify_paged(phydev, MSCC_PHY_PAGE_EXTENDED_2, |
820 | phy_write(phydev, MSCC_PHY_RGMII_CNTL, reg_val); | 817 | MSCC_PHY_RGMII_CNTL, RGMII_RX_CLK_DELAY_MASK, |
818 | reg_val); | ||
821 | 819 | ||
822 | out_unlock: | ||
823 | rc = phy_restore_page(phydev, rc, rc > 0 ? 0 : rc); | ||
824 | mutex_unlock(&phydev->lock); | 820 | mutex_unlock(&phydev->lock); |
825 | 821 | ||
826 | return rc; | 822 | return rc; |
diff --git a/drivers/net/team/team.c b/drivers/net/team/team.c index db633ae9f784..364f514d56d8 100644 --- a/drivers/net/team/team.c +++ b/drivers/net/team/team.c | |||
@@ -985,8 +985,6 @@ static void team_port_disable(struct team *team, | |||
985 | team->en_port_count--; | 985 | team->en_port_count--; |
986 | team_queue_override_port_del(team, port); | 986 | team_queue_override_port_del(team, port); |
987 | team_adjust_ops(team); | 987 | team_adjust_ops(team); |
988 | team_notify_peers(team); | ||
989 | team_mcast_rejoin(team); | ||
990 | team_lower_state_changed(port); | 988 | team_lower_state_changed(port); |
991 | } | 989 | } |
992 | 990 | ||
diff --git a/drivers/net/tun.c b/drivers/net/tun.c index 060135ceaf0e..e244f5d7512a 100644 --- a/drivers/net/tun.c +++ b/drivers/net/tun.c | |||
@@ -1536,6 +1536,7 @@ static void tun_rx_batched(struct tun_struct *tun, struct tun_file *tfile, | |||
1536 | 1536 | ||
1537 | if (!rx_batched || (!more && skb_queue_empty(queue))) { | 1537 | if (!rx_batched || (!more && skb_queue_empty(queue))) { |
1538 | local_bh_disable(); | 1538 | local_bh_disable(); |
1539 | skb_record_rx_queue(skb, tfile->queue_index); | ||
1539 | netif_receive_skb(skb); | 1540 | netif_receive_skb(skb); |
1540 | local_bh_enable(); | 1541 | local_bh_enable(); |
1541 | return; | 1542 | return; |
@@ -1555,8 +1556,11 @@ static void tun_rx_batched(struct tun_struct *tun, struct tun_file *tfile, | |||
1555 | struct sk_buff *nskb; | 1556 | struct sk_buff *nskb; |
1556 | 1557 | ||
1557 | local_bh_disable(); | 1558 | local_bh_disable(); |
1558 | while ((nskb = __skb_dequeue(&process_queue))) | 1559 | while ((nskb = __skb_dequeue(&process_queue))) { |
1560 | skb_record_rx_queue(nskb, tfile->queue_index); | ||
1559 | netif_receive_skb(nskb); | 1561 | netif_receive_skb(nskb); |
1562 | } | ||
1563 | skb_record_rx_queue(skb, tfile->queue_index); | ||
1560 | netif_receive_skb(skb); | 1564 | netif_receive_skb(skb); |
1561 | local_bh_enable(); | 1565 | local_bh_enable(); |
1562 | } | 1566 | } |
@@ -2451,6 +2455,7 @@ build: | |||
2451 | if (!rcu_dereference(tun->steering_prog)) | 2455 | if (!rcu_dereference(tun->steering_prog)) |
2452 | rxhash = __skb_get_hash_symmetric(skb); | 2456 | rxhash = __skb_get_hash_symmetric(skb); |
2453 | 2457 | ||
2458 | skb_record_rx_queue(skb, tfile->queue_index); | ||
2454 | netif_receive_skb(skb); | 2459 | netif_receive_skb(skb); |
2455 | 2460 | ||
2456 | stats = get_cpu_ptr(tun->pcpu_stats); | 2461 | stats = get_cpu_ptr(tun->pcpu_stats); |
diff --git a/drivers/net/virtio_net.c b/drivers/net/virtio_net.c index 3e2c041d76ac..cecfd77c9f3c 100644 --- a/drivers/net/virtio_net.c +++ b/drivers/net/virtio_net.c | |||
@@ -70,7 +70,8 @@ static const unsigned long guest_offloads[] = { | |||
70 | VIRTIO_NET_F_GUEST_TSO4, | 70 | VIRTIO_NET_F_GUEST_TSO4, |
71 | VIRTIO_NET_F_GUEST_TSO6, | 71 | VIRTIO_NET_F_GUEST_TSO6, |
72 | VIRTIO_NET_F_GUEST_ECN, | 72 | VIRTIO_NET_F_GUEST_ECN, |
73 | VIRTIO_NET_F_GUEST_UFO | 73 | VIRTIO_NET_F_GUEST_UFO, |
74 | VIRTIO_NET_F_GUEST_CSUM | ||
74 | }; | 75 | }; |
75 | 76 | ||
76 | struct virtnet_stat_desc { | 77 | struct virtnet_stat_desc { |
@@ -2334,9 +2335,6 @@ static int virtnet_clear_guest_offloads(struct virtnet_info *vi) | |||
2334 | if (!vi->guest_offloads) | 2335 | if (!vi->guest_offloads) |
2335 | return 0; | 2336 | return 0; |
2336 | 2337 | ||
2337 | if (virtio_has_feature(vi->vdev, VIRTIO_NET_F_GUEST_CSUM)) | ||
2338 | offloads = 1ULL << VIRTIO_NET_F_GUEST_CSUM; | ||
2339 | |||
2340 | return virtnet_set_guest_offloads(vi, offloads); | 2338 | return virtnet_set_guest_offloads(vi, offloads); |
2341 | } | 2339 | } |
2342 | 2340 | ||
@@ -2346,8 +2344,6 @@ static int virtnet_restore_guest_offloads(struct virtnet_info *vi) | |||
2346 | 2344 | ||
2347 | if (!vi->guest_offloads) | 2345 | if (!vi->guest_offloads) |
2348 | return 0; | 2346 | return 0; |
2349 | if (virtio_has_feature(vi->vdev, VIRTIO_NET_F_GUEST_CSUM)) | ||
2350 | offloads |= 1ULL << VIRTIO_NET_F_GUEST_CSUM; | ||
2351 | 2347 | ||
2352 | return virtnet_set_guest_offloads(vi, offloads); | 2348 | return virtnet_set_guest_offloads(vi, offloads); |
2353 | } | 2349 | } |
@@ -2365,8 +2361,9 @@ static int virtnet_xdp_set(struct net_device *dev, struct bpf_prog *prog, | |||
2365 | && (virtio_has_feature(vi->vdev, VIRTIO_NET_F_GUEST_TSO4) || | 2361 | && (virtio_has_feature(vi->vdev, VIRTIO_NET_F_GUEST_TSO4) || |
2366 | virtio_has_feature(vi->vdev, VIRTIO_NET_F_GUEST_TSO6) || | 2362 | virtio_has_feature(vi->vdev, VIRTIO_NET_F_GUEST_TSO6) || |
2367 | virtio_has_feature(vi->vdev, VIRTIO_NET_F_GUEST_ECN) || | 2363 | virtio_has_feature(vi->vdev, VIRTIO_NET_F_GUEST_ECN) || |
2368 | virtio_has_feature(vi->vdev, VIRTIO_NET_F_GUEST_UFO))) { | 2364 | virtio_has_feature(vi->vdev, VIRTIO_NET_F_GUEST_UFO) || |
2369 | NL_SET_ERR_MSG_MOD(extack, "Can't set XDP while host is implementing LRO, disable LRO first"); | 2365 | virtio_has_feature(vi->vdev, VIRTIO_NET_F_GUEST_CSUM))) { |
2366 | NL_SET_ERR_MSG_MOD(extack, "Can't set XDP while host is implementing LRO/CSUM, disable LRO/CSUM first"); | ||
2370 | return -EOPNOTSUPP; | 2367 | return -EOPNOTSUPP; |
2371 | } | 2368 | } |
2372 | 2369 | ||
diff --git a/drivers/net/wireless/ath/ath10k/mac.c b/drivers/net/wireless/ath/ath10k/mac.c index a1c2801ded10..7e49342bae38 100644 --- a/drivers/net/wireless/ath/ath10k/mac.c +++ b/drivers/net/wireless/ath/ath10k/mac.c | |||
@@ -6867,7 +6867,7 @@ static void ath10k_flush(struct ieee80211_hw *hw, struct ieee80211_vif *vif, | |||
6867 | u32 bitmap; | 6867 | u32 bitmap; |
6868 | 6868 | ||
6869 | if (drop) { | 6869 | if (drop) { |
6870 | if (vif->type == NL80211_IFTYPE_STATION) { | 6870 | if (vif && vif->type == NL80211_IFTYPE_STATION) { |
6871 | bitmap = ~(1 << WMI_MGMT_TID); | 6871 | bitmap = ~(1 << WMI_MGMT_TID); |
6872 | list_for_each_entry(arvif, &ar->arvifs, list) { | 6872 | list_for_each_entry(arvif, &ar->arvifs, list) { |
6873 | if (arvif->vdev_type == WMI_VDEV_TYPE_STA) | 6873 | if (arvif->vdev_type == WMI_VDEV_TYPE_STA) |
diff --git a/drivers/net/wireless/ath/ath9k/main.c b/drivers/net/wireless/ath/ath9k/main.c index 1e3b5f4a4cf9..f23cb2f3d296 100644 --- a/drivers/net/wireless/ath/ath9k/main.c +++ b/drivers/net/wireless/ath/ath9k/main.c | |||
@@ -1251,6 +1251,7 @@ static int ath9k_add_interface(struct ieee80211_hw *hw, | |||
1251 | struct ath_vif *avp = (void *)vif->drv_priv; | 1251 | struct ath_vif *avp = (void *)vif->drv_priv; |
1252 | struct ath_node *an = &avp->mcast_node; | 1252 | struct ath_node *an = &avp->mcast_node; |
1253 | 1253 | ||
1254 | mutex_lock(&sc->mutex); | ||
1254 | if (IS_ENABLED(CONFIG_ATH9K_TX99)) { | 1255 | if (IS_ENABLED(CONFIG_ATH9K_TX99)) { |
1255 | if (sc->cur_chan->nvifs >= 1) { | 1256 | if (sc->cur_chan->nvifs >= 1) { |
1256 | mutex_unlock(&sc->mutex); | 1257 | mutex_unlock(&sc->mutex); |
@@ -1259,8 +1260,6 @@ static int ath9k_add_interface(struct ieee80211_hw *hw, | |||
1259 | sc->tx99_vif = vif; | 1260 | sc->tx99_vif = vif; |
1260 | } | 1261 | } |
1261 | 1262 | ||
1262 | mutex_lock(&sc->mutex); | ||
1263 | |||
1264 | ath_dbg(common, CONFIG, "Attach a VIF of type: %d\n", vif->type); | 1263 | ath_dbg(common, CONFIG, "Attach a VIF of type: %d\n", vif->type); |
1265 | sc->cur_chan->nvifs++; | 1264 | sc->cur_chan->nvifs++; |
1266 | 1265 | ||
diff --git a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/cfg80211.c b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/cfg80211.c index 230a378c26fc..7f0a5bade70a 100644 --- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/cfg80211.c +++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/cfg80211.c | |||
@@ -6005,7 +6005,8 @@ static int brcmf_construct_chaninfo(struct brcmf_cfg80211_info *cfg, | |||
6005 | * for subsequent chanspecs. | 6005 | * for subsequent chanspecs. |
6006 | */ | 6006 | */ |
6007 | channel->flags = IEEE80211_CHAN_NO_HT40 | | 6007 | channel->flags = IEEE80211_CHAN_NO_HT40 | |
6008 | IEEE80211_CHAN_NO_80MHZ; | 6008 | IEEE80211_CHAN_NO_80MHZ | |
6009 | IEEE80211_CHAN_NO_160MHZ; | ||
6009 | ch.bw = BRCMU_CHAN_BW_20; | 6010 | ch.bw = BRCMU_CHAN_BW_20; |
6010 | cfg->d11inf.encchspec(&ch); | 6011 | cfg->d11inf.encchspec(&ch); |
6011 | chaninfo = ch.chspec; | 6012 | chaninfo = ch.chspec; |
diff --git a/drivers/net/wireless/broadcom/brcm80211/brcmutil/d11.c b/drivers/net/wireless/broadcom/brcm80211/brcmutil/d11.c index e7584b842dce..eb5db94f5745 100644 --- a/drivers/net/wireless/broadcom/brcm80211/brcmutil/d11.c +++ b/drivers/net/wireless/broadcom/brcm80211/brcmutil/d11.c | |||
@@ -193,6 +193,9 @@ static void brcmu_d11ac_decchspec(struct brcmu_chan *ch) | |||
193 | } | 193 | } |
194 | break; | 194 | break; |
195 | case BRCMU_CHSPEC_D11AC_BW_160: | 195 | case BRCMU_CHSPEC_D11AC_BW_160: |
196 | ch->bw = BRCMU_CHAN_BW_160; | ||
197 | ch->sb = brcmu_maskget16(ch->chspec, BRCMU_CHSPEC_D11AC_SB_MASK, | ||
198 | BRCMU_CHSPEC_D11AC_SB_SHIFT); | ||
196 | switch (ch->sb) { | 199 | switch (ch->sb) { |
197 | case BRCMU_CHAN_SB_LLL: | 200 | case BRCMU_CHAN_SB_LLL: |
198 | ch->control_ch_num -= CH_70MHZ_APART; | 201 | ch->control_ch_num -= CH_70MHZ_APART; |
diff --git a/drivers/net/wireless/intel/iwlwifi/fw/acpi.h b/drivers/net/wireless/intel/iwlwifi/fw/acpi.h index 2439e98431ee..7492dfb6729b 100644 --- a/drivers/net/wireless/intel/iwlwifi/fw/acpi.h +++ b/drivers/net/wireless/intel/iwlwifi/fw/acpi.h | |||
@@ -6,6 +6,7 @@ | |||
6 | * GPL LICENSE SUMMARY | 6 | * GPL LICENSE SUMMARY |
7 | * | 7 | * |
8 | * Copyright(c) 2017 Intel Deutschland GmbH | 8 | * Copyright(c) 2017 Intel Deutschland GmbH |
9 | * Copyright(c) 2018 Intel Corporation | ||
9 | * | 10 | * |
10 | * This program is free software; you can redistribute it and/or modify | 11 | * This program is free software; you can redistribute it and/or modify |
11 | * it under the terms of version 2 of the GNU General Public License as | 12 | * it under the terms of version 2 of the GNU General Public License as |
@@ -26,6 +27,7 @@ | |||
26 | * BSD LICENSE | 27 | * BSD LICENSE |
27 | * | 28 | * |
28 | * Copyright(c) 2017 Intel Deutschland GmbH | 29 | * Copyright(c) 2017 Intel Deutschland GmbH |
30 | * Copyright(c) 2018 Intel Corporation | ||
29 | * All rights reserved. | 31 | * All rights reserved. |
30 | * | 32 | * |
31 | * Redistribution and use in source and binary forms, with or without | 33 | * Redistribution and use in source and binary forms, with or without |
@@ -81,7 +83,7 @@ | |||
81 | #define ACPI_WRDS_WIFI_DATA_SIZE (ACPI_SAR_TABLE_SIZE + 2) | 83 | #define ACPI_WRDS_WIFI_DATA_SIZE (ACPI_SAR_TABLE_SIZE + 2) |
82 | #define ACPI_EWRD_WIFI_DATA_SIZE ((ACPI_SAR_PROFILE_NUM - 1) * \ | 84 | #define ACPI_EWRD_WIFI_DATA_SIZE ((ACPI_SAR_PROFILE_NUM - 1) * \ |
83 | ACPI_SAR_TABLE_SIZE + 3) | 85 | ACPI_SAR_TABLE_SIZE + 3) |
84 | #define ACPI_WGDS_WIFI_DATA_SIZE 18 | 86 | #define ACPI_WGDS_WIFI_DATA_SIZE 19 |
85 | #define ACPI_WRDD_WIFI_DATA_SIZE 2 | 87 | #define ACPI_WRDD_WIFI_DATA_SIZE 2 |
86 | #define ACPI_SPLC_WIFI_DATA_SIZE 2 | 88 | #define ACPI_SPLC_WIFI_DATA_SIZE 2 |
87 | 89 | ||
diff --git a/drivers/net/wireless/intel/iwlwifi/fw/runtime.h b/drivers/net/wireless/intel/iwlwifi/fw/runtime.h index 6b95d0e75889..2b8b50a77990 100644 --- a/drivers/net/wireless/intel/iwlwifi/fw/runtime.h +++ b/drivers/net/wireless/intel/iwlwifi/fw/runtime.h | |||
@@ -154,7 +154,11 @@ void iwl_fw_runtime_init(struct iwl_fw_runtime *fwrt, struct iwl_trans *trans, | |||
154 | const struct iwl_fw_runtime_ops *ops, void *ops_ctx, | 154 | const struct iwl_fw_runtime_ops *ops, void *ops_ctx, |
155 | struct dentry *dbgfs_dir); | 155 | struct dentry *dbgfs_dir); |
156 | 156 | ||
157 | void iwl_fw_runtime_exit(struct iwl_fw_runtime *fwrt); | 157 | static inline void iwl_fw_runtime_free(struct iwl_fw_runtime *fwrt) |
158 | { | ||
159 | kfree(fwrt->dump.d3_debug_data); | ||
160 | fwrt->dump.d3_debug_data = NULL; | ||
161 | } | ||
158 | 162 | ||
159 | void iwl_fw_runtime_suspend(struct iwl_fw_runtime *fwrt); | 163 | void iwl_fw_runtime_suspend(struct iwl_fw_runtime *fwrt); |
160 | 164 | ||
diff --git a/drivers/net/wireless/intel/iwlwifi/mvm/fw.c b/drivers/net/wireless/intel/iwlwifi/mvm/fw.c index dade206d5511..2ba890445c35 100644 --- a/drivers/net/wireless/intel/iwlwifi/mvm/fw.c +++ b/drivers/net/wireless/intel/iwlwifi/mvm/fw.c | |||
@@ -893,7 +893,7 @@ static int iwl_mvm_sar_geo_init(struct iwl_mvm *mvm) | |||
893 | IWL_DEBUG_RADIO(mvm, "Sending GEO_TX_POWER_LIMIT\n"); | 893 | IWL_DEBUG_RADIO(mvm, "Sending GEO_TX_POWER_LIMIT\n"); |
894 | 894 | ||
895 | BUILD_BUG_ON(ACPI_NUM_GEO_PROFILES * ACPI_WGDS_NUM_BANDS * | 895 | BUILD_BUG_ON(ACPI_NUM_GEO_PROFILES * ACPI_WGDS_NUM_BANDS * |
896 | ACPI_WGDS_TABLE_SIZE != ACPI_WGDS_WIFI_DATA_SIZE); | 896 | ACPI_WGDS_TABLE_SIZE + 1 != ACPI_WGDS_WIFI_DATA_SIZE); |
897 | 897 | ||
898 | BUILD_BUG_ON(ACPI_NUM_GEO_PROFILES > IWL_NUM_GEO_PROFILES); | 898 | BUILD_BUG_ON(ACPI_NUM_GEO_PROFILES > IWL_NUM_GEO_PROFILES); |
899 | 899 | ||
@@ -928,6 +928,11 @@ static int iwl_mvm_sar_get_ewrd_table(struct iwl_mvm *mvm) | |||
928 | return -ENOENT; | 928 | return -ENOENT; |
929 | } | 929 | } |
930 | 930 | ||
931 | static int iwl_mvm_sar_get_wgds_table(struct iwl_mvm *mvm) | ||
932 | { | ||
933 | return -ENOENT; | ||
934 | } | ||
935 | |||
931 | static int iwl_mvm_sar_geo_init(struct iwl_mvm *mvm) | 936 | static int iwl_mvm_sar_geo_init(struct iwl_mvm *mvm) |
932 | { | 937 | { |
933 | return 0; | 938 | return 0; |
@@ -954,8 +959,11 @@ static int iwl_mvm_sar_init(struct iwl_mvm *mvm) | |||
954 | IWL_DEBUG_RADIO(mvm, | 959 | IWL_DEBUG_RADIO(mvm, |
955 | "WRDS SAR BIOS table invalid or unavailable. (%d)\n", | 960 | "WRDS SAR BIOS table invalid or unavailable. (%d)\n", |
956 | ret); | 961 | ret); |
957 | /* if not available, don't fail and don't bother with EWRD */ | 962 | /* |
958 | return 0; | 963 | * If not available, don't fail and don't bother with EWRD. |
964 | * Return 1 to tell that we can't use WGDS either. | ||
965 | */ | ||
966 | return 1; | ||
959 | } | 967 | } |
960 | 968 | ||
961 | ret = iwl_mvm_sar_get_ewrd_table(mvm); | 969 | ret = iwl_mvm_sar_get_ewrd_table(mvm); |
@@ -968,9 +976,13 @@ static int iwl_mvm_sar_init(struct iwl_mvm *mvm) | |||
968 | /* choose profile 1 (WRDS) as default for both chains */ | 976 | /* choose profile 1 (WRDS) as default for both chains */ |
969 | ret = iwl_mvm_sar_select_profile(mvm, 1, 1); | 977 | ret = iwl_mvm_sar_select_profile(mvm, 1, 1); |
970 | 978 | ||
971 | /* if we don't have profile 0 from BIOS, just skip it */ | 979 | /* |
980 | * If we don't have profile 0 from BIOS, just skip it. This | ||
981 | * means that SAR Geo will not be enabled either, even if we | ||
982 | * have other valid profiles. | ||
983 | */ | ||
972 | if (ret == -ENOENT) | 984 | if (ret == -ENOENT) |
973 | return 0; | 985 | return 1; |
974 | 986 | ||
975 | return ret; | 987 | return ret; |
976 | } | 988 | } |
@@ -1168,11 +1180,19 @@ int iwl_mvm_up(struct iwl_mvm *mvm) | |||
1168 | iwl_mvm_unref(mvm, IWL_MVM_REF_UCODE_DOWN); | 1180 | iwl_mvm_unref(mvm, IWL_MVM_REF_UCODE_DOWN); |
1169 | 1181 | ||
1170 | ret = iwl_mvm_sar_init(mvm); | 1182 | ret = iwl_mvm_sar_init(mvm); |
1171 | if (ret) | 1183 | if (ret == 0) { |
1172 | goto error; | 1184 | ret = iwl_mvm_sar_geo_init(mvm); |
1185 | } else if (ret > 0 && !iwl_mvm_sar_get_wgds_table(mvm)) { | ||
1186 | /* | ||
1187 | * If basic SAR is not available, we check for WGDS, | ||
1188 | * which should *not* be available either. If it is | ||
1189 | * available, issue an error, because we can't use SAR | ||
1190 | * Geo without basic SAR. | ||
1191 | */ | ||
1192 | IWL_ERR(mvm, "BIOS contains WGDS but no WRDS\n"); | ||
1193 | } | ||
1173 | 1194 | ||
1174 | ret = iwl_mvm_sar_geo_init(mvm); | 1195 | if (ret < 0) |
1175 | if (ret) | ||
1176 | goto error; | 1196 | goto error; |
1177 | 1197 | ||
1178 | iwl_mvm_leds_sync(mvm); | 1198 | iwl_mvm_leds_sync(mvm); |
diff --git a/drivers/net/wireless/intel/iwlwifi/mvm/mac80211.c b/drivers/net/wireless/intel/iwlwifi/mvm/mac80211.c index 505b0385d800..00f831d88366 100644 --- a/drivers/net/wireless/intel/iwlwifi/mvm/mac80211.c +++ b/drivers/net/wireless/intel/iwlwifi/mvm/mac80211.c | |||
@@ -301,8 +301,12 @@ struct ieee80211_regdomain *iwl_mvm_get_regdomain(struct wiphy *wiphy, | |||
301 | goto out; | 301 | goto out; |
302 | } | 302 | } |
303 | 303 | ||
304 | if (changed) | 304 | if (changed) { |
305 | *changed = (resp->status == MCC_RESP_NEW_CHAN_PROFILE); | 305 | u32 status = le32_to_cpu(resp->status); |
306 | |||
307 | *changed = (status == MCC_RESP_NEW_CHAN_PROFILE || | ||
308 | status == MCC_RESP_ILLEGAL); | ||
309 | } | ||
306 | 310 | ||
307 | regd = iwl_parse_nvm_mcc_info(mvm->trans->dev, mvm->cfg, | 311 | regd = iwl_parse_nvm_mcc_info(mvm->trans->dev, mvm->cfg, |
308 | __le32_to_cpu(resp->n_channels), | 312 | __le32_to_cpu(resp->n_channels), |
@@ -4444,10 +4448,6 @@ static void iwl_mvm_mac_sta_statistics(struct ieee80211_hw *hw, | |||
4444 | sinfo->filled |= BIT_ULL(NL80211_STA_INFO_SIGNAL_AVG); | 4448 | sinfo->filled |= BIT_ULL(NL80211_STA_INFO_SIGNAL_AVG); |
4445 | } | 4449 | } |
4446 | 4450 | ||
4447 | if (!fw_has_capa(&mvm->fw->ucode_capa, | ||
4448 | IWL_UCODE_TLV_CAPA_RADIO_BEACON_STATS)) | ||
4449 | return; | ||
4450 | |||
4451 | /* if beacon filtering isn't on mac80211 does it anyway */ | 4451 | /* if beacon filtering isn't on mac80211 does it anyway */ |
4452 | if (!(vif->driver_flags & IEEE80211_VIF_BEACON_FILTER)) | 4452 | if (!(vif->driver_flags & IEEE80211_VIF_BEACON_FILTER)) |
4453 | return; | 4453 | return; |
diff --git a/drivers/net/wireless/intel/iwlwifi/mvm/nvm.c b/drivers/net/wireless/intel/iwlwifi/mvm/nvm.c index 3633f27d048a..6fc5cc1f2b5b 100644 --- a/drivers/net/wireless/intel/iwlwifi/mvm/nvm.c +++ b/drivers/net/wireless/intel/iwlwifi/mvm/nvm.c | |||
@@ -539,9 +539,8 @@ iwl_mvm_update_mcc(struct iwl_mvm *mvm, const char *alpha2, | |||
539 | } | 539 | } |
540 | 540 | ||
541 | IWL_DEBUG_LAR(mvm, | 541 | IWL_DEBUG_LAR(mvm, |
542 | "MCC response status: 0x%x. new MCC: 0x%x ('%c%c') change: %d n_chans: %d\n", | 542 | "MCC response status: 0x%x. new MCC: 0x%x ('%c%c') n_chans: %d\n", |
543 | status, mcc, mcc >> 8, mcc & 0xff, | 543 | status, mcc, mcc >> 8, mcc & 0xff, n_channels); |
544 | !!(status == MCC_RESP_NEW_CHAN_PROFILE), n_channels); | ||
545 | 544 | ||
546 | exit: | 545 | exit: |
547 | iwl_free_resp(&cmd); | 546 | iwl_free_resp(&cmd); |
diff --git a/drivers/net/wireless/intel/iwlwifi/mvm/ops.c b/drivers/net/wireless/intel/iwlwifi/mvm/ops.c index 0e2092526fae..af3fba10abc1 100644 --- a/drivers/net/wireless/intel/iwlwifi/mvm/ops.c +++ b/drivers/net/wireless/intel/iwlwifi/mvm/ops.c | |||
@@ -858,6 +858,7 @@ iwl_op_mode_mvm_start(struct iwl_trans *trans, const struct iwl_cfg *cfg, | |||
858 | iwl_mvm_thermal_exit(mvm); | 858 | iwl_mvm_thermal_exit(mvm); |
859 | out_free: | 859 | out_free: |
860 | iwl_fw_flush_dump(&mvm->fwrt); | 860 | iwl_fw_flush_dump(&mvm->fwrt); |
861 | iwl_fw_runtime_free(&mvm->fwrt); | ||
861 | 862 | ||
862 | if (iwlmvm_mod_params.init_dbg) | 863 | if (iwlmvm_mod_params.init_dbg) |
863 | return op_mode; | 864 | return op_mode; |
@@ -910,6 +911,7 @@ static void iwl_op_mode_mvm_stop(struct iwl_op_mode *op_mode) | |||
910 | 911 | ||
911 | iwl_mvm_tof_clean(mvm); | 912 | iwl_mvm_tof_clean(mvm); |
912 | 913 | ||
914 | iwl_fw_runtime_free(&mvm->fwrt); | ||
913 | mutex_destroy(&mvm->mutex); | 915 | mutex_destroy(&mvm->mutex); |
914 | mutex_destroy(&mvm->d0i3_suspend_mutex); | 916 | mutex_destroy(&mvm->d0i3_suspend_mutex); |
915 | 917 | ||
diff --git a/drivers/net/wireless/mediatek/mt76/Kconfig b/drivers/net/wireless/mediatek/mt76/Kconfig index 0ccbcd7e887d..c30d8f5bbf2a 100644 --- a/drivers/net/wireless/mediatek/mt76/Kconfig +++ b/drivers/net/wireless/mediatek/mt76/Kconfig | |||
@@ -1,6 +1,12 @@ | |||
1 | config MT76_CORE | 1 | config MT76_CORE |
2 | tristate | 2 | tristate |
3 | 3 | ||
4 | config MT76_LEDS | ||
5 | bool | ||
6 | depends on MT76_CORE | ||
7 | depends on LEDS_CLASS=y || MT76_CORE=LEDS_CLASS | ||
8 | default y | ||
9 | |||
4 | config MT76_USB | 10 | config MT76_USB |
5 | tristate | 11 | tristate |
6 | depends on MT76_CORE | 12 | depends on MT76_CORE |
diff --git a/drivers/net/wireless/mediatek/mt76/mac80211.c b/drivers/net/wireless/mediatek/mt76/mac80211.c index 2a699e8b79bf..7d219ff2d480 100644 --- a/drivers/net/wireless/mediatek/mt76/mac80211.c +++ b/drivers/net/wireless/mediatek/mt76/mac80211.c | |||
@@ -345,9 +345,11 @@ int mt76_register_device(struct mt76_dev *dev, bool vht, | |||
345 | mt76_check_sband(dev, NL80211_BAND_2GHZ); | 345 | mt76_check_sband(dev, NL80211_BAND_2GHZ); |
346 | mt76_check_sband(dev, NL80211_BAND_5GHZ); | 346 | mt76_check_sband(dev, NL80211_BAND_5GHZ); |
347 | 347 | ||
348 | ret = mt76_led_init(dev); | 348 | if (IS_ENABLED(CONFIG_MT76_LEDS)) { |
349 | if (ret) | 349 | ret = mt76_led_init(dev); |
350 | return ret; | 350 | if (ret) |
351 | return ret; | ||
352 | } | ||
351 | 353 | ||
352 | return ieee80211_register_hw(hw); | 354 | return ieee80211_register_hw(hw); |
353 | } | 355 | } |
diff --git a/drivers/net/wireless/mediatek/mt76/mt76x02.h b/drivers/net/wireless/mediatek/mt76/mt76x02.h index 47c42c607964..7806963b1905 100644 --- a/drivers/net/wireless/mediatek/mt76/mt76x02.h +++ b/drivers/net/wireless/mediatek/mt76/mt76x02.h | |||
@@ -71,7 +71,6 @@ struct mt76x02_dev { | |||
71 | struct mac_address macaddr_list[8]; | 71 | struct mac_address macaddr_list[8]; |
72 | 72 | ||
73 | struct mutex phy_mutex; | 73 | struct mutex phy_mutex; |
74 | struct mutex mutex; | ||
75 | 74 | ||
76 | u8 txdone_seq; | 75 | u8 txdone_seq; |
77 | DECLARE_KFIFO_PTR(txstatus_fifo, struct mt76x02_tx_status); | 76 | DECLARE_KFIFO_PTR(txstatus_fifo, struct mt76x02_tx_status); |
diff --git a/drivers/net/wireless/mediatek/mt76/mt76x2/pci_init.c b/drivers/net/wireless/mediatek/mt76/mt76x2/pci_init.c index 3824290b219d..fd125722d1fb 100644 --- a/drivers/net/wireless/mediatek/mt76/mt76x2/pci_init.c +++ b/drivers/net/wireless/mediatek/mt76/mt76x2/pci_init.c | |||
@@ -507,8 +507,10 @@ int mt76x2_register_device(struct mt76x02_dev *dev) | |||
507 | mt76x2_dfs_init_detector(dev); | 507 | mt76x2_dfs_init_detector(dev); |
508 | 508 | ||
509 | /* init led callbacks */ | 509 | /* init led callbacks */ |
510 | dev->mt76.led_cdev.brightness_set = mt76x2_led_set_brightness; | 510 | if (IS_ENABLED(CONFIG_MT76_LEDS)) { |
511 | dev->mt76.led_cdev.blink_set = mt76x2_led_set_blink; | 511 | dev->mt76.led_cdev.brightness_set = mt76x2_led_set_brightness; |
512 | dev->mt76.led_cdev.blink_set = mt76x2_led_set_blink; | ||
513 | } | ||
512 | 514 | ||
513 | ret = mt76_register_device(&dev->mt76, true, mt76x02_rates, | 515 | ret = mt76_register_device(&dev->mt76, true, mt76x02_rates, |
514 | ARRAY_SIZE(mt76x02_rates)); | 516 | ARRAY_SIZE(mt76x02_rates)); |
diff --git a/drivers/net/wireless/mediatek/mt76/mt76x2/pci_main.c b/drivers/net/wireless/mediatek/mt76/mt76x2/pci_main.c index 034a06295668..3f001bd6806c 100644 --- a/drivers/net/wireless/mediatek/mt76/mt76x2/pci_main.c +++ b/drivers/net/wireless/mediatek/mt76/mt76x2/pci_main.c | |||
@@ -272,9 +272,9 @@ mt76x2_set_rts_threshold(struct ieee80211_hw *hw, u32 val) | |||
272 | if (val != ~0 && val > 0xffff) | 272 | if (val != ~0 && val > 0xffff) |
273 | return -EINVAL; | 273 | return -EINVAL; |
274 | 274 | ||
275 | mutex_lock(&dev->mutex); | 275 | mutex_lock(&dev->mt76.mutex); |
276 | mt76x2_mac_set_tx_protection(dev, val); | 276 | mt76x2_mac_set_tx_protection(dev, val); |
277 | mutex_unlock(&dev->mutex); | 277 | mutex_unlock(&dev->mt76.mutex); |
278 | 278 | ||
279 | return 0; | 279 | return 0; |
280 | } | 280 | } |
diff --git a/drivers/net/wireless/ti/wlcore/sdio.c b/drivers/net/wireless/ti/wlcore/sdio.c index 4c2154b9e6a3..bd10165d7eec 100644 --- a/drivers/net/wireless/ti/wlcore/sdio.c +++ b/drivers/net/wireless/ti/wlcore/sdio.c | |||
@@ -285,7 +285,7 @@ static int wl1271_probe(struct sdio_func *func, | |||
285 | struct resource res[2]; | 285 | struct resource res[2]; |
286 | mmc_pm_flag_t mmcflags; | 286 | mmc_pm_flag_t mmcflags; |
287 | int ret = -ENOMEM; | 287 | int ret = -ENOMEM; |
288 | int irq, wakeirq; | 288 | int irq, wakeirq, num_irqs; |
289 | const char *chip_family; | 289 | const char *chip_family; |
290 | 290 | ||
291 | /* We are only able to handle the wlan function */ | 291 | /* We are only able to handle the wlan function */ |
@@ -353,12 +353,17 @@ static int wl1271_probe(struct sdio_func *func, | |||
353 | irqd_get_trigger_type(irq_get_irq_data(irq)); | 353 | irqd_get_trigger_type(irq_get_irq_data(irq)); |
354 | res[0].name = "irq"; | 354 | res[0].name = "irq"; |
355 | 355 | ||
356 | res[1].start = wakeirq; | ||
357 | res[1].flags = IORESOURCE_IRQ | | ||
358 | irqd_get_trigger_type(irq_get_irq_data(wakeirq)); | ||
359 | res[1].name = "wakeirq"; | ||
360 | 356 | ||
361 | ret = platform_device_add_resources(glue->core, res, ARRAY_SIZE(res)); | 357 | if (wakeirq > 0) { |
358 | res[1].start = wakeirq; | ||
359 | res[1].flags = IORESOURCE_IRQ | | ||
360 | irqd_get_trigger_type(irq_get_irq_data(wakeirq)); | ||
361 | res[1].name = "wakeirq"; | ||
362 | num_irqs = 2; | ||
363 | } else { | ||
364 | num_irqs = 1; | ||
365 | } | ||
366 | ret = platform_device_add_resources(glue->core, res, num_irqs); | ||
362 | if (ret) { | 367 | if (ret) { |
363 | dev_err(glue->dev, "can't add resources\n"); | 368 | dev_err(glue->dev, "can't add resources\n"); |
364 | goto out_dev_put; | 369 | goto out_dev_put; |