Re: [PATCH] ata: pata_rb532: Add OF support and make COMPILE_TESTable

2021-04-20 Thread Thomas Bogendoerfer
On Tue, Apr 20, 2021 at 07:09:26PM +0300, Sergei Shtylyov wrote:
> Hello!
> 
> On 4/20/21 5:04 PM, Thomas Bogendoerfer wrote:
> 
> > Add OF support for switching RB532 do device tree possible.
> 
>I couldnb't parse that. :-)

no wonder ;-) I'll rephrase in v2.

> 
> > By removing
> > the not needed asm/mach-rc32434/rb.h include the driver could be
> > compile tested now.
> 
>   I think it's a separte issue worth its own patch.

Jens, do you want this in an extra patch ?

Thomas.

-- 
Crap can work. Given enough thrust pigs will fly, but it's not necessarily a
good idea.[ RFC1925, 2.3 ]


[PATCH v2 2/2] dt-bindings: interrupt-controller: Add IDT 79RC3243x Interrupt Controller

2021-04-20 Thread Thomas Bogendoerfer
Document DT bindings for IDT 79RC3243x Interrupt Controller.

Signed-off-by: Thomas Bogendoerfer 
---
 .../interrupt-controller/idt,3243x-pic.yaml   | 48 +++
 1 file changed, 48 insertions(+)
 create mode 100644 
Documentation/devicetree/bindings/interrupt-controller/idt,3243x-pic.yaml

diff --git 
a/Documentation/devicetree/bindings/interrupt-controller/idt,3243x-pic.yaml 
b/Documentation/devicetree/bindings/interrupt-controller/idt,3243x-pic.yaml
new file mode 100644
index ..6a1c5ac75f1a
--- /dev/null
+++ b/Documentation/devicetree/bindings/interrupt-controller/idt,3243x-pic.yaml
@@ -0,0 +1,48 @@
+# SPDX-License-Identifier: (GPL-2.0 OR BSD-2-Clause)
+%YAML 1.2
+---
+$id: http://devicetree.org/schemas/interrupt-controller/idt,3243x-pic.yaml#
+$schema: http://devicetree.org/meta-schemas/core.yaml#
+
+title: IDT 79RC3243x Interrupt Controller Device Tree Bindings
+
+maintainers:
+  - Thomas Bogendoerfer 
+
+allOf:
+  - $ref: /schemas/interrupt-controller.yaml#
+
+properties:
+  "#interrupt-cells":
+const: 1
+
+  compatible:
+const: idt,3243x-pci
+
+  reg:
+maxItems: 1
+
+  interrupt-controller: true
+
+required:
+  - "#interrupt-cells"
+  - compatible
+  - reg
+  - interrupt-controller
+
+additionalProperties: false
+
+examples:
+  - |
+idtpic3: interrupt-controller@3800c {
+compatible = "idt,rc3243x-pic";
+reg = <0x3800c 0x0c>;
+
+interrupt-controller;
+#interrupt-cells = <1>;
+
+interrupt-parent = <>;
+interrupts = <3>;
+};
+
+...
-- 
2.29.2



[PATCH v2 1/2] irqchip: Add support for IDT 79rc3243x interrupt controller

2021-04-20 Thread Thomas Bogendoerfer
IDT 79rc3243x SoCs have rather simple interrupt controllers connected
to the MIPS CPU interrupt lines. Each of them has room for up to
32 interrupts.

Signed-off-by: Thomas Bogendoerfer 
---
 drivers/irqchip/Kconfig|   5 ++
 drivers/irqchip/Makefile   |   1 +
 drivers/irqchip/irq-idt3243x.c | 124 +
 3 files changed, 130 insertions(+)
 create mode 100644 drivers/irqchip/irq-idt3243x.c

diff --git a/drivers/irqchip/Kconfig b/drivers/irqchip/Kconfig
index e74fa206240a..55562b36bf3c 100644
--- a/drivers/irqchip/Kconfig
+++ b/drivers/irqchip/Kconfig
@@ -586,4 +586,9 @@ config MST_IRQ
help
  Support MStar Interrupt Controller.
 
+config IRQ_IDT3243X
+   bool
+   select GENERIC_IRQ_CHIP
+   select IRQ_DOMAIN
+
 endmenu
diff --git a/drivers/irqchip/Makefile b/drivers/irqchip/Makefile
index c59b95a0532c..341891443eec 100644
--- a/drivers/irqchip/Makefile
+++ b/drivers/irqchip/Makefile
@@ -113,3 +113,4 @@ obj-$(CONFIG_LOONGSON_PCH_MSI)  += 
irq-loongson-pch-msi.o
 obj-$(CONFIG_MST_IRQ)  += irq-mst-intc.o
 obj-$(CONFIG_SL28CPLD_INTC)+= irq-sl28cpld.o
 obj-$(CONFIG_MACH_REALTEK_RTL) += irq-realtek-rtl.o
+obj-$(CONFIG_IRQ_IDT3243X) += irq-idt3243x.o
diff --git a/drivers/irqchip/irq-idt3243x.c b/drivers/irqchip/irq-idt3243x.c
new file mode 100644
index ..61caf21ef46c
--- /dev/null
+++ b/drivers/irqchip/irq-idt3243x.c
@@ -0,0 +1,124 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * Driver for IDT/Renesas 79RC3243x Interrupt Controller.
+ */
+
+#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
+
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+
+#define IDT_PIC_NR_IRQS32
+
+#define IDT_PIC_IRQ_PEND   0x00
+#define IDT_PIC_IRQ_MASK   0x08
+
+struct idt_pic_data {
+   void __iomem *base;
+   struct irq_domain *irq_domain;
+   struct irq_chip_generic *gc;
+};
+
+static void idt_irq_dispatch(struct irq_desc *desc)
+{
+   struct idt_pic_data *idtpic = irq_desc_get_handler_data(desc);
+   struct irq_chip *host_chip = irq_desc_get_chip(desc);
+   u32 pending, hwirq, virq;
+
+   chained_irq_enter(host_chip, desc);
+
+   pending = irq_reg_readl(idtpic->gc, IDT_PIC_IRQ_PEND);
+   pending &= ~idtpic->gc->mask_cache;
+   while (pending) {
+   hwirq = __fls(pending);
+   virq = irq_linear_revmap(idtpic->irq_domain, hwirq);
+   if (virq)
+   generic_handle_irq(virq);
+   pending &= ~(1 << hwirq);
+   }
+
+   chained_irq_exit(host_chip, desc);
+}
+
+static int idt_pic_init(struct device_node *of_node, struct device_node 
*parent)
+{
+   struct irq_domain *domain;
+   struct idt_pic_data *idtpic;
+   struct irq_chip_generic *gc;
+   struct irq_chip_type *ct;
+   unsigned int parent_irq;
+   int ret = 0;
+
+   idtpic = kzalloc(sizeof(*idtpic), GFP_KERNEL);
+   if (!idtpic) {
+   ret = -ENOMEM;
+   goto out_err;
+   }
+
+   parent_irq = irq_of_parse_and_map(of_node, 0);
+   if (!parent_irq) {
+   pr_err("Failed to map parent IRQ!\n");
+   ret = -EINVAL;
+   goto out_free;
+   }
+
+   idtpic->base = of_iomap(of_node, 0);
+   if (!idtpic->base) {
+   pr_err("Failed to map base address!\n");
+   ret = -ENOMEM;
+   goto out_unmap_irq;
+   }
+
+   domain = irq_domain_add_linear(of_node, IDT_PIC_NR_IRQS,
+  _generic_chip_ops, NULL);
+   if (!domain) {
+   pr_err("Failed to add irqdomain!\n");
+   ret = -ENOMEM;
+   goto out_iounmap;
+   }
+   idtpic->irq_domain = domain;
+
+   ret = irq_alloc_domain_generic_chips(domain, 32, 1, "IDTPIC",
+handle_level_irq, 0,
+IRQ_NOPROBE | IRQ_LEVEL, 0);
+   if (ret)
+   goto out_domain_remove;
+
+   gc = irq_get_domain_generic_chip(domain, 0);
+   gc->reg_base = idtpic->base;
+   gc->private = idtpic;
+
+   ct = gc->chip_types;
+   ct->regs.mask = IDT_PIC_IRQ_MASK;
+   ct->chip.irq_mask = irq_gc_mask_set_bit;
+   ct->chip.irq_unmask = irq_gc_mask_clr_bit;
+   idtpic->gc = gc;
+
+   /* Mask interrupts. */
+   writel(0x, idtpic->base + IDT_PIC_IRQ_MASK);
+   gc->mask_cache = 0x;
+
+   irq_set_chained_handler_and_data(parent_irq,
+idt_irq_dispatch, idtpic);
+
+   return 0;
+
+out_domain_remove:
+   irq_domain_remove(domain);
+out_iounmap:
+   iounmap(idtpic->base);
+out_unmap_irq:
+   irq_dispose_mapping(parent_irq);
+

Re: [PATCH] irqchip: Add support for IDT 79rc3243x interrupt controller

2021-04-20 Thread Thomas Bogendoerfer
On Tue, Apr 20, 2021 at 06:34:59PM +0100, Marc Zyngier wrote:
> On 2021-04-20 13:34, Thomas Bogendoerfer wrote:
> > IDT 79rc3243x SoCs have rather simple interrupt controllers connected
> > to the MIPS CPU interrupt lines. Each of them has room for up to
> > 32 interrupts.
> > 
> > Signed-off-by: Thomas Bogendoerfer 
> 
> Is there a DT binding for this irqchip? The code looks fine, but
> it'd be good if the binding was merged at the same time as the driver.

I'll write one and send a v2.

Thomas.

-- 
Crap can work. Given enough thrust pigs will fly, but it's not necessarily a
good idea.[ RFC1925, 2.3 ]


[PATCH] ata: pata_rb532: Add OF support and make COMPILE_TESTable

2021-04-20 Thread Thomas Bogendoerfer
Add OF support for switching RB532 do device tree possible. By removing
the not needed asm/mach-rc32434/rb.h include the driver could be
compile tested now.

Signed-off-by: Thomas Bogendoerfer 
---
 drivers/ata/Kconfig |  2 +-
 drivers/ata/pata_rb532_cf.c | 11 +--
 2 files changed, 10 insertions(+), 3 deletions(-)

diff --git a/drivers/ata/Kconfig b/drivers/ata/Kconfig
index 030cb32da980..53f40f92e4eb 100644
--- a/drivers/ata/Kconfig
+++ b/drivers/ata/Kconfig
@@ -1139,7 +1139,7 @@ config PATA_QDI
 
 config PATA_RB532
tristate "RouterBoard 532 PATA CompactFlash support"
-   depends on MIKROTIK_RB532
+   depends on MIKROTIK_RB532 || COMPILE_TEST
help
  This option enables support for the RouterBoard 532
  PATA CompactFlash controller.
diff --git a/drivers/ata/pata_rb532_cf.c b/drivers/ata/pata_rb532_cf.c
index 479c4b29b856..93d839ab9654 100644
--- a/drivers/ata/pata_rb532_cf.c
+++ b/drivers/ata/pata_rb532_cf.c
@@ -28,8 +28,6 @@
 #include 
 #include 
 
-#include 
-
 #define DRV_NAME   "pata-rb532-cf"
 #define DRV_VERSION"0.1.0"
 #define DRV_DESC   "PATA driver for RouterBOARD 532 Compact Flash"
@@ -164,11 +162,20 @@ static int rb532_pata_driver_remove(struct 
platform_device *pdev)
return 0;
 }
 
+#ifdef CONFIG_OF
+static const struct of_device_id pata_rb532_match[] = {
+   { .compatible = "mikrotik,rb532-pata", },
+   { }
+};
+MODULE_DEVICE_TABLE(of, pata_rb532_match);
+#endif
+
 static struct platform_driver rb532_pata_platform_driver = {
.probe  = rb532_pata_driver_probe,
.remove = rb532_pata_driver_remove,
.driver  = {
.name   = DRV_NAME,
+   .of_match_table = of_match_ptr(pata_rb532_match),
},
 };
 
-- 
2.29.2



[PATCH 2/2] dt-bindings: gpio: Add devicetree binding for IDT 79RC3243x GPIO controller

2021-04-20 Thread Thomas Bogendoerfer
Add YAML devicetree binding for IDT 79RC3243x GPIO controller

Signed-off-by: Thomas Bogendoerfer 
---
 .../bindings/gpio/gpio-idt3243x.yaml  | 73 +++
 1 file changed, 73 insertions(+)
 create mode 100644 Documentation/devicetree/bindings/gpio/gpio-idt3243x.yaml

diff --git a/Documentation/devicetree/bindings/gpio/gpio-idt3243x.yaml 
b/Documentation/devicetree/bindings/gpio/gpio-idt3243x.yaml
new file mode 100644
index ..346a57ef8298
--- /dev/null
+++ b/Documentation/devicetree/bindings/gpio/gpio-idt3243x.yaml
@@ -0,0 +1,73 @@
+# SPDX-License-Identifier: (GPL-2.0 OR BSD-2-Clause)
+%YAML 1.2
+---
+$id: http://devicetree.org/schemas/gpio/gpio-idt3243x.yaml#
+$schema: http://devicetree.org/meta-schemas/core.yaml#
+
+title: IDT 79RC32434x GPIO controller
+
+maintainers:
+  - Thomas Bogendoerfer 
+
+properties:
+  compatible:
+const: idt,3243x-gpio
+
+  reg:
+maxItems: 2
+
+  reg-names:
+items:
+  - const: gpio
+  - const: pic
+
+  gpio-controller: true
+
+  "#gpio-cells":
+const: 2
+
+  ngpios:
+description:
+  Number of available gpios in a bank.
+minimum: 1
+maximum: 32
+
+  interrupt-controller: true
+
+  "#interrupt-cells":
+const: 2
+
+  interrupts:
+maxItems: 1
+
+required:
+  - compatible
+  - reg
+  - reg-names
+  - gpio-controller
+  - "#gpio-cells"
+  - ngpios
+  - interrupt-controller
+  - "#interrupt-cells"
+  - interrupts
+
+additionalProperties: false
+
+examples:
+  - |
+gpio0: interrupt-controller@5 {
+compatible = "idt,3243x-gpio";
+reg = <0x5 0x14>, <0x38030 0x0c>;
+reg-names = "gpio", "pic";
+
+interrupt-controller;
+#interrupt-cells = <2>;
+
+interrupt-parent = <>;
+interrupts = <6>;
+
+gpio-controller;
+#gpio-cells = <2>;
+
+ngpios = <14>;
+};
-- 
2.29.2



[PATCH 1/2] gpio: Add support for IDT 79RC3243x GPIO controller

2021-04-20 Thread Thomas Bogendoerfer
IDT 79RC3243x SoCs integrated a gpio controller, which handles up
to 32 gpios. All gpios could be used as interrupt source.

Signed-off-by: Thomas Bogendoerfer 
---
 drivers/gpio/Kconfig |  10 ++
 drivers/gpio/Makefile|   1 +
 drivers/gpio/gpio-idt3243x.c | 210 +++
 3 files changed, 221 insertions(+)
 create mode 100644 drivers/gpio/gpio-idt3243x.c

diff --git a/drivers/gpio/Kconfig b/drivers/gpio/Kconfig
index e3607ec4c2e8..6847a06ffcfe 100644
--- a/drivers/gpio/Kconfig
+++ b/drivers/gpio/Kconfig
@@ -770,6 +770,16 @@ config GPIO_MSC313
  Say Y here to support the main GPIO block on MStar/SigmaStar
  ARMv7 based SoCs.
 
+config GPIO_IDT3243X
+   bool "IDT 79RC3243X GPIO support"
+   default y if MIKROTIK_RB532
+   depends on MIKROTIK_RB532 || COMPILE_TEST
+   select GPIO_GENERIC
+   select GPIOLIB_IRQCHIP
+   help
+ Select this option to enable GPIO driver for
+ IDT 79RC3243X SoC devices.
+
 endmenu
 
 menu "Port-mapped I/O GPIO drivers"
diff --git a/drivers/gpio/Makefile b/drivers/gpio/Makefile
index c58a90a3c3b1..75dd9c5665c5 100644
--- a/drivers/gpio/Makefile
+++ b/drivers/gpio/Makefile
@@ -67,6 +67,7 @@ obj-$(CONFIG_GPIO_HISI) += gpio-hisi.o
 obj-$(CONFIG_GPIO_HLWD)+= gpio-hlwd.o
 obj-$(CONFIG_HTC_EGPIO)+= gpio-htc-egpio.o
 obj-$(CONFIG_GPIO_ICH) += gpio-ich.o
+obj-$(CONFIG_GPIO_IDT3243X)+= gpio-idt3243x.o
 obj-$(CONFIG_GPIO_IOP) += gpio-iop.o
 obj-$(CONFIG_GPIO_IT87)+= gpio-it87.o
 obj-$(CONFIG_GPIO_IXP4XX)  += gpio-ixp4xx.o
diff --git a/drivers/gpio/gpio-idt3243x.c b/drivers/gpio/gpio-idt3243x.c
new file mode 100644
index ..eaee46480268
--- /dev/null
+++ b/drivers/gpio/gpio-idt3243x.c
@@ -0,0 +1,210 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * Driver for IDT/Renesas 79RC3243x Interrupt Controller.
+ */
+
+#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
+
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+
+#define IDT_GPIO_NR_IRQS   32
+
+#define IDT_PIC_IRQ_PEND   0x00
+#define IDT_PIC_IRQ_MASK   0x08
+
+#define IDT_GPIO_DIR   0x04
+#define IDT_GPIO_DATA  0x08
+#define IDT_GPIO_ILEVEL0x0C
+#define IDT_GPIO_ISTAT 0x10
+
+struct idt_gpio_ctrl {
+   struct gpio_chip gc;
+   void __iomem *pic;
+   void __iomem *gpio;
+   u32 mask_cache;
+};
+
+static struct idt_gpio_ctrl *irq_data_to_idt_gpio(struct irq_data *d)
+{
+   struct gpio_chip *gc = irq_data_get_irq_chip_data(d);
+
+   return container_of(gc, struct idt_gpio_ctrl, gc);
+}
+
+static void idt_gpio_dispatch(struct irq_desc *desc)
+{
+   struct gpio_chip *gc = irq_desc_get_handler_data(desc);
+   struct idt_gpio_ctrl *ctrl = container_of(gc, struct idt_gpio_ctrl, gc);
+   struct irq_chip *host_chip = irq_desc_get_chip(desc);
+   u32 pending, hwirq, virq;
+
+   chained_irq_enter(host_chip, desc);
+
+   pending = readl(ctrl->pic + IDT_PIC_IRQ_PEND);
+   pending &= ~ctrl->mask_cache;
+   while (pending) {
+   hwirq = __fls(pending);
+   virq = irq_linear_revmap(gc->irq.domain, hwirq);
+   if (virq)
+   generic_handle_irq(virq);
+   pending &= ~(1 << hwirq);
+   }
+
+   chained_irq_exit(host_chip, desc);
+}
+
+static int idt_gpio_irq_set_type(struct irq_data *d, unsigned int flow_type)
+{
+   struct idt_gpio_ctrl *ctrl = irq_data_to_idt_gpio(d);
+   unsigned int sense = flow_type & IRQ_TYPE_SENSE_MASK;
+   u32 ilevel;
+
+   if (sense & ~(IRQ_TYPE_LEVEL_HIGH | IRQ_TYPE_LEVEL_LOW))
+   return -EINVAL;
+
+   ilevel = readl(ctrl->gpio + IDT_GPIO_ILEVEL);
+   if (sense & IRQ_TYPE_LEVEL_HIGH)
+   ilevel |= BIT(d->hwirq);
+   else if (sense & IRQ_TYPE_LEVEL_LOW)
+   ilevel &= ~BIT(d->hwirq);
+   else
+   return -EINVAL;
+
+   writel(ilevel, ctrl->gpio + IDT_GPIO_ILEVEL);
+   return 0;
+}
+
+static void idt_gpio_ack(struct irq_data *d)
+{
+   struct idt_gpio_ctrl *ctrl = irq_data_to_idt_gpio(d);
+
+   writel(~BIT(d->hwirq), ctrl->gpio + IDT_GPIO_ISTAT);
+}
+
+static void idt_gpio_mask(struct irq_data *d)
+{
+   struct idt_gpio_ctrl *ctrl = irq_data_to_idt_gpio(d);
+
+   ctrl->mask_cache |= BIT(d->hwirq);
+   writel(ctrl->mask_cache, ctrl->pic + IDT_PIC_IRQ_MASK);
+}
+
+static void idt_gpio_unmask(struct irq_data *d)
+{
+   struct idt_gpio_ctrl *ctrl = irq_data_to_idt_gpio(d);
+
+   ctrl->mask_cache &= ~BIT(d->hwirq);
+   writel(ctrl->mask_cache, ctrl->pic + IDT_PIC_IRQ_MASK);
+}
+
+static struct irq_chip idt_gpio_irqchip = {
+   .name

[PATCH] irqchip: Add support for IDT 79rc3243x interrupt controller

2021-04-20 Thread Thomas Bogendoerfer
IDT 79rc3243x SoCs have rather simple interrupt controllers connected
to the MIPS CPU interrupt lines. Each of them has room for up to
32 interrupts.

Signed-off-by: Thomas Bogendoerfer 
---
 drivers/irqchip/Kconfig|   5 ++
 drivers/irqchip/Makefile   |   1 +
 drivers/irqchip/irq-idt3243x.c | 124 +
 3 files changed, 130 insertions(+)
 create mode 100644 drivers/irqchip/irq-idt3243x.c

diff --git a/drivers/irqchip/Kconfig b/drivers/irqchip/Kconfig
index e74fa206240a..55562b36bf3c 100644
--- a/drivers/irqchip/Kconfig
+++ b/drivers/irqchip/Kconfig
@@ -586,4 +586,9 @@ config MST_IRQ
help
  Support MStar Interrupt Controller.
 
+config IRQ_IDT3243X
+   bool
+   select GENERIC_IRQ_CHIP
+   select IRQ_DOMAIN
+
 endmenu
diff --git a/drivers/irqchip/Makefile b/drivers/irqchip/Makefile
index c59b95a0532c..341891443eec 100644
--- a/drivers/irqchip/Makefile
+++ b/drivers/irqchip/Makefile
@@ -113,3 +113,4 @@ obj-$(CONFIG_LOONGSON_PCH_MSI)  += 
irq-loongson-pch-msi.o
 obj-$(CONFIG_MST_IRQ)  += irq-mst-intc.o
 obj-$(CONFIG_SL28CPLD_INTC)+= irq-sl28cpld.o
 obj-$(CONFIG_MACH_REALTEK_RTL) += irq-realtek-rtl.o
+obj-$(CONFIG_IRQ_IDT3243X) += irq-idt3243x.o
diff --git a/drivers/irqchip/irq-idt3243x.c b/drivers/irqchip/irq-idt3243x.c
new file mode 100644
index ..61caf21ef46c
--- /dev/null
+++ b/drivers/irqchip/irq-idt3243x.c
@@ -0,0 +1,124 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * Driver for IDT/Renesas 79RC3243x Interrupt Controller.
+ */
+
+#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
+
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+
+#define IDT_PIC_NR_IRQS32
+
+#define IDT_PIC_IRQ_PEND   0x00
+#define IDT_PIC_IRQ_MASK   0x08
+
+struct idt_pic_data {
+   void __iomem *base;
+   struct irq_domain *irq_domain;
+   struct irq_chip_generic *gc;
+};
+
+static void idt_irq_dispatch(struct irq_desc *desc)
+{
+   struct idt_pic_data *idtpic = irq_desc_get_handler_data(desc);
+   struct irq_chip *host_chip = irq_desc_get_chip(desc);
+   u32 pending, hwirq, virq;
+
+   chained_irq_enter(host_chip, desc);
+
+   pending = irq_reg_readl(idtpic->gc, IDT_PIC_IRQ_PEND);
+   pending &= ~idtpic->gc->mask_cache;
+   while (pending) {
+   hwirq = __fls(pending);
+   virq = irq_linear_revmap(idtpic->irq_domain, hwirq);
+   if (virq)
+   generic_handle_irq(virq);
+   pending &= ~(1 << hwirq);
+   }
+
+   chained_irq_exit(host_chip, desc);
+}
+
+static int idt_pic_init(struct device_node *of_node, struct device_node 
*parent)
+{
+   struct irq_domain *domain;
+   struct idt_pic_data *idtpic;
+   struct irq_chip_generic *gc;
+   struct irq_chip_type *ct;
+   unsigned int parent_irq;
+   int ret = 0;
+
+   idtpic = kzalloc(sizeof(*idtpic), GFP_KERNEL);
+   if (!idtpic) {
+   ret = -ENOMEM;
+   goto out_err;
+   }
+
+   parent_irq = irq_of_parse_and_map(of_node, 0);
+   if (!parent_irq) {
+   pr_err("Failed to map parent IRQ!\n");
+   ret = -EINVAL;
+   goto out_free;
+   }
+
+   idtpic->base = of_iomap(of_node, 0);
+   if (!idtpic->base) {
+   pr_err("Failed to map base address!\n");
+   ret = -ENOMEM;
+   goto out_unmap_irq;
+   }
+
+   domain = irq_domain_add_linear(of_node, IDT_PIC_NR_IRQS,
+  _generic_chip_ops, NULL);
+   if (!domain) {
+   pr_err("Failed to add irqdomain!\n");
+   ret = -ENOMEM;
+   goto out_iounmap;
+   }
+   idtpic->irq_domain = domain;
+
+   ret = irq_alloc_domain_generic_chips(domain, 32, 1, "IDTPIC",
+handle_level_irq, 0,
+IRQ_NOPROBE | IRQ_LEVEL, 0);
+   if (ret)
+   goto out_domain_remove;
+
+   gc = irq_get_domain_generic_chip(domain, 0);
+   gc->reg_base = idtpic->base;
+   gc->private = idtpic;
+
+   ct = gc->chip_types;
+   ct->regs.mask = IDT_PIC_IRQ_MASK;
+   ct->chip.irq_mask = irq_gc_mask_set_bit;
+   ct->chip.irq_unmask = irq_gc_mask_clr_bit;
+   idtpic->gc = gc;
+
+   /* Mask interrupts. */
+   writel(0x, idtpic->base + IDT_PIC_IRQ_MASK);
+   gc->mask_cache = 0x;
+
+   irq_set_chained_handler_and_data(parent_irq,
+idt_irq_dispatch, idtpic);
+
+   return 0;
+
+out_domain_remove:
+   irq_domain_remove(domain);
+out_iounmap:
+   iounmap(idtpic->base);
+out_unmap_irq:
+   irq_dispose_mapping(parent_irq);
+

Re: build failure of malta_qemu_32r6_defconfig

2021-04-20 Thread Thomas Bogendoerfer
On Sun, Apr 18, 2021 at 12:01:36AM +0100, Sudip Mukherjee wrote:
> Hi Thomas,
> 
> On Fri, Apr 9, 2021 at 1:17 PM Thomas Bogendoerfer
>  wrote:
> >
> > On Thu, Apr 08, 2021 at 09:42:11AM +0800, YunQiang Su wrote:
> > > Sudip Mukherjee  于2021年4月8日周四 上午2:26写道:
> > > >
> > > > Hi Thomas,
> > > >
> > > > I was building v5.10.28 with malta_qemu_32r6_defconfig and noticed that
> > > > it fails to build, so tried next-20210407 to see if it has been fixed.
> > > > But linux-next also has the issue with gcc-10.
> > > >
> > > > The error is:
> > > >
> > > > ./arch/mips/include/asm/vdso/gettimeofday.h: In function 
> > > > '__vdso_clock_gettime':
> > > > ./arch/mips/include/asm/vdso/gettimeofday.h:103:2: error: the register 
> > > > 'lo' cannot be clobbered in 'asm' for the current target
> > > >   103 |  asm volatile(
> > > >   |  ^~~
> > >
> > > this operation try to save lo and hi register, while they are not
> > > exisiting on r6.
> > > We are working on figure out a patch for it.
> >
> > looks like there is already a patch in patchwork, which just needs
> > a workup:
> >
> > https://patchwork.kernel.org/project/linux-mips/patch/20200801154401.4177009-1-romain.na...@gmail.com/
> 
> Looks like there has been no response to it since last 8 months. Do
> you want me to respin it and send a proper patch?

that would me fantastic and much appreciated :-)

Thomas.

-- 
Crap can work. Given enough thrust pigs will fly, but it's not necessarily a
good idea.[ RFC1925, 2.3 ]


[PATCH v6 net-next 09/10] net: korina: Make driver COMPILE_TESTable

2021-04-18 Thread Thomas Bogendoerfer
Move structs/defines for ethernet/dma register into driver, since they
are only used for this driver and remove any MIPS specific includes.
This makes it possible to COMPILE_TEST the driver.

Signed-off-by: Thomas Bogendoerfer 
---
 drivers/net/ethernet/Kconfig  |   2 +-
 drivers/net/ethernet/korina.c | 249 --
 2 files changed, 239 insertions(+), 12 deletions(-)

diff --git a/drivers/net/ethernet/Kconfig b/drivers/net/ethernet/Kconfig
index c059b4bd3f23..453d202a28c1 100644
--- a/drivers/net/ethernet/Kconfig
+++ b/drivers/net/ethernet/Kconfig
@@ -97,7 +97,7 @@ config JME
 
 config KORINA
tristate "Korina (IDT RC32434) Ethernet support"
-   depends on MIKROTIK_RB532
+   depends on MIKROTIK_RB532 || COMPILE_TEST
select MII
help
  If you have a Mikrotik RouterBoard 500 or IDT RC32434
diff --git a/drivers/net/ethernet/korina.c b/drivers/net/ethernet/korina.c
index 19f226428f89..4878e527e3c8 100644
--- a/drivers/net/ethernet/korina.c
+++ b/drivers/net/ethernet/korina.c
@@ -59,18 +59,244 @@
 #include 
 #include 
 
-#include 
-#include 
-#include 
-#include 
-
-#include 
-#include 
-
 #define DRV_NAME   "korina"
 #define DRV_VERSION"0.20"
 #define DRV_RELDATE"15Sep2017"
 
+struct eth_regs {
+   u32 ethintfc;
+   u32 ethfifott;
+   u32 etharc;
+   u32 ethhash0;
+   u32 ethhash1;
+   u32 ethu0[4];   /* Reserved. */
+   u32 ethpfs;
+   u32 ethmcp;
+   u32 eth_u1[10]; /* Reserved. */
+   u32 ethspare;
+   u32 eth_u2[42]; /* Reserved. */
+   u32 ethsal0;
+   u32 ethsah0;
+   u32 ethsal1;
+   u32 ethsah1;
+   u32 ethsal2;
+   u32 ethsah2;
+   u32 ethsal3;
+   u32 ethsah3;
+   u32 ethrbc;
+   u32 ethrpc;
+   u32 ethrupc;
+   u32 ethrfc;
+   u32 ethtbc;
+   u32 ethgpf;
+   u32 eth_u9[50]; /* Reserved. */
+   u32 ethmac1;
+   u32 ethmac2;
+   u32 ethipgt;
+   u32 ethipgr;
+   u32 ethclrt;
+   u32 ethmaxf;
+   u32 eth_u10;/* Reserved. */
+   u32 ethmtest;
+   u32 miimcfg;
+   u32 miimcmd;
+   u32 miimaddr;
+   u32 miimwtd;
+   u32 miimrdd;
+   u32 miimind;
+   u32 eth_u11;/* Reserved. */
+   u32 eth_u12;/* Reserved. */
+   u32 ethcfsa0;
+   u32 ethcfsa1;
+   u32 ethcfsa2;
+};
+
+/* Ethernet interrupt registers */
+#define ETH_INT_FC_EN  BIT(0)
+#define ETH_INT_FC_ITS BIT(1)
+#define ETH_INT_FC_RIP BIT(2)
+#define ETH_INT_FC_JAM BIT(3)
+#define ETH_INT_FC_OVR BIT(4)
+#define ETH_INT_FC_UND BIT(5)
+#define ETH_INT_FC_IOC 0x00c0
+
+/* Ethernet FIFO registers */
+#define ETH_FIFI_TT_TTH_BIT0
+#define ETH_FIFO_TT_TTH0x007f
+
+/* Ethernet ARC/multicast registers */
+#define ETH_ARC_PROBIT(0)
+#define ETH_ARC_AM BIT(1)
+#define ETH_ARC_AFMBIT(2)
+#define ETH_ARC_AB BIT(3)
+
+/* Ethernet SAL registers */
+#define ETH_SAL_BYTE_5 0x00ff
+#define ETH_SAL_BYTE_4 0xff00
+#define ETH_SAL_BYTE_3 0x00ff
+#define ETH_SAL_BYTE_2 0xff00
+
+/* Ethernet SAH registers */
+#define ETH_SAH_BYTE1  0x00ff
+#define ETH_SAH_BYTE0  0xff00
+
+/* Ethernet GPF register */
+#define ETH_GPF_PTV0x
+
+/* Ethernet PFG register */
+#define ETH_PFS_PFDBIT(0)
+
+/* Ethernet CFSA[0-3] registers */
+#define ETH_CFSA0_CFSA40x00ff
+#define ETH_CFSA0_CFSA50xff00
+#define ETH_CFSA1_CFSA20x00ff
+#define ETH_CFSA1_CFSA30xff00
+#define ETH_CFSA1_CFSA00x00ff
+#define ETH_CFSA1_CFSA10xff00
+
+/* Ethernet MAC1 registers */
+#define ETH_MAC1_REBIT(0)
+#define ETH_MAC1_PAF   BIT(1)
+#define ETH_MAC1_RFC   BIT(2)
+#define ETH_MAC1_TFC   BIT(3)
+#define ETH_MAC1_LBBIT(4)
+#define ETH_MAC1_MRBIT(31)
+
+/* Ethernet MAC2 registers */
+#define ETH_MAC2_FDBIT(0)
+#define ETH_MAC2_FLC   BIT(1)
+#define ETH_MAC2_HFE   BIT(2)
+#define ETH_MAC2_DCBIT(3)
+#define ETH_MAC2_CEN   BIT(4)
+#define ETH_MAC2_PEBIT(5)
+#define ETH_MAC2_VPE   BIT(6)
+#define ETH_MAC2_APE   BIT(7)
+#define ETH_MAC2_PPE   BIT(8)
+#define ETH_MAC2_LPE   BIT(9)
+#define ETH_MAC2_NBBIT(12)
+#define ETH_MAC2_BPBIT(13)
+#define ETH_MAC2_EDBIT(14)
+
+/* Ethernet IPGT register */
+#define ETH_IPGT   0x007f
+
+/* Ethernet IPGR registers */
+#define ETH_IPGR_IPGR2 0x007f
+#define ETH_IPGR_IPGR1 0x7f00
+
+/* Ethernet CLRT registers */
+#define ETH_CLRT_MAX_RET   0x000f
+#

[PATCH v6 net-next 10/10] dt-bindings: net: korina: Add DT bindings for IDT 79RC3243x SoCs

2021-04-18 Thread Thomas Bogendoerfer
Add device tree bindings for ethernet controller integrated into
IDT 79RC3243x SoCs.

Signed-off-by: Thomas Bogendoerfer 
---
 .../bindings/net/idt,3243x-emac.yaml  | 73 +++
 1 file changed, 73 insertions(+)
 create mode 100644 Documentation/devicetree/bindings/net/idt,3243x-emac.yaml

diff --git a/Documentation/devicetree/bindings/net/idt,3243x-emac.yaml 
b/Documentation/devicetree/bindings/net/idt,3243x-emac.yaml
new file mode 100644
index ..11ffc306dd54
--- /dev/null
+++ b/Documentation/devicetree/bindings/net/idt,3243x-emac.yaml
@@ -0,0 +1,73 @@
+# SPDX-License-Identifier: GPL-2.0-only OR BSD-2-Clause
+%YAML 1.2
+---
+$id: http://devicetree.org/schemas/net/idt,3243x-emac.yaml#
+$schema: http://devicetree.org/meta-schemas/core.yaml#
+
+title: IDT 79rc3243x Ethernet controller
+
+description: Ethernet controller integrated into IDT 79RC3243x family SoCs
+
+maintainers:
+  - Thomas Bogendoerfer 
+
+allOf:
+  - $ref: ethernet-controller.yaml#
+
+properties:
+  compatible:
+const: idt,3243x-emac
+
+  reg:
+maxItems: 3
+
+  reg-names:
+items:
+  - const: emac
+  - const: dma_rx
+  - const: dma_tx
+
+  interrupts:
+items:
+  - description: RX interrupt
+  - description: TX interrupt
+
+  interrupt-names:
+items:
+  - const: rx
+  - const: tx
+
+  clocks:
+maxItems: 1
+
+  clock-names:
+items:
+  - const: mdioclk
+
+required:
+  - compatible
+  - reg
+  - reg-names
+  - interrupts
+  - interrupt-names
+
+additionalProperties: false
+
+examples:
+  - |
+
+ethernet@6 {
+compatible = "idt,3243x-emac";
+
+reg = <0x6 0x1>,
+  <0x4 0x14>,
+  <0x40014 0x14>;
+reg-names = "emac", "dma_rx", "dma_tx";
+
+interrupt-parent = <>;
+interrupts = <0>, <1>;
+interrupt-names = "rx", "tx";
+
+clocks = <>;
+clock-names = "mdioclk";
+};
-- 
2.29.2



[PATCH v6 net-next 08/10] net: korina: Get mdio input clock via common clock framework

2021-04-18 Thread Thomas Bogendoerfer
With device tree clock is provided via CCF. For non device tree
use a maximum clock value to not overclock the PHY. The non device
tree usage will go away after platform is converted to DT.

Signed-off-by: Thomas Bogendoerfer 
---
 drivers/net/ethernet/korina.c | 21 +++--
 1 file changed, 15 insertions(+), 6 deletions(-)

diff --git a/drivers/net/ethernet/korina.c b/drivers/net/ethernet/korina.c
index a1f53d7753ae..19f226428f89 100644
--- a/drivers/net/ethernet/korina.c
+++ b/drivers/net/ethernet/korina.c
@@ -57,14 +57,13 @@
 #include 
 #include 
 #include 
+#include 
 
 #include 
 #include 
 #include 
 #include 
 
-#include 
-#include 
 #include 
 #include 
 
@@ -146,10 +145,9 @@ struct korina_private {
struct work_struct restart_task;
struct net_device *dev;
struct device *dmadev;
+   int mii_clock_freq;
 };
 
-extern unsigned int idt_cpu_freq;
-
 static dma_addr_t korina_tx_dma(struct korina_private *lp, int idx)
 {
return lp->td_dma + (idx * sizeof(struct dma_desc));
@@ -899,8 +897,8 @@ static int korina_init(struct net_device *dev)
 
/* Management Clock Prescaler Divisor
 * Clock independent setting */
-   writel(((idt_cpu_freq) / MII_CLOCK + 1) & ~1,
-   >eth_regs->ethmcp);
+   writel(((lp->mii_clock_freq) / MII_CLOCK + 1) & ~1,
+  >eth_regs->ethmcp);
writel(0, >eth_regs->miimcfg);
 
/* don't transmit until fifo contains 48b */
@@ -1060,6 +1058,7 @@ static int korina_probe(struct platform_device *pdev)
u8 *mac_addr = dev_get_platdata(>dev);
struct korina_private *lp;
struct net_device *dev;
+   struct clk *clk;
void __iomem *p;
int rc;
 
@@ -1075,6 +1074,16 @@ static int korina_probe(struct platform_device *pdev)
else if (of_get_mac_address(pdev->dev.of_node, dev->dev_addr) < 0)
eth_hw_addr_random(dev);
 
+   clk = devm_clk_get_optional(>dev, "mdioclk");
+   if (IS_ERR(clk))
+   return PTR_ERR(clk);
+   if (clk) {
+   clk_prepare_enable(clk);
+   lp->mii_clock_freq = clk_get_rate(clk);
+   } else {
+   lp->mii_clock_freq = 2; /* max possible input clk */
+   }
+
lp->rx_irq = platform_get_irq_byname(pdev, "rx");
lp->tx_irq = platform_get_irq_byname(pdev, "tx");
 
-- 
2.29.2



[PATCH v6 net-next 06/10] net: korina: Only pass mac address via platform data

2021-04-18 Thread Thomas Bogendoerfer
Get rid of access to struct korina_device by just passing the mac
address via platform data and use drvdata for passing netdev to remove
function.

Signed-off-by: Thomas Bogendoerfer 
---
 arch/mips/rb532/devices.c |  5 +++--
 drivers/net/ethernet/korina.c | 11 ++-
 2 files changed, 9 insertions(+), 7 deletions(-)

diff --git a/arch/mips/rb532/devices.c b/arch/mips/rb532/devices.c
index dd34f1b32b79..5fc3c8ee4f31 100644
--- a/arch/mips/rb532/devices.c
+++ b/arch/mips/rb532/devices.c
@@ -105,6 +105,9 @@ static struct platform_device korina_dev0 = {
.name = "korina",
.resource = korina_dev0_res,
.num_resources = ARRAY_SIZE(korina_dev0_res),
+   .dev = {
+   .platform_data = _dev0_data.mac,
+   }
 };
 
 static struct resource cf_slot0_res[] = {
@@ -299,8 +302,6 @@ static int __init plat_setup_devices(void)
/* set the uart clock to the current cpu frequency */
rb532_uart_res[0].uartclk = idt_cpu_freq;
 
-   dev_set_drvdata(_dev0.dev, _dev0_data);
-
gpiod_add_lookup_table(_slot0_gpio_table);
return platform_add_devices(rb532_devs, ARRAY_SIZE(rb532_devs));
 }
diff --git a/drivers/net/ethernet/korina.c b/drivers/net/ethernet/korina.c
index 44fad9e924ca..d6dbbdd43d7c 100644
--- a/drivers/net/ethernet/korina.c
+++ b/drivers/net/ethernet/korina.c
@@ -1055,7 +1055,7 @@ static const struct net_device_ops korina_netdev_ops = {
 
 static int korina_probe(struct platform_device *pdev)
 {
-   struct korina_device *bif = platform_get_drvdata(pdev);
+   u8 *mac_addr = dev_get_platdata(>dev);
struct korina_private *lp;
struct net_device *dev;
void __iomem *p;
@@ -1068,8 +1068,7 @@ static int korina_probe(struct platform_device *pdev)
SET_NETDEV_DEV(dev, >dev);
lp = netdev_priv(dev);
 
-   bif->dev = dev;
-   memcpy(dev->dev_addr, bif->mac, ETH_ALEN);
+   memcpy(dev->dev_addr, mac_addr, ETH_ALEN);
 
lp->rx_irq = platform_get_irq_byname(pdev, "korina_rx");
lp->tx_irq = platform_get_irq_byname(pdev, "korina_tx");
@@ -1123,6 +1122,8 @@ static int korina_probe(struct platform_device *pdev)
lp->mii_if.phy_id_mask = 0x1f;
lp->mii_if.reg_num_mask = 0x1f;
 
+   platform_set_drvdata(pdev, dev);
+
rc = register_netdev(dev);
if (rc < 0) {
printk(KERN_ERR DRV_NAME
@@ -1140,9 +1141,9 @@ static int korina_probe(struct platform_device *pdev)
 
 static int korina_remove(struct platform_device *pdev)
 {
-   struct korina_device *bif = platform_get_drvdata(pdev);
+   struct net_device *dev = platform_get_drvdata(pdev);
 
-   unregister_netdev(bif->dev);
+   unregister_netdev(dev);
 
return 0;
 }
-- 
2.29.2



[PATCH v6 net-next 05/10] net: korina: Use DMA API

2021-04-18 Thread Thomas Bogendoerfer
Instead of messing with MIPS specific macros use DMA API for mapping
descriptors and skbs.

Reviewed-by: Andrew Lunn 
Signed-off-by: Thomas Bogendoerfer 
---
 drivers/net/ethernet/korina.c | 158 +-
 1 file changed, 98 insertions(+), 60 deletions(-)

diff --git a/drivers/net/ethernet/korina.c b/drivers/net/ethernet/korina.c
index 955fe3d3da06..44fad9e924ca 100644
--- a/drivers/net/ethernet/korina.c
+++ b/drivers/net/ethernet/korina.c
@@ -110,10 +110,15 @@ struct korina_private {
struct dma_reg __iomem *tx_dma_regs;
struct dma_desc *td_ring; /* transmit descriptor ring */
struct dma_desc *rd_ring; /* receive descriptor ring  */
+   dma_addr_t td_dma;
+   dma_addr_t rd_dma;
 
struct sk_buff *tx_skb[KORINA_NUM_TDS];
struct sk_buff *rx_skb[KORINA_NUM_RDS];
 
+   dma_addr_t rx_skb_dma[KORINA_NUM_RDS];
+   dma_addr_t tx_skb_dma[KORINA_NUM_TDS];
+
int rx_next_done;
int rx_chain_head;
int rx_chain_tail;
@@ -138,10 +143,21 @@ struct korina_private {
struct mii_if_info mii_if;
struct work_struct restart_task;
struct net_device *dev;
+   struct device *dmadev;
 };
 
 extern unsigned int idt_cpu_freq;
 
+static dma_addr_t korina_tx_dma(struct korina_private *lp, int idx)
+{
+   return lp->td_dma + (idx * sizeof(struct dma_desc));
+}
+
+static dma_addr_t korina_rx_dma(struct korina_private *lp, int idx)
+{
+   return lp->rd_dma + (idx * sizeof(struct dma_desc));
+}
+
 static inline void korina_abort_dma(struct net_device *dev,
struct dma_reg *ch)
 {
@@ -176,14 +192,17 @@ static void korina_abort_rx(struct net_device *dev)
 static int korina_send_packet(struct sk_buff *skb, struct net_device *dev)
 {
struct korina_private *lp = netdev_priv(dev);
-   unsigned long flags;
-   u32 length;
u32 chain_prev, chain_next;
+   unsigned long flags;
struct dma_desc *td;
+   dma_addr_t ca;
+   u32 length;
+   int idx;
 
spin_lock_irqsave(>lock, flags);
 
-   td = >td_ring[lp->tx_chain_tail];
+   idx = lp->tx_chain_tail;
+   td = >td_ring[idx];
 
/* stop queue when full, drop pkts if queue already full */
if (lp->tx_count >= (KORINA_NUM_TDS - 2)) {
@@ -191,26 +210,26 @@ static int korina_send_packet(struct sk_buff *skb, struct 
net_device *dev)
 
if (lp->tx_count == (KORINA_NUM_TDS - 2))
netif_stop_queue(dev);
-   else {
-   dev->stats.tx_dropped++;
-   dev_kfree_skb_any(skb);
-   spin_unlock_irqrestore(>lock, flags);
-
-   return NETDEV_TX_OK;
-   }
+   else
+   goto drop_packet;
}
 
lp->tx_count++;
 
-   lp->tx_skb[lp->tx_chain_tail] = skb;
+   lp->tx_skb[idx] = skb;
 
length = skb->len;
-   dma_cache_wback((u32)skb->data, skb->len);
 
/* Setup the transmit descriptor. */
-   td->ca = CPHYSADDR(skb->data);
-   chain_prev = (lp->tx_chain_tail - 1) & KORINA_TDS_MASK;
-   chain_next = (lp->tx_chain_tail + 1) & KORINA_TDS_MASK;
+   ca = dma_map_single(lp->dmadev, skb->data, length, DMA_TO_DEVICE);
+   if (dma_mapping_error(lp->dmadev, ca))
+   goto drop_packet;
+
+   lp->tx_skb_dma[idx] = ca;
+   td->ca = ca;
+
+   chain_prev = (idx - 1) & KORINA_TDS_MASK;
+   chain_next = (idx + 1) & KORINA_TDS_MASK;
 
if (readl(&(lp->tx_dma_regs->dmandptr)) == 0) {
if (lp->tx_chain_status == desc_empty) {
@@ -220,8 +239,8 @@ static int korina_send_packet(struct sk_buff *skb, struct 
net_device *dev)
/* Move tail */
lp->tx_chain_tail = chain_next;
/* Write to NDPTR */
-   writel(CPHYSADDR(>td_ring[lp->tx_chain_head]),
-   >tx_dma_regs->dmandptr);
+   writel(korina_tx_dma(lp, lp->tx_chain_head),
+  >tx_dma_regs->dmandptr);
/* Move head to tail */
lp->tx_chain_head = lp->tx_chain_tail;
} else {
@@ -232,12 +251,12 @@ static int korina_send_packet(struct sk_buff *skb, struct 
net_device *dev)
lp->td_ring[chain_prev].control &=
~DMA_DESC_COF;
/* Link to prev */
-   lp->td_ring[chain_prev].link =  CPHYSADDR(td);
+   lp->td_ring[chain_prev].link = korina_tx_dma(lp, idx);
/* Move tail */
lp->tx_chain_tail = chain_next;
  

[PATCH v6 net-next 07/10] net: korina: Add support for device tree

2021-04-18 Thread Thomas Bogendoerfer
If there is no mac address passed via platform data try to get it via
device tree and fall back to a random mac address, if all fail.

Signed-off-by: Thomas Bogendoerfer 
---
 arch/mips/rb532/devices.c | 20 +---
 drivers/net/ethernet/korina.c | 32 +---
 2 files changed, 30 insertions(+), 22 deletions(-)

diff --git a/arch/mips/rb532/devices.c b/arch/mips/rb532/devices.c
index 5fc3c8ee4f31..04684990e28e 100644
--- a/arch/mips/rb532/devices.c
+++ b/arch/mips/rb532/devices.c
@@ -58,37 +58,27 @@ EXPORT_SYMBOL(get_latch_u5);
 
 static struct resource korina_dev0_res[] = {
{
-   .name = "korina_regs",
+   .name = "emac",
.start = ETH0_BASE_ADDR,
.end = ETH0_BASE_ADDR + sizeof(struct eth_regs),
.flags = IORESOURCE_MEM,
 }, {
-   .name = "korina_rx",
+   .name = "rx",
.start = ETH0_DMA_RX_IRQ,
.end = ETH0_DMA_RX_IRQ,
.flags = IORESOURCE_IRQ
}, {
-   .name = "korina_tx",
+   .name = "tx",
.start = ETH0_DMA_TX_IRQ,
.end = ETH0_DMA_TX_IRQ,
.flags = IORESOURCE_IRQ
}, {
-   .name = "korina_ovr",
-   .start = ETH0_RX_OVR_IRQ,
-   .end = ETH0_RX_OVR_IRQ,
-   .flags = IORESOURCE_IRQ
-   }, {
-   .name = "korina_und",
-   .start = ETH0_TX_UND_IRQ,
-   .end = ETH0_TX_UND_IRQ,
-   .flags = IORESOURCE_IRQ
-   }, {
-   .name = "korina_dma_rx",
+   .name = "dma_rx",
.start = ETH0_RX_DMA_ADDR,
.end = ETH0_RX_DMA_ADDR + DMA_CHAN_OFFSET - 1,
.flags = IORESOURCE_MEM,
 }, {
-   .name = "korina_dma_tx",
+   .name = "dma_tx",
.start = ETH0_TX_DMA_ADDR,
.end = ETH0_TX_DMA_ADDR + DMA_CHAN_OFFSET - 1,
.flags = IORESOURCE_MEM,
diff --git a/drivers/net/ethernet/korina.c b/drivers/net/ethernet/korina.c
index d6dbbdd43d7c..a1f53d7753ae 100644
--- a/drivers/net/ethernet/korina.c
+++ b/drivers/net/ethernet/korina.c
@@ -43,6 +43,8 @@
 #include 
 #include 
 #include 
+#include 
+#include 
 #include 
 #include 
 #include 
@@ -1068,26 +1070,29 @@ static int korina_probe(struct platform_device *pdev)
SET_NETDEV_DEV(dev, >dev);
lp = netdev_priv(dev);
 
-   memcpy(dev->dev_addr, mac_addr, ETH_ALEN);
+   if (mac_addr)
+   ether_addr_copy(dev->dev_addr, mac_addr);
+   else if (of_get_mac_address(pdev->dev.of_node, dev->dev_addr) < 0)
+   eth_hw_addr_random(dev);
 
-   lp->rx_irq = platform_get_irq_byname(pdev, "korina_rx");
-   lp->tx_irq = platform_get_irq_byname(pdev, "korina_tx");
+   lp->rx_irq = platform_get_irq_byname(pdev, "rx");
+   lp->tx_irq = platform_get_irq_byname(pdev, "tx");
 
-   p = devm_platform_ioremap_resource_byname(pdev, "korina_regs");
+   p = devm_platform_ioremap_resource_byname(pdev, "emac");
if (!p) {
printk(KERN_ERR DRV_NAME ": cannot remap registers\n");
return -ENOMEM;
}
lp->eth_regs = p;
 
-   p = devm_platform_ioremap_resource_byname(pdev, "korina_dma_rx");
+   p = devm_platform_ioremap_resource_byname(pdev, "dma_rx");
if (!p) {
printk(KERN_ERR DRV_NAME ": cannot remap Rx DMA registers\n");
return -ENOMEM;
}
lp->rx_dma_regs = p;
 
-   p = devm_platform_ioremap_resource_byname(pdev, "korina_dma_tx");
+   p = devm_platform_ioremap_resource_byname(pdev, "dma_tx");
if (!p) {
printk(KERN_ERR DRV_NAME ": cannot remap Tx DMA registers\n");
return -ENOMEM;
@@ -1148,8 +1153,21 @@ static int korina_remove(struct platform_device *pdev)
return 0;
 }
 
+#ifdef CONFIG_OF
+static const struct of_device_id korina_match[] = {
+   {
+   .compatible = "idt,3243x-emac",
+   },
+   { }
+};
+MODULE_DEVICE_TABLE(of, korina_match);
+#endif
+
 static struct platform_driver korina_driver = {
-   .driver.name = "korina",
+   .driver = {
+   .name = "korina",
+   .of_match_table = of_match_ptr(korina_match),
+   },
.probe = korina_probe,
.remove = korina_remove,
 };
-- 
2.29.2



[PATCH v6 net-next 04/10] net: korina: Remove nested helpers

2021-04-18 Thread Thomas Bogendoerfer
Remove helpers, which are only used in one call site.

Reviewed-by: Andrew Lunn 
Signed-off-by: Thomas Bogendoerfer 
---
 drivers/net/ethernet/korina.c | 28 +++-
 1 file changed, 3 insertions(+), 25 deletions(-)

diff --git a/drivers/net/ethernet/korina.c b/drivers/net/ethernet/korina.c
index c7abb4a8dd37..955fe3d3da06 100644
--- a/drivers/net/ethernet/korina.c
+++ b/drivers/net/ethernet/korina.c
@@ -142,12 +142,6 @@ struct korina_private {
 
 extern unsigned int idt_cpu_freq;
 
-static inline void korina_start_dma(struct dma_reg *ch, u32 dma_addr)
-{
-   writel(0, >dmandptr);
-   writel(dma_addr, >dmadptr);
-}
-
 static inline void korina_abort_dma(struct net_device *dev,
struct dma_reg *ch)
 {
@@ -164,11 +158,6 @@ static inline void korina_abort_dma(struct net_device *dev,
writel(0, >dmandptr);
 }
 
-static inline void korina_chain_dma(struct dma_reg *ch, u32 dma_addr)
-{
-   writel(dma_addr, >dmandptr);
-}
-
 static void korina_abort_tx(struct net_device *dev)
 {
struct korina_private *lp = netdev_priv(dev);
@@ -183,18 +172,6 @@ static void korina_abort_rx(struct net_device *dev)
korina_abort_dma(dev, lp->rx_dma_regs);
 }
 
-static void korina_start_rx(struct korina_private *lp,
-   struct dma_desc *rd)
-{
-   korina_start_dma(lp->rx_dma_regs, CPHYSADDR(rd));
-}
-
-static void korina_chain_rx(struct korina_private *lp,
-   struct dma_desc *rd)
-{
-   korina_chain_dma(lp->rx_dma_regs, CPHYSADDR(rd));
-}
-
 /* transmit packet */
 static int korina_send_packet(struct sk_buff *skb, struct net_device *dev)
 {
@@ -463,7 +440,7 @@ static int korina_rx(struct net_device *dev, int limit)
rd->devcs = 0;
skb = lp->rx_skb[lp->rx_next_done];
rd->ca = CPHYSADDR(skb->data);
-   korina_chain_rx(lp, rd);
+   writel(CPHYSADDR(rd), >rx_dma_regs->dmandptr);
}
 
return count;
@@ -840,7 +817,8 @@ static int korina_init(struct net_device *dev)
 
writel(0, >rx_dma_regs->dmas);
/* Start Rx DMA */
-   korina_start_rx(lp, >rd_ring[0]);
+   writel(0, >rx_dma_regs->dmandptr);
+   writel(CPHYSADDR(>rd_ring[0]), >rx_dma_regs->dmadptr);
 
writel(readl(>tx_dma_regs->dmasm) &
~(DMA_STAT_FINI | DMA_STAT_ERR),
-- 
2.29.2



[PATCH v6 net-next 03/10] net: korina: Remove not needed cache flushes

2021-04-18 Thread Thomas Bogendoerfer
Descriptors are mapped uncached so there is no need to do any cache
handling for them.

Reviewed-by: Andrew Lunn 
Signed-off-by: Thomas Bogendoerfer 
---
 drivers/net/ethernet/korina.c | 6 --
 1 file changed, 6 deletions(-)

diff --git a/drivers/net/ethernet/korina.c b/drivers/net/ethernet/korina.c
index b56de01f6bb8..c7abb4a8dd37 100644
--- a/drivers/net/ethernet/korina.c
+++ b/drivers/net/ethernet/korina.c
@@ -231,7 +231,6 @@ static int korina_send_packet(struct sk_buff *skb, struct 
net_device *dev)
dma_cache_wback((u32)skb->data, skb->len);
 
/* Setup the transmit descriptor. */
-   dma_cache_inv((u32) td, sizeof(*td));
td->ca = CPHYSADDR(skb->data);
chain_prev = (lp->tx_chain_tail - 1) & KORINA_TDS_MASK;
chain_next = (lp->tx_chain_tail + 1) & KORINA_TDS_MASK;
@@ -284,7 +283,6 @@ static int korina_send_packet(struct sk_buff *skb, struct 
net_device *dev)
lp->tx_chain_tail = chain_next;
}
}
-   dma_cache_wback((u32) td, sizeof(*td));
 
netif_trans_update(dev);
spin_unlock_irqrestore(>lock, flags);
@@ -373,8 +371,6 @@ static int korina_rx(struct net_device *dev, int limit)
u32 devcs, pkt_len, dmas;
int count;
 
-   dma_cache_inv((u32)rd, sizeof(*rd));
-
for (count = 0; count < limit; count++) {
skb = lp->rx_skb[lp->rx_next_done];
skb_new = NULL;
@@ -453,7 +449,6 @@ static int korina_rx(struct net_device *dev, int limit)
~DMA_DESC_COD;
 
lp->rx_next_done = (lp->rx_next_done + 1) & KORINA_RDS_MASK;
-   dma_cache_wback((u32)rd, sizeof(*rd));
rd = >rd_ring[lp->rx_next_done];
writel(~DMA_STAT_DONE, >rx_dma_regs->dmas);
}
@@ -468,7 +463,6 @@ static int korina_rx(struct net_device *dev, int limit)
rd->devcs = 0;
skb = lp->rx_skb[lp->rx_next_done];
rd->ca = CPHYSADDR(skb->data);
-   dma_cache_wback((u32)rd, sizeof(*rd));
korina_chain_rx(lp, rd);
}
 
-- 
2.29.2



[PATCH v6 net-next 02/10] net: korina: Use devres functions

2021-04-18 Thread Thomas Bogendoerfer
Simplify probe/remove code by using devm_ functions.

Reviewed-by: Andrew Lunn 
Signed-off-by: Thomas Bogendoerfer 
---
 drivers/net/ethernet/korina.c | 64 ---
 1 file changed, 21 insertions(+), 43 deletions(-)

diff --git a/drivers/net/ethernet/korina.c b/drivers/net/ethernet/korina.c
index 1b7e1c75ed9e..b56de01f6bb8 100644
--- a/drivers/net/ethernet/korina.c
+++ b/drivers/net/ethernet/korina.c
@@ -105,9 +105,9 @@ enum chain_status {
 
 /* Information that need to be kept for each board. */
 struct korina_private {
-   struct eth_regs *eth_regs;
-   struct dma_reg *rx_dma_regs;
-   struct dma_reg *tx_dma_regs;
+   struct eth_regs __iomem *eth_regs;
+   struct dma_reg __iomem *rx_dma_regs;
+   struct dma_reg __iomem *tx_dma_regs;
struct dma_desc *td_ring; /* transmit descriptor ring */
struct dma_desc *rd_ring; /* receive descriptor ring  */
 
@@ -1044,10 +1044,10 @@ static int korina_probe(struct platform_device *pdev)
struct korina_device *bif = platform_get_drvdata(pdev);
struct korina_private *lp;
struct net_device *dev;
-   struct resource *r;
+   void __iomem *p;
int rc;
 
-   dev = alloc_etherdev(sizeof(struct korina_private));
+   dev = devm_alloc_etherdev(>dev, sizeof(struct korina_private));
if (!dev)
return -ENOMEM;
 
@@ -1060,36 +1060,30 @@ static int korina_probe(struct platform_device *pdev)
lp->rx_irq = platform_get_irq_byname(pdev, "korina_rx");
lp->tx_irq = platform_get_irq_byname(pdev, "korina_tx");
 
-   r = platform_get_resource_byname(pdev, IORESOURCE_MEM, "korina_regs");
-   dev->base_addr = r->start;
-   lp->eth_regs = ioremap(r->start, resource_size(r));
-   if (!lp->eth_regs) {
+   p = devm_platform_ioremap_resource_byname(pdev, "korina_regs");
+   if (!p) {
printk(KERN_ERR DRV_NAME ": cannot remap registers\n");
-   rc = -ENXIO;
-   goto probe_err_out;
+   return -ENOMEM;
}
+   lp->eth_regs = p;
 
-   r = platform_get_resource_byname(pdev, IORESOURCE_MEM, "korina_dma_rx");
-   lp->rx_dma_regs = ioremap(r->start, resource_size(r));
-   if (!lp->rx_dma_regs) {
+   p = devm_platform_ioremap_resource_byname(pdev, "korina_dma_rx");
+   if (!p) {
printk(KERN_ERR DRV_NAME ": cannot remap Rx DMA registers\n");
-   rc = -ENXIO;
-   goto probe_err_dma_rx;
+   return -ENOMEM;
}
+   lp->rx_dma_regs = p;
 
-   r = platform_get_resource_byname(pdev, IORESOURCE_MEM, "korina_dma_tx");
-   lp->tx_dma_regs = ioremap(r->start, resource_size(r));
-   if (!lp->tx_dma_regs) {
+   p = devm_platform_ioremap_resource_byname(pdev, "korina_dma_tx");
+   if (!p) {
printk(KERN_ERR DRV_NAME ": cannot remap Tx DMA registers\n");
-   rc = -ENXIO;
-   goto probe_err_dma_tx;
+   return -ENOMEM;
}
+   lp->tx_dma_regs = p;
 
lp->td_ring = kmalloc(TD_RING_SIZE + RD_RING_SIZE, GFP_KERNEL);
-   if (!lp->td_ring) {
-   rc = -ENXIO;
-   goto probe_err_td_ring;
-   }
+   if (!lp->td_ring)
+   return -ENOMEM;
 
dma_cache_inv((unsigned long)(lp->td_ring),
TD_RING_SIZE + RD_RING_SIZE);
@@ -1119,7 +1113,8 @@ static int korina_probe(struct platform_device *pdev)
if (rc < 0) {
printk(KERN_ERR DRV_NAME
": cannot register net device: %d\n", rc);
-   goto probe_err_register;
+   kfree((struct dma_desc *)KSEG0ADDR(lp->td_ring));
+   return rc;
}
timer_setup(>media_check_timer, korina_poll_media, 0);
 
@@ -1127,20 +1122,7 @@ static int korina_probe(struct platform_device *pdev)
 
printk(KERN_INFO "%s: " DRV_NAME "-" DRV_VERSION " " DRV_RELDATE "\n",
dev->name);
-out:
return rc;
-
-probe_err_register:
-   kfree((struct dma_desc *)KSEG0ADDR(lp->td_ring));
-probe_err_td_ring:
-   iounmap(lp->tx_dma_regs);
-probe_err_dma_tx:
-   iounmap(lp->rx_dma_regs);
-probe_err_dma_rx:
-   iounmap(lp->eth_regs);
-probe_err_out:
-   free_netdev(dev);
-   goto out;
 }
 
 static int korina_remove(struct platform_device *pdev)
@@ -1148,13 +1130,9 @@ static int korina_remove(struct platform_device *pdev)
struct korina_device *bif = platform_get_drvdata(pdev);
struct korina_private *lp = netdev_priv(bif->dev);
 
-   iounmap(lp->eth_regs);
-   iounmap(lp->rx_dma_regs);
-   iounmap(lp->tx_dma_regs);
kfree((struct dma_desc *)KSEG0ADDR(lp->td_ring));
 
unregister_netdev(bif->dev);
-   free_netdev(bif->dev);
 
return 0;
 }
-- 
2.29.2



[PATCH v6 net-next 01/10] net: korina: Fix MDIO functions

2021-04-18 Thread Thomas Bogendoerfer
Fixed MDIO functions to work reliable and not just by accident.

Signed-off-by: Thomas Bogendoerfer 
---
 drivers/net/ethernet/Kconfig  |  1 +
 drivers/net/ethernet/korina.c | 56 +++
 2 files changed, 38 insertions(+), 19 deletions(-)

diff --git a/drivers/net/ethernet/Kconfig b/drivers/net/ethernet/Kconfig
index ad04660b97b8..c059b4bd3f23 100644
--- a/drivers/net/ethernet/Kconfig
+++ b/drivers/net/ethernet/Kconfig
@@ -98,6 +98,7 @@ config JME
 config KORINA
tristate "Korina (IDT RC32434) Ethernet support"
depends on MIKROTIK_RB532
+   select MII
help
  If you have a Mikrotik RouterBoard 500 or IDT RC32434
  based system say Y. Otherwise say N.
diff --git a/drivers/net/ethernet/korina.c b/drivers/net/ethernet/korina.c
index 925161959b9b..1b7e1c75ed9e 100644
--- a/drivers/net/ethernet/korina.c
+++ b/drivers/net/ethernet/korina.c
@@ -41,6 +41,7 @@
 #include 
 #include 
 #include 
+#include 
 #include 
 #include 
 #include 
@@ -137,7 +138,6 @@ struct korina_private {
struct mii_if_info mii_if;
struct work_struct restart_task;
struct net_device *dev;
-   int phy_addr;
 };
 
 extern unsigned int idt_cpu_freq;
@@ -292,32 +292,48 @@ static int korina_send_packet(struct sk_buff *skb, struct 
net_device *dev)
return NETDEV_TX_OK;
 }
 
-static int mdio_read(struct net_device *dev, int mii_id, int reg)
+static int korina_mdio_wait(struct korina_private *lp)
+{
+   u32 value;
+
+   return readl_poll_timeout_atomic(>eth_regs->miimind,
+value, value & ETH_MII_IND_BSY,
+1, 1000);
+}
+
+static int korina_mdio_read(struct net_device *dev, int phy, int reg)
 {
struct korina_private *lp = netdev_priv(dev);
int ret;
 
-   mii_id = ((lp->rx_irq == 0x2c ? 1 : 0) << 8);
+   ret = korina_mdio_wait(lp);
+   if (ret < 0)
+   return ret;
 
-   writel(0, >eth_regs->miimcfg);
-   writel(0, >eth_regs->miimcmd);
-   writel(mii_id | reg, >eth_regs->miimaddr);
-   writel(ETH_MII_CMD_SCN, >eth_regs->miimcmd);
+   writel(phy << 8 | reg, >eth_regs->miimaddr);
+   writel(1, >eth_regs->miimcmd);
 
-   ret = (int)(readl(>eth_regs->miimrdd));
+   ret = korina_mdio_wait(lp);
+   if (ret < 0)
+   return ret;
+
+   if (readl(>eth_regs->miimind) & ETH_MII_IND_NV)
+   return -EINVAL;
+
+   ret = readl(>eth_regs->miimrdd);
+   writel(0, >eth_regs->miimcmd);
return ret;
 }
 
-static void mdio_write(struct net_device *dev, int mii_id, int reg, int val)
+static void korina_mdio_write(struct net_device *dev, int phy, int reg, int 
val)
 {
struct korina_private *lp = netdev_priv(dev);
 
-   mii_id = ((lp->rx_irq == 0x2c ? 1 : 0) << 8);
+   if (korina_mdio_wait(lp))
+   return;
 
-   writel(0, >eth_regs->miimcfg);
-   writel(1, >eth_regs->miimcmd);
-   writel(mii_id | reg, >eth_regs->miimaddr);
-   writel(ETH_MII_CMD_SCN, >eth_regs->miimcmd);
+   writel(0, >eth_regs->miimcmd);
+   writel(phy << 8 | reg, >eth_regs->miimaddr);
writel(val, >eth_regs->miimwtd);
 }
 
@@ -643,7 +659,7 @@ static void korina_check_media(struct net_device *dev, 
unsigned int init_media)
 {
struct korina_private *lp = netdev_priv(dev);
 
-   mii_check_media(>mii_if, 0, init_media);
+   mii_check_media(>mii_if, 1, init_media);
 
if (lp->mii_if.full_duplex)
writel(readl(>eth_regs->ethmac2) | ETH_MAC2_FD,
@@ -869,12 +885,15 @@ static int korina_init(struct net_device *dev)
 * Clock independent setting */
writel(((idt_cpu_freq) / MII_CLOCK + 1) & ~1,
>eth_regs->ethmcp);
+   writel(0, >eth_regs->miimcfg);
 
/* don't transmit until fifo contains 48b */
writel(48, >eth_regs->ethfifott);
 
writel(ETH_MAC1_RE, >eth_regs->ethmac1);
 
+   korina_check_media(dev, 1);
+
napi_enable(>napi);
netif_start_queue(dev);
 
@@ -1089,11 +1108,10 @@ static int korina_probe(struct platform_device *pdev)
dev->watchdog_timeo = TX_TIMEOUT;
netif_napi_add(dev, >napi, korina_poll, NAPI_POLL_WEIGHT);
 
-   lp->phy_addr = (((lp->rx_irq == 0x2c? 1:0) << 8) | 0x05);
lp->mii_if.dev = dev;
-   lp->mii_if.mdio_read = mdio_read;
-   lp->mii_if.mdio_write = mdio_write;
-   lp->mii_if.phy_id = lp->phy_addr;
+   lp->mii_if.mdio_read = korina_mdio_read;
+   lp->mii_if.mdio_write = korina_mdio_write;
+   lp->mii_if.phy_id = 1;
lp->mii_if.phy_id_mask = 0x1f;
lp->mii_if.reg_num_mask = 0x1f;
 
-- 
2.29.2



[PATCH v6 net-next 00/10] net: Korina improvements

2021-04-18 Thread Thomas Bogendoerfer
While converting Mikrotik RB532 support to use device tree I stumbled
over the korina ethernet driver, which used way too many MIPS specific
hacks. This series cleans this all up and adds support for device tree.

Changes in v6:
 - remove korina from resource names and adapt DT binding to it
 - removed superfluous braces around of_get_mac_address

Changes in v5:
  - fixed email address in binding document, which prevented sending it

Changes in v4:
  - improve error returns in mdio_read further
  - added clock name and improved clk handling
  - fixed binding errors

Changes in v3:
  - use readl_poll_timeout_atomic in mdio_wait
  - return -ETIMEDOUT, if mdio_wait failed
  - added DT binding and changed name to idt,3243x-emac
  - fixed usage of of_get_mac_address for net-next

Changes in v2:
  - added device tree support to get rid of idt_cpu_freq
  - fixed compile test on 64bit archs
  - fixed descriptor current address handling by storing/using mapped
dma addresses (dma controller modifies current address)


Thomas Bogendoerfer (10):
  net: korina: Fix MDIO functions
  net: korina: Use devres functions
  net: korina: Remove not needed cache flushes
  net: korina: Remove nested helpers
  net: korina: Use DMA API
  net: korina: Only pass mac address via platform data
  net: korina: Add support for device tree
  net: korina: Get mdio input clock via common clock framework
  net: korina: Make driver COMPILE_TESTable
  dt-bindings: net: korina: Add DT bindings for IDT 79RC3243x SoCs

 .../bindings/net/idt,3243x-emac.yaml  |  73 +++
 arch/mips/rb532/devices.c |  25 +-
 drivers/net/ethernet/Kconfig  |   3 +-
 drivers/net/ethernet/korina.c | 603 +-
 4 files changed, 515 insertions(+), 189 deletions(-)
 create mode 100644 Documentation/devicetree/bindings/net/idt,3243x-emac.yaml

-- 
2.29.2



Re: [PATCH v5 net-next 10/10] dt-bindings: net: korina: Add DT bindings for IDT 79RC3243x SoCs

2021-04-16 Thread Thomas Bogendoerfer
On Fri, Apr 16, 2021 at 12:29:46PM +0300, Sergei Shtylyov wrote:
> On 16.04.2021 11:52, Thomas Bogendoerfer wrote:
> 
> > Add device tree bindings for ethernet controller integrated into
> > IDT 79RC3243x SoCs.
> > 
> > Signed-off-by: Thomas Bogendoerfer 
> > ---
> >   .../bindings/net/idt,3243x-emac.yaml  | 74 +++
> >   1 file changed, 74 insertions(+)
> >   create mode 100644 
> > Documentation/devicetree/bindings/net/idt,3243x-emac.yaml
> > 
> > diff --git a/Documentation/devicetree/bindings/net/idt,3243x-emac.yaml 
> > b/Documentation/devicetree/bindings/net/idt,3243x-emac.yaml
> > new file mode 100644
> > index ..3697af5cb66f
> > --- /dev/null
> > +++ b/Documentation/devicetree/bindings/net/idt,3243x-emac.yaml
> > @@ -0,0 +1,74 @@
> > +# SPDX-License-Identifier: GPL-2.0-only OR BSD-2-Clause
> > +%YAML 1.2
> > +---
> > +$id: http://devicetree.org/schemas/net/idt,3243x-emac.yaml#
> > +$schema: http://devicetree.org/meta-schemas/core.yaml#
> > +
> > +title: IDT 79rc3243x Ethernet controller
> > +
> > +description: Ethernet controller integrated into IDT 79RC3243x family SoCs
> > +
> > +maintainers:
> > +  - Thomas Bogendoerfer 
> > +
> > +allOf:
> > +  - $ref: ethernet-controller.yaml#
> > +
> > +properties:
> > +  compatible:
> > +const: idt,3243x-emac
> > +
> > +  reg:
> > +maxItems: 3
> > +
> > +  reg-names:
> > +items:
> > +  - const: korina_regs
> > +  - const: korina_dma_rx
> > +  - const: korina_dma_tx
> > +
> > +  interrupts:
> > +items:
> > +  - description: RX interrupt
> > +  - description: TX interrupt
> > +
> > +  interrupt-names:
> > +items:
> > +  - const: korina_rx
> > +  - const: korina_tx
> > +
> > +  clocks:
> > +maxItems: 1
> > +
> > +  clock-names:
> > +items:
> > +  - const: mdioclk
> > +
> > +required:
> > +  - compatible
> > +  - reg
> > +  - reg-names
> > +  - interrupts
> > +  - interrupt-names
> > +
> > +additionalProperties: false
> > +
> > +examples:
> > +  - |
> > +
> > +ethernet@6 {
> > +compatible = "idt,3243x-emac";
> > +
> > +reg = <0x6 0x1>,
> > +  <0x4 0x14>,
> > +  <0x40014 0x14>;
> > +reg-names = "korina_regs",
> > +"korina_dma_rx",
> > +"korina_dma_tx";
> > +
> > +interrupts-extended = < 0>, < 1>;
> 
>You use this prop, yet don't describe it?

that's just interrupt-parent and interrupts in one statement. And since
make dt_binding_check didn't complained I thought that's good this way.
Rob, do I need to describe interrupts-extended as well ?

I could change that to interrupt-parent/interrupts as the driver no
longer uses dma under/overrun interrupts, which have a different
interrupt-parent.

Thomas.

-- 
Crap can work. Given enough thrust pigs will fly, but it's not necessarily a
good idea.[ RFC1925, 2.3 ]


[PATCH v5 net-next 09/10] net: korina: Make driver COMPILE_TESTable

2021-04-16 Thread Thomas Bogendoerfer
Move structs/defines for ethernet/dma register into driver, since they
are only used for this driver and remove any MIPS specific includes.
This makes it possible to COMPILE_TEST the driver.

Signed-off-by: Thomas Bogendoerfer 
---
 drivers/net/ethernet/Kconfig  |   2 +-
 drivers/net/ethernet/korina.c | 249 --
 2 files changed, 239 insertions(+), 12 deletions(-)

diff --git a/drivers/net/ethernet/Kconfig b/drivers/net/ethernet/Kconfig
index c059b4bd3f23..453d202a28c1 100644
--- a/drivers/net/ethernet/Kconfig
+++ b/drivers/net/ethernet/Kconfig
@@ -97,7 +97,7 @@ config JME
 
 config KORINA
tristate "Korina (IDT RC32434) Ethernet support"
-   depends on MIKROTIK_RB532
+   depends on MIKROTIK_RB532 || COMPILE_TEST
select MII
help
  If you have a Mikrotik RouterBoard 500 or IDT RC32434
diff --git a/drivers/net/ethernet/korina.c b/drivers/net/ethernet/korina.c
index e95c8d87d893..5f39a5bba531 100644
--- a/drivers/net/ethernet/korina.c
+++ b/drivers/net/ethernet/korina.c
@@ -59,18 +59,244 @@
 #include 
 #include 
 
-#include 
-#include 
-#include 
-#include 
-
-#include 
-#include 
-
 #define DRV_NAME   "korina"
 #define DRV_VERSION"0.20"
 #define DRV_RELDATE"15Sep2017"
 
+struct eth_regs {
+   u32 ethintfc;
+   u32 ethfifott;
+   u32 etharc;
+   u32 ethhash0;
+   u32 ethhash1;
+   u32 ethu0[4];   /* Reserved. */
+   u32 ethpfs;
+   u32 ethmcp;
+   u32 eth_u1[10]; /* Reserved. */
+   u32 ethspare;
+   u32 eth_u2[42]; /* Reserved. */
+   u32 ethsal0;
+   u32 ethsah0;
+   u32 ethsal1;
+   u32 ethsah1;
+   u32 ethsal2;
+   u32 ethsah2;
+   u32 ethsal3;
+   u32 ethsah3;
+   u32 ethrbc;
+   u32 ethrpc;
+   u32 ethrupc;
+   u32 ethrfc;
+   u32 ethtbc;
+   u32 ethgpf;
+   u32 eth_u9[50]; /* Reserved. */
+   u32 ethmac1;
+   u32 ethmac2;
+   u32 ethipgt;
+   u32 ethipgr;
+   u32 ethclrt;
+   u32 ethmaxf;
+   u32 eth_u10;/* Reserved. */
+   u32 ethmtest;
+   u32 miimcfg;
+   u32 miimcmd;
+   u32 miimaddr;
+   u32 miimwtd;
+   u32 miimrdd;
+   u32 miimind;
+   u32 eth_u11;/* Reserved. */
+   u32 eth_u12;/* Reserved. */
+   u32 ethcfsa0;
+   u32 ethcfsa1;
+   u32 ethcfsa2;
+};
+
+/* Ethernet interrupt registers */
+#define ETH_INT_FC_EN  BIT(0)
+#define ETH_INT_FC_ITS BIT(1)
+#define ETH_INT_FC_RIP BIT(2)
+#define ETH_INT_FC_JAM BIT(3)
+#define ETH_INT_FC_OVR BIT(4)
+#define ETH_INT_FC_UND BIT(5)
+#define ETH_INT_FC_IOC 0x00c0
+
+/* Ethernet FIFO registers */
+#define ETH_FIFI_TT_TTH_BIT0
+#define ETH_FIFO_TT_TTH0x007f
+
+/* Ethernet ARC/multicast registers */
+#define ETH_ARC_PROBIT(0)
+#define ETH_ARC_AM BIT(1)
+#define ETH_ARC_AFMBIT(2)
+#define ETH_ARC_AB BIT(3)
+
+/* Ethernet SAL registers */
+#define ETH_SAL_BYTE_5 0x00ff
+#define ETH_SAL_BYTE_4 0xff00
+#define ETH_SAL_BYTE_3 0x00ff
+#define ETH_SAL_BYTE_2 0xff00
+
+/* Ethernet SAH registers */
+#define ETH_SAH_BYTE1  0x00ff
+#define ETH_SAH_BYTE0  0xff00
+
+/* Ethernet GPF register */
+#define ETH_GPF_PTV0x
+
+/* Ethernet PFG register */
+#define ETH_PFS_PFDBIT(0)
+
+/* Ethernet CFSA[0-3] registers */
+#define ETH_CFSA0_CFSA40x00ff
+#define ETH_CFSA0_CFSA50xff00
+#define ETH_CFSA1_CFSA20x00ff
+#define ETH_CFSA1_CFSA30xff00
+#define ETH_CFSA1_CFSA00x00ff
+#define ETH_CFSA1_CFSA10xff00
+
+/* Ethernet MAC1 registers */
+#define ETH_MAC1_REBIT(0)
+#define ETH_MAC1_PAF   BIT(1)
+#define ETH_MAC1_RFC   BIT(2)
+#define ETH_MAC1_TFC   BIT(3)
+#define ETH_MAC1_LBBIT(4)
+#define ETH_MAC1_MRBIT(31)
+
+/* Ethernet MAC2 registers */
+#define ETH_MAC2_FDBIT(0)
+#define ETH_MAC2_FLC   BIT(1)
+#define ETH_MAC2_HFE   BIT(2)
+#define ETH_MAC2_DCBIT(3)
+#define ETH_MAC2_CEN   BIT(4)
+#define ETH_MAC2_PEBIT(5)
+#define ETH_MAC2_VPE   BIT(6)
+#define ETH_MAC2_APE   BIT(7)
+#define ETH_MAC2_PPE   BIT(8)
+#define ETH_MAC2_LPE   BIT(9)
+#define ETH_MAC2_NBBIT(12)
+#define ETH_MAC2_BPBIT(13)
+#define ETH_MAC2_EDBIT(14)
+
+/* Ethernet IPGT register */
+#define ETH_IPGT   0x007f
+
+/* Ethernet IPGR registers */
+#define ETH_IPGR_IPGR2 0x007f
+#define ETH_IPGR_IPGR1 0x7f00
+
+/* Ethernet CLRT registers */
+#define ETH_CLRT_MAX_RET   0x000f
+#

[PATCH v5 net-next 10/10] dt-bindings: net: korina: Add DT bindings for IDT 79RC3243x SoCs

2021-04-16 Thread Thomas Bogendoerfer
Add device tree bindings for ethernet controller integrated into
IDT 79RC3243x SoCs.

Signed-off-by: Thomas Bogendoerfer 
---
 .../bindings/net/idt,3243x-emac.yaml  | 74 +++
 1 file changed, 74 insertions(+)
 create mode 100644 Documentation/devicetree/bindings/net/idt,3243x-emac.yaml

diff --git a/Documentation/devicetree/bindings/net/idt,3243x-emac.yaml 
b/Documentation/devicetree/bindings/net/idt,3243x-emac.yaml
new file mode 100644
index ..3697af5cb66f
--- /dev/null
+++ b/Documentation/devicetree/bindings/net/idt,3243x-emac.yaml
@@ -0,0 +1,74 @@
+# SPDX-License-Identifier: GPL-2.0-only OR BSD-2-Clause
+%YAML 1.2
+---
+$id: http://devicetree.org/schemas/net/idt,3243x-emac.yaml#
+$schema: http://devicetree.org/meta-schemas/core.yaml#
+
+title: IDT 79rc3243x Ethernet controller
+
+description: Ethernet controller integrated into IDT 79RC3243x family SoCs
+
+maintainers:
+  - Thomas Bogendoerfer 
+
+allOf:
+  - $ref: ethernet-controller.yaml#
+
+properties:
+  compatible:
+const: idt,3243x-emac
+
+  reg:
+maxItems: 3
+
+  reg-names:
+items:
+  - const: korina_regs
+  - const: korina_dma_rx
+  - const: korina_dma_tx
+
+  interrupts:
+items:
+  - description: RX interrupt
+  - description: TX interrupt
+
+  interrupt-names:
+items:
+  - const: korina_rx
+  - const: korina_tx
+
+  clocks:
+maxItems: 1
+
+  clock-names:
+items:
+  - const: mdioclk
+
+required:
+  - compatible
+  - reg
+  - reg-names
+  - interrupts
+  - interrupt-names
+
+additionalProperties: false
+
+examples:
+  - |
+
+ethernet@6 {
+compatible = "idt,3243x-emac";
+
+reg = <0x6 0x1>,
+  <0x4 0x14>,
+  <0x40014 0x14>;
+reg-names = "korina_regs",
+"korina_dma_rx",
+"korina_dma_tx";
+
+interrupts-extended = < 0>, < 1>;
+interrupt-names = "korina_rx", "korina_tx";
+
+clocks = <>;
+clock-names = "mdioclk";
+};
-- 
2.29.2



[PATCH v5 net-next 07/10] net: korina: Add support for device tree

2021-04-16 Thread Thomas Bogendoerfer
If there is no mac address passed via platform data try to get it via
device tree and fall back to a random mac address, if all fail.

Signed-off-by: Thomas Bogendoerfer 
---
 drivers/net/ethernet/korina.c | 24 ++--
 1 file changed, 22 insertions(+), 2 deletions(-)

diff --git a/drivers/net/ethernet/korina.c b/drivers/net/ethernet/korina.c
index d6dbbdd43d7c..cd078a5c679b 100644
--- a/drivers/net/ethernet/korina.c
+++ b/drivers/net/ethernet/korina.c
@@ -43,6 +43,8 @@
 #include 
 #include 
 #include 
+#include 
+#include 
 #include 
 #include 
 #include 
@@ -1068,7 +1070,12 @@ static int korina_probe(struct platform_device *pdev)
SET_NETDEV_DEV(dev, >dev);
lp = netdev_priv(dev);
 
-   memcpy(dev->dev_addr, mac_addr, ETH_ALEN);
+   if (mac_addr) {
+   ether_addr_copy(dev->dev_addr, mac_addr);
+   } else {
+   if (of_get_mac_address(pdev->dev.of_node, dev->dev_addr))
+   eth_hw_addr_random(dev);
+   }
 
lp->rx_irq = platform_get_irq_byname(pdev, "korina_rx");
lp->tx_irq = platform_get_irq_byname(pdev, "korina_tx");
@@ -1148,8 +1155,21 @@ static int korina_remove(struct platform_device *pdev)
return 0;
 }
 
+#ifdef CONFIG_OF
+static const struct of_device_id korina_match[] = {
+   {
+   .compatible = "idt,3243x-emac",
+   },
+   { }
+};
+MODULE_DEVICE_TABLE(of, korina_match);
+#endif
+
 static struct platform_driver korina_driver = {
-   .driver.name = "korina",
+   .driver = {
+   .name = "korina",
+   .of_match_table = of_match_ptr(korina_match),
+   },
.probe = korina_probe,
.remove = korina_remove,
 };
-- 
2.29.2



[PATCH v5 net-next 06/10] net: korina: Only pass mac address via platform data

2021-04-16 Thread Thomas Bogendoerfer
Get rid of access to struct korina_device by just passing the mac
address via platform data and use drvdata for passing netdev to remove
function.

Signed-off-by: Thomas Bogendoerfer 
---
 arch/mips/rb532/devices.c |  5 +++--
 drivers/net/ethernet/korina.c | 11 ++-
 2 files changed, 9 insertions(+), 7 deletions(-)

diff --git a/arch/mips/rb532/devices.c b/arch/mips/rb532/devices.c
index dd34f1b32b79..5fc3c8ee4f31 100644
--- a/arch/mips/rb532/devices.c
+++ b/arch/mips/rb532/devices.c
@@ -105,6 +105,9 @@ static struct platform_device korina_dev0 = {
.name = "korina",
.resource = korina_dev0_res,
.num_resources = ARRAY_SIZE(korina_dev0_res),
+   .dev = {
+   .platform_data = _dev0_data.mac,
+   }
 };
 
 static struct resource cf_slot0_res[] = {
@@ -299,8 +302,6 @@ static int __init plat_setup_devices(void)
/* set the uart clock to the current cpu frequency */
rb532_uart_res[0].uartclk = idt_cpu_freq;
 
-   dev_set_drvdata(_dev0.dev, _dev0_data);
-
gpiod_add_lookup_table(_slot0_gpio_table);
return platform_add_devices(rb532_devs, ARRAY_SIZE(rb532_devs));
 }
diff --git a/drivers/net/ethernet/korina.c b/drivers/net/ethernet/korina.c
index 44fad9e924ca..d6dbbdd43d7c 100644
--- a/drivers/net/ethernet/korina.c
+++ b/drivers/net/ethernet/korina.c
@@ -1055,7 +1055,7 @@ static const struct net_device_ops korina_netdev_ops = {
 
 static int korina_probe(struct platform_device *pdev)
 {
-   struct korina_device *bif = platform_get_drvdata(pdev);
+   u8 *mac_addr = dev_get_platdata(>dev);
struct korina_private *lp;
struct net_device *dev;
void __iomem *p;
@@ -1068,8 +1068,7 @@ static int korina_probe(struct platform_device *pdev)
SET_NETDEV_DEV(dev, >dev);
lp = netdev_priv(dev);
 
-   bif->dev = dev;
-   memcpy(dev->dev_addr, bif->mac, ETH_ALEN);
+   memcpy(dev->dev_addr, mac_addr, ETH_ALEN);
 
lp->rx_irq = platform_get_irq_byname(pdev, "korina_rx");
lp->tx_irq = platform_get_irq_byname(pdev, "korina_tx");
@@ -1123,6 +1122,8 @@ static int korina_probe(struct platform_device *pdev)
lp->mii_if.phy_id_mask = 0x1f;
lp->mii_if.reg_num_mask = 0x1f;
 
+   platform_set_drvdata(pdev, dev);
+
rc = register_netdev(dev);
if (rc < 0) {
printk(KERN_ERR DRV_NAME
@@ -1140,9 +1141,9 @@ static int korina_probe(struct platform_device *pdev)
 
 static int korina_remove(struct platform_device *pdev)
 {
-   struct korina_device *bif = platform_get_drvdata(pdev);
+   struct net_device *dev = platform_get_drvdata(pdev);
 
-   unregister_netdev(bif->dev);
+   unregister_netdev(dev);
 
return 0;
 }
-- 
2.29.2



[PATCH v5 net-next 08/10] net: korina: Get mdio input clock via common clock framework

2021-04-16 Thread Thomas Bogendoerfer
With device tree clock is provided via CCF. For non device tree
use a maximum clock value to not overclock the PHY. The non device
tree usage will go away after platform is converted to DT.

Signed-off-by: Thomas Bogendoerfer 
---
 drivers/net/ethernet/korina.c | 21 +++--
 1 file changed, 15 insertions(+), 6 deletions(-)

diff --git a/drivers/net/ethernet/korina.c b/drivers/net/ethernet/korina.c
index cd078a5c679b..e95c8d87d893 100644
--- a/drivers/net/ethernet/korina.c
+++ b/drivers/net/ethernet/korina.c
@@ -57,14 +57,13 @@
 #include 
 #include 
 #include 
+#include 
 
 #include 
 #include 
 #include 
 #include 
 
-#include 
-#include 
 #include 
 #include 
 
@@ -146,10 +145,9 @@ struct korina_private {
struct work_struct restart_task;
struct net_device *dev;
struct device *dmadev;
+   int mii_clock_freq;
 };
 
-extern unsigned int idt_cpu_freq;
-
 static dma_addr_t korina_tx_dma(struct korina_private *lp, int idx)
 {
return lp->td_dma + (idx * sizeof(struct dma_desc));
@@ -899,8 +897,8 @@ static int korina_init(struct net_device *dev)
 
/* Management Clock Prescaler Divisor
 * Clock independent setting */
-   writel(((idt_cpu_freq) / MII_CLOCK + 1) & ~1,
-   >eth_regs->ethmcp);
+   writel(((lp->mii_clock_freq) / MII_CLOCK + 1) & ~1,
+  >eth_regs->ethmcp);
writel(0, >eth_regs->miimcfg);
 
/* don't transmit until fifo contains 48b */
@@ -1060,6 +1058,7 @@ static int korina_probe(struct platform_device *pdev)
u8 *mac_addr = dev_get_platdata(>dev);
struct korina_private *lp;
struct net_device *dev;
+   struct clk *clk;
void __iomem *p;
int rc;
 
@@ -1077,6 +1076,16 @@ static int korina_probe(struct platform_device *pdev)
eth_hw_addr_random(dev);
}
 
+   clk = devm_clk_get_optional(>dev, "mdioclk");
+   if (IS_ERR(clk))
+   return PTR_ERR(clk);
+   if (clk) {
+   clk_prepare_enable(clk);
+   lp->mii_clock_freq = clk_get_rate(clk);
+   } else {
+   lp->mii_clock_freq = 2; /* max possible input clk */
+   }
+
lp->rx_irq = platform_get_irq_byname(pdev, "korina_rx");
lp->tx_irq = platform_get_irq_byname(pdev, "korina_tx");
 
-- 
2.29.2



[PATCH v5 net-next 05/10] net: korina: Use DMA API

2021-04-16 Thread Thomas Bogendoerfer
Instead of messing with MIPS specific macros use DMA API for mapping
descriptors and skbs.

Reviewed-by: Andrew Lunn 
Signed-off-by: Thomas Bogendoerfer 
---
 drivers/net/ethernet/korina.c | 158 +-
 1 file changed, 98 insertions(+), 60 deletions(-)

diff --git a/drivers/net/ethernet/korina.c b/drivers/net/ethernet/korina.c
index 955fe3d3da06..44fad9e924ca 100644
--- a/drivers/net/ethernet/korina.c
+++ b/drivers/net/ethernet/korina.c
@@ -110,10 +110,15 @@ struct korina_private {
struct dma_reg __iomem *tx_dma_regs;
struct dma_desc *td_ring; /* transmit descriptor ring */
struct dma_desc *rd_ring; /* receive descriptor ring  */
+   dma_addr_t td_dma;
+   dma_addr_t rd_dma;
 
struct sk_buff *tx_skb[KORINA_NUM_TDS];
struct sk_buff *rx_skb[KORINA_NUM_RDS];
 
+   dma_addr_t rx_skb_dma[KORINA_NUM_RDS];
+   dma_addr_t tx_skb_dma[KORINA_NUM_TDS];
+
int rx_next_done;
int rx_chain_head;
int rx_chain_tail;
@@ -138,10 +143,21 @@ struct korina_private {
struct mii_if_info mii_if;
struct work_struct restart_task;
struct net_device *dev;
+   struct device *dmadev;
 };
 
 extern unsigned int idt_cpu_freq;
 
+static dma_addr_t korina_tx_dma(struct korina_private *lp, int idx)
+{
+   return lp->td_dma + (idx * sizeof(struct dma_desc));
+}
+
+static dma_addr_t korina_rx_dma(struct korina_private *lp, int idx)
+{
+   return lp->rd_dma + (idx * sizeof(struct dma_desc));
+}
+
 static inline void korina_abort_dma(struct net_device *dev,
struct dma_reg *ch)
 {
@@ -176,14 +192,17 @@ static void korina_abort_rx(struct net_device *dev)
 static int korina_send_packet(struct sk_buff *skb, struct net_device *dev)
 {
struct korina_private *lp = netdev_priv(dev);
-   unsigned long flags;
-   u32 length;
u32 chain_prev, chain_next;
+   unsigned long flags;
struct dma_desc *td;
+   dma_addr_t ca;
+   u32 length;
+   int idx;
 
spin_lock_irqsave(>lock, flags);
 
-   td = >td_ring[lp->tx_chain_tail];
+   idx = lp->tx_chain_tail;
+   td = >td_ring[idx];
 
/* stop queue when full, drop pkts if queue already full */
if (lp->tx_count >= (KORINA_NUM_TDS - 2)) {
@@ -191,26 +210,26 @@ static int korina_send_packet(struct sk_buff *skb, struct 
net_device *dev)
 
if (lp->tx_count == (KORINA_NUM_TDS - 2))
netif_stop_queue(dev);
-   else {
-   dev->stats.tx_dropped++;
-   dev_kfree_skb_any(skb);
-   spin_unlock_irqrestore(>lock, flags);
-
-   return NETDEV_TX_OK;
-   }
+   else
+   goto drop_packet;
}
 
lp->tx_count++;
 
-   lp->tx_skb[lp->tx_chain_tail] = skb;
+   lp->tx_skb[idx] = skb;
 
length = skb->len;
-   dma_cache_wback((u32)skb->data, skb->len);
 
/* Setup the transmit descriptor. */
-   td->ca = CPHYSADDR(skb->data);
-   chain_prev = (lp->tx_chain_tail - 1) & KORINA_TDS_MASK;
-   chain_next = (lp->tx_chain_tail + 1) & KORINA_TDS_MASK;
+   ca = dma_map_single(lp->dmadev, skb->data, length, DMA_TO_DEVICE);
+   if (dma_mapping_error(lp->dmadev, ca))
+   goto drop_packet;
+
+   lp->tx_skb_dma[idx] = ca;
+   td->ca = ca;
+
+   chain_prev = (idx - 1) & KORINA_TDS_MASK;
+   chain_next = (idx + 1) & KORINA_TDS_MASK;
 
if (readl(&(lp->tx_dma_regs->dmandptr)) == 0) {
if (lp->tx_chain_status == desc_empty) {
@@ -220,8 +239,8 @@ static int korina_send_packet(struct sk_buff *skb, struct 
net_device *dev)
/* Move tail */
lp->tx_chain_tail = chain_next;
/* Write to NDPTR */
-   writel(CPHYSADDR(>td_ring[lp->tx_chain_head]),
-   >tx_dma_regs->dmandptr);
+   writel(korina_tx_dma(lp, lp->tx_chain_head),
+  >tx_dma_regs->dmandptr);
/* Move head to tail */
lp->tx_chain_head = lp->tx_chain_tail;
} else {
@@ -232,12 +251,12 @@ static int korina_send_packet(struct sk_buff *skb, struct 
net_device *dev)
lp->td_ring[chain_prev].control &=
~DMA_DESC_COF;
/* Link to prev */
-   lp->td_ring[chain_prev].link =  CPHYSADDR(td);
+   lp->td_ring[chain_prev].link = korina_tx_dma(lp, idx);
/* Move tail */
lp->tx_chain_tail = chain_next;
  

[PATCH v5 net-next 04/10] net: korina: Remove nested helpers

2021-04-16 Thread Thomas Bogendoerfer
Remove helpers, which are only used in one call site.

Reviewed-by: Andrew Lunn 
Signed-off-by: Thomas Bogendoerfer 
---
 drivers/net/ethernet/korina.c | 28 +++-
 1 file changed, 3 insertions(+), 25 deletions(-)

diff --git a/drivers/net/ethernet/korina.c b/drivers/net/ethernet/korina.c
index c7abb4a8dd37..955fe3d3da06 100644
--- a/drivers/net/ethernet/korina.c
+++ b/drivers/net/ethernet/korina.c
@@ -142,12 +142,6 @@ struct korina_private {
 
 extern unsigned int idt_cpu_freq;
 
-static inline void korina_start_dma(struct dma_reg *ch, u32 dma_addr)
-{
-   writel(0, >dmandptr);
-   writel(dma_addr, >dmadptr);
-}
-
 static inline void korina_abort_dma(struct net_device *dev,
struct dma_reg *ch)
 {
@@ -164,11 +158,6 @@ static inline void korina_abort_dma(struct net_device *dev,
writel(0, >dmandptr);
 }
 
-static inline void korina_chain_dma(struct dma_reg *ch, u32 dma_addr)
-{
-   writel(dma_addr, >dmandptr);
-}
-
 static void korina_abort_tx(struct net_device *dev)
 {
struct korina_private *lp = netdev_priv(dev);
@@ -183,18 +172,6 @@ static void korina_abort_rx(struct net_device *dev)
korina_abort_dma(dev, lp->rx_dma_regs);
 }
 
-static void korina_start_rx(struct korina_private *lp,
-   struct dma_desc *rd)
-{
-   korina_start_dma(lp->rx_dma_regs, CPHYSADDR(rd));
-}
-
-static void korina_chain_rx(struct korina_private *lp,
-   struct dma_desc *rd)
-{
-   korina_chain_dma(lp->rx_dma_regs, CPHYSADDR(rd));
-}
-
 /* transmit packet */
 static int korina_send_packet(struct sk_buff *skb, struct net_device *dev)
 {
@@ -463,7 +440,7 @@ static int korina_rx(struct net_device *dev, int limit)
rd->devcs = 0;
skb = lp->rx_skb[lp->rx_next_done];
rd->ca = CPHYSADDR(skb->data);
-   korina_chain_rx(lp, rd);
+   writel(CPHYSADDR(rd), >rx_dma_regs->dmandptr);
}
 
return count;
@@ -840,7 +817,8 @@ static int korina_init(struct net_device *dev)
 
writel(0, >rx_dma_regs->dmas);
/* Start Rx DMA */
-   korina_start_rx(lp, >rd_ring[0]);
+   writel(0, >rx_dma_regs->dmandptr);
+   writel(CPHYSADDR(>rd_ring[0]), >rx_dma_regs->dmadptr);
 
writel(readl(>tx_dma_regs->dmasm) &
~(DMA_STAT_FINI | DMA_STAT_ERR),
-- 
2.29.2



[PATCH v5 net-next 02/10] net: korina: Use devres functions

2021-04-16 Thread Thomas Bogendoerfer
Simplify probe/remove code by using devm_ functions.

Reviewed-by: Andrew Lunn 
Signed-off-by: Thomas Bogendoerfer 
---
 drivers/net/ethernet/korina.c | 64 ---
 1 file changed, 21 insertions(+), 43 deletions(-)

diff --git a/drivers/net/ethernet/korina.c b/drivers/net/ethernet/korina.c
index 1b7e1c75ed9e..b56de01f6bb8 100644
--- a/drivers/net/ethernet/korina.c
+++ b/drivers/net/ethernet/korina.c
@@ -105,9 +105,9 @@ enum chain_status {
 
 /* Information that need to be kept for each board. */
 struct korina_private {
-   struct eth_regs *eth_regs;
-   struct dma_reg *rx_dma_regs;
-   struct dma_reg *tx_dma_regs;
+   struct eth_regs __iomem *eth_regs;
+   struct dma_reg __iomem *rx_dma_regs;
+   struct dma_reg __iomem *tx_dma_regs;
struct dma_desc *td_ring; /* transmit descriptor ring */
struct dma_desc *rd_ring; /* receive descriptor ring  */
 
@@ -1044,10 +1044,10 @@ static int korina_probe(struct platform_device *pdev)
struct korina_device *bif = platform_get_drvdata(pdev);
struct korina_private *lp;
struct net_device *dev;
-   struct resource *r;
+   void __iomem *p;
int rc;
 
-   dev = alloc_etherdev(sizeof(struct korina_private));
+   dev = devm_alloc_etherdev(>dev, sizeof(struct korina_private));
if (!dev)
return -ENOMEM;
 
@@ -1060,36 +1060,30 @@ static int korina_probe(struct platform_device *pdev)
lp->rx_irq = platform_get_irq_byname(pdev, "korina_rx");
lp->tx_irq = platform_get_irq_byname(pdev, "korina_tx");
 
-   r = platform_get_resource_byname(pdev, IORESOURCE_MEM, "korina_regs");
-   dev->base_addr = r->start;
-   lp->eth_regs = ioremap(r->start, resource_size(r));
-   if (!lp->eth_regs) {
+   p = devm_platform_ioremap_resource_byname(pdev, "korina_regs");
+   if (!p) {
printk(KERN_ERR DRV_NAME ": cannot remap registers\n");
-   rc = -ENXIO;
-   goto probe_err_out;
+   return -ENOMEM;
}
+   lp->eth_regs = p;
 
-   r = platform_get_resource_byname(pdev, IORESOURCE_MEM, "korina_dma_rx");
-   lp->rx_dma_regs = ioremap(r->start, resource_size(r));
-   if (!lp->rx_dma_regs) {
+   p = devm_platform_ioremap_resource_byname(pdev, "korina_dma_rx");
+   if (!p) {
printk(KERN_ERR DRV_NAME ": cannot remap Rx DMA registers\n");
-   rc = -ENXIO;
-   goto probe_err_dma_rx;
+   return -ENOMEM;
}
+   lp->rx_dma_regs = p;
 
-   r = platform_get_resource_byname(pdev, IORESOURCE_MEM, "korina_dma_tx");
-   lp->tx_dma_regs = ioremap(r->start, resource_size(r));
-   if (!lp->tx_dma_regs) {
+   p = devm_platform_ioremap_resource_byname(pdev, "korina_dma_tx");
+   if (!p) {
printk(KERN_ERR DRV_NAME ": cannot remap Tx DMA registers\n");
-   rc = -ENXIO;
-   goto probe_err_dma_tx;
+   return -ENOMEM;
}
+   lp->tx_dma_regs = p;
 
lp->td_ring = kmalloc(TD_RING_SIZE + RD_RING_SIZE, GFP_KERNEL);
-   if (!lp->td_ring) {
-   rc = -ENXIO;
-   goto probe_err_td_ring;
-   }
+   if (!lp->td_ring)
+   return -ENOMEM;
 
dma_cache_inv((unsigned long)(lp->td_ring),
TD_RING_SIZE + RD_RING_SIZE);
@@ -1119,7 +1113,8 @@ static int korina_probe(struct platform_device *pdev)
if (rc < 0) {
printk(KERN_ERR DRV_NAME
": cannot register net device: %d\n", rc);
-   goto probe_err_register;
+   kfree((struct dma_desc *)KSEG0ADDR(lp->td_ring));
+   return rc;
}
timer_setup(>media_check_timer, korina_poll_media, 0);
 
@@ -1127,20 +1122,7 @@ static int korina_probe(struct platform_device *pdev)
 
printk(KERN_INFO "%s: " DRV_NAME "-" DRV_VERSION " " DRV_RELDATE "\n",
dev->name);
-out:
return rc;
-
-probe_err_register:
-   kfree((struct dma_desc *)KSEG0ADDR(lp->td_ring));
-probe_err_td_ring:
-   iounmap(lp->tx_dma_regs);
-probe_err_dma_tx:
-   iounmap(lp->rx_dma_regs);
-probe_err_dma_rx:
-   iounmap(lp->eth_regs);
-probe_err_out:
-   free_netdev(dev);
-   goto out;
 }
 
 static int korina_remove(struct platform_device *pdev)
@@ -1148,13 +1130,9 @@ static int korina_remove(struct platform_device *pdev)
struct korina_device *bif = platform_get_drvdata(pdev);
struct korina_private *lp = netdev_priv(bif->dev);
 
-   iounmap(lp->eth_regs);
-   iounmap(lp->rx_dma_regs);
-   iounmap(lp->tx_dma_regs);
kfree((struct dma_desc *)KSEG0ADDR(lp->td_ring));
 
unregister_netdev(bif->dev);
-   free_netdev(bif->dev);
 
return 0;
 }
-- 
2.29.2



[PATCH v5 net-next 03/10] net: korina: Remove not needed cache flushes

2021-04-16 Thread Thomas Bogendoerfer
Descriptors are mapped uncached so there is no need to do any cache
handling for them.

Reviewed-by: Andrew Lunn 
Signed-off-by: Thomas Bogendoerfer 
---
 drivers/net/ethernet/korina.c | 6 --
 1 file changed, 6 deletions(-)

diff --git a/drivers/net/ethernet/korina.c b/drivers/net/ethernet/korina.c
index b56de01f6bb8..c7abb4a8dd37 100644
--- a/drivers/net/ethernet/korina.c
+++ b/drivers/net/ethernet/korina.c
@@ -231,7 +231,6 @@ static int korina_send_packet(struct sk_buff *skb, struct 
net_device *dev)
dma_cache_wback((u32)skb->data, skb->len);
 
/* Setup the transmit descriptor. */
-   dma_cache_inv((u32) td, sizeof(*td));
td->ca = CPHYSADDR(skb->data);
chain_prev = (lp->tx_chain_tail - 1) & KORINA_TDS_MASK;
chain_next = (lp->tx_chain_tail + 1) & KORINA_TDS_MASK;
@@ -284,7 +283,6 @@ static int korina_send_packet(struct sk_buff *skb, struct 
net_device *dev)
lp->tx_chain_tail = chain_next;
}
}
-   dma_cache_wback((u32) td, sizeof(*td));
 
netif_trans_update(dev);
spin_unlock_irqrestore(>lock, flags);
@@ -373,8 +371,6 @@ static int korina_rx(struct net_device *dev, int limit)
u32 devcs, pkt_len, dmas;
int count;
 
-   dma_cache_inv((u32)rd, sizeof(*rd));
-
for (count = 0; count < limit; count++) {
skb = lp->rx_skb[lp->rx_next_done];
skb_new = NULL;
@@ -453,7 +449,6 @@ static int korina_rx(struct net_device *dev, int limit)
~DMA_DESC_COD;
 
lp->rx_next_done = (lp->rx_next_done + 1) & KORINA_RDS_MASK;
-   dma_cache_wback((u32)rd, sizeof(*rd));
rd = >rd_ring[lp->rx_next_done];
writel(~DMA_STAT_DONE, >rx_dma_regs->dmas);
}
@@ -468,7 +463,6 @@ static int korina_rx(struct net_device *dev, int limit)
rd->devcs = 0;
skb = lp->rx_skb[lp->rx_next_done];
rd->ca = CPHYSADDR(skb->data);
-   dma_cache_wback((u32)rd, sizeof(*rd));
korina_chain_rx(lp, rd);
}
 
-- 
2.29.2



[PATCH v5 net-next 01/10] net: korina: Fix MDIO functions

2021-04-16 Thread Thomas Bogendoerfer
Fixed MDIO functions to work reliable and not just by accident.

Signed-off-by: Thomas Bogendoerfer 
---
 drivers/net/ethernet/Kconfig  |  1 +
 drivers/net/ethernet/korina.c | 56 +++
 2 files changed, 38 insertions(+), 19 deletions(-)

diff --git a/drivers/net/ethernet/Kconfig b/drivers/net/ethernet/Kconfig
index ad04660b97b8..c059b4bd3f23 100644
--- a/drivers/net/ethernet/Kconfig
+++ b/drivers/net/ethernet/Kconfig
@@ -98,6 +98,7 @@ config JME
 config KORINA
tristate "Korina (IDT RC32434) Ethernet support"
depends on MIKROTIK_RB532
+   select MII
help
  If you have a Mikrotik RouterBoard 500 or IDT RC32434
  based system say Y. Otherwise say N.
diff --git a/drivers/net/ethernet/korina.c b/drivers/net/ethernet/korina.c
index 925161959b9b..1b7e1c75ed9e 100644
--- a/drivers/net/ethernet/korina.c
+++ b/drivers/net/ethernet/korina.c
@@ -41,6 +41,7 @@
 #include 
 #include 
 #include 
+#include 
 #include 
 #include 
 #include 
@@ -137,7 +138,6 @@ struct korina_private {
struct mii_if_info mii_if;
struct work_struct restart_task;
struct net_device *dev;
-   int phy_addr;
 };
 
 extern unsigned int idt_cpu_freq;
@@ -292,32 +292,48 @@ static int korina_send_packet(struct sk_buff *skb, struct 
net_device *dev)
return NETDEV_TX_OK;
 }
 
-static int mdio_read(struct net_device *dev, int mii_id, int reg)
+static int korina_mdio_wait(struct korina_private *lp)
+{
+   u32 value;
+
+   return readl_poll_timeout_atomic(>eth_regs->miimind,
+value, value & ETH_MII_IND_BSY,
+1, 1000);
+}
+
+static int korina_mdio_read(struct net_device *dev, int phy, int reg)
 {
struct korina_private *lp = netdev_priv(dev);
int ret;
 
-   mii_id = ((lp->rx_irq == 0x2c ? 1 : 0) << 8);
+   ret = korina_mdio_wait(lp);
+   if (ret < 0)
+   return ret;
 
-   writel(0, >eth_regs->miimcfg);
-   writel(0, >eth_regs->miimcmd);
-   writel(mii_id | reg, >eth_regs->miimaddr);
-   writel(ETH_MII_CMD_SCN, >eth_regs->miimcmd);
+   writel(phy << 8 | reg, >eth_regs->miimaddr);
+   writel(1, >eth_regs->miimcmd);
 
-   ret = (int)(readl(>eth_regs->miimrdd));
+   ret = korina_mdio_wait(lp);
+   if (ret < 0)
+   return ret;
+
+   if (readl(>eth_regs->miimind) & ETH_MII_IND_NV)
+   return -EINVAL;
+
+   ret = readl(>eth_regs->miimrdd);
+   writel(0, >eth_regs->miimcmd);
return ret;
 }
 
-static void mdio_write(struct net_device *dev, int mii_id, int reg, int val)
+static void korina_mdio_write(struct net_device *dev, int phy, int reg, int 
val)
 {
struct korina_private *lp = netdev_priv(dev);
 
-   mii_id = ((lp->rx_irq == 0x2c ? 1 : 0) << 8);
+   if (korina_mdio_wait(lp))
+   return;
 
-   writel(0, >eth_regs->miimcfg);
-   writel(1, >eth_regs->miimcmd);
-   writel(mii_id | reg, >eth_regs->miimaddr);
-   writel(ETH_MII_CMD_SCN, >eth_regs->miimcmd);
+   writel(0, >eth_regs->miimcmd);
+   writel(phy << 8 | reg, >eth_regs->miimaddr);
writel(val, >eth_regs->miimwtd);
 }
 
@@ -643,7 +659,7 @@ static void korina_check_media(struct net_device *dev, 
unsigned int init_media)
 {
struct korina_private *lp = netdev_priv(dev);
 
-   mii_check_media(>mii_if, 0, init_media);
+   mii_check_media(>mii_if, 1, init_media);
 
if (lp->mii_if.full_duplex)
writel(readl(>eth_regs->ethmac2) | ETH_MAC2_FD,
@@ -869,12 +885,15 @@ static int korina_init(struct net_device *dev)
 * Clock independent setting */
writel(((idt_cpu_freq) / MII_CLOCK + 1) & ~1,
>eth_regs->ethmcp);
+   writel(0, >eth_regs->miimcfg);
 
/* don't transmit until fifo contains 48b */
writel(48, >eth_regs->ethfifott);
 
writel(ETH_MAC1_RE, >eth_regs->ethmac1);
 
+   korina_check_media(dev, 1);
+
napi_enable(>napi);
netif_start_queue(dev);
 
@@ -1089,11 +1108,10 @@ static int korina_probe(struct platform_device *pdev)
dev->watchdog_timeo = TX_TIMEOUT;
netif_napi_add(dev, >napi, korina_poll, NAPI_POLL_WEIGHT);
 
-   lp->phy_addr = (((lp->rx_irq == 0x2c? 1:0) << 8) | 0x05);
lp->mii_if.dev = dev;
-   lp->mii_if.mdio_read = mdio_read;
-   lp->mii_if.mdio_write = mdio_write;
-   lp->mii_if.phy_id = lp->phy_addr;
+   lp->mii_if.mdio_read = korina_mdio_read;
+   lp->mii_if.mdio_write = korina_mdio_write;
+   lp->mii_if.phy_id = 1;
lp->mii_if.phy_id_mask = 0x1f;
lp->mii_if.reg_num_mask = 0x1f;
 
-- 
2.29.2



[PATCH v5 net-next 00/10] net: Korina improvements

2021-04-16 Thread Thomas Bogendoerfer
While converting Mikrotik RB532 support to use device tree I stumbled
over the korina ethernet driver, which used way too many MIPS specific
hacks. This series cleans this all up and adds support for device tree.

Changes in v5:
  - fixed email address in binding document, which prevented sending it

Changes in v4:
  - improve error returns in mdio_read further
  - added clock name and improved clk handling
  - fixed bindind errors

Changes in v3:
  - use readl_poll_timeout_atomic in mdio_wait
  - return -ETIMEDOUT, if mdio_wait failed
  - added DT binding and changed name to idt,3243x-emac
  - fixed usage of of_get_mac_address for net-next

Changes in v2:
  - added device tree support to get rid of idt_cpu_freq
  - fixed compile test on 64bit archs
  - fixed descriptor current address handling by storing/using mapped
dma addresses (dma controller modifies current address)

Thomas Bogendoerfer (10):
  net: korina: Fix MDIO functions
  net: korina: Use devres functions
  net: korina: Remove not needed cache flushes
  net: korina: Remove nested helpers
  net: korina: Use DMA API
  net: korina: Only pass mac address via platform data
  net: korina: Add support for device tree
  net: korina: Get mdio input clock via common clock framework
  net: korina: Make driver COMPILE_TESTable
  dt-bindings: net: korina: Add DT bindings for IDT 79RC3243x SoCs

 .../bindings/net/idt,3243x-emac.yaml  |  74 +++
 arch/mips/rb532/devices.c |   5 +-
 drivers/net/ethernet/Kconfig  |   3 +-
 drivers/net/ethernet/korina.c | 601 +-
 4 files changed, 511 insertions(+), 172 deletions(-)
 create mode 100644 Documentation/devicetree/bindings/net/idt,3243x-emac.yaml

-- 
2.29.2



[PATCH v4 net-next 09/10] net: korina: Make driver COMPILE_TESTable

2021-04-16 Thread Thomas Bogendoerfer
Move structs/defines for ethernet/dma register into driver, since they
are only used for this driver and remove any MIPS specific includes.
This makes it possible to COMPILE_TEST the driver.

Signed-off-by: Thomas Bogendoerfer 
---
 drivers/net/ethernet/Kconfig  |   2 +-
 drivers/net/ethernet/korina.c | 249 --
 2 files changed, 239 insertions(+), 12 deletions(-)

diff --git a/drivers/net/ethernet/Kconfig b/drivers/net/ethernet/Kconfig
index c059b4bd3f23..453d202a28c1 100644
--- a/drivers/net/ethernet/Kconfig
+++ b/drivers/net/ethernet/Kconfig
@@ -97,7 +97,7 @@ config JME
 
 config KORINA
tristate "Korina (IDT RC32434) Ethernet support"
-   depends on MIKROTIK_RB532
+   depends on MIKROTIK_RB532 || COMPILE_TEST
select MII
help
  If you have a Mikrotik RouterBoard 500 or IDT RC32434
diff --git a/drivers/net/ethernet/korina.c b/drivers/net/ethernet/korina.c
index e95c8d87d893..5f39a5bba531 100644
--- a/drivers/net/ethernet/korina.c
+++ b/drivers/net/ethernet/korina.c
@@ -59,18 +59,244 @@
 #include 
 #include 
 
-#include 
-#include 
-#include 
-#include 
-
-#include 
-#include 
-
 #define DRV_NAME   "korina"
 #define DRV_VERSION"0.20"
 #define DRV_RELDATE"15Sep2017"
 
+struct eth_regs {
+   u32 ethintfc;
+   u32 ethfifott;
+   u32 etharc;
+   u32 ethhash0;
+   u32 ethhash1;
+   u32 ethu0[4];   /* Reserved. */
+   u32 ethpfs;
+   u32 ethmcp;
+   u32 eth_u1[10]; /* Reserved. */
+   u32 ethspare;
+   u32 eth_u2[42]; /* Reserved. */
+   u32 ethsal0;
+   u32 ethsah0;
+   u32 ethsal1;
+   u32 ethsah1;
+   u32 ethsal2;
+   u32 ethsah2;
+   u32 ethsal3;
+   u32 ethsah3;
+   u32 ethrbc;
+   u32 ethrpc;
+   u32 ethrupc;
+   u32 ethrfc;
+   u32 ethtbc;
+   u32 ethgpf;
+   u32 eth_u9[50]; /* Reserved. */
+   u32 ethmac1;
+   u32 ethmac2;
+   u32 ethipgt;
+   u32 ethipgr;
+   u32 ethclrt;
+   u32 ethmaxf;
+   u32 eth_u10;/* Reserved. */
+   u32 ethmtest;
+   u32 miimcfg;
+   u32 miimcmd;
+   u32 miimaddr;
+   u32 miimwtd;
+   u32 miimrdd;
+   u32 miimind;
+   u32 eth_u11;/* Reserved. */
+   u32 eth_u12;/* Reserved. */
+   u32 ethcfsa0;
+   u32 ethcfsa1;
+   u32 ethcfsa2;
+};
+
+/* Ethernet interrupt registers */
+#define ETH_INT_FC_EN  BIT(0)
+#define ETH_INT_FC_ITS BIT(1)
+#define ETH_INT_FC_RIP BIT(2)
+#define ETH_INT_FC_JAM BIT(3)
+#define ETH_INT_FC_OVR BIT(4)
+#define ETH_INT_FC_UND BIT(5)
+#define ETH_INT_FC_IOC 0x00c0
+
+/* Ethernet FIFO registers */
+#define ETH_FIFI_TT_TTH_BIT0
+#define ETH_FIFO_TT_TTH0x007f
+
+/* Ethernet ARC/multicast registers */
+#define ETH_ARC_PROBIT(0)
+#define ETH_ARC_AM BIT(1)
+#define ETH_ARC_AFMBIT(2)
+#define ETH_ARC_AB BIT(3)
+
+/* Ethernet SAL registers */
+#define ETH_SAL_BYTE_5 0x00ff
+#define ETH_SAL_BYTE_4 0xff00
+#define ETH_SAL_BYTE_3 0x00ff
+#define ETH_SAL_BYTE_2 0xff00
+
+/* Ethernet SAH registers */
+#define ETH_SAH_BYTE1  0x00ff
+#define ETH_SAH_BYTE0  0xff00
+
+/* Ethernet GPF register */
+#define ETH_GPF_PTV0x
+
+/* Ethernet PFG register */
+#define ETH_PFS_PFDBIT(0)
+
+/* Ethernet CFSA[0-3] registers */
+#define ETH_CFSA0_CFSA40x00ff
+#define ETH_CFSA0_CFSA50xff00
+#define ETH_CFSA1_CFSA20x00ff
+#define ETH_CFSA1_CFSA30xff00
+#define ETH_CFSA1_CFSA00x00ff
+#define ETH_CFSA1_CFSA10xff00
+
+/* Ethernet MAC1 registers */
+#define ETH_MAC1_REBIT(0)
+#define ETH_MAC1_PAF   BIT(1)
+#define ETH_MAC1_RFC   BIT(2)
+#define ETH_MAC1_TFC   BIT(3)
+#define ETH_MAC1_LBBIT(4)
+#define ETH_MAC1_MRBIT(31)
+
+/* Ethernet MAC2 registers */
+#define ETH_MAC2_FDBIT(0)
+#define ETH_MAC2_FLC   BIT(1)
+#define ETH_MAC2_HFE   BIT(2)
+#define ETH_MAC2_DCBIT(3)
+#define ETH_MAC2_CEN   BIT(4)
+#define ETH_MAC2_PEBIT(5)
+#define ETH_MAC2_VPE   BIT(6)
+#define ETH_MAC2_APE   BIT(7)
+#define ETH_MAC2_PPE   BIT(8)
+#define ETH_MAC2_LPE   BIT(9)
+#define ETH_MAC2_NBBIT(12)
+#define ETH_MAC2_BPBIT(13)
+#define ETH_MAC2_EDBIT(14)
+
+/* Ethernet IPGT register */
+#define ETH_IPGT   0x007f
+
+/* Ethernet IPGR registers */
+#define ETH_IPGR_IPGR2 0x007f
+#define ETH_IPGR_IPGR1 0x7f00
+
+/* Ethernet CLRT registers */
+#define ETH_CLRT_MAX_RET   0x000f
+#

[PATCH v4 net-next 08/10] net: korina: Get mdio input clock via common clock framework

2021-04-16 Thread Thomas Bogendoerfer
With device tree clock is provided via CCF. For non device tree
use a maximum clock value to not overclock the PHY. The non device
tree usage will go away after platform is converted to DT.

Signed-off-by: Thomas Bogendoerfer 
---
 drivers/net/ethernet/korina.c | 21 +++--
 1 file changed, 15 insertions(+), 6 deletions(-)

diff --git a/drivers/net/ethernet/korina.c b/drivers/net/ethernet/korina.c
index cd078a5c679b..e95c8d87d893 100644
--- a/drivers/net/ethernet/korina.c
+++ b/drivers/net/ethernet/korina.c
@@ -57,14 +57,13 @@
 #include 
 #include 
 #include 
+#include 
 
 #include 
 #include 
 #include 
 #include 
 
-#include 
-#include 
 #include 
 #include 
 
@@ -146,10 +145,9 @@ struct korina_private {
struct work_struct restart_task;
struct net_device *dev;
struct device *dmadev;
+   int mii_clock_freq;
 };
 
-extern unsigned int idt_cpu_freq;
-
 static dma_addr_t korina_tx_dma(struct korina_private *lp, int idx)
 {
return lp->td_dma + (idx * sizeof(struct dma_desc));
@@ -899,8 +897,8 @@ static int korina_init(struct net_device *dev)
 
/* Management Clock Prescaler Divisor
 * Clock independent setting */
-   writel(((idt_cpu_freq) / MII_CLOCK + 1) & ~1,
-   >eth_regs->ethmcp);
+   writel(((lp->mii_clock_freq) / MII_CLOCK + 1) & ~1,
+  >eth_regs->ethmcp);
writel(0, >eth_regs->miimcfg);
 
/* don't transmit until fifo contains 48b */
@@ -1060,6 +1058,7 @@ static int korina_probe(struct platform_device *pdev)
u8 *mac_addr = dev_get_platdata(>dev);
struct korina_private *lp;
struct net_device *dev;
+   struct clk *clk;
void __iomem *p;
int rc;
 
@@ -1077,6 +1076,16 @@ static int korina_probe(struct platform_device *pdev)
eth_hw_addr_random(dev);
}
 
+   clk = devm_clk_get_optional(>dev, "mdioclk");
+   if (IS_ERR(clk))
+   return PTR_ERR(clk);
+   if (clk) {
+   clk_prepare_enable(clk);
+   lp->mii_clock_freq = clk_get_rate(clk);
+   } else {
+   lp->mii_clock_freq = 2; /* max possible input clk */
+   }
+
lp->rx_irq = platform_get_irq_byname(pdev, "korina_rx");
lp->tx_irq = platform_get_irq_byname(pdev, "korina_tx");
 
-- 
2.29.2



[PATCH v4 net-next 07/10] net: korina: Add support for device tree

2021-04-16 Thread Thomas Bogendoerfer
If there is no mac address passed via platform data try to get it via
device tree and fall back to a random mac address, if all fail.

Signed-off-by: Thomas Bogendoerfer 
---
 drivers/net/ethernet/korina.c | 24 ++--
 1 file changed, 22 insertions(+), 2 deletions(-)

diff --git a/drivers/net/ethernet/korina.c b/drivers/net/ethernet/korina.c
index d6dbbdd43d7c..cd078a5c679b 100644
--- a/drivers/net/ethernet/korina.c
+++ b/drivers/net/ethernet/korina.c
@@ -43,6 +43,8 @@
 #include 
 #include 
 #include 
+#include 
+#include 
 #include 
 #include 
 #include 
@@ -1068,7 +1070,12 @@ static int korina_probe(struct platform_device *pdev)
SET_NETDEV_DEV(dev, >dev);
lp = netdev_priv(dev);
 
-   memcpy(dev->dev_addr, mac_addr, ETH_ALEN);
+   if (mac_addr) {
+   ether_addr_copy(dev->dev_addr, mac_addr);
+   } else {
+   if (of_get_mac_address(pdev->dev.of_node, dev->dev_addr))
+   eth_hw_addr_random(dev);
+   }
 
lp->rx_irq = platform_get_irq_byname(pdev, "korina_rx");
lp->tx_irq = platform_get_irq_byname(pdev, "korina_tx");
@@ -1148,8 +1155,21 @@ static int korina_remove(struct platform_device *pdev)
return 0;
 }
 
+#ifdef CONFIG_OF
+static const struct of_device_id korina_match[] = {
+   {
+   .compatible = "idt,3243x-emac",
+   },
+   { }
+};
+MODULE_DEVICE_TABLE(of, korina_match);
+#endif
+
 static struct platform_driver korina_driver = {
-   .driver.name = "korina",
+   .driver = {
+   .name = "korina",
+   .of_match_table = of_match_ptr(korina_match),
+   },
.probe = korina_probe,
.remove = korina_remove,
 };
-- 
2.29.2



[PATCH v4 net-next 05/10] net: korina: Use DMA API

2021-04-16 Thread Thomas Bogendoerfer
Instead of messing with MIPS specific macros use DMA API for mapping
descriptors and skbs.

Reviewed-by: Andrew Lunn 
Signed-off-by: Thomas Bogendoerfer 
---
 drivers/net/ethernet/korina.c | 158 +-
 1 file changed, 98 insertions(+), 60 deletions(-)

diff --git a/drivers/net/ethernet/korina.c b/drivers/net/ethernet/korina.c
index 955fe3d3da06..44fad9e924ca 100644
--- a/drivers/net/ethernet/korina.c
+++ b/drivers/net/ethernet/korina.c
@@ -110,10 +110,15 @@ struct korina_private {
struct dma_reg __iomem *tx_dma_regs;
struct dma_desc *td_ring; /* transmit descriptor ring */
struct dma_desc *rd_ring; /* receive descriptor ring  */
+   dma_addr_t td_dma;
+   dma_addr_t rd_dma;
 
struct sk_buff *tx_skb[KORINA_NUM_TDS];
struct sk_buff *rx_skb[KORINA_NUM_RDS];
 
+   dma_addr_t rx_skb_dma[KORINA_NUM_RDS];
+   dma_addr_t tx_skb_dma[KORINA_NUM_TDS];
+
int rx_next_done;
int rx_chain_head;
int rx_chain_tail;
@@ -138,10 +143,21 @@ struct korina_private {
struct mii_if_info mii_if;
struct work_struct restart_task;
struct net_device *dev;
+   struct device *dmadev;
 };
 
 extern unsigned int idt_cpu_freq;
 
+static dma_addr_t korina_tx_dma(struct korina_private *lp, int idx)
+{
+   return lp->td_dma + (idx * sizeof(struct dma_desc));
+}
+
+static dma_addr_t korina_rx_dma(struct korina_private *lp, int idx)
+{
+   return lp->rd_dma + (idx * sizeof(struct dma_desc));
+}
+
 static inline void korina_abort_dma(struct net_device *dev,
struct dma_reg *ch)
 {
@@ -176,14 +192,17 @@ static void korina_abort_rx(struct net_device *dev)
 static int korina_send_packet(struct sk_buff *skb, struct net_device *dev)
 {
struct korina_private *lp = netdev_priv(dev);
-   unsigned long flags;
-   u32 length;
u32 chain_prev, chain_next;
+   unsigned long flags;
struct dma_desc *td;
+   dma_addr_t ca;
+   u32 length;
+   int idx;
 
spin_lock_irqsave(>lock, flags);
 
-   td = >td_ring[lp->tx_chain_tail];
+   idx = lp->tx_chain_tail;
+   td = >td_ring[idx];
 
/* stop queue when full, drop pkts if queue already full */
if (lp->tx_count >= (KORINA_NUM_TDS - 2)) {
@@ -191,26 +210,26 @@ static int korina_send_packet(struct sk_buff *skb, struct 
net_device *dev)
 
if (lp->tx_count == (KORINA_NUM_TDS - 2))
netif_stop_queue(dev);
-   else {
-   dev->stats.tx_dropped++;
-   dev_kfree_skb_any(skb);
-   spin_unlock_irqrestore(>lock, flags);
-
-   return NETDEV_TX_OK;
-   }
+   else
+   goto drop_packet;
}
 
lp->tx_count++;
 
-   lp->tx_skb[lp->tx_chain_tail] = skb;
+   lp->tx_skb[idx] = skb;
 
length = skb->len;
-   dma_cache_wback((u32)skb->data, skb->len);
 
/* Setup the transmit descriptor. */
-   td->ca = CPHYSADDR(skb->data);
-   chain_prev = (lp->tx_chain_tail - 1) & KORINA_TDS_MASK;
-   chain_next = (lp->tx_chain_tail + 1) & KORINA_TDS_MASK;
+   ca = dma_map_single(lp->dmadev, skb->data, length, DMA_TO_DEVICE);
+   if (dma_mapping_error(lp->dmadev, ca))
+   goto drop_packet;
+
+   lp->tx_skb_dma[idx] = ca;
+   td->ca = ca;
+
+   chain_prev = (idx - 1) & KORINA_TDS_MASK;
+   chain_next = (idx + 1) & KORINA_TDS_MASK;
 
if (readl(&(lp->tx_dma_regs->dmandptr)) == 0) {
if (lp->tx_chain_status == desc_empty) {
@@ -220,8 +239,8 @@ static int korina_send_packet(struct sk_buff *skb, struct 
net_device *dev)
/* Move tail */
lp->tx_chain_tail = chain_next;
/* Write to NDPTR */
-   writel(CPHYSADDR(>td_ring[lp->tx_chain_head]),
-   >tx_dma_regs->dmandptr);
+   writel(korina_tx_dma(lp, lp->tx_chain_head),
+  >tx_dma_regs->dmandptr);
/* Move head to tail */
lp->tx_chain_head = lp->tx_chain_tail;
} else {
@@ -232,12 +251,12 @@ static int korina_send_packet(struct sk_buff *skb, struct 
net_device *dev)
lp->td_ring[chain_prev].control &=
~DMA_DESC_COF;
/* Link to prev */
-   lp->td_ring[chain_prev].link =  CPHYSADDR(td);
+   lp->td_ring[chain_prev].link = korina_tx_dma(lp, idx);
/* Move tail */
lp->tx_chain_tail = chain_next;
  

[PATCH v4 net-next 06/10] net: korina: Only pass mac address via platform data

2021-04-16 Thread Thomas Bogendoerfer
Get rid of access to struct korina_device by just passing the mac
address via platform data and use drvdata for passing netdev to remove
function.

Signed-off-by: Thomas Bogendoerfer 
---
 arch/mips/rb532/devices.c |  5 +++--
 drivers/net/ethernet/korina.c | 11 ++-
 2 files changed, 9 insertions(+), 7 deletions(-)

diff --git a/arch/mips/rb532/devices.c b/arch/mips/rb532/devices.c
index dd34f1b32b79..5fc3c8ee4f31 100644
--- a/arch/mips/rb532/devices.c
+++ b/arch/mips/rb532/devices.c
@@ -105,6 +105,9 @@ static struct platform_device korina_dev0 = {
.name = "korina",
.resource = korina_dev0_res,
.num_resources = ARRAY_SIZE(korina_dev0_res),
+   .dev = {
+   .platform_data = _dev0_data.mac,
+   }
 };
 
 static struct resource cf_slot0_res[] = {
@@ -299,8 +302,6 @@ static int __init plat_setup_devices(void)
/* set the uart clock to the current cpu frequency */
rb532_uart_res[0].uartclk = idt_cpu_freq;
 
-   dev_set_drvdata(_dev0.dev, _dev0_data);
-
gpiod_add_lookup_table(_slot0_gpio_table);
return platform_add_devices(rb532_devs, ARRAY_SIZE(rb532_devs));
 }
diff --git a/drivers/net/ethernet/korina.c b/drivers/net/ethernet/korina.c
index 44fad9e924ca..d6dbbdd43d7c 100644
--- a/drivers/net/ethernet/korina.c
+++ b/drivers/net/ethernet/korina.c
@@ -1055,7 +1055,7 @@ static const struct net_device_ops korina_netdev_ops = {
 
 static int korina_probe(struct platform_device *pdev)
 {
-   struct korina_device *bif = platform_get_drvdata(pdev);
+   u8 *mac_addr = dev_get_platdata(>dev);
struct korina_private *lp;
struct net_device *dev;
void __iomem *p;
@@ -1068,8 +1068,7 @@ static int korina_probe(struct platform_device *pdev)
SET_NETDEV_DEV(dev, >dev);
lp = netdev_priv(dev);
 
-   bif->dev = dev;
-   memcpy(dev->dev_addr, bif->mac, ETH_ALEN);
+   memcpy(dev->dev_addr, mac_addr, ETH_ALEN);
 
lp->rx_irq = platform_get_irq_byname(pdev, "korina_rx");
lp->tx_irq = platform_get_irq_byname(pdev, "korina_tx");
@@ -1123,6 +1122,8 @@ static int korina_probe(struct platform_device *pdev)
lp->mii_if.phy_id_mask = 0x1f;
lp->mii_if.reg_num_mask = 0x1f;
 
+   platform_set_drvdata(pdev, dev);
+
rc = register_netdev(dev);
if (rc < 0) {
printk(KERN_ERR DRV_NAME
@@ -1140,9 +1141,9 @@ static int korina_probe(struct platform_device *pdev)
 
 static int korina_remove(struct platform_device *pdev)
 {
-   struct korina_device *bif = platform_get_drvdata(pdev);
+   struct net_device *dev = platform_get_drvdata(pdev);
 
-   unregister_netdev(bif->dev);
+   unregister_netdev(dev);
 
return 0;
 }
-- 
2.29.2



[PATCH v4 net-next 04/10] net: korina: Remove nested helpers

2021-04-16 Thread Thomas Bogendoerfer
Remove helpers, which are only used in one call site.

Reviewed-by: Andrew Lunn 
Signed-off-by: Thomas Bogendoerfer 
---
 drivers/net/ethernet/korina.c | 28 +++-
 1 file changed, 3 insertions(+), 25 deletions(-)

diff --git a/drivers/net/ethernet/korina.c b/drivers/net/ethernet/korina.c
index c7abb4a8dd37..955fe3d3da06 100644
--- a/drivers/net/ethernet/korina.c
+++ b/drivers/net/ethernet/korina.c
@@ -142,12 +142,6 @@ struct korina_private {
 
 extern unsigned int idt_cpu_freq;
 
-static inline void korina_start_dma(struct dma_reg *ch, u32 dma_addr)
-{
-   writel(0, >dmandptr);
-   writel(dma_addr, >dmadptr);
-}
-
 static inline void korina_abort_dma(struct net_device *dev,
struct dma_reg *ch)
 {
@@ -164,11 +158,6 @@ static inline void korina_abort_dma(struct net_device *dev,
writel(0, >dmandptr);
 }
 
-static inline void korina_chain_dma(struct dma_reg *ch, u32 dma_addr)
-{
-   writel(dma_addr, >dmandptr);
-}
-
 static void korina_abort_tx(struct net_device *dev)
 {
struct korina_private *lp = netdev_priv(dev);
@@ -183,18 +172,6 @@ static void korina_abort_rx(struct net_device *dev)
korina_abort_dma(dev, lp->rx_dma_regs);
 }
 
-static void korina_start_rx(struct korina_private *lp,
-   struct dma_desc *rd)
-{
-   korina_start_dma(lp->rx_dma_regs, CPHYSADDR(rd));
-}
-
-static void korina_chain_rx(struct korina_private *lp,
-   struct dma_desc *rd)
-{
-   korina_chain_dma(lp->rx_dma_regs, CPHYSADDR(rd));
-}
-
 /* transmit packet */
 static int korina_send_packet(struct sk_buff *skb, struct net_device *dev)
 {
@@ -463,7 +440,7 @@ static int korina_rx(struct net_device *dev, int limit)
rd->devcs = 0;
skb = lp->rx_skb[lp->rx_next_done];
rd->ca = CPHYSADDR(skb->data);
-   korina_chain_rx(lp, rd);
+   writel(CPHYSADDR(rd), >rx_dma_regs->dmandptr);
}
 
return count;
@@ -840,7 +817,8 @@ static int korina_init(struct net_device *dev)
 
writel(0, >rx_dma_regs->dmas);
/* Start Rx DMA */
-   korina_start_rx(lp, >rd_ring[0]);
+   writel(0, >rx_dma_regs->dmandptr);
+   writel(CPHYSADDR(>rd_ring[0]), >rx_dma_regs->dmadptr);
 
writel(readl(>tx_dma_regs->dmasm) &
~(DMA_STAT_FINI | DMA_STAT_ERR),
-- 
2.29.2



[PATCH v4 net-next 02/10] net: korina: Use devres functions

2021-04-16 Thread Thomas Bogendoerfer
Simplify probe/remove code by using devm_ functions.

Reviewed-by: Andrew Lunn 
Signed-off-by: Thomas Bogendoerfer 
---
 drivers/net/ethernet/korina.c | 64 ---
 1 file changed, 21 insertions(+), 43 deletions(-)

diff --git a/drivers/net/ethernet/korina.c b/drivers/net/ethernet/korina.c
index 1b7e1c75ed9e..b56de01f6bb8 100644
--- a/drivers/net/ethernet/korina.c
+++ b/drivers/net/ethernet/korina.c
@@ -105,9 +105,9 @@ enum chain_status {
 
 /* Information that need to be kept for each board. */
 struct korina_private {
-   struct eth_regs *eth_regs;
-   struct dma_reg *rx_dma_regs;
-   struct dma_reg *tx_dma_regs;
+   struct eth_regs __iomem *eth_regs;
+   struct dma_reg __iomem *rx_dma_regs;
+   struct dma_reg __iomem *tx_dma_regs;
struct dma_desc *td_ring; /* transmit descriptor ring */
struct dma_desc *rd_ring; /* receive descriptor ring  */
 
@@ -1044,10 +1044,10 @@ static int korina_probe(struct platform_device *pdev)
struct korina_device *bif = platform_get_drvdata(pdev);
struct korina_private *lp;
struct net_device *dev;
-   struct resource *r;
+   void __iomem *p;
int rc;
 
-   dev = alloc_etherdev(sizeof(struct korina_private));
+   dev = devm_alloc_etherdev(>dev, sizeof(struct korina_private));
if (!dev)
return -ENOMEM;
 
@@ -1060,36 +1060,30 @@ static int korina_probe(struct platform_device *pdev)
lp->rx_irq = platform_get_irq_byname(pdev, "korina_rx");
lp->tx_irq = platform_get_irq_byname(pdev, "korina_tx");
 
-   r = platform_get_resource_byname(pdev, IORESOURCE_MEM, "korina_regs");
-   dev->base_addr = r->start;
-   lp->eth_regs = ioremap(r->start, resource_size(r));
-   if (!lp->eth_regs) {
+   p = devm_platform_ioremap_resource_byname(pdev, "korina_regs");
+   if (!p) {
printk(KERN_ERR DRV_NAME ": cannot remap registers\n");
-   rc = -ENXIO;
-   goto probe_err_out;
+   return -ENOMEM;
}
+   lp->eth_regs = p;
 
-   r = platform_get_resource_byname(pdev, IORESOURCE_MEM, "korina_dma_rx");
-   lp->rx_dma_regs = ioremap(r->start, resource_size(r));
-   if (!lp->rx_dma_regs) {
+   p = devm_platform_ioremap_resource_byname(pdev, "korina_dma_rx");
+   if (!p) {
printk(KERN_ERR DRV_NAME ": cannot remap Rx DMA registers\n");
-   rc = -ENXIO;
-   goto probe_err_dma_rx;
+   return -ENOMEM;
}
+   lp->rx_dma_regs = p;
 
-   r = platform_get_resource_byname(pdev, IORESOURCE_MEM, "korina_dma_tx");
-   lp->tx_dma_regs = ioremap(r->start, resource_size(r));
-   if (!lp->tx_dma_regs) {
+   p = devm_platform_ioremap_resource_byname(pdev, "korina_dma_tx");
+   if (!p) {
printk(KERN_ERR DRV_NAME ": cannot remap Tx DMA registers\n");
-   rc = -ENXIO;
-   goto probe_err_dma_tx;
+   return -ENOMEM;
}
+   lp->tx_dma_regs = p;
 
lp->td_ring = kmalloc(TD_RING_SIZE + RD_RING_SIZE, GFP_KERNEL);
-   if (!lp->td_ring) {
-   rc = -ENXIO;
-   goto probe_err_td_ring;
-   }
+   if (!lp->td_ring)
+   return -ENOMEM;
 
dma_cache_inv((unsigned long)(lp->td_ring),
TD_RING_SIZE + RD_RING_SIZE);
@@ -1119,7 +1113,8 @@ static int korina_probe(struct platform_device *pdev)
if (rc < 0) {
printk(KERN_ERR DRV_NAME
": cannot register net device: %d\n", rc);
-   goto probe_err_register;
+   kfree((struct dma_desc *)KSEG0ADDR(lp->td_ring));
+   return rc;
}
timer_setup(>media_check_timer, korina_poll_media, 0);
 
@@ -1127,20 +1122,7 @@ static int korina_probe(struct platform_device *pdev)
 
printk(KERN_INFO "%s: " DRV_NAME "-" DRV_VERSION " " DRV_RELDATE "\n",
dev->name);
-out:
return rc;
-
-probe_err_register:
-   kfree((struct dma_desc *)KSEG0ADDR(lp->td_ring));
-probe_err_td_ring:
-   iounmap(lp->tx_dma_regs);
-probe_err_dma_tx:
-   iounmap(lp->rx_dma_regs);
-probe_err_dma_rx:
-   iounmap(lp->eth_regs);
-probe_err_out:
-   free_netdev(dev);
-   goto out;
 }
 
 static int korina_remove(struct platform_device *pdev)
@@ -1148,13 +1130,9 @@ static int korina_remove(struct platform_device *pdev)
struct korina_device *bif = platform_get_drvdata(pdev);
struct korina_private *lp = netdev_priv(bif->dev);
 
-   iounmap(lp->eth_regs);
-   iounmap(lp->rx_dma_regs);
-   iounmap(lp->tx_dma_regs);
kfree((struct dma_desc *)KSEG0ADDR(lp->td_ring));
 
unregister_netdev(bif->dev);
-   free_netdev(bif->dev);
 
return 0;
 }
-- 
2.29.2



[PATCH v4 net-next 03/10] net: korina: Remove not needed cache flushes

2021-04-16 Thread Thomas Bogendoerfer
Descriptors are mapped uncached so there is no need to do any cache
handling for them.

Reviewed-by: Andrew Lunn 
Signed-off-by: Thomas Bogendoerfer 
---
 drivers/net/ethernet/korina.c | 6 --
 1 file changed, 6 deletions(-)

diff --git a/drivers/net/ethernet/korina.c b/drivers/net/ethernet/korina.c
index b56de01f6bb8..c7abb4a8dd37 100644
--- a/drivers/net/ethernet/korina.c
+++ b/drivers/net/ethernet/korina.c
@@ -231,7 +231,6 @@ static int korina_send_packet(struct sk_buff *skb, struct 
net_device *dev)
dma_cache_wback((u32)skb->data, skb->len);
 
/* Setup the transmit descriptor. */
-   dma_cache_inv((u32) td, sizeof(*td));
td->ca = CPHYSADDR(skb->data);
chain_prev = (lp->tx_chain_tail - 1) & KORINA_TDS_MASK;
chain_next = (lp->tx_chain_tail + 1) & KORINA_TDS_MASK;
@@ -284,7 +283,6 @@ static int korina_send_packet(struct sk_buff *skb, struct 
net_device *dev)
lp->tx_chain_tail = chain_next;
}
}
-   dma_cache_wback((u32) td, sizeof(*td));
 
netif_trans_update(dev);
spin_unlock_irqrestore(>lock, flags);
@@ -373,8 +371,6 @@ static int korina_rx(struct net_device *dev, int limit)
u32 devcs, pkt_len, dmas;
int count;
 
-   dma_cache_inv((u32)rd, sizeof(*rd));
-
for (count = 0; count < limit; count++) {
skb = lp->rx_skb[lp->rx_next_done];
skb_new = NULL;
@@ -453,7 +449,6 @@ static int korina_rx(struct net_device *dev, int limit)
~DMA_DESC_COD;
 
lp->rx_next_done = (lp->rx_next_done + 1) & KORINA_RDS_MASK;
-   dma_cache_wback((u32)rd, sizeof(*rd));
rd = >rd_ring[lp->rx_next_done];
writel(~DMA_STAT_DONE, >rx_dma_regs->dmas);
}
@@ -468,7 +463,6 @@ static int korina_rx(struct net_device *dev, int limit)
rd->devcs = 0;
skb = lp->rx_skb[lp->rx_next_done];
rd->ca = CPHYSADDR(skb->data);
-   dma_cache_wback((u32)rd, sizeof(*rd));
korina_chain_rx(lp, rd);
}
 
-- 
2.29.2



[PATCH v4 net-next 01/10] net: korina: Fix MDIO functions

2021-04-16 Thread Thomas Bogendoerfer
Fixed MDIO functions to work reliable and not just by accident.

Signed-off-by: Thomas Bogendoerfer 
---
 drivers/net/ethernet/Kconfig  |  1 +
 drivers/net/ethernet/korina.c | 56 +++
 2 files changed, 38 insertions(+), 19 deletions(-)

diff --git a/drivers/net/ethernet/Kconfig b/drivers/net/ethernet/Kconfig
index ad04660b97b8..c059b4bd3f23 100644
--- a/drivers/net/ethernet/Kconfig
+++ b/drivers/net/ethernet/Kconfig
@@ -98,6 +98,7 @@ config JME
 config KORINA
tristate "Korina (IDT RC32434) Ethernet support"
depends on MIKROTIK_RB532
+   select MII
help
  If you have a Mikrotik RouterBoard 500 or IDT RC32434
  based system say Y. Otherwise say N.
diff --git a/drivers/net/ethernet/korina.c b/drivers/net/ethernet/korina.c
index 925161959b9b..1b7e1c75ed9e 100644
--- a/drivers/net/ethernet/korina.c
+++ b/drivers/net/ethernet/korina.c
@@ -41,6 +41,7 @@
 #include 
 #include 
 #include 
+#include 
 #include 
 #include 
 #include 
@@ -137,7 +138,6 @@ struct korina_private {
struct mii_if_info mii_if;
struct work_struct restart_task;
struct net_device *dev;
-   int phy_addr;
 };
 
 extern unsigned int idt_cpu_freq;
@@ -292,32 +292,48 @@ static int korina_send_packet(struct sk_buff *skb, struct 
net_device *dev)
return NETDEV_TX_OK;
 }
 
-static int mdio_read(struct net_device *dev, int mii_id, int reg)
+static int korina_mdio_wait(struct korina_private *lp)
+{
+   u32 value;
+
+   return readl_poll_timeout_atomic(>eth_regs->miimind,
+value, value & ETH_MII_IND_BSY,
+1, 1000);
+}
+
+static int korina_mdio_read(struct net_device *dev, int phy, int reg)
 {
struct korina_private *lp = netdev_priv(dev);
int ret;
 
-   mii_id = ((lp->rx_irq == 0x2c ? 1 : 0) << 8);
+   ret = korina_mdio_wait(lp);
+   if (ret < 0)
+   return ret;
 
-   writel(0, >eth_regs->miimcfg);
-   writel(0, >eth_regs->miimcmd);
-   writel(mii_id | reg, >eth_regs->miimaddr);
-   writel(ETH_MII_CMD_SCN, >eth_regs->miimcmd);
+   writel(phy << 8 | reg, >eth_regs->miimaddr);
+   writel(1, >eth_regs->miimcmd);
 
-   ret = (int)(readl(>eth_regs->miimrdd));
+   ret = korina_mdio_wait(lp);
+   if (ret < 0)
+   return ret;
+
+   if (readl(>eth_regs->miimind) & ETH_MII_IND_NV)
+   return -EINVAL;
+
+   ret = readl(>eth_regs->miimrdd);
+   writel(0, >eth_regs->miimcmd);
return ret;
 }
 
-static void mdio_write(struct net_device *dev, int mii_id, int reg, int val)
+static void korina_mdio_write(struct net_device *dev, int phy, int reg, int 
val)
 {
struct korina_private *lp = netdev_priv(dev);
 
-   mii_id = ((lp->rx_irq == 0x2c ? 1 : 0) << 8);
+   if (korina_mdio_wait(lp))
+   return;
 
-   writel(0, >eth_regs->miimcfg);
-   writel(1, >eth_regs->miimcmd);
-   writel(mii_id | reg, >eth_regs->miimaddr);
-   writel(ETH_MII_CMD_SCN, >eth_regs->miimcmd);
+   writel(0, >eth_regs->miimcmd);
+   writel(phy << 8 | reg, >eth_regs->miimaddr);
writel(val, >eth_regs->miimwtd);
 }
 
@@ -643,7 +659,7 @@ static void korina_check_media(struct net_device *dev, 
unsigned int init_media)
 {
struct korina_private *lp = netdev_priv(dev);
 
-   mii_check_media(>mii_if, 0, init_media);
+   mii_check_media(>mii_if, 1, init_media);
 
if (lp->mii_if.full_duplex)
writel(readl(>eth_regs->ethmac2) | ETH_MAC2_FD,
@@ -869,12 +885,15 @@ static int korina_init(struct net_device *dev)
 * Clock independent setting */
writel(((idt_cpu_freq) / MII_CLOCK + 1) & ~1,
>eth_regs->ethmcp);
+   writel(0, >eth_regs->miimcfg);
 
/* don't transmit until fifo contains 48b */
writel(48, >eth_regs->ethfifott);
 
writel(ETH_MAC1_RE, >eth_regs->ethmac1);
 
+   korina_check_media(dev, 1);
+
napi_enable(>napi);
netif_start_queue(dev);
 
@@ -1089,11 +1108,10 @@ static int korina_probe(struct platform_device *pdev)
dev->watchdog_timeo = TX_TIMEOUT;
netif_napi_add(dev, >napi, korina_poll, NAPI_POLL_WEIGHT);
 
-   lp->phy_addr = (((lp->rx_irq == 0x2c? 1:0) << 8) | 0x05);
lp->mii_if.dev = dev;
-   lp->mii_if.mdio_read = mdio_read;
-   lp->mii_if.mdio_write = mdio_write;
-   lp->mii_if.phy_id = lp->phy_addr;
+   lp->mii_if.mdio_read = korina_mdio_read;
+   lp->mii_if.mdio_write = korina_mdio_write;
+   lp->mii_if.phy_id = 1;
lp->mii_if.phy_id_mask = 0x1f;
lp->mii_if.reg_num_mask = 0x1f;
 
-- 
2.29.2



[PATCH v4 net-next 00/10] net: Korina improvements

2021-04-16 Thread Thomas Bogendoerfer
While converting Mikrotik RB532 support to use device tree I stumbled
over the korina ethernet driver, which used way too many MIPS specific
hacks. This series cleans this all up and adds support for device tree.

Changes in v4:
  - improve error returns in mdio_read further
  - added clock name and improved clk handling
  - fixed bindind errors

Changes in v3:
  - use readl_poll_timeout_atomic in mdio_wait
  - return -ETIMEDOUT, if mdio_wait failed
  - added DT binding and changed name to idt,3243x-emac
  - fixed usage of of_get_mac_address for net-next

Changes in v2:
  - added device tree support to get rid of idt_cpu_freq
  - fixed compile test on 64bit archs
  - fixed descriptor current address handling by storing/using mapped
dma addresses (dma controller modifies current address)

Thomas Bogendoerfer (10):
  net: korina: Fix MDIO functions
  net: korina: Use devres functions
  net: korina: Remove not needed cache flushes
  net: korina: Remove nested helpers
  net: korina: Use DMA API
  net: korina: Only pass mac address via platform data
  net: korina: Add support for device tree
  net: korina: Get mdio input clock via common clock framework
  net: korina: Make driver COMPILE_TESTable
  dt-bindings: net: korina: Add DT bindings for IDT 79RC3243x SoCs

 .../bindings/net/idt,3243x-emac.yaml  |  74 +++
 arch/mips/rb532/devices.c |   5 +-
 drivers/net/ethernet/Kconfig  |   3 +-
 drivers/net/ethernet/korina.c | 601 +-
 4 files changed, 511 insertions(+), 172 deletions(-)
 create mode 100644 Documentation/devicetree/bindings/net/idt,3243x-emac.yaml

-- 
2.29.2



Re: [PATCH v3 net-next 07/10] net: korina: Add support for device tree

2021-04-16 Thread Thomas Bogendoerfer
On Fri, Apr 16, 2021 at 01:49:07AM +0200, Andrew Lunn wrote:
> > -   memcpy(dev->dev_addr, mac_addr, ETH_ALEN);
> > +   if (mac_addr) {
> > +   ether_addr_copy(dev->dev_addr, mac_addr);
> > +   } else {
> > +   u8 ofmac[ETH_ALEN];
> > +
> > +   if (of_get_mac_address(pdev->dev.of_node, ofmac) == 0)
> > +   ether_addr_copy(dev->dev_addr, ofmac);
> 
> You should be able to skip the ether_addr_copy() by passing 
> dev->dev_addr directly to of_get_mac_address().

good point

> 
> > +   else
> > +   eth_hw_addr_random(dev);
> > +   }
> >  
> > lp->rx_irq = platform_get_irq_byname(pdev, "korina_rx");
> > lp->tx_irq = platform_get_irq_byname(pdev, "korina_tx");
> > @@ -1146,8 +1157,21 @@ static int korina_remove(struct platform_device 
> > *pdev)
> > return 0;
> >  }
> >  
> > +#ifdef CONFIG_OF
> > +static const struct of_device_id korina_match[] = {
> > +   {
> > +   .compatible = "idt,3243x-emac",
> 
> You need to document this compatible somewhere under 
> Documentation/devicetree/binding

checkpatch hinted to put it in an extra patch, it's patch 10 of this
series and looking at my inbox it didn't get through :-(.

Thomas.

-- 
Crap can work. Given enough thrust pigs will fly, but it's not necessarily a
good idea.[ RFC1925, 2.3 ]


Re: [PATCH v2 0/8] MIPS: fixes for PCI legacy drivers (rt2880, rt3883)

2021-04-16 Thread Thomas Bogendoerfer
On Tue, Apr 13, 2021 at 08:12:32PM -0700, Ilya Lipnitskiy wrote:
> One major fix for rt2880-pci in the first patch - fixes breakage that
> existed since v4.14.
> 
> Other more minor fixes, cleanups, and improvements that either free up
> memory, make dmesg messages clearer, or remove redundant dmesg output.
> 
> v2:
> - Do not use internal pci-rt2880 config read and write functions after
>   the device has been registered with the PCI subsystem to avoid races.
>   Use safe pci_bus_{read,write}_config_{d}word wrappers instead.
> 
> Ilya Lipnitskiy (8):
>   MIPS: pci-rt2880: fix slot 0 configuration
>   MIPS: pci-rt2880: remove unneeded locks
>   MIPS: pci-rt3883: trivial: remove unused variable
>   MIPS: pci-rt3883: more accurate DT error messages
>   MIPS: pci-legacy: stop using of_pci_range_to_resource
>   MIPS: pci-legacy: remove redundant info messages
>   MIPS: pci-legacy: remove busn_resource field
>   MIPS: pci-legacy: use generic pci_enable_resources
> 
>  arch/mips/include/asm/pci.h |  1 -
>  arch/mips/pci/pci-legacy.c  | 57 ++---
>  arch/mips/pci/pci-rt2880.c  | 50 
>  arch/mips/pci/pci-rt3883.c  | 10 ++-
>  4 files changed, 35 insertions(+), 83 deletions(-)

series applied to mips-next.

Thomas.

-- 
Crap can work. Given enough thrust pigs will fly, but it's not necessarily a
good idea.[ RFC1925, 2.3 ]


Re: [PATCH] MIPS: Fix strnlen_user access check

2021-04-16 Thread Thomas Bogendoerfer
On Thu, Apr 15, 2021 at 11:26:40PM +0200, Thomas Bogendoerfer wrote:
> Commit 04324f44cb69 ("MIPS: Remove get_fs/set_fs") changed the access_ok
> for strnlen_user to check the whole range, which broke some callers
> of strndup_user(). Restore the old behaviour and just check the first byte.
> 
> Fixes: 04324f44cb69 ("MIPS: Remove get_fs/set_fs")
> Signed-off-by: Thomas Bogendoerfer 
> ---
>  arch/mips/include/asm/uaccess.h | 4 ++--
>  1 file changed, 2 insertions(+), 2 deletions(-)

applied to mips-next.

Thomas.

-- 
Crap can work. Given enough thrust pigs will fly, but it's not necessarily a
good idea.[ RFC1925, 2.3 ]


Re: [PATCH v3 net-next 06/10] net: korina: Only pass mac address via platform data

2021-04-16 Thread Thomas Bogendoerfer
On Fri, Apr 16, 2021 at 01:30:04AM +0200, Andrew Lunn wrote:
> On Thu, Apr 15, 2021 at 01:06:43AM +0200, Thomas Bogendoerfer wrote:
> > Get rid of access to struct korina_device by just passing the mac
> > address via platform data and use drvdata for passing netdev to remove
> > function.
> > 
> > Signed-off-by: Thomas Bogendoerfer 
> > ---
> >  arch/mips/rb532/devices.c |  5 +++--
> >  drivers/net/ethernet/korina.c | 11 ++-
> >  2 files changed, 9 insertions(+), 7 deletions(-)
> > 
> > diff --git a/arch/mips/rb532/devices.c b/arch/mips/rb532/devices.c
> > index dd34f1b32b79..5fc3c8ee4f31 100644
> > --- a/arch/mips/rb532/devices.c
> > +++ b/arch/mips/rb532/devices.c
> > @@ -105,6 +105,9 @@ static struct platform_device korina_dev0 = {
> > .name = "korina",
> > .resource = korina_dev0_res,
> > .num_resources = ARRAY_SIZE(korina_dev0_res),
> > +   .dev = {
> > +   .platform_data = _dev0_data.mac,
> > +   }
> 
> This is a bit unusual. Normally you define a structure in
> include/linux/platform/data/koriana.h, and use that.
> 
> What about the name? "korina0" How is that passed?

this is just for transition purpose. My DT patches remove this struct
completly.

Thomas.

-- 
Crap can work. Given enough thrust pigs will fly, but it's not necessarily a
good idea.[ RFC1925, 2.3 ]


[PATCH] MIPS: Fix strnlen_user access check

2021-04-15 Thread Thomas Bogendoerfer
Commit 04324f44cb69 ("MIPS: Remove get_fs/set_fs") changed the access_ok
for strnlen_user to check the whole range, which broke some callers
of strndup_user(). Restore the old behaviour and just check the first byte.

Fixes: 04324f44cb69 ("MIPS: Remove get_fs/set_fs")
Signed-off-by: Thomas Bogendoerfer 
---
 arch/mips/include/asm/uaccess.h | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/arch/mips/include/asm/uaccess.h b/arch/mips/include/asm/uaccess.h
index ab47e597656a..783fecce65c8 100644
--- a/arch/mips/include/asm/uaccess.h
+++ b/arch/mips/include/asm/uaccess.h
@@ -614,8 +614,8 @@ static inline long strnlen_user(const char __user *s, long 
n)
 {
long res;
 
-   if (!access_ok(s, n))
-   return -0;
+   if (!access_ok(s, 1))
+   return 0;
 
might_fault();
__asm__ __volatile__(
-- 
2.29.2



[PATCH v3 net-next 09/10] net: korina: Make driver COMPILE_TESTable

2021-04-14 Thread Thomas Bogendoerfer
Move structs/defines for ethernet/dma register into driver, since they
are only used for this driver and remove any MIPS specific includes.
This makes it possible to COMPILE_TEST the driver.

Signed-off-by: Thomas Bogendoerfer 
---
 drivers/net/ethernet/Kconfig  |   2 +-
 drivers/net/ethernet/korina.c | 249 --
 2 files changed, 239 insertions(+), 12 deletions(-)

diff --git a/drivers/net/ethernet/Kconfig b/drivers/net/ethernet/Kconfig
index c059b4bd3f23..453d202a28c1 100644
--- a/drivers/net/ethernet/Kconfig
+++ b/drivers/net/ethernet/Kconfig
@@ -97,7 +97,7 @@ config JME
 
 config KORINA
tristate "Korina (IDT RC32434) Ethernet support"
-   depends on MIKROTIK_RB532
+   depends on MIKROTIK_RB532 || COMPILE_TEST
select MII
help
  If you have a Mikrotik RouterBoard 500 or IDT RC32434
diff --git a/drivers/net/ethernet/korina.c b/drivers/net/ethernet/korina.c
index 62bb691c8354..a065f111281b 100644
--- a/drivers/net/ethernet/korina.c
+++ b/drivers/net/ethernet/korina.c
@@ -59,18 +59,244 @@
 #include 
 #include 
 
-#include 
-#include 
-#include 
-#include 
-
-#include 
-#include 
-
 #define DRV_NAME   "korina"
 #define DRV_VERSION"0.20"
 #define DRV_RELDATE"15Sep2017"
 
+struct eth_regs {
+   u32 ethintfc;
+   u32 ethfifott;
+   u32 etharc;
+   u32 ethhash0;
+   u32 ethhash1;
+   u32 ethu0[4];   /* Reserved. */
+   u32 ethpfs;
+   u32 ethmcp;
+   u32 eth_u1[10]; /* Reserved. */
+   u32 ethspare;
+   u32 eth_u2[42]; /* Reserved. */
+   u32 ethsal0;
+   u32 ethsah0;
+   u32 ethsal1;
+   u32 ethsah1;
+   u32 ethsal2;
+   u32 ethsah2;
+   u32 ethsal3;
+   u32 ethsah3;
+   u32 ethrbc;
+   u32 ethrpc;
+   u32 ethrupc;
+   u32 ethrfc;
+   u32 ethtbc;
+   u32 ethgpf;
+   u32 eth_u9[50]; /* Reserved. */
+   u32 ethmac1;
+   u32 ethmac2;
+   u32 ethipgt;
+   u32 ethipgr;
+   u32 ethclrt;
+   u32 ethmaxf;
+   u32 eth_u10;/* Reserved. */
+   u32 ethmtest;
+   u32 miimcfg;
+   u32 miimcmd;
+   u32 miimaddr;
+   u32 miimwtd;
+   u32 miimrdd;
+   u32 miimind;
+   u32 eth_u11;/* Reserved. */
+   u32 eth_u12;/* Reserved. */
+   u32 ethcfsa0;
+   u32 ethcfsa1;
+   u32 ethcfsa2;
+};
+
+/* Ethernet interrupt registers */
+#define ETH_INT_FC_EN  BIT(0)
+#define ETH_INT_FC_ITS BIT(1)
+#define ETH_INT_FC_RIP BIT(2)
+#define ETH_INT_FC_JAM BIT(3)
+#define ETH_INT_FC_OVR BIT(4)
+#define ETH_INT_FC_UND BIT(5)
+#define ETH_INT_FC_IOC 0x00c0
+
+/* Ethernet FIFO registers */
+#define ETH_FIFI_TT_TTH_BIT0
+#define ETH_FIFO_TT_TTH0x007f
+
+/* Ethernet ARC/multicast registers */
+#define ETH_ARC_PROBIT(0)
+#define ETH_ARC_AM BIT(1)
+#define ETH_ARC_AFMBIT(2)
+#define ETH_ARC_AB BIT(3)
+
+/* Ethernet SAL registers */
+#define ETH_SAL_BYTE_5 0x00ff
+#define ETH_SAL_BYTE_4 0xff00
+#define ETH_SAL_BYTE_3 0x00ff
+#define ETH_SAL_BYTE_2 0xff00
+
+/* Ethernet SAH registers */
+#define ETH_SAH_BYTE1  0x00ff
+#define ETH_SAH_BYTE0  0xff00
+
+/* Ethernet GPF register */
+#define ETH_GPF_PTV0x
+
+/* Ethernet PFG register */
+#define ETH_PFS_PFDBIT(0)
+
+/* Ethernet CFSA[0-3] registers */
+#define ETH_CFSA0_CFSA40x00ff
+#define ETH_CFSA0_CFSA50xff00
+#define ETH_CFSA1_CFSA20x00ff
+#define ETH_CFSA1_CFSA30xff00
+#define ETH_CFSA1_CFSA00x00ff
+#define ETH_CFSA1_CFSA10xff00
+
+/* Ethernet MAC1 registers */
+#define ETH_MAC1_REBIT(0)
+#define ETH_MAC1_PAF   BIT(1)
+#define ETH_MAC1_RFC   BIT(2)
+#define ETH_MAC1_TFC   BIT(3)
+#define ETH_MAC1_LBBIT(4)
+#define ETH_MAC1_MRBIT(31)
+
+/* Ethernet MAC2 registers */
+#define ETH_MAC2_FDBIT(0)
+#define ETH_MAC2_FLC   BIT(1)
+#define ETH_MAC2_HFE   BIT(2)
+#define ETH_MAC2_DCBIT(3)
+#define ETH_MAC2_CEN   BIT(4)
+#define ETH_MAC2_PEBIT(5)
+#define ETH_MAC2_VPE   BIT(6)
+#define ETH_MAC2_APE   BIT(7)
+#define ETH_MAC2_PPE   BIT(8)
+#define ETH_MAC2_LPE   BIT(9)
+#define ETH_MAC2_NBBIT(12)
+#define ETH_MAC2_BPBIT(13)
+#define ETH_MAC2_EDBIT(14)
+
+/* Ethernet IPGT register */
+#define ETH_IPGT   0x007f
+
+/* Ethernet IPGR registers */
+#define ETH_IPGR_IPGR2 0x007f
+#define ETH_IPGR_IPGR1 0x7f00
+
+/* Ethernet CLRT registers */
+#define ETH_CLRT_MAX_RET   0x000f
+#

[PATCH v3 net-next 05/10] net: korina: Use DMA API

2021-04-14 Thread Thomas Bogendoerfer
Instead of messing with MIPS specific macros use DMA API for mapping
descriptors and skbs.

Signed-off-by: Thomas Bogendoerfer 
---
 drivers/net/ethernet/korina.c | 158 +-
 1 file changed, 98 insertions(+), 60 deletions(-)

diff --git a/drivers/net/ethernet/korina.c b/drivers/net/ethernet/korina.c
index 479142c5166f..f00ffbbdfba7 100644
--- a/drivers/net/ethernet/korina.c
+++ b/drivers/net/ethernet/korina.c
@@ -110,10 +110,15 @@ struct korina_private {
struct dma_reg __iomem *tx_dma_regs;
struct dma_desc *td_ring; /* transmit descriptor ring */
struct dma_desc *rd_ring; /* receive descriptor ring  */
+   dma_addr_t td_dma;
+   dma_addr_t rd_dma;
 
struct sk_buff *tx_skb[KORINA_NUM_TDS];
struct sk_buff *rx_skb[KORINA_NUM_RDS];
 
+   dma_addr_t rx_skb_dma[KORINA_NUM_RDS];
+   dma_addr_t tx_skb_dma[KORINA_NUM_TDS];
+
int rx_next_done;
int rx_chain_head;
int rx_chain_tail;
@@ -138,10 +143,21 @@ struct korina_private {
struct mii_if_info mii_if;
struct work_struct restart_task;
struct net_device *dev;
+   struct device *dmadev;
 };
 
 extern unsigned int idt_cpu_freq;
 
+static dma_addr_t korina_tx_dma(struct korina_private *lp, int idx)
+{
+   return lp->td_dma + (idx * sizeof(struct dma_desc));
+}
+
+static dma_addr_t korina_rx_dma(struct korina_private *lp, int idx)
+{
+   return lp->rd_dma + (idx * sizeof(struct dma_desc));
+}
+
 static inline void korina_abort_dma(struct net_device *dev,
struct dma_reg *ch)
 {
@@ -176,14 +192,17 @@ static void korina_abort_rx(struct net_device *dev)
 static int korina_send_packet(struct sk_buff *skb, struct net_device *dev)
 {
struct korina_private *lp = netdev_priv(dev);
-   unsigned long flags;
-   u32 length;
u32 chain_prev, chain_next;
+   unsigned long flags;
struct dma_desc *td;
+   dma_addr_t ca;
+   u32 length;
+   int idx;
 
spin_lock_irqsave(>lock, flags);
 
-   td = >td_ring[lp->tx_chain_tail];
+   idx = lp->tx_chain_tail;
+   td = >td_ring[idx];
 
/* stop queue when full, drop pkts if queue already full */
if (lp->tx_count >= (KORINA_NUM_TDS - 2)) {
@@ -191,26 +210,26 @@ static int korina_send_packet(struct sk_buff *skb, struct 
net_device *dev)
 
if (lp->tx_count == (KORINA_NUM_TDS - 2))
netif_stop_queue(dev);
-   else {
-   dev->stats.tx_dropped++;
-   dev_kfree_skb_any(skb);
-   spin_unlock_irqrestore(>lock, flags);
-
-   return NETDEV_TX_OK;
-   }
+   else
+   goto drop_packet;
}
 
lp->tx_count++;
 
-   lp->tx_skb[lp->tx_chain_tail] = skb;
+   lp->tx_skb[idx] = skb;
 
length = skb->len;
-   dma_cache_wback((u32)skb->data, skb->len);
 
/* Setup the transmit descriptor. */
-   td->ca = CPHYSADDR(skb->data);
-   chain_prev = (lp->tx_chain_tail - 1) & KORINA_TDS_MASK;
-   chain_next = (lp->tx_chain_tail + 1) & KORINA_TDS_MASK;
+   ca = dma_map_single(lp->dmadev, skb->data, length, DMA_TO_DEVICE);
+   if (dma_mapping_error(lp->dmadev, ca))
+   goto drop_packet;
+
+   lp->tx_skb_dma[idx] = ca;
+   td->ca = ca;
+
+   chain_prev = (idx - 1) & KORINA_TDS_MASK;
+   chain_next = (idx + 1) & KORINA_TDS_MASK;
 
if (readl(&(lp->tx_dma_regs->dmandptr)) == 0) {
if (lp->tx_chain_status == desc_empty) {
@@ -220,8 +239,8 @@ static int korina_send_packet(struct sk_buff *skb, struct 
net_device *dev)
/* Move tail */
lp->tx_chain_tail = chain_next;
/* Write to NDPTR */
-   writel(CPHYSADDR(>td_ring[lp->tx_chain_head]),
-   >tx_dma_regs->dmandptr);
+   writel(korina_tx_dma(lp, lp->tx_chain_head),
+  >tx_dma_regs->dmandptr);
/* Move head to tail */
lp->tx_chain_head = lp->tx_chain_tail;
} else {
@@ -232,12 +251,12 @@ static int korina_send_packet(struct sk_buff *skb, struct 
net_device *dev)
lp->td_ring[chain_prev].control &=
~DMA_DESC_COF;
/* Link to prev */
-   lp->td_ring[chain_prev].link =  CPHYSADDR(td);
+   lp->td_ring[chain_prev].link = korina_tx_dma(lp, idx);
/* Move tail */
lp->tx_chain_tail = chain_next;

[PATCH v3 net-next 08/10] net: korina: Get mdio input clock via common clock framework

2021-04-14 Thread Thomas Bogendoerfer
With device tree clock is provided via CCF. For non device tree
use a maximum clock value to not overclock the PHY. The non device
tree usage will go away after platform is converted to DT.

Signed-off-by: Thomas Bogendoerfer 
---
 drivers/net/ethernet/korina.c | 19 +--
 1 file changed, 13 insertions(+), 6 deletions(-)

diff --git a/drivers/net/ethernet/korina.c b/drivers/net/ethernet/korina.c
index 7646ccc9d7e8..62bb691c8354 100644
--- a/drivers/net/ethernet/korina.c
+++ b/drivers/net/ethernet/korina.c
@@ -57,14 +57,13 @@
 #include 
 #include 
 #include 
+#include 
 
 #include 
 #include 
 #include 
 #include 
 
-#include 
-#include 
 #include 
 #include 
 
@@ -146,10 +145,9 @@ struct korina_private {
struct work_struct restart_task;
struct net_device *dev;
struct device *dmadev;
+   int mii_clock_freq;
 };
 
-extern unsigned int idt_cpu_freq;
-
 static dma_addr_t korina_tx_dma(struct korina_private *lp, int idx)
 {
return lp->td_dma + (idx * sizeof(struct dma_desc));
@@ -897,8 +895,8 @@ static int korina_init(struct net_device *dev)
 
/* Management Clock Prescaler Divisor
 * Clock independent setting */
-   writel(((idt_cpu_freq) / MII_CLOCK + 1) & ~1,
-   >eth_regs->ethmcp);
+   writel(((lp->mii_clock_freq) / MII_CLOCK + 1) & ~1,
+  >eth_regs->ethmcp);
writel(0, >eth_regs->miimcfg);
 
/* don't transmit until fifo contains 48b */
@@ -1058,6 +1056,7 @@ static int korina_probe(struct platform_device *pdev)
u8 *mac_addr = dev_get_platdata(>dev);
struct korina_private *lp;
struct net_device *dev;
+   struct clk *clk;
void __iomem *p;
int rc;
 
@@ -1079,6 +1078,14 @@ static int korina_probe(struct platform_device *pdev)
eth_hw_addr_random(dev);
}
 
+   clk = devm_clk_get(>dev, NULL);
+   if (!IS_ERR(clk)) {
+   clk_prepare_enable(clk);
+   lp->mii_clock_freq = clk_get_rate(clk);
+   } else {
+   lp->mii_clock_freq = 2; /* max possible input clk */
+   }
+
lp->rx_irq = platform_get_irq_byname(pdev, "korina_rx");
lp->tx_irq = platform_get_irq_byname(pdev, "korina_tx");
 
-- 
2.29.2



[PATCH v3 net-next 07/10] net: korina: Add support for device tree

2021-04-14 Thread Thomas Bogendoerfer
If there is no mac address passed via platform data try to get it via
device tree and fall back to a random mac address, if all fail.

Signed-off-by: Thomas Bogendoerfer 
---
 drivers/net/ethernet/korina.c | 28 ++--
 1 file changed, 26 insertions(+), 2 deletions(-)

diff --git a/drivers/net/ethernet/korina.c b/drivers/net/ethernet/korina.c
index 1d7dead17ac3..7646ccc9d7e8 100644
--- a/drivers/net/ethernet/korina.c
+++ b/drivers/net/ethernet/korina.c
@@ -43,6 +43,8 @@
 #include 
 #include 
 #include 
+#include 
+#include 
 #include 
 #include 
 #include 
@@ -1066,7 +1068,16 @@ static int korina_probe(struct platform_device *pdev)
SET_NETDEV_DEV(dev, >dev);
lp = netdev_priv(dev);
 
-   memcpy(dev->dev_addr, mac_addr, ETH_ALEN);
+   if (mac_addr) {
+   ether_addr_copy(dev->dev_addr, mac_addr);
+   } else {
+   u8 ofmac[ETH_ALEN];
+
+   if (of_get_mac_address(pdev->dev.of_node, ofmac) == 0)
+   ether_addr_copy(dev->dev_addr, ofmac);
+   else
+   eth_hw_addr_random(dev);
+   }
 
lp->rx_irq = platform_get_irq_byname(pdev, "korina_rx");
lp->tx_irq = platform_get_irq_byname(pdev, "korina_tx");
@@ -1146,8 +1157,21 @@ static int korina_remove(struct platform_device *pdev)
return 0;
 }
 
+#ifdef CONFIG_OF
+static const struct of_device_id korina_match[] = {
+   {
+   .compatible = "idt,3243x-emac",
+   },
+   { }
+};
+MODULE_DEVICE_TABLE(of, korina_match);
+#endif
+
 static struct platform_driver korina_driver = {
-   .driver.name = "korina",
+   .driver = {
+   .name = "korina",
+   .of_match_table = of_match_ptr(korina_match),
+   },
.probe = korina_probe,
.remove = korina_remove,
 };
-- 
2.29.2



[PATCH v3 net-next 03/10] net: korina: Remove not needed cache flushes

2021-04-14 Thread Thomas Bogendoerfer
Descriptors are mapped uncached so there is no need to do any cache
handling for them.

Signed-off-by: Thomas Bogendoerfer 
---
 drivers/net/ethernet/korina.c | 6 --
 1 file changed, 6 deletions(-)

diff --git a/drivers/net/ethernet/korina.c b/drivers/net/ethernet/korina.c
index 6bef5d590ebe..408cb2dedb95 100644
--- a/drivers/net/ethernet/korina.c
+++ b/drivers/net/ethernet/korina.c
@@ -231,7 +231,6 @@ static int korina_send_packet(struct sk_buff *skb, struct 
net_device *dev)
dma_cache_wback((u32)skb->data, skb->len);
 
/* Setup the transmit descriptor. */
-   dma_cache_inv((u32) td, sizeof(*td));
td->ca = CPHYSADDR(skb->data);
chain_prev = (lp->tx_chain_tail - 1) & KORINA_TDS_MASK;
chain_next = (lp->tx_chain_tail + 1) & KORINA_TDS_MASK;
@@ -284,7 +283,6 @@ static int korina_send_packet(struct sk_buff *skb, struct 
net_device *dev)
lp->tx_chain_tail = chain_next;
}
}
-   dma_cache_wback((u32) td, sizeof(*td));
 
netif_trans_update(dev);
spin_unlock_irqrestore(>lock, flags);
@@ -371,8 +369,6 @@ static int korina_rx(struct net_device *dev, int limit)
u32 devcs, pkt_len, dmas;
int count;
 
-   dma_cache_inv((u32)rd, sizeof(*rd));
-
for (count = 0; count < limit; count++) {
skb = lp->rx_skb[lp->rx_next_done];
skb_new = NULL;
@@ -451,7 +447,6 @@ static int korina_rx(struct net_device *dev, int limit)
~DMA_DESC_COD;
 
lp->rx_next_done = (lp->rx_next_done + 1) & KORINA_RDS_MASK;
-   dma_cache_wback((u32)rd, sizeof(*rd));
rd = >rd_ring[lp->rx_next_done];
writel(~DMA_STAT_DONE, >rx_dma_regs->dmas);
}
@@ -466,7 +461,6 @@ static int korina_rx(struct net_device *dev, int limit)
rd->devcs = 0;
skb = lp->rx_skb[lp->rx_next_done];
rd->ca = CPHYSADDR(skb->data);
-   dma_cache_wback((u32)rd, sizeof(*rd));
korina_chain_rx(lp, rd);
}
 
-- 
2.29.2



[PATCH v3 net-next 06/10] net: korina: Only pass mac address via platform data

2021-04-14 Thread Thomas Bogendoerfer
Get rid of access to struct korina_device by just passing the mac
address via platform data and use drvdata for passing netdev to remove
function.

Signed-off-by: Thomas Bogendoerfer 
---
 arch/mips/rb532/devices.c |  5 +++--
 drivers/net/ethernet/korina.c | 11 ++-
 2 files changed, 9 insertions(+), 7 deletions(-)

diff --git a/arch/mips/rb532/devices.c b/arch/mips/rb532/devices.c
index dd34f1b32b79..5fc3c8ee4f31 100644
--- a/arch/mips/rb532/devices.c
+++ b/arch/mips/rb532/devices.c
@@ -105,6 +105,9 @@ static struct platform_device korina_dev0 = {
.name = "korina",
.resource = korina_dev0_res,
.num_resources = ARRAY_SIZE(korina_dev0_res),
+   .dev = {
+   .platform_data = _dev0_data.mac,
+   }
 };
 
 static struct resource cf_slot0_res[] = {
@@ -299,8 +302,6 @@ static int __init plat_setup_devices(void)
/* set the uart clock to the current cpu frequency */
rb532_uart_res[0].uartclk = idt_cpu_freq;
 
-   dev_set_drvdata(_dev0.dev, _dev0_data);
-
gpiod_add_lookup_table(_slot0_gpio_table);
return platform_add_devices(rb532_devs, ARRAY_SIZE(rb532_devs));
 }
diff --git a/drivers/net/ethernet/korina.c b/drivers/net/ethernet/korina.c
index f00ffbbdfba7..1d7dead17ac3 100644
--- a/drivers/net/ethernet/korina.c
+++ b/drivers/net/ethernet/korina.c
@@ -1053,7 +1053,7 @@ static const struct net_device_ops korina_netdev_ops = {
 
 static int korina_probe(struct platform_device *pdev)
 {
-   struct korina_device *bif = platform_get_drvdata(pdev);
+   u8 *mac_addr = dev_get_platdata(>dev);
struct korina_private *lp;
struct net_device *dev;
void __iomem *p;
@@ -1066,8 +1066,7 @@ static int korina_probe(struct platform_device *pdev)
SET_NETDEV_DEV(dev, >dev);
lp = netdev_priv(dev);
 
-   bif->dev = dev;
-   memcpy(dev->dev_addr, bif->mac, ETH_ALEN);
+   memcpy(dev->dev_addr, mac_addr, ETH_ALEN);
 
lp->rx_irq = platform_get_irq_byname(pdev, "korina_rx");
lp->tx_irq = platform_get_irq_byname(pdev, "korina_tx");
@@ -1121,6 +1120,8 @@ static int korina_probe(struct platform_device *pdev)
lp->mii_if.phy_id_mask = 0x1f;
lp->mii_if.reg_num_mask = 0x1f;
 
+   platform_set_drvdata(pdev, dev);
+
rc = register_netdev(dev);
if (rc < 0) {
printk(KERN_ERR DRV_NAME
@@ -1138,9 +1139,9 @@ static int korina_probe(struct platform_device *pdev)
 
 static int korina_remove(struct platform_device *pdev)
 {
-   struct korina_device *bif = platform_get_drvdata(pdev);
+   struct net_device *dev = platform_get_drvdata(pdev);
 
-   unregister_netdev(bif->dev);
+   unregister_netdev(dev);
 
return 0;
 }
-- 
2.29.2



[PATCH v3 net-next 04/10] net: korina: Remove nested helpers

2021-04-14 Thread Thomas Bogendoerfer
Remove helpers, which are only used in one call site.

Signed-off-by: Thomas Bogendoerfer 
---
 drivers/net/ethernet/korina.c | 28 +++-
 1 file changed, 3 insertions(+), 25 deletions(-)

diff --git a/drivers/net/ethernet/korina.c b/drivers/net/ethernet/korina.c
index 408cb2dedb95..479142c5166f 100644
--- a/drivers/net/ethernet/korina.c
+++ b/drivers/net/ethernet/korina.c
@@ -142,12 +142,6 @@ struct korina_private {
 
 extern unsigned int idt_cpu_freq;
 
-static inline void korina_start_dma(struct dma_reg *ch, u32 dma_addr)
-{
-   writel(0, >dmandptr);
-   writel(dma_addr, >dmadptr);
-}
-
 static inline void korina_abort_dma(struct net_device *dev,
struct dma_reg *ch)
 {
@@ -164,11 +158,6 @@ static inline void korina_abort_dma(struct net_device *dev,
writel(0, >dmandptr);
 }
 
-static inline void korina_chain_dma(struct dma_reg *ch, u32 dma_addr)
-{
-   writel(dma_addr, >dmandptr);
-}
-
 static void korina_abort_tx(struct net_device *dev)
 {
struct korina_private *lp = netdev_priv(dev);
@@ -183,18 +172,6 @@ static void korina_abort_rx(struct net_device *dev)
korina_abort_dma(dev, lp->rx_dma_regs);
 }
 
-static void korina_start_rx(struct korina_private *lp,
-   struct dma_desc *rd)
-{
-   korina_start_dma(lp->rx_dma_regs, CPHYSADDR(rd));
-}
-
-static void korina_chain_rx(struct korina_private *lp,
-   struct dma_desc *rd)
-{
-   korina_chain_dma(lp->rx_dma_regs, CPHYSADDR(rd));
-}
-
 /* transmit packet */
 static int korina_send_packet(struct sk_buff *skb, struct net_device *dev)
 {
@@ -461,7 +438,7 @@ static int korina_rx(struct net_device *dev, int limit)
rd->devcs = 0;
skb = lp->rx_skb[lp->rx_next_done];
rd->ca = CPHYSADDR(skb->data);
-   korina_chain_rx(lp, rd);
+   writel(CPHYSADDR(rd), >rx_dma_regs->dmandptr);
}
 
return count;
@@ -838,7 +815,8 @@ static int korina_init(struct net_device *dev)
 
writel(0, >rx_dma_regs->dmas);
/* Start Rx DMA */
-   korina_start_rx(lp, >rd_ring[0]);
+   writel(0, >rx_dma_regs->dmandptr);
+   writel(CPHYSADDR(>rd_ring[0]), >rx_dma_regs->dmadptr);
 
writel(readl(>tx_dma_regs->dmasm) &
~(DMA_STAT_FINI | DMA_STAT_ERR),
-- 
2.29.2



[PATCH v3 net-next 02/10] net: korina: Use devres functions

2021-04-14 Thread Thomas Bogendoerfer
Simplify probe/remove code by using devm_ functions.

Signed-off-by: Thomas Bogendoerfer 
---
 drivers/net/ethernet/korina.c | 64 ---
 1 file changed, 21 insertions(+), 43 deletions(-)

diff --git a/drivers/net/ethernet/korina.c b/drivers/net/ethernet/korina.c
index 3f6f4835a9bc..6bef5d590ebe 100644
--- a/drivers/net/ethernet/korina.c
+++ b/drivers/net/ethernet/korina.c
@@ -105,9 +105,9 @@ enum chain_status {
 
 /* Information that need to be kept for each board. */
 struct korina_private {
-   struct eth_regs *eth_regs;
-   struct dma_reg *rx_dma_regs;
-   struct dma_reg *tx_dma_regs;
+   struct eth_regs __iomem *eth_regs;
+   struct dma_reg __iomem *rx_dma_regs;
+   struct dma_reg __iomem *tx_dma_regs;
struct dma_desc *td_ring; /* transmit descriptor ring */
struct dma_desc *rd_ring; /* receive descriptor ring  */
 
@@ -1042,10 +1042,10 @@ static int korina_probe(struct platform_device *pdev)
struct korina_device *bif = platform_get_drvdata(pdev);
struct korina_private *lp;
struct net_device *dev;
-   struct resource *r;
+   void __iomem *p;
int rc;
 
-   dev = alloc_etherdev(sizeof(struct korina_private));
+   dev = devm_alloc_etherdev(>dev, sizeof(struct korina_private));
if (!dev)
return -ENOMEM;
 
@@ -1058,36 +1058,30 @@ static int korina_probe(struct platform_device *pdev)
lp->rx_irq = platform_get_irq_byname(pdev, "korina_rx");
lp->tx_irq = platform_get_irq_byname(pdev, "korina_tx");
 
-   r = platform_get_resource_byname(pdev, IORESOURCE_MEM, "korina_regs");
-   dev->base_addr = r->start;
-   lp->eth_regs = ioremap(r->start, resource_size(r));
-   if (!lp->eth_regs) {
+   p = devm_platform_ioremap_resource_byname(pdev, "korina_regs");
+   if (!p) {
printk(KERN_ERR DRV_NAME ": cannot remap registers\n");
-   rc = -ENXIO;
-   goto probe_err_out;
+   return -ENOMEM;
}
+   lp->eth_regs = p;
 
-   r = platform_get_resource_byname(pdev, IORESOURCE_MEM, "korina_dma_rx");
-   lp->rx_dma_regs = ioremap(r->start, resource_size(r));
-   if (!lp->rx_dma_regs) {
+   p = devm_platform_ioremap_resource_byname(pdev, "korina_dma_rx");
+   if (!p) {
printk(KERN_ERR DRV_NAME ": cannot remap Rx DMA registers\n");
-   rc = -ENXIO;
-   goto probe_err_dma_rx;
+   return -ENOMEM;
}
+   lp->rx_dma_regs = p;
 
-   r = platform_get_resource_byname(pdev, IORESOURCE_MEM, "korina_dma_tx");
-   lp->tx_dma_regs = ioremap(r->start, resource_size(r));
-   if (!lp->tx_dma_regs) {
+   p = devm_platform_ioremap_resource_byname(pdev, "korina_dma_tx");
+   if (!p) {
printk(KERN_ERR DRV_NAME ": cannot remap Tx DMA registers\n");
-   rc = -ENXIO;
-   goto probe_err_dma_tx;
+   return -ENOMEM;
}
+   lp->tx_dma_regs = p;
 
lp->td_ring = kmalloc(TD_RING_SIZE + RD_RING_SIZE, GFP_KERNEL);
-   if (!lp->td_ring) {
-   rc = -ENXIO;
-   goto probe_err_td_ring;
-   }
+   if (!lp->td_ring)
+   return -ENOMEM;
 
dma_cache_inv((unsigned long)(lp->td_ring),
TD_RING_SIZE + RD_RING_SIZE);
@@ -1117,7 +,8 @@ static int korina_probe(struct platform_device *pdev)
if (rc < 0) {
printk(KERN_ERR DRV_NAME
": cannot register net device: %d\n", rc);
-   goto probe_err_register;
+   kfree((struct dma_desc *)KSEG0ADDR(lp->td_ring));
+   return rc;
}
timer_setup(>media_check_timer, korina_poll_media, 0);
 
@@ -1125,20 +1120,7 @@ static int korina_probe(struct platform_device *pdev)
 
printk(KERN_INFO "%s: " DRV_NAME "-" DRV_VERSION " " DRV_RELDATE "\n",
dev->name);
-out:
return rc;
-
-probe_err_register:
-   kfree((struct dma_desc *)KSEG0ADDR(lp->td_ring));
-probe_err_td_ring:
-   iounmap(lp->tx_dma_regs);
-probe_err_dma_tx:
-   iounmap(lp->rx_dma_regs);
-probe_err_dma_rx:
-   iounmap(lp->eth_regs);
-probe_err_out:
-   free_netdev(dev);
-   goto out;
 }
 
 static int korina_remove(struct platform_device *pdev)
@@ -1146,13 +1128,9 @@ static int korina_remove(struct platform_device *pdev)
struct korina_device *bif = platform_get_drvdata(pdev);
struct korina_private *lp = netdev_priv(bif->dev);
 
-   iounmap(lp->eth_regs);
-   iounmap(lp->rx_dma_regs);
-   iounmap(lp->tx_dma_regs);
kfree((struct dma_desc *)KSEG0ADDR(lp->td_ring));
 
unregister_netdev(bif->dev);
-   free_netdev(bif->dev);
 
return 0;
 }
-- 
2.29.2



[PATCH v3 net-next 01/10] net: korina: Fix MDIO functions

2021-04-14 Thread Thomas Bogendoerfer
Fixed MDIO functions to work reliable and not just by accident.

Signed-off-by: Thomas Bogendoerfer 
---
 drivers/net/ethernet/Kconfig  |  1 +
 drivers/net/ethernet/korina.c | 54 +++
 2 files changed, 36 insertions(+), 19 deletions(-)

diff --git a/drivers/net/ethernet/Kconfig b/drivers/net/ethernet/Kconfig
index ad04660b97b8..c059b4bd3f23 100644
--- a/drivers/net/ethernet/Kconfig
+++ b/drivers/net/ethernet/Kconfig
@@ -98,6 +98,7 @@ config JME
 config KORINA
tristate "Korina (IDT RC32434) Ethernet support"
depends on MIKROTIK_RB532
+   select MII
help
  If you have a Mikrotik RouterBoard 500 or IDT RC32434
  based system say Y. Otherwise say N.
diff --git a/drivers/net/ethernet/korina.c b/drivers/net/ethernet/korina.c
index 925161959b9b..3f6f4835a9bc 100644
--- a/drivers/net/ethernet/korina.c
+++ b/drivers/net/ethernet/korina.c
@@ -41,6 +41,7 @@
 #include 
 #include 
 #include 
+#include 
 #include 
 #include 
 #include 
@@ -137,7 +138,6 @@ struct korina_private {
struct mii_if_info mii_if;
struct work_struct restart_task;
struct net_device *dev;
-   int phy_addr;
 };
 
 extern unsigned int idt_cpu_freq;
@@ -292,32 +292,46 @@ static int korina_send_packet(struct sk_buff *skb, struct 
net_device *dev)
return NETDEV_TX_OK;
 }
 
-static int mdio_read(struct net_device *dev, int mii_id, int reg)
+static int korina_mdio_wait(struct korina_private *lp)
+{
+   u32 value;
+
+   return readl_poll_timeout_atomic(>eth_regs->miimind,
+value, value & ETH_MII_IND_BSY,
+1, 1000);
+}
+
+static int korina_mdio_read(struct net_device *dev, int phy, int reg)
 {
struct korina_private *lp = netdev_priv(dev);
int ret;
 
-   mii_id = ((lp->rx_irq == 0x2c ? 1 : 0) << 8);
+   if (korina_mdio_wait(lp))
+   return -ETIMEDOUT;
 
-   writel(0, >eth_regs->miimcfg);
-   writel(0, >eth_regs->miimcmd);
-   writel(mii_id | reg, >eth_regs->miimaddr);
-   writel(ETH_MII_CMD_SCN, >eth_regs->miimcmd);
+   writel(phy << 8 | reg, >eth_regs->miimaddr);
+   writel(1, >eth_regs->miimcmd);
+
+   if (korina_mdio_wait(lp))
+   return -ETIMEDOUT;
 
-   ret = (int)(readl(>eth_regs->miimrdd));
+   if (readl(>eth_regs->miimind) & ETH_MII_IND_NV)
+   return -1;
+
+   ret = readl(>eth_regs->miimrdd);
+   writel(0, >eth_regs->miimcmd);
return ret;
 }
 
-static void mdio_write(struct net_device *dev, int mii_id, int reg, int val)
+static void korina_mdio_write(struct net_device *dev, int phy, int reg, int 
val)
 {
struct korina_private *lp = netdev_priv(dev);
 
-   mii_id = ((lp->rx_irq == 0x2c ? 1 : 0) << 8);
+   if (korina_mdio_wait(lp))
+   return;
 
-   writel(0, >eth_regs->miimcfg);
-   writel(1, >eth_regs->miimcmd);
-   writel(mii_id | reg, >eth_regs->miimaddr);
-   writel(ETH_MII_CMD_SCN, >eth_regs->miimcmd);
+   writel(0, >eth_regs->miimcmd);
+   writel(phy << 8 | reg, >eth_regs->miimaddr);
writel(val, >eth_regs->miimwtd);
 }
 
@@ -643,7 +657,7 @@ static void korina_check_media(struct net_device *dev, 
unsigned int init_media)
 {
struct korina_private *lp = netdev_priv(dev);
 
-   mii_check_media(>mii_if, 0, init_media);
+   mii_check_media(>mii_if, 1, init_media);
 
if (lp->mii_if.full_duplex)
writel(readl(>eth_regs->ethmac2) | ETH_MAC2_FD,
@@ -869,12 +883,15 @@ static int korina_init(struct net_device *dev)
 * Clock independent setting */
writel(((idt_cpu_freq) / MII_CLOCK + 1) & ~1,
>eth_regs->ethmcp);
+   writel(0, >eth_regs->miimcfg);
 
/* don't transmit until fifo contains 48b */
writel(48, >eth_regs->ethfifott);
 
writel(ETH_MAC1_RE, >eth_regs->ethmac1);
 
+   korina_check_media(dev, 1);
+
napi_enable(>napi);
netif_start_queue(dev);
 
@@ -1089,11 +1106,10 @@ static int korina_probe(struct platform_device *pdev)
dev->watchdog_timeo = TX_TIMEOUT;
netif_napi_add(dev, >napi, korina_poll, NAPI_POLL_WEIGHT);
 
-   lp->phy_addr = (((lp->rx_irq == 0x2c? 1:0) << 8) | 0x05);
lp->mii_if.dev = dev;
-   lp->mii_if.mdio_read = mdio_read;
-   lp->mii_if.mdio_write = mdio_write;
-   lp->mii_if.phy_id = lp->phy_addr;
+   lp->mii_if.mdio_read = korina_mdio_read;
+   lp->mii_if.mdio_write = korina_mdio_write;
+   lp->mii_if.phy_id = 1;
lp->mii_if.phy_id_mask = 0x1f;
lp->mii_if.reg_num_mask = 0x1f;
 
-- 
2.29.2



[PATCH v3 net-next 00/10] net: Korina improvements

2021-04-14 Thread Thomas Bogendoerfer
While converting Mikrotik RB532 support to use device tree I stumbled
over the korina ethernet driver, which used way too many MIPS specific
hacks. This series cleans this all up and adds support for device tree.

Changes in v3:
  - fixed usage of of_get_mac_address for net-next
  - use readl_poll_timeout_atomic in mdio_wait
  - return -ETIMEDOUT, if mdio_wait fails
  - added DT binding and changed compatible name to idt,3243x-emac

Changes in v2:
  - added device tree support to get rid of idt_cpu_freq
  - fixed compile test on 64bit archs
  - fixed descriptor current address handling by storing/using mapped
dma addresses (dma controller modifies current address)

Thomas Bogendoerfer (10):
  net: korina: Fix MDIO functions
  net: korina: Use devres functions
  net: korina: Remove not needed cache flushes
  net: korina: Remove nested helpers
  net: korina: Use DMA API
  net: korina: Only pass mac address via platform data
  net: korina: Add support for device tree
  net: korina: Get mdio input clock via common clock framework
  net: korina: Make driver COMPILE_TESTable
  dt-bindings: net: korina: Add DT bindings for IDT 79RC3243x SoCs

 .../bindings/net/idt,3243x-emac.yaml  |  82 +++
 arch/mips/rb532/devices.c |   5 +-
 drivers/net/ethernet/Kconfig  |   3 +-
 drivers/net/ethernet/korina.c | 601 +-
 4 files changed, 519 insertions(+), 172 deletions(-)
 create mode 100644 Documentation/devicetree/bindings/net/idt,3243x-emac.yaml

-- 
2.29.2



Re: [PATCH net-next 1/7] net: korina: Fix MDIO functions

2021-04-14 Thread Thomas Bogendoerfer
On Wed, Apr 14, 2021 at 09:36:04PM +0200, Andrew Lunn wrote:
> > +static int korina_mdio_wait(struct korina_private *lp)
> > +{
> > +   int timeout = 1000;
> > +
> > +   while ((readl(>eth_regs->miimind) & 1) && timeout-- > 0)
> > +   udelay(1);
> > +
> > +   if (timeout <= 0)
> > +   return -1;
> > +
> > +   return 0;
> 
> Using readl_poll_timeout_atomic() would be better.

I'll have a look

> 
> 
> > +}
> > +
> > +static int korina_mdio_read(struct net_device *dev, int phy, int reg)
> >  {
> > struct korina_private *lp = netdev_priv(dev);
> > int ret;
> >  
> > -   mii_id = ((lp->rx_irq == 0x2c ? 1 : 0) << 8);
> > +   if (korina_mdio_wait(lp))
> > +   return -1;
> 
> This should really be -ETIMEDOUT

ok.

> > dev->watchdog_timeo = TX_TIMEOUT;
> > netif_napi_add(dev, >napi, korina_poll, NAPI_POLL_WEIGHT);
> >  
> > -   lp->phy_addr = (((lp->rx_irq == 0x2c? 1:0) << 8) | 0x05);
> > lp->mii_if.dev = dev;
> > -   lp->mii_if.mdio_read = mdio_read;
> > -   lp->mii_if.mdio_write = mdio_write;
> > -   lp->mii_if.phy_id = lp->phy_addr;
> > +   lp->mii_if.mdio_read = korina_mdio_read;
> > +   lp->mii_if.mdio_write = korina_mdio_write;
> > +   lp->mii_if.phy_id = 1;
> > lp->mii_if.phy_id_mask = 0x1f;
> > lp->mii_if.reg_num_mask = 0x1f;
> 
> You could also replace all the mii code with phylib.

that's on my todo.

Thomas.

-- 
Crap can work. Given enough thrust pigs will fly, but it's not necessarily a
good idea.[ RFC1925, 2.3 ]


[PATCH v2 net-next 8/9] net: korina: Get mdio input clock via common clock framework

2021-04-14 Thread Thomas Bogendoerfer
With device tree clock is provided via CCF. For non device tree
use a maximum clock value to not overclock the PHY. The non device
tree usage will go away after platform is converted to DT.

Signed-off-by: Thomas Bogendoerfer 
---
 drivers/net/ethernet/korina.c | 19 +--
 1 file changed, 13 insertions(+), 6 deletions(-)

diff --git a/drivers/net/ethernet/korina.c b/drivers/net/ethernet/korina.c
index c4590b2c65aa..df75dd5d1638 100644
--- a/drivers/net/ethernet/korina.c
+++ b/drivers/net/ethernet/korina.c
@@ -56,14 +56,13 @@
 #include 
 #include 
 #include 
+#include 
 
 #include 
 #include 
 #include 
 #include 
 
-#include 
-#include 
 #include 
 #include 
 
@@ -145,10 +144,9 @@ struct korina_private {
struct work_struct restart_task;
struct net_device *dev;
struct device *dmadev;
+   int mii_clock_freq;
 };
 
-extern unsigned int idt_cpu_freq;
-
 static dma_addr_t korina_tx_dma(struct korina_private *lp, int idx)
 {
return lp->td_dma + (idx * sizeof(struct dma_desc));
@@ -900,8 +898,8 @@ static int korina_init(struct net_device *dev)
 
/* Management Clock Prescaler Divisor
 * Clock independent setting */
-   writel(((idt_cpu_freq) / MII_CLOCK + 1) & ~1,
-   >eth_regs->ethmcp);
+   writel(((lp->mii_clock_freq) / MII_CLOCK + 1) & ~1,
+  >eth_regs->ethmcp);
writel(0, >eth_regs->miimcfg);
 
/* don't transmit until fifo contains 48b */
@@ -1061,6 +1059,7 @@ static int korina_probe(struct platform_device *pdev)
const u8 *mac_addr = dev_get_platdata(>dev);
struct korina_private *lp;
struct net_device *dev;
+   struct clk *clk;
void __iomem *p;
int rc;
 
@@ -1081,6 +1080,14 @@ static int korina_probe(struct platform_device *pdev)
eth_hw_addr_random(dev);
}
 
+   clk = devm_clk_get(>dev, NULL);
+   if (!IS_ERR(clk)) {
+   clk_prepare_enable(clk);
+   lp->mii_clock_freq = clk_get_rate(clk);
+   } else {
+   lp->mii_clock_freq = 2; /* max possible input clk */
+   }
+
lp->rx_irq = platform_get_irq_byname(pdev, "korina_rx");
lp->tx_irq = platform_get_irq_byname(pdev, "korina_tx");
 
-- 
2.29.2



[PATCH v2 net-next 6/9] net: korina: Only pass mac address via platform data

2021-04-14 Thread Thomas Bogendoerfer
Get rid of access to struct korina_device by just passing the mac
address via platform data and use drvdata for passing netdev to remove
function.

Signed-off-by: Thomas Bogendoerfer 
---
 arch/mips/rb532/devices.c |  5 +++--
 drivers/net/ethernet/korina.c | 11 ++-
 2 files changed, 9 insertions(+), 7 deletions(-)

diff --git a/arch/mips/rb532/devices.c b/arch/mips/rb532/devices.c
index dd34f1b32b79..5fc3c8ee4f31 100644
--- a/arch/mips/rb532/devices.c
+++ b/arch/mips/rb532/devices.c
@@ -105,6 +105,9 @@ static struct platform_device korina_dev0 = {
.name = "korina",
.resource = korina_dev0_res,
.num_resources = ARRAY_SIZE(korina_dev0_res),
+   .dev = {
+   .platform_data = _dev0_data.mac,
+   }
 };
 
 static struct resource cf_slot0_res[] = {
@@ -299,8 +302,6 @@ static int __init plat_setup_devices(void)
/* set the uart clock to the current cpu frequency */
rb532_uart_res[0].uartclk = idt_cpu_freq;
 
-   dev_set_drvdata(_dev0.dev, _dev0_data);
-
gpiod_add_lookup_table(_slot0_gpio_table);
return platform_add_devices(rb532_devs, ARRAY_SIZE(rb532_devs));
 }
diff --git a/drivers/net/ethernet/korina.c b/drivers/net/ethernet/korina.c
index 5e0fd9058701..69c8baa87a6e 100644
--- a/drivers/net/ethernet/korina.c
+++ b/drivers/net/ethernet/korina.c
@@ -1056,7 +1056,7 @@ static const struct net_device_ops korina_netdev_ops = {
 
 static int korina_probe(struct platform_device *pdev)
 {
-   struct korina_device *bif = platform_get_drvdata(pdev);
+   u8 *mac_addr = dev_get_platdata(>dev);
struct korina_private *lp;
struct net_device *dev;
void __iomem *p;
@@ -1069,8 +1069,7 @@ static int korina_probe(struct platform_device *pdev)
SET_NETDEV_DEV(dev, >dev);
lp = netdev_priv(dev);
 
-   bif->dev = dev;
-   memcpy(dev->dev_addr, bif->mac, ETH_ALEN);
+   memcpy(dev->dev_addr, mac_addr, ETH_ALEN);
 
lp->rx_irq = platform_get_irq_byname(pdev, "korina_rx");
lp->tx_irq = platform_get_irq_byname(pdev, "korina_tx");
@@ -1124,6 +1123,8 @@ static int korina_probe(struct platform_device *pdev)
lp->mii_if.phy_id_mask = 0x1f;
lp->mii_if.reg_num_mask = 0x1f;
 
+   platform_set_drvdata(pdev, dev);
+
rc = register_netdev(dev);
if (rc < 0) {
printk(KERN_ERR DRV_NAME
@@ -1141,9 +1142,9 @@ static int korina_probe(struct platform_device *pdev)
 
 static int korina_remove(struct platform_device *pdev)
 {
-   struct korina_device *bif = platform_get_drvdata(pdev);
+   struct net_device *dev = platform_get_drvdata(pdev);
 
-   unregister_netdev(bif->dev);
+   unregister_netdev(dev);
 
return 0;
 }
-- 
2.29.2



[PATCH v2 net-next 9/9] net: korina: Make driver COMPILE_TESTable

2021-04-14 Thread Thomas Bogendoerfer
Move structs/defines for ethernet/dma register into driver, since they
are only used for this driver and remove any MIPS specific includes.
This makes it possible to COMPILE_TEST the driver.

Signed-off-by: Thomas Bogendoerfer 
---
 drivers/net/ethernet/Kconfig  |   2 +-
 drivers/net/ethernet/korina.c | 249 --
 2 files changed, 239 insertions(+), 12 deletions(-)

diff --git a/drivers/net/ethernet/Kconfig b/drivers/net/ethernet/Kconfig
index c059b4bd3f23..453d202a28c1 100644
--- a/drivers/net/ethernet/Kconfig
+++ b/drivers/net/ethernet/Kconfig
@@ -97,7 +97,7 @@ config JME
 
 config KORINA
tristate "Korina (IDT RC32434) Ethernet support"
-   depends on MIKROTIK_RB532
+   depends on MIKROTIK_RB532 || COMPILE_TEST
select MII
help
  If you have a Mikrotik RouterBoard 500 or IDT RC32434
diff --git a/drivers/net/ethernet/korina.c b/drivers/net/ethernet/korina.c
index df75dd5d1638..025f88ae99be 100644
--- a/drivers/net/ethernet/korina.c
+++ b/drivers/net/ethernet/korina.c
@@ -58,18 +58,244 @@
 #include 
 #include 
 
-#include 
-#include 
-#include 
-#include 
-
-#include 
-#include 
-
 #define DRV_NAME   "korina"
 #define DRV_VERSION"0.20"
 #define DRV_RELDATE"15Sep2017"
 
+struct eth_regs {
+   u32 ethintfc;
+   u32 ethfifott;
+   u32 etharc;
+   u32 ethhash0;
+   u32 ethhash1;
+   u32 ethu0[4];   /* Reserved. */
+   u32 ethpfs;
+   u32 ethmcp;
+   u32 eth_u1[10]; /* Reserved. */
+   u32 ethspare;
+   u32 eth_u2[42]; /* Reserved. */
+   u32 ethsal0;
+   u32 ethsah0;
+   u32 ethsal1;
+   u32 ethsah1;
+   u32 ethsal2;
+   u32 ethsah2;
+   u32 ethsal3;
+   u32 ethsah3;
+   u32 ethrbc;
+   u32 ethrpc;
+   u32 ethrupc;
+   u32 ethrfc;
+   u32 ethtbc;
+   u32 ethgpf;
+   u32 eth_u9[50]; /* Reserved. */
+   u32 ethmac1;
+   u32 ethmac2;
+   u32 ethipgt;
+   u32 ethipgr;
+   u32 ethclrt;
+   u32 ethmaxf;
+   u32 eth_u10;/* Reserved. */
+   u32 ethmtest;
+   u32 miimcfg;
+   u32 miimcmd;
+   u32 miimaddr;
+   u32 miimwtd;
+   u32 miimrdd;
+   u32 miimind;
+   u32 eth_u11;/* Reserved. */
+   u32 eth_u12;/* Reserved. */
+   u32 ethcfsa0;
+   u32 ethcfsa1;
+   u32 ethcfsa2;
+};
+
+/* Ethernet interrupt registers */
+#define ETH_INT_FC_EN  BIT(0)
+#define ETH_INT_FC_ITS BIT(1)
+#define ETH_INT_FC_RIP BIT(2)
+#define ETH_INT_FC_JAM BIT(3)
+#define ETH_INT_FC_OVR BIT(4)
+#define ETH_INT_FC_UND BIT(5)
+#define ETH_INT_FC_IOC 0x00c0
+
+/* Ethernet FIFO registers */
+#define ETH_FIFI_TT_TTH_BIT0
+#define ETH_FIFO_TT_TTH0x007f
+
+/* Ethernet ARC/multicast registers */
+#define ETH_ARC_PROBIT(0)
+#define ETH_ARC_AM BIT(1)
+#define ETH_ARC_AFMBIT(2)
+#define ETH_ARC_AB BIT(3)
+
+/* Ethernet SAL registers */
+#define ETH_SAL_BYTE_5 0x00ff
+#define ETH_SAL_BYTE_4 0xff00
+#define ETH_SAL_BYTE_3 0x00ff
+#define ETH_SAL_BYTE_2 0xff00
+
+/* Ethernet SAH registers */
+#define ETH_SAH_BYTE1  0x00ff
+#define ETH_SAH_BYTE0  0xff00
+
+/* Ethernet GPF register */
+#define ETH_GPF_PTV0x
+
+/* Ethernet PFG register */
+#define ETH_PFS_PFDBIT(0)
+
+/* Ethernet CFSA[0-3] registers */
+#define ETH_CFSA0_CFSA40x00ff
+#define ETH_CFSA0_CFSA50xff00
+#define ETH_CFSA1_CFSA20x00ff
+#define ETH_CFSA1_CFSA30xff00
+#define ETH_CFSA1_CFSA00x00ff
+#define ETH_CFSA1_CFSA10xff00
+
+/* Ethernet MAC1 registers */
+#define ETH_MAC1_REBIT(0)
+#define ETH_MAC1_PAF   BIT(1)
+#define ETH_MAC1_RFC   BIT(2)
+#define ETH_MAC1_TFC   BIT(3)
+#define ETH_MAC1_LBBIT(4)
+#define ETH_MAC1_MRBIT(31)
+
+/* Ethernet MAC2 registers */
+#define ETH_MAC2_FDBIT(0)
+#define ETH_MAC2_FLC   BIT(1)
+#define ETH_MAC2_HFE   BIT(2)
+#define ETH_MAC2_DCBIT(3)
+#define ETH_MAC2_CEN   BIT(4)
+#define ETH_MAC2_PEBIT(5)
+#define ETH_MAC2_VPE   BIT(6)
+#define ETH_MAC2_APE   BIT(7)
+#define ETH_MAC2_PPE   BIT(8)
+#define ETH_MAC2_LPE   BIT(9)
+#define ETH_MAC2_NBBIT(12)
+#define ETH_MAC2_BPBIT(13)
+#define ETH_MAC2_EDBIT(14)
+
+/* Ethernet IPGT register */
+#define ETH_IPGT   0x007f
+
+/* Ethernet IPGR registers */
+#define ETH_IPGR_IPGR2 0x007f
+#define ETH_IPGR_IPGR1 0x7f00
+
+/* Ethernet CLRT registers */
+#define ETH_CLRT_MAX_RET   0x000f
+#

[PATCH v2 net-next 7/9] net: korina: Add support for device tree

2021-04-14 Thread Thomas Bogendoerfer
If there is no mac address passed via platform data try to get it via
device tree and fall back to a random mac address, if all fail.

Signed-off-by: Thomas Bogendoerfer 
---
 drivers/net/ethernet/korina.c | 29 ++---
 1 file changed, 26 insertions(+), 3 deletions(-)

diff --git a/drivers/net/ethernet/korina.c b/drivers/net/ethernet/korina.c
index 69c8baa87a6e..c4590b2c65aa 100644
--- a/drivers/net/ethernet/korina.c
+++ b/drivers/net/ethernet/korina.c
@@ -42,6 +42,8 @@
 #include 
 #include 
 #include 
+#include 
+#include 
 #include 
 #include 
 #include 
@@ -1056,7 +1058,7 @@ static const struct net_device_ops korina_netdev_ops = {
 
 static int korina_probe(struct platform_device *pdev)
 {
-   u8 *mac_addr = dev_get_platdata(>dev);
+   const u8 *mac_addr = dev_get_platdata(>dev);
struct korina_private *lp;
struct net_device *dev;
void __iomem *p;
@@ -1069,7 +1071,15 @@ static int korina_probe(struct platform_device *pdev)
SET_NETDEV_DEV(dev, >dev);
lp = netdev_priv(dev);
 
-   memcpy(dev->dev_addr, mac_addr, ETH_ALEN);
+   if (mac_addr) {
+   ether_addr_copy(dev->dev_addr, mac_addr);
+   } else {
+   mac_addr = of_get_mac_address(pdev->dev.of_node);
+   if (!IS_ERR(mac_addr))
+   ether_addr_copy(dev->dev_addr, mac_addr);
+   else
+   eth_hw_addr_random(dev);
+   }
 
lp->rx_irq = platform_get_irq_byname(pdev, "korina_rx");
lp->tx_irq = platform_get_irq_byname(pdev, "korina_tx");
@@ -1149,8 +1159,21 @@ static int korina_remove(struct platform_device *pdev)
return 0;
 }
 
+#ifdef CONFIG_OF
+static const struct of_device_id korina_match[] = {
+   {
+   .compatible = "korina",
+   },
+   { }
+};
+MODULE_DEVICE_TABLE(of, korina_match);
+#endif
+
 static struct platform_driver korina_driver = {
-   .driver.name = "korina",
+   .driver = {
+   .name = "korina",
+   .of_match_table = of_match_ptr(korina_match),
+   },
.probe = korina_probe,
.remove = korina_remove,
 };
-- 
2.29.2



[PATCH v2 net-next 5/9] net: korina: Use DMA API

2021-04-14 Thread Thomas Bogendoerfer
Instead of messing with MIPS specific macros use DMA API for mapping
descriptors and skbs.

Signed-off-by: Thomas Bogendoerfer 
---
 drivers/net/ethernet/korina.c | 158 +-
 1 file changed, 98 insertions(+), 60 deletions(-)

diff --git a/drivers/net/ethernet/korina.c b/drivers/net/ethernet/korina.c
index 728c4baa3eee..5e0fd9058701 100644
--- a/drivers/net/ethernet/korina.c
+++ b/drivers/net/ethernet/korina.c
@@ -109,10 +109,15 @@ struct korina_private {
struct dma_reg __iomem *tx_dma_regs;
struct dma_desc *td_ring; /* transmit descriptor ring */
struct dma_desc *rd_ring; /* receive descriptor ring  */
+   dma_addr_t td_dma;
+   dma_addr_t rd_dma;
 
struct sk_buff *tx_skb[KORINA_NUM_TDS];
struct sk_buff *rx_skb[KORINA_NUM_RDS];
 
+   dma_addr_t rx_skb_dma[KORINA_NUM_RDS];
+   dma_addr_t tx_skb_dma[KORINA_NUM_TDS];
+
int rx_next_done;
int rx_chain_head;
int rx_chain_tail;
@@ -137,10 +142,21 @@ struct korina_private {
struct mii_if_info mii_if;
struct work_struct restart_task;
struct net_device *dev;
+   struct device *dmadev;
 };
 
 extern unsigned int idt_cpu_freq;
 
+static dma_addr_t korina_tx_dma(struct korina_private *lp, int idx)
+{
+   return lp->td_dma + (idx * sizeof(struct dma_desc));
+}
+
+static dma_addr_t korina_rx_dma(struct korina_private *lp, int idx)
+{
+   return lp->rd_dma + (idx * sizeof(struct dma_desc));
+}
+
 static inline void korina_abort_dma(struct net_device *dev,
struct dma_reg *ch)
 {
@@ -175,14 +191,17 @@ static void korina_abort_rx(struct net_device *dev)
 static int korina_send_packet(struct sk_buff *skb, struct net_device *dev)
 {
struct korina_private *lp = netdev_priv(dev);
-   unsigned long flags;
-   u32 length;
u32 chain_prev, chain_next;
+   unsigned long flags;
struct dma_desc *td;
+   dma_addr_t ca;
+   u32 length;
+   int idx;
 
spin_lock_irqsave(>lock, flags);
 
-   td = >td_ring[lp->tx_chain_tail];
+   idx = lp->tx_chain_tail;
+   td = >td_ring[idx];
 
/* stop queue when full, drop pkts if queue already full */
if (lp->tx_count >= (KORINA_NUM_TDS - 2)) {
@@ -190,26 +209,26 @@ static int korina_send_packet(struct sk_buff *skb, struct 
net_device *dev)
 
if (lp->tx_count == (KORINA_NUM_TDS - 2))
netif_stop_queue(dev);
-   else {
-   dev->stats.tx_dropped++;
-   dev_kfree_skb_any(skb);
-   spin_unlock_irqrestore(>lock, flags);
-
-   return NETDEV_TX_OK;
-   }
+   else
+   goto drop_packet;
}
 
lp->tx_count++;
 
-   lp->tx_skb[lp->tx_chain_tail] = skb;
+   lp->tx_skb[idx] = skb;
 
length = skb->len;
-   dma_cache_wback((u32)skb->data, skb->len);
 
/* Setup the transmit descriptor. */
-   td->ca = CPHYSADDR(skb->data);
-   chain_prev = (lp->tx_chain_tail - 1) & KORINA_TDS_MASK;
-   chain_next = (lp->tx_chain_tail + 1) & KORINA_TDS_MASK;
+   ca = dma_map_single(lp->dmadev, skb->data, length, DMA_TO_DEVICE);
+   if (dma_mapping_error(lp->dmadev, ca))
+   goto drop_packet;
+
+   lp->tx_skb_dma[idx] = ca;
+   td->ca = ca;
+
+   chain_prev = (idx - 1) & KORINA_TDS_MASK;
+   chain_next = (idx + 1) & KORINA_TDS_MASK;
 
if (readl(&(lp->tx_dma_regs->dmandptr)) == 0) {
if (lp->tx_chain_status == desc_empty) {
@@ -219,8 +238,8 @@ static int korina_send_packet(struct sk_buff *skb, struct 
net_device *dev)
/* Move tail */
lp->tx_chain_tail = chain_next;
/* Write to NDPTR */
-   writel(CPHYSADDR(>td_ring[lp->tx_chain_head]),
-   >tx_dma_regs->dmandptr);
+   writel(korina_tx_dma(lp, lp->tx_chain_head),
+  >tx_dma_regs->dmandptr);
/* Move head to tail */
lp->tx_chain_head = lp->tx_chain_tail;
} else {
@@ -231,12 +250,12 @@ static int korina_send_packet(struct sk_buff *skb, struct 
net_device *dev)
lp->td_ring[chain_prev].control &=
~DMA_DESC_COF;
/* Link to prev */
-   lp->td_ring[chain_prev].link =  CPHYSADDR(td);
+   lp->td_ring[chain_prev].link = korina_tx_dma(lp, idx);
/* Move tail */
lp->tx_chain_tail = chain_next;

[PATCH v2 net-next 4/9] net: korina: Remove nested helpers

2021-04-14 Thread Thomas Bogendoerfer
Remove helpers, which are only used in one call site.

Signed-off-by: Thomas Bogendoerfer 
---
 drivers/net/ethernet/korina.c | 28 +++-
 1 file changed, 3 insertions(+), 25 deletions(-)

diff --git a/drivers/net/ethernet/korina.c b/drivers/net/ethernet/korina.c
index b6dcbb6d5e05..728c4baa3eee 100644
--- a/drivers/net/ethernet/korina.c
+++ b/drivers/net/ethernet/korina.c
@@ -141,12 +141,6 @@ struct korina_private {
 
 extern unsigned int idt_cpu_freq;
 
-static inline void korina_start_dma(struct dma_reg *ch, u32 dma_addr)
-{
-   writel(0, >dmandptr);
-   writel(dma_addr, >dmadptr);
-}
-
 static inline void korina_abort_dma(struct net_device *dev,
struct dma_reg *ch)
 {
@@ -163,11 +157,6 @@ static inline void korina_abort_dma(struct net_device *dev,
writel(0, >dmandptr);
 }
 
-static inline void korina_chain_dma(struct dma_reg *ch, u32 dma_addr)
-{
-   writel(dma_addr, >dmandptr);
-}
-
 static void korina_abort_tx(struct net_device *dev)
 {
struct korina_private *lp = netdev_priv(dev);
@@ -182,18 +171,6 @@ static void korina_abort_rx(struct net_device *dev)
korina_abort_dma(dev, lp->rx_dma_regs);
 }
 
-static void korina_start_rx(struct korina_private *lp,
-   struct dma_desc *rd)
-{
-   korina_start_dma(lp->rx_dma_regs, CPHYSADDR(rd));
-}
-
-static void korina_chain_rx(struct korina_private *lp,
-   struct dma_desc *rd)
-{
-   korina_chain_dma(lp->rx_dma_regs, CPHYSADDR(rd));
-}
-
 /* transmit packet */
 static int korina_send_packet(struct sk_buff *skb, struct net_device *dev)
 {
@@ -464,7 +441,7 @@ static int korina_rx(struct net_device *dev, int limit)
rd->devcs = 0;
skb = lp->rx_skb[lp->rx_next_done];
rd->ca = CPHYSADDR(skb->data);
-   korina_chain_rx(lp, rd);
+   writel(CPHYSADDR(rd), >rx_dma_regs->dmandptr);
}
 
return count;
@@ -841,7 +818,8 @@ static int korina_init(struct net_device *dev)
 
writel(0, >rx_dma_regs->dmas);
/* Start Rx DMA */
-   korina_start_rx(lp, >rd_ring[0]);
+   writel(0, >rx_dma_regs->dmandptr);
+   writel(CPHYSADDR(>rd_ring[0]), >rx_dma_regs->dmadptr);
 
writel(readl(>tx_dma_regs->dmasm) &
~(DMA_STAT_FINI | DMA_STAT_ERR),
-- 
2.29.2



[PATCH v2 net-next 3/9] net: korina: Remove not needed cache flushes

2021-04-14 Thread Thomas Bogendoerfer
Descriptors are mapped uncached so there is no need to do any cache
handling for them.

Signed-off-by: Thomas Bogendoerfer 
---
 drivers/net/ethernet/korina.c | 6 --
 1 file changed, 6 deletions(-)

diff --git a/drivers/net/ethernet/korina.c b/drivers/net/ethernet/korina.c
index 3a454f6214b0..b6dcbb6d5e05 100644
--- a/drivers/net/ethernet/korina.c
+++ b/drivers/net/ethernet/korina.c
@@ -230,7 +230,6 @@ static int korina_send_packet(struct sk_buff *skb, struct 
net_device *dev)
dma_cache_wback((u32)skb->data, skb->len);
 
/* Setup the transmit descriptor. */
-   dma_cache_inv((u32) td, sizeof(*td));
td->ca = CPHYSADDR(skb->data);
chain_prev = (lp->tx_chain_tail - 1) & KORINA_TDS_MASK;
chain_next = (lp->tx_chain_tail + 1) & KORINA_TDS_MASK;
@@ -283,7 +282,6 @@ static int korina_send_packet(struct sk_buff *skb, struct 
net_device *dev)
lp->tx_chain_tail = chain_next;
}
}
-   dma_cache_wback((u32) td, sizeof(*td));
 
netif_trans_update(dev);
spin_unlock_irqrestore(>lock, flags);
@@ -374,8 +372,6 @@ static int korina_rx(struct net_device *dev, int limit)
u32 devcs, pkt_len, dmas;
int count;
 
-   dma_cache_inv((u32)rd, sizeof(*rd));
-
for (count = 0; count < limit; count++) {
skb = lp->rx_skb[lp->rx_next_done];
skb_new = NULL;
@@ -454,7 +450,6 @@ static int korina_rx(struct net_device *dev, int limit)
~DMA_DESC_COD;
 
lp->rx_next_done = (lp->rx_next_done + 1) & KORINA_RDS_MASK;
-   dma_cache_wback((u32)rd, sizeof(*rd));
rd = >rd_ring[lp->rx_next_done];
writel(~DMA_STAT_DONE, >rx_dma_regs->dmas);
}
@@ -469,7 +464,6 @@ static int korina_rx(struct net_device *dev, int limit)
rd->devcs = 0;
skb = lp->rx_skb[lp->rx_next_done];
rd->ca = CPHYSADDR(skb->data);
-   dma_cache_wback((u32)rd, sizeof(*rd));
korina_chain_rx(lp, rd);
}
 
-- 
2.29.2



[PATCH v2 net-next 2/9] net: korina: Use devres functions

2021-04-14 Thread Thomas Bogendoerfer
Simplify probe/remove code by using devm_ functions.

Signed-off-by: Thomas Bogendoerfer 
---
 drivers/net/ethernet/korina.c | 64 ---
 1 file changed, 21 insertions(+), 43 deletions(-)

diff --git a/drivers/net/ethernet/korina.c b/drivers/net/ethernet/korina.c
index 2266b18c1377..3a454f6214b0 100644
--- a/drivers/net/ethernet/korina.c
+++ b/drivers/net/ethernet/korina.c
@@ -104,9 +104,9 @@ enum chain_status {
 
 /* Information that need to be kept for each board. */
 struct korina_private {
-   struct eth_regs *eth_regs;
-   struct dma_reg *rx_dma_regs;
-   struct dma_reg *tx_dma_regs;
+   struct eth_regs __iomem *eth_regs;
+   struct dma_reg __iomem *rx_dma_regs;
+   struct dma_reg __iomem *tx_dma_regs;
struct dma_desc *td_ring; /* transmit descriptor ring */
struct dma_desc *rd_ring; /* receive descriptor ring  */
 
@@ -1045,10 +1045,10 @@ static int korina_probe(struct platform_device *pdev)
struct korina_device *bif = platform_get_drvdata(pdev);
struct korina_private *lp;
struct net_device *dev;
-   struct resource *r;
+   void __iomem *p;
int rc;
 
-   dev = alloc_etherdev(sizeof(struct korina_private));
+   dev = devm_alloc_etherdev(>dev, sizeof(struct korina_private));
if (!dev)
return -ENOMEM;
 
@@ -1061,36 +1061,30 @@ static int korina_probe(struct platform_device *pdev)
lp->rx_irq = platform_get_irq_byname(pdev, "korina_rx");
lp->tx_irq = platform_get_irq_byname(pdev, "korina_tx");
 
-   r = platform_get_resource_byname(pdev, IORESOURCE_MEM, "korina_regs");
-   dev->base_addr = r->start;
-   lp->eth_regs = ioremap(r->start, resource_size(r));
-   if (!lp->eth_regs) {
+   p = devm_platform_ioremap_resource_byname(pdev, "korina_regs");
+   if (!p) {
printk(KERN_ERR DRV_NAME ": cannot remap registers\n");
-   rc = -ENXIO;
-   goto probe_err_out;
+   return -ENOMEM;
}
+   lp->eth_regs = p;
 
-   r = platform_get_resource_byname(pdev, IORESOURCE_MEM, "korina_dma_rx");
-   lp->rx_dma_regs = ioremap(r->start, resource_size(r));
-   if (!lp->rx_dma_regs) {
+   p = devm_platform_ioremap_resource_byname(pdev, "korina_dma_rx");
+   if (!p) {
printk(KERN_ERR DRV_NAME ": cannot remap Rx DMA registers\n");
-   rc = -ENXIO;
-   goto probe_err_dma_rx;
+   return -ENOMEM;
}
+   lp->rx_dma_regs = p;
 
-   r = platform_get_resource_byname(pdev, IORESOURCE_MEM, "korina_dma_tx");
-   lp->tx_dma_regs = ioremap(r->start, resource_size(r));
-   if (!lp->tx_dma_regs) {
+   p = devm_platform_ioremap_resource_byname(pdev, "korina_dma_tx");
+   if (!p) {
printk(KERN_ERR DRV_NAME ": cannot remap Tx DMA registers\n");
-   rc = -ENXIO;
-   goto probe_err_dma_tx;
+   return -ENOMEM;
}
+   lp->tx_dma_regs = p;
 
lp->td_ring = kmalloc(TD_RING_SIZE + RD_RING_SIZE, GFP_KERNEL);
-   if (!lp->td_ring) {
-   rc = -ENXIO;
-   goto probe_err_td_ring;
-   }
+   if (!lp->td_ring)
+   return -ENOMEM;
 
dma_cache_inv((unsigned long)(lp->td_ring),
TD_RING_SIZE + RD_RING_SIZE);
@@ -1120,7 +1114,8 @@ static int korina_probe(struct platform_device *pdev)
if (rc < 0) {
printk(KERN_ERR DRV_NAME
": cannot register net device: %d\n", rc);
-   goto probe_err_register;
+   kfree((struct dma_desc *)KSEG0ADDR(lp->td_ring));
+   return rc;
}
timer_setup(>media_check_timer, korina_poll_media, 0);
 
@@ -1128,20 +1123,7 @@ static int korina_probe(struct platform_device *pdev)
 
printk(KERN_INFO "%s: " DRV_NAME "-" DRV_VERSION " " DRV_RELDATE "\n",
dev->name);
-out:
return rc;
-
-probe_err_register:
-   kfree((struct dma_desc *)KSEG0ADDR(lp->td_ring));
-probe_err_td_ring:
-   iounmap(lp->tx_dma_regs);
-probe_err_dma_tx:
-   iounmap(lp->rx_dma_regs);
-probe_err_dma_rx:
-   iounmap(lp->eth_regs);
-probe_err_out:
-   free_netdev(dev);
-   goto out;
 }
 
 static int korina_remove(struct platform_device *pdev)
@@ -1149,13 +1131,9 @@ static int korina_remove(struct platform_device *pdev)
struct korina_device *bif = platform_get_drvdata(pdev);
struct korina_private *lp = netdev_priv(bif->dev);
 
-   iounmap(lp->eth_regs);
-   iounmap(lp->rx_dma_regs);
-   iounmap(lp->tx_dma_regs);
kfree((struct dma_desc *)KSEG0ADDR(lp->td_ring));
 
unregister_netdev(bif->dev);
-   free_netdev(bif->dev);
 
return 0;
 }
-- 
2.29.2



[PATCH v2 net-next 1/9] net: korina: Fix MDIO functions

2021-04-14 Thread Thomas Bogendoerfer
Fixed MDIO functions to work reliable and not just by accident.

Signed-off-by: Thomas Bogendoerfer 
---
 drivers/net/ethernet/Kconfig  |  1 +
 drivers/net/ethernet/korina.c | 57 +++
 2 files changed, 39 insertions(+), 19 deletions(-)

diff --git a/drivers/net/ethernet/Kconfig b/drivers/net/ethernet/Kconfig
index ad04660b97b8..c059b4bd3f23 100644
--- a/drivers/net/ethernet/Kconfig
+++ b/drivers/net/ethernet/Kconfig
@@ -98,6 +98,7 @@ config JME
 config KORINA
tristate "Korina (IDT RC32434) Ethernet support"
depends on MIKROTIK_RB532
+   select MII
help
  If you have a Mikrotik RouterBoard 500 or IDT RC32434
  based system say Y. Otherwise say N.
diff --git a/drivers/net/ethernet/korina.c b/drivers/net/ethernet/korina.c
index 925161959b9b..2266b18c1377 100644
--- a/drivers/net/ethernet/korina.c
+++ b/drivers/net/ethernet/korina.c
@@ -137,7 +137,6 @@ struct korina_private {
struct mii_if_info mii_if;
struct work_struct restart_task;
struct net_device *dev;
-   int phy_addr;
 };
 
 extern unsigned int idt_cpu_freq;
@@ -292,32 +291,50 @@ static int korina_send_packet(struct sk_buff *skb, struct 
net_device *dev)
return NETDEV_TX_OK;
 }
 
-static int mdio_read(struct net_device *dev, int mii_id, int reg)
+static int korina_mdio_wait(struct korina_private *lp)
+{
+   int timeout = 1000;
+
+   while ((readl(>eth_regs->miimind) & 1) && timeout-- > 0)
+   udelay(1);
+
+   if (timeout <= 0)
+   return -1;
+
+   return 0;
+}
+
+static int korina_mdio_read(struct net_device *dev, int phy, int reg)
 {
struct korina_private *lp = netdev_priv(dev);
int ret;
 
-   mii_id = ((lp->rx_irq == 0x2c ? 1 : 0) << 8);
+   if (korina_mdio_wait(lp))
+   return -1;
 
-   writel(0, >eth_regs->miimcfg);
-   writel(0, >eth_regs->miimcmd);
-   writel(mii_id | reg, >eth_regs->miimaddr);
-   writel(ETH_MII_CMD_SCN, >eth_regs->miimcmd);
+   writel(phy << 8 | reg, >eth_regs->miimaddr);
+   writel(1, >eth_regs->miimcmd);
 
-   ret = (int)(readl(>eth_regs->miimrdd));
+   if (korina_mdio_wait(lp))
+   return -1;
+
+   if (readl(>eth_regs->miimind) & 4)
+   return -1;
+
+   ret = readl(>eth_regs->miimrdd);
+   writel(0, >eth_regs->miimcmd);
return ret;
 }
 
-static void mdio_write(struct net_device *dev, int mii_id, int reg, int val)
+static void korina_mdio_write(struct net_device *dev, int phy, int reg, int 
val)
 {
struct korina_private *lp = netdev_priv(dev);
 
-   mii_id = ((lp->rx_irq == 0x2c ? 1 : 0) << 8);
+   if (korina_mdio_wait(lp))
+   return;
 
-   writel(0, >eth_regs->miimcfg);
-   writel(1, >eth_regs->miimcmd);
-   writel(mii_id | reg, >eth_regs->miimaddr);
-   writel(ETH_MII_CMD_SCN, >eth_regs->miimcmd);
+   writel(0, >eth_regs->miimcmd);
+   writel(phy << 8 | reg, >eth_regs->miimaddr);
writel(val, >eth_regs->miimwtd);
 }
 
@@ -643,7 +660,7 @@ static void korina_check_media(struct net_device *dev, 
unsigned int init_media)
 {
struct korina_private *lp = netdev_priv(dev);
 
-   mii_check_media(>mii_if, 0, init_media);
+   mii_check_media(>mii_if, 1, init_media);
 
if (lp->mii_if.full_duplex)
writel(readl(>eth_regs->ethmac2) | ETH_MAC2_FD,
@@ -869,12 +886,15 @@ static int korina_init(struct net_device *dev)
 * Clock independent setting */
writel(((idt_cpu_freq) / MII_CLOCK + 1) & ~1,
>eth_regs->ethmcp);
+   writel(0, >eth_regs->miimcfg);
 
/* don't transmit until fifo contains 48b */
writel(48, >eth_regs->ethfifott);
 
writel(ETH_MAC1_RE, >eth_regs->ethmac1);
 
+   korina_check_media(dev, 1);
+
napi_enable(>napi);
netif_start_queue(dev);
 
@@ -1089,11 +1109,10 @@ static int korina_probe(struct platform_device *pdev)
dev->watchdog_timeo = TX_TIMEOUT;
netif_napi_add(dev, >napi, korina_poll, NAPI_POLL_WEIGHT);
 
-   lp->phy_addr = (((lp->rx_irq == 0x2c? 1:0) << 8) | 0x05);
lp->mii_if.dev = dev;
-   lp->mii_if.mdio_read = mdio_read;
-   lp->mii_if.mdio_write = mdio_write;
-   lp->mii_if.phy_id = lp->phy_addr;
+   lp->mii_if.mdio_read = korina_mdio_read;
+   lp->mii_if.mdio_write = korina_mdio_write;
+   lp->mii_if.phy_id = 1;
lp->mii_if.phy_id_mask = 0x1f;
lp->mii_if.reg_num_mask = 0x1f;
 
-- 
2.29.2



[PATCH v2 net-next 0/9] net: Korina improvements

2021-04-14 Thread Thomas Bogendoerfer
While converting Mikrotik RB532 support to use device tree I stumbled
over the korina ethernet driver, which used way too many MIPS specific
hacks. This series cleans this all up and adds support for device tree.

Changes in v2:
  - added device tree support to get rid of idt_cpu_freq
  - fixed compile test on 64bit archs
  - fixed descriptor current address handling by storing/using mapped
dma addresses (dma controller modifies current address)

Thomas Bogendoerfer (9):
  net: korina: Fix MDIO functions
  net: korina: Use devres functions
  net: korina: Remove not needed cache flushes
  net: korina: Remove nested helpers
  net: korina: Use DMA API
  net: korina: Only pass mac address via platform data
  net: korina: Add support for device tree
  net: korina: Get mdio input clock via common clock framework
  net: korina: Make driver COMPILE_TESTable

 arch/mips/rb532/devices.c |   5 +-
 drivers/net/ethernet/Kconfig  |   3 +-
 drivers/net/ethernet/korina.c | 603 --
 3 files changed, 439 insertions(+), 172 deletions(-)

-- 
2.29.2



Re: [PATCH] MIPS: Fix strnlen_user access check

2021-04-14 Thread Thomas Bogendoerfer
On Tue, Apr 13, 2021 at 04:01:13PM +, David Laight wrote:
> From: Thomas Bogendoerfer
> > Sent: 13 April 2021 16:19
> > 
> > On Tue, Apr 13, 2021 at 12:37:25PM +, David Laight wrote:
> > > From: Thomas Bogendoerfer 
> > > > Sent: 13 April 2021 12:15
> > > ...
> > > > > The __access_ok() is noted with `Ensure that the range [addr, 
> > > > > addr+size)
> > > > > is within the process's address space`. Does the range checked by
> > > > > __access_ok() on MIPS is [addr, addr+size]. So if we want to use
> > > > > access_ok(s, 1), should we modify __access_ok()? Or my 
> > > > > misunderstanding?
> > > >
> > > > you are right, I'm going to apply
> > > >
> > > > https://patchwork.kernel.org/project/linux-mips/patch/20190209194718.1294-1-paul.bur...@mips.com/
> > > >
> > > > to fix that.
> > >
> > > Isn't that still wrong?
> > > If an application does:
> > >   write(fd, (void *)0x, 0);
> > > it should return 0, not -1 and EFAULT/SIGSEGV.
> > 
> > WRITE(2)   Linux Programmer's Manual  
> > WRITE(2)
> > [...]
> >If  count  is  zero  and  fd refers to a regular file, then write() 
> > may
> >return a failure status if one of the errors below is detected.  If  
> > no
> >errors  are  detected,  or  error detection is not performed, 0 will 
> > be
> >returned without causing any other effect.  If count  is  zero  and  
> > fd
> >refers  to a file other than a regular file, the results are not 
> > speci-
> >fied.
> > [...]
> >EFAULT buf is outside your accessible address space.
> > 
> > at least it's covered by the man page on my Linux system.
> 
> Something related definitely caused grief in the setsockopt() changes.
> 
> > > There is also the question about why this makes any difference
> > > to the original problem of logging in via the graphical interface.
> > 
> > kernel/module.c:mod->args = strndup_user(uargs, ~0UL >> 1);
> > 
> > and strndup_user does a strnlen_user.
> 
> That call is just gross.
> Why did it work before the removal of set_fs() etc.

strnlen_user just did the equivalent of access_ok(s, 0) and I copy
the wrong access_ok() statement :-( 

> Or was there another change that affected strndup_user() ?

no, just the change in strnlen_user.

Thomas.

-- 
Crap can work. Given enough thrust pigs will fly, but it's not necessarily a
good idea.[ RFC1925, 2.3 ]


[PATCH net-next 6/7] net: korina: Only pass mac address via platform data

2021-04-13 Thread Thomas Bogendoerfer
Get rid of access to struct korina_device by just passing the mac
address via platform data and use drvdata for passing netdev to remove
function.

Signed-off-by: Thomas Bogendoerfer 
---
 arch/mips/rb532/devices.c |  5 +++--
 drivers/net/ethernet/korina.c | 11 ++-
 2 files changed, 9 insertions(+), 7 deletions(-)

diff --git a/arch/mips/rb532/devices.c b/arch/mips/rb532/devices.c
index dd34f1b32b79..5fc3c8ee4f31 100644
--- a/arch/mips/rb532/devices.c
+++ b/arch/mips/rb532/devices.c
@@ -105,6 +105,9 @@ static struct platform_device korina_dev0 = {
.name = "korina",
.resource = korina_dev0_res,
.num_resources = ARRAY_SIZE(korina_dev0_res),
+   .dev = {
+   .platform_data = _dev0_data.mac,
+   }
 };
 
 static struct resource cf_slot0_res[] = {
@@ -299,8 +302,6 @@ static int __init plat_setup_devices(void)
/* set the uart clock to the current cpu frequency */
rb532_uart_res[0].uartclk = idt_cpu_freq;
 
-   dev_set_drvdata(_dev0.dev, _dev0_data);
-
gpiod_add_lookup_table(_slot0_gpio_table);
return platform_add_devices(rb532_devs, ARRAY_SIZE(rb532_devs));
 }
diff --git a/drivers/net/ethernet/korina.c b/drivers/net/ethernet/korina.c
index 0224cd179b03..d7972965eb14 100644
--- a/drivers/net/ethernet/korina.c
+++ b/drivers/net/ethernet/korina.c
@@ -1045,7 +1045,7 @@ static const struct net_device_ops korina_netdev_ops = {
 
 static int korina_probe(struct platform_device *pdev)
 {
-   struct korina_device *bif = platform_get_drvdata(pdev);
+   u8 *mac_addr = dev_get_platdata(>dev);
struct korina_private *lp;
struct net_device *dev;
void __iomem *p;
@@ -1058,8 +1058,7 @@ static int korina_probe(struct platform_device *pdev)
SET_NETDEV_DEV(dev, >dev);
lp = netdev_priv(dev);
 
-   bif->dev = dev;
-   memcpy(dev->dev_addr, bif->mac, ETH_ALEN);
+   memcpy(dev->dev_addr, mac_addr, ETH_ALEN);
 
lp->rx_irq = platform_get_irq_byname(pdev, "korina_rx");
lp->tx_irq = platform_get_irq_byname(pdev, "korina_tx");
@@ -1113,6 +1112,8 @@ static int korina_probe(struct platform_device *pdev)
lp->mii_if.phy_id_mask = 0x1f;
lp->mii_if.reg_num_mask = 0x1f;
 
+   platform_set_drvdata(pdev, dev);
+
rc = register_netdev(dev);
if (rc < 0) {
printk(KERN_ERR DRV_NAME
@@ -1130,9 +1131,9 @@ static int korina_probe(struct platform_device *pdev)
 
 static int korina_remove(struct platform_device *pdev)
 {
-   struct korina_device *bif = platform_get_drvdata(pdev);
+   struct net_device *dev = platform_get_drvdata(pdev);
 
-   unregister_netdev(bif->dev);
+   unregister_netdev(dev);
 
return 0;
 }
-- 
2.29.2



[PATCH net-next 5/7] net: korina: Use DMA API

2021-04-13 Thread Thomas Bogendoerfer
Instead of messing with MIPS specific macros use DMA API for mapping
descriptors and skbs.

Signed-off-by: Thomas Bogendoerfer 
---
 drivers/net/ethernet/korina.c | 143 --
 1 file changed, 85 insertions(+), 58 deletions(-)

diff --git a/drivers/net/ethernet/korina.c b/drivers/net/ethernet/korina.c
index 728c4baa3eee..0224cd179b03 100644
--- a/drivers/net/ethernet/korina.c
+++ b/drivers/net/ethernet/korina.c
@@ -109,6 +109,8 @@ struct korina_private {
struct dma_reg __iomem *tx_dma_regs;
struct dma_desc *td_ring; /* transmit descriptor ring */
struct dma_desc *rd_ring; /* receive descriptor ring  */
+   dma_addr_t td_dma;
+   dma_addr_t rd_dma;
 
struct sk_buff *tx_skb[KORINA_NUM_TDS];
struct sk_buff *rx_skb[KORINA_NUM_RDS];
@@ -137,10 +139,21 @@ struct korina_private {
struct mii_if_info mii_if;
struct work_struct restart_task;
struct net_device *dev;
+   struct device *dmadev;
 };
 
 extern unsigned int idt_cpu_freq;
 
+static dma_addr_t korina_tx_dma(struct korina_private *lp, int idx)
+{
+   return lp->td_dma + (idx * sizeof(struct dma_desc));
+}
+
+static dma_addr_t korina_rx_dma(struct korina_private *lp, int idx)
+{
+   return lp->rd_dma + (idx * sizeof(struct dma_desc));
+}
+
 static inline void korina_abort_dma(struct net_device *dev,
struct dma_reg *ch)
 {
@@ -179,10 +192,12 @@ static int korina_send_packet(struct sk_buff *skb, struct 
net_device *dev)
u32 length;
u32 chain_prev, chain_next;
struct dma_desc *td;
+   int idx;
 
spin_lock_irqsave(>lock, flags);
 
-   td = >td_ring[lp->tx_chain_tail];
+   idx = lp->tx_chain_tail;
+   td = >td_ring[idx];
 
/* stop queue when full, drop pkts if queue already full */
if (lp->tx_count >= (KORINA_NUM_TDS - 2)) {
@@ -190,26 +205,23 @@ static int korina_send_packet(struct sk_buff *skb, struct 
net_device *dev)
 
if (lp->tx_count == (KORINA_NUM_TDS - 2))
netif_stop_queue(dev);
-   else {
-   dev->stats.tx_dropped++;
-   dev_kfree_skb_any(skb);
-   spin_unlock_irqrestore(>lock, flags);
-
-   return NETDEV_TX_OK;
-   }
+   else
+   goto drop_packet;
}
 
lp->tx_count++;
 
-   lp->tx_skb[lp->tx_chain_tail] = skb;
+   lp->tx_skb[idx] = skb;
 
length = skb->len;
-   dma_cache_wback((u32)skb->data, skb->len);
 
/* Setup the transmit descriptor. */
-   td->ca = CPHYSADDR(skb->data);
-   chain_prev = (lp->tx_chain_tail - 1) & KORINA_TDS_MASK;
-   chain_next = (lp->tx_chain_tail + 1) & KORINA_TDS_MASK;
+   td->ca = dma_map_single(lp->dmadev, skb->data, length, DMA_TO_DEVICE);
+   if (dma_mapping_error(lp->dmadev, td->ca))
+   goto drop_packet;
+
+   chain_prev = (idx - 1) & KORINA_TDS_MASK;
+   chain_next = (idx + 1) & KORINA_TDS_MASK;
 
if (readl(&(lp->tx_dma_regs->dmandptr)) == 0) {
if (lp->tx_chain_status == desc_empty) {
@@ -219,8 +231,8 @@ static int korina_send_packet(struct sk_buff *skb, struct 
net_device *dev)
/* Move tail */
lp->tx_chain_tail = chain_next;
/* Write to NDPTR */
-   writel(CPHYSADDR(>td_ring[lp->tx_chain_head]),
-   >tx_dma_regs->dmandptr);
+   writel(korina_tx_dma(lp, lp->tx_chain_head),
+  >tx_dma_regs->dmandptr);
/* Move head to tail */
lp->tx_chain_head = lp->tx_chain_tail;
} else {
@@ -231,12 +243,12 @@ static int korina_send_packet(struct sk_buff *skb, struct 
net_device *dev)
lp->td_ring[chain_prev].control &=
~DMA_DESC_COF;
/* Link to prev */
-   lp->td_ring[chain_prev].link =  CPHYSADDR(td);
+   lp->td_ring[chain_prev].link = korina_tx_dma(lp, idx);
/* Move tail */
lp->tx_chain_tail = chain_next;
/* Write to NDPTR */
-   writel(CPHYSADDR(>td_ring[lp->tx_chain_head]),
-   &(lp->tx_dma_regs->dmandptr));
+   writel(korina_tx_dma(lp, lp->tx_chain_head),
+  >tx_dma_regs->dmandptr);
/* Move head to tail */
lp->tx_chain_head = lp->tx_chain_tail;
lp->

[PATCH net-next 7/7] net: korina: Make driver COMPILE_TESTable

2021-04-13 Thread Thomas Bogendoerfer
Move structs/defines for ethernet/dma register into driver, since they
are only used for this driver and remove any MIPS specific includes.
This makes it possible to COMPILE_TEST the driver.

Signed-off-by: Thomas Bogendoerfer 
---
 drivers/net/ethernet/Kconfig  |   2 +-
 drivers/net/ethernet/korina.c | 245 --
 2 files changed, 236 insertions(+), 11 deletions(-)

diff --git a/drivers/net/ethernet/Kconfig b/drivers/net/ethernet/Kconfig
index ad04660b97b8..c61368968cee 100644
--- a/drivers/net/ethernet/Kconfig
+++ b/drivers/net/ethernet/Kconfig
@@ -97,7 +97,7 @@ config JME
 
 config KORINA
tristate "Korina (IDT RC32434) Ethernet support"
-   depends on MIKROTIK_RB532
+   depends on MIKROTIK_RB532 || COMPILE_TEST
help
  If you have a Mikrotik RouterBoard 500 or IDT RC32434
  based system say Y. Otherwise say N.
diff --git a/drivers/net/ethernet/korina.c b/drivers/net/ethernet/korina.c
index d7972965eb14..98aa7f007f8e 100644
--- a/drivers/net/ethernet/korina.c
+++ b/drivers/net/ethernet/korina.c
@@ -55,20 +55,244 @@
 #include 
 #include 
 
-#include 
-#include 
-#include 
-#include 
-
-#include 
-#include 
-#include 
-#include 
-
 #define DRV_NAME   "korina"
 #define DRV_VERSION"0.20"
 #define DRV_RELDATE"15Sep2017"
 
+struct eth_regs {
+   u32 ethintfc;
+   u32 ethfifott;
+   u32 etharc;
+   u32 ethhash0;
+   u32 ethhash1;
+   u32 ethu0[4];   /* Reserved. */
+   u32 ethpfs;
+   u32 ethmcp;
+   u32 eth_u1[10]; /* Reserved. */
+   u32 ethspare;
+   u32 eth_u2[42]; /* Reserved. */
+   u32 ethsal0;
+   u32 ethsah0;
+   u32 ethsal1;
+   u32 ethsah1;
+   u32 ethsal2;
+   u32 ethsah2;
+   u32 ethsal3;
+   u32 ethsah3;
+   u32 ethrbc;
+   u32 ethrpc;
+   u32 ethrupc;
+   u32 ethrfc;
+   u32 ethtbc;
+   u32 ethgpf;
+   u32 eth_u9[50]; /* Reserved. */
+   u32 ethmac1;
+   u32 ethmac2;
+   u32 ethipgt;
+   u32 ethipgr;
+   u32 ethclrt;
+   u32 ethmaxf;
+   u32 eth_u10;/* Reserved. */
+   u32 ethmtest;
+   u32 miimcfg;
+   u32 miimcmd;
+   u32 miimaddr;
+   u32 miimwtd;
+   u32 miimrdd;
+   u32 miimind;
+   u32 eth_u11;/* Reserved. */
+   u32 eth_u12;/* Reserved. */
+   u32 ethcfsa0;
+   u32 ethcfsa1;
+   u32 ethcfsa2;
+};
+
+/* Ethernet interrupt registers */
+#define ETH_INT_FC_EN  BIT(0)
+#define ETH_INT_FC_ITS BIT(1)
+#define ETH_INT_FC_RIP BIT(2)
+#define ETH_INT_FC_JAM BIT(3)
+#define ETH_INT_FC_OVR BIT(4)
+#define ETH_INT_FC_UND BIT(5)
+#define ETH_INT_FC_IOC 0x00c0
+
+/* Ethernet FIFO registers */
+#define ETH_FIFI_TT_TTH_BIT0
+#define ETH_FIFO_TT_TTH0x007f
+
+/* Ethernet ARC/multicast registers */
+#define ETH_ARC_PROBIT(0)
+#define ETH_ARC_AM BIT(1)
+#define ETH_ARC_AFMBIT(2)
+#define ETH_ARC_AB BIT(3)
+
+/* Ethernet SAL registers */
+#define ETH_SAL_BYTE_5 0x00ff
+#define ETH_SAL_BYTE_4 0xff00
+#define ETH_SAL_BYTE_3 0x00ff
+#define ETH_SAL_BYTE_2 0xff00
+
+/* Ethernet SAH registers */
+#define ETH_SAH_BYTE1  0x00ff
+#define ETH_SAH_BYTE0  0xff00
+
+/* Ethernet GPF register */
+#define ETH_GPF_PTV0x
+
+/* Ethernet PFG register */
+#define ETH_PFS_PFDBIT(0)
+
+/* Ethernet CFSA[0-3] registers */
+#define ETH_CFSA0_CFSA40x00ff
+#define ETH_CFSA0_CFSA50xff00
+#define ETH_CFSA1_CFSA20x00ff
+#define ETH_CFSA1_CFSA30xff00
+#define ETH_CFSA1_CFSA00x00ff
+#define ETH_CFSA1_CFSA10xff00
+
+/* Ethernet MAC1 registers */
+#define ETH_MAC1_REBIT(0)
+#define ETH_MAC1_PAF   BIT(1)
+#define ETH_MAC1_RFC   BIT(2)
+#define ETH_MAC1_TFC   BIT(3)
+#define ETH_MAC1_LBBIT(4)
+#define ETH_MAC1_MRBIT(31)
+
+/* Ethernet MAC2 registers */
+#define ETH_MAC2_FDBIT(0)
+#define ETH_MAC2_FLC   BIT(1)
+#define ETH_MAC2_HFE   BIT(2)
+#define ETH_MAC2_DCBIT(3)
+#define ETH_MAC2_CEN   BIT(4)
+#define ETH_MAC2_PEBIT(5)
+#define ETH_MAC2_VPE   BIT(6)
+#define ETH_MAC2_APE   BIT(7)
+#define ETH_MAC2_PPE   BIT(8)
+#define ETH_MAC2_LPE   BIT(9)
+#define ETH_MAC2_NBBIT(12)
+#define ETH_MAC2_BPBIT(13)
+#define ETH_MAC2_EDBIT(14)
+
+/* Ethernet IPGT register */
+#define ETH_IPGT   0x007f
+
+/* Ethernet IPGR registers */
+#define ETH_IPGR_IPGR2 0x007f
+#define ETH_IPGR_IPGR1 0x7f00
+
+/* Ethernet CLR

[PATCH net-next 4/7] net: korina: Remove nested helpers

2021-04-13 Thread Thomas Bogendoerfer
Remove helpers, which are only used in one call site.

Signed-off-by: Thomas Bogendoerfer 
---
 drivers/net/ethernet/korina.c | 28 +++-
 1 file changed, 3 insertions(+), 25 deletions(-)

diff --git a/drivers/net/ethernet/korina.c b/drivers/net/ethernet/korina.c
index b6dcbb6d5e05..728c4baa3eee 100644
--- a/drivers/net/ethernet/korina.c
+++ b/drivers/net/ethernet/korina.c
@@ -141,12 +141,6 @@ struct korina_private {
 
 extern unsigned int idt_cpu_freq;
 
-static inline void korina_start_dma(struct dma_reg *ch, u32 dma_addr)
-{
-   writel(0, >dmandptr);
-   writel(dma_addr, >dmadptr);
-}
-
 static inline void korina_abort_dma(struct net_device *dev,
struct dma_reg *ch)
 {
@@ -163,11 +157,6 @@ static inline void korina_abort_dma(struct net_device *dev,
writel(0, >dmandptr);
 }
 
-static inline void korina_chain_dma(struct dma_reg *ch, u32 dma_addr)
-{
-   writel(dma_addr, >dmandptr);
-}
-
 static void korina_abort_tx(struct net_device *dev)
 {
struct korina_private *lp = netdev_priv(dev);
@@ -182,18 +171,6 @@ static void korina_abort_rx(struct net_device *dev)
korina_abort_dma(dev, lp->rx_dma_regs);
 }
 
-static void korina_start_rx(struct korina_private *lp,
-   struct dma_desc *rd)
-{
-   korina_start_dma(lp->rx_dma_regs, CPHYSADDR(rd));
-}
-
-static void korina_chain_rx(struct korina_private *lp,
-   struct dma_desc *rd)
-{
-   korina_chain_dma(lp->rx_dma_regs, CPHYSADDR(rd));
-}
-
 /* transmit packet */
 static int korina_send_packet(struct sk_buff *skb, struct net_device *dev)
 {
@@ -464,7 +441,7 @@ static int korina_rx(struct net_device *dev, int limit)
rd->devcs = 0;
skb = lp->rx_skb[lp->rx_next_done];
rd->ca = CPHYSADDR(skb->data);
-   korina_chain_rx(lp, rd);
+   writel(CPHYSADDR(rd), >rx_dma_regs->dmandptr);
}
 
return count;
@@ -841,7 +818,8 @@ static int korina_init(struct net_device *dev)
 
writel(0, >rx_dma_regs->dmas);
/* Start Rx DMA */
-   korina_start_rx(lp, >rd_ring[0]);
+   writel(0, >rx_dma_regs->dmandptr);
+   writel(CPHYSADDR(>rd_ring[0]), >rx_dma_regs->dmadptr);
 
writel(readl(>tx_dma_regs->dmasm) &
~(DMA_STAT_FINI | DMA_STAT_ERR),
-- 
2.29.2



[PATCH net-next 3/7] net: korina: Remove not needed cache flushes

2021-04-13 Thread Thomas Bogendoerfer
Descriptors are mapped uncached so there is no need to do any cache
handling for them.

Signed-off-by: Thomas Bogendoerfer 
---
 drivers/net/ethernet/korina.c | 6 --
 1 file changed, 6 deletions(-)

diff --git a/drivers/net/ethernet/korina.c b/drivers/net/ethernet/korina.c
index 3a454f6214b0..b6dcbb6d5e05 100644
--- a/drivers/net/ethernet/korina.c
+++ b/drivers/net/ethernet/korina.c
@@ -230,7 +230,6 @@ static int korina_send_packet(struct sk_buff *skb, struct 
net_device *dev)
dma_cache_wback((u32)skb->data, skb->len);
 
/* Setup the transmit descriptor. */
-   dma_cache_inv((u32) td, sizeof(*td));
td->ca = CPHYSADDR(skb->data);
chain_prev = (lp->tx_chain_tail - 1) & KORINA_TDS_MASK;
chain_next = (lp->tx_chain_tail + 1) & KORINA_TDS_MASK;
@@ -283,7 +282,6 @@ static int korina_send_packet(struct sk_buff *skb, struct 
net_device *dev)
lp->tx_chain_tail = chain_next;
}
}
-   dma_cache_wback((u32) td, sizeof(*td));
 
netif_trans_update(dev);
spin_unlock_irqrestore(>lock, flags);
@@ -374,8 +372,6 @@ static int korina_rx(struct net_device *dev, int limit)
u32 devcs, pkt_len, dmas;
int count;
 
-   dma_cache_inv((u32)rd, sizeof(*rd));
-
for (count = 0; count < limit; count++) {
skb = lp->rx_skb[lp->rx_next_done];
skb_new = NULL;
@@ -454,7 +450,6 @@ static int korina_rx(struct net_device *dev, int limit)
~DMA_DESC_COD;
 
lp->rx_next_done = (lp->rx_next_done + 1) & KORINA_RDS_MASK;
-   dma_cache_wback((u32)rd, sizeof(*rd));
rd = >rd_ring[lp->rx_next_done];
writel(~DMA_STAT_DONE, >rx_dma_regs->dmas);
}
@@ -469,7 +464,6 @@ static int korina_rx(struct net_device *dev, int limit)
rd->devcs = 0;
skb = lp->rx_skb[lp->rx_next_done];
rd->ca = CPHYSADDR(skb->data);
-   dma_cache_wback((u32)rd, sizeof(*rd));
korina_chain_rx(lp, rd);
}
 
-- 
2.29.2



[PATCH net-next 2/7] net: korina: Use devres functions

2021-04-13 Thread Thomas Bogendoerfer
Simplify probe/remove code by using devm_ functions.

Signed-off-by: Thomas Bogendoerfer 
---
 drivers/net/ethernet/korina.c | 64 ---
 1 file changed, 21 insertions(+), 43 deletions(-)

diff --git a/drivers/net/ethernet/korina.c b/drivers/net/ethernet/korina.c
index 2266b18c1377..3a454f6214b0 100644
--- a/drivers/net/ethernet/korina.c
+++ b/drivers/net/ethernet/korina.c
@@ -104,9 +104,9 @@ enum chain_status {
 
 /* Information that need to be kept for each board. */
 struct korina_private {
-   struct eth_regs *eth_regs;
-   struct dma_reg *rx_dma_regs;
-   struct dma_reg *tx_dma_regs;
+   struct eth_regs __iomem *eth_regs;
+   struct dma_reg __iomem *rx_dma_regs;
+   struct dma_reg __iomem *tx_dma_regs;
struct dma_desc *td_ring; /* transmit descriptor ring */
struct dma_desc *rd_ring; /* receive descriptor ring  */
 
@@ -1045,10 +1045,10 @@ static int korina_probe(struct platform_device *pdev)
struct korina_device *bif = platform_get_drvdata(pdev);
struct korina_private *lp;
struct net_device *dev;
-   struct resource *r;
+   void __iomem *p;
int rc;
 
-   dev = alloc_etherdev(sizeof(struct korina_private));
+   dev = devm_alloc_etherdev(>dev, sizeof(struct korina_private));
if (!dev)
return -ENOMEM;
 
@@ -1061,36 +1061,30 @@ static int korina_probe(struct platform_device *pdev)
lp->rx_irq = platform_get_irq_byname(pdev, "korina_rx");
lp->tx_irq = platform_get_irq_byname(pdev, "korina_tx");
 
-   r = platform_get_resource_byname(pdev, IORESOURCE_MEM, "korina_regs");
-   dev->base_addr = r->start;
-   lp->eth_regs = ioremap(r->start, resource_size(r));
-   if (!lp->eth_regs) {
+   p = devm_platform_ioremap_resource_byname(pdev, "korina_regs");
+   if (!p) {
printk(KERN_ERR DRV_NAME ": cannot remap registers\n");
-   rc = -ENXIO;
-   goto probe_err_out;
+   return -ENOMEM;
}
+   lp->eth_regs = p;
 
-   r = platform_get_resource_byname(pdev, IORESOURCE_MEM, "korina_dma_rx");
-   lp->rx_dma_regs = ioremap(r->start, resource_size(r));
-   if (!lp->rx_dma_regs) {
+   p = devm_platform_ioremap_resource_byname(pdev, "korina_dma_rx");
+   if (!p) {
printk(KERN_ERR DRV_NAME ": cannot remap Rx DMA registers\n");
-   rc = -ENXIO;
-   goto probe_err_dma_rx;
+   return -ENOMEM;
}
+   lp->rx_dma_regs = p;
 
-   r = platform_get_resource_byname(pdev, IORESOURCE_MEM, "korina_dma_tx");
-   lp->tx_dma_regs = ioremap(r->start, resource_size(r));
-   if (!lp->tx_dma_regs) {
+   p = devm_platform_ioremap_resource_byname(pdev, "korina_dma_tx");
+   if (!p) {
printk(KERN_ERR DRV_NAME ": cannot remap Tx DMA registers\n");
-   rc = -ENXIO;
-   goto probe_err_dma_tx;
+   return -ENOMEM;
}
+   lp->tx_dma_regs = p;
 
lp->td_ring = kmalloc(TD_RING_SIZE + RD_RING_SIZE, GFP_KERNEL);
-   if (!lp->td_ring) {
-   rc = -ENXIO;
-   goto probe_err_td_ring;
-   }
+   if (!lp->td_ring)
+   return -ENOMEM;
 
dma_cache_inv((unsigned long)(lp->td_ring),
TD_RING_SIZE + RD_RING_SIZE);
@@ -1120,7 +1114,8 @@ static int korina_probe(struct platform_device *pdev)
if (rc < 0) {
printk(KERN_ERR DRV_NAME
": cannot register net device: %d\n", rc);
-   goto probe_err_register;
+   kfree((struct dma_desc *)KSEG0ADDR(lp->td_ring));
+   return rc;
}
timer_setup(>media_check_timer, korina_poll_media, 0);
 
@@ -1128,20 +1123,7 @@ static int korina_probe(struct platform_device *pdev)
 
printk(KERN_INFO "%s: " DRV_NAME "-" DRV_VERSION " " DRV_RELDATE "\n",
dev->name);
-out:
return rc;
-
-probe_err_register:
-   kfree((struct dma_desc *)KSEG0ADDR(lp->td_ring));
-probe_err_td_ring:
-   iounmap(lp->tx_dma_regs);
-probe_err_dma_tx:
-   iounmap(lp->rx_dma_regs);
-probe_err_dma_rx:
-   iounmap(lp->eth_regs);
-probe_err_out:
-   free_netdev(dev);
-   goto out;
 }
 
 static int korina_remove(struct platform_device *pdev)
@@ -1149,13 +1131,9 @@ static int korina_remove(struct platform_device *pdev)
struct korina_device *bif = platform_get_drvdata(pdev);
struct korina_private *lp = netdev_priv(bif->dev);
 
-   iounmap(lp->eth_regs);
-   iounmap(lp->rx_dma_regs);
-   iounmap(lp->tx_dma_regs);
kfree((struct dma_desc *)KSEG0ADDR(lp->td_ring));
 
unregister_netdev(bif->dev);
-   free_netdev(bif->dev);
 
return 0;
 }
-- 
2.29.2



[PATCH net-next 1/7] net: korina: Fix MDIO functions

2021-04-13 Thread Thomas Bogendoerfer
Fixed MDIO functions to work reliable and not just by accident.

Signed-off-by: Thomas Bogendoerfer 
---
 drivers/net/ethernet/korina.c | 57 +++
 1 file changed, 38 insertions(+), 19 deletions(-)

diff --git a/drivers/net/ethernet/korina.c b/drivers/net/ethernet/korina.c
index 925161959b9b..2266b18c1377 100644
--- a/drivers/net/ethernet/korina.c
+++ b/drivers/net/ethernet/korina.c
@@ -137,7 +137,6 @@ struct korina_private {
struct mii_if_info mii_if;
struct work_struct restart_task;
struct net_device *dev;
-   int phy_addr;
 };
 
 extern unsigned int idt_cpu_freq;
@@ -292,32 +291,50 @@ static int korina_send_packet(struct sk_buff *skb, struct 
net_device *dev)
return NETDEV_TX_OK;
 }
 
-static int mdio_read(struct net_device *dev, int mii_id, int reg)
+static int korina_mdio_wait(struct korina_private *lp)
+{
+   int timeout = 1000;
+
+   while ((readl(>eth_regs->miimind) & 1) && timeout-- > 0)
+   udelay(1);
+
+   if (timeout <= 0)
+   return -1;
+
+   return 0;
+}
+
+static int korina_mdio_read(struct net_device *dev, int phy, int reg)
 {
struct korina_private *lp = netdev_priv(dev);
int ret;
 
-   mii_id = ((lp->rx_irq == 0x2c ? 1 : 0) << 8);
+   if (korina_mdio_wait(lp))
+   return -1;
 
-   writel(0, >eth_regs->miimcfg);
-   writel(0, >eth_regs->miimcmd);
-   writel(mii_id | reg, >eth_regs->miimaddr);
-   writel(ETH_MII_CMD_SCN, >eth_regs->miimcmd);
+   writel(phy << 8 | reg, >eth_regs->miimaddr);
+   writel(1, >eth_regs->miimcmd);
 
-   ret = (int)(readl(>eth_regs->miimrdd));
+   if (korina_mdio_wait(lp))
+   return -1;
+
+   if (readl(>eth_regs->miimind) & 4)
+   return -1;
+
+   ret = readl(>eth_regs->miimrdd);
+   writel(0, >eth_regs->miimcmd);
return ret;
 }
 
-static void mdio_write(struct net_device *dev, int mii_id, int reg, int val)
+static void korina_mdio_write(struct net_device *dev, int phy, int reg, int 
val)
 {
struct korina_private *lp = netdev_priv(dev);
 
-   mii_id = ((lp->rx_irq == 0x2c ? 1 : 0) << 8);
+   if (korina_mdio_wait(lp))
+   return;
 
-   writel(0, >eth_regs->miimcfg);
-   writel(1, >eth_regs->miimcmd);
-   writel(mii_id | reg, >eth_regs->miimaddr);
-   writel(ETH_MII_CMD_SCN, >eth_regs->miimcmd);
+   writel(0, >eth_regs->miimcmd);
+   writel(phy << 8 | reg, >eth_regs->miimaddr);
writel(val, >eth_regs->miimwtd);
 }
 
@@ -643,7 +660,7 @@ static void korina_check_media(struct net_device *dev, 
unsigned int init_media)
 {
struct korina_private *lp = netdev_priv(dev);
 
-   mii_check_media(>mii_if, 0, init_media);
+   mii_check_media(>mii_if, 1, init_media);
 
if (lp->mii_if.full_duplex)
writel(readl(>eth_regs->ethmac2) | ETH_MAC2_FD,
@@ -869,12 +886,15 @@ static int korina_init(struct net_device *dev)
 * Clock independent setting */
writel(((idt_cpu_freq) / MII_CLOCK + 1) & ~1,
>eth_regs->ethmcp);
+   writel(0, >eth_regs->miimcfg);
 
/* don't transmit until fifo contains 48b */
writel(48, >eth_regs->ethfifott);
 
writel(ETH_MAC1_RE, >eth_regs->ethmac1);
 
+   korina_check_media(dev, 1);
+
napi_enable(>napi);
netif_start_queue(dev);
 
@@ -1089,11 +1109,10 @@ static int korina_probe(struct platform_device *pdev)
dev->watchdog_timeo = TX_TIMEOUT;
netif_napi_add(dev, >napi, korina_poll, NAPI_POLL_WEIGHT);
 
-   lp->phy_addr = (((lp->rx_irq == 0x2c? 1:0) << 8) | 0x05);
lp->mii_if.dev = dev;
-   lp->mii_if.mdio_read = mdio_read;
-   lp->mii_if.mdio_write = mdio_write;
-   lp->mii_if.phy_id = lp->phy_addr;
+   lp->mii_if.mdio_read = korina_mdio_read;
+   lp->mii_if.mdio_write = korina_mdio_write;
+   lp->mii_if.phy_id = 1;
lp->mii_if.phy_id_mask = 0x1f;
lp->mii_if.reg_num_mask = 0x1f;
 
-- 
2.29.2



[PATCH net-next 0/7] net: Korina improvements

2021-04-13 Thread Thomas Bogendoerfer
While converting Mikrotik RB532 support to use device tree I stumbled
over the korina ethernet driver, which used way too many MIPS specific
hacks. This series cleans this all up.

Thomas Bogendoerfer (7):
  net: korina: Fix MDIO functions
  net: korina: Use devres functions
  net: korina: Remove not needed cache flushes
  net: korina: Remove nested helpers
  net: korina: Use DMA API
  net: korina: Only pass mac address via platform data
  net: korina: Make driver COMPILE_TESTable

 arch/mips/rb532/devices.c |   5 +-
 drivers/net/ethernet/Kconfig  |   2 +-
 drivers/net/ethernet/korina.c | 542 --
 3 files changed, 386 insertions(+), 163 deletions(-)

-- 
2.29.2



Re: [PATCH] MIPS: Fix strnlen_user access check

2021-04-13 Thread Thomas Bogendoerfer
On Tue, Apr 13, 2021 at 12:37:25PM +, David Laight wrote:
> From: Thomas Bogendoerfer 
> > Sent: 13 April 2021 12:15
> ...
> > > The __access_ok() is noted with `Ensure that the range [addr, addr+size)
> > > is within the process's address space`. Does the range checked by
> > > __access_ok() on MIPS is [addr, addr+size]. So if we want to use
> > > access_ok(s, 1), should we modify __access_ok()? Or my misunderstanding?
> > 
> > you are right, I'm going to apply
> > 
> > https://patchwork.kernel.org/project/linux-mips/patch/20190209194718.1294-1-paul.bur...@mips.com/
> > 
> > to fix that.
> 
> Isn't that still wrong?
> If an application does:
>   write(fd, (void *)0x, 0);
> it should return 0, not -1 and EFAULT/SIGSEGV.

WRITE(2)   Linux Programmer's Manual  WRITE(2)
[...]
   If  count  is  zero  and  fd refers to a regular file, then write() may
   return a failure status if one of the errors below is detected.  If  no
   errors  are  detected,  or  error detection is not performed, 0 will be
   returned without causing any other effect.  If count  is  zero  and  fd
   refers  to a file other than a regular file, the results are not speci-
   fied.
[...]
   EFAULT buf is outside your accessible address space.

at least it's covered by the man page on my Linux system.

> There is also the question about why this makes any difference
> to the original problem of logging in via the graphical interface.

kernel/module.c:mod->args = strndup_user(uargs, ~0UL >> 1);

and strndup_user does a strnlen_user.

> ISTM that it is very unlikely that the length passed to strnlen_user()
> is long enough to take potential buffer beyond the end of user
> address space.

see above.

Thomas.

-- 
Crap can work. Given enough thrust pigs will fly, but it's not necessarily a
good idea.[ RFC1925, 2.3 ]


Re: [PATCH] MIPS: Fix strnlen_user access check

2021-04-13 Thread Thomas Bogendoerfer
On Tue, Apr 13, 2021 at 09:15:48AM +0800, Jinyang He wrote:
> On 04/12/2021 10:27 PM, Thomas Bogendoerfer wrote:
> > > diff --git a/arch/mips/include/asm/uaccess.h 
> > > b/arch/mips/include/asm/uaccess.h
> > > index 91bc7fb..eafc99b 100644
> > > --- a/arch/mips/include/asm/uaccess.h
> > > +++ b/arch/mips/include/asm/uaccess.h
> > > @@ -630,8 +630,8 @@ static inline long strnlen_user(const char __user *s, 
> > > long n)
> > >   {
> > >  long res;
> > > -   if (!access_ok(s, n))
> > > -   return -0;
> > > +   if (!access_ok(s, 1))
> > > +   return 0;
> > >  might_fault();
> > >  __asm__ __volatile__(
> > that's the fix I'd like to apply. Could someone send it as a formal
> > patch ? Thanks.
> > 
> > Thomas.
> > 
> Hi, Thomas,
> 
> I always think it is better to use access_ok(s, 0) on MIPS. I have been
> curious about the difference between access_ok(s, 0) and access_ok(s, 1)
> until I saw __access_ok() on RISCV at arch/riscv/include/asm/uaccess.h
> 
> The __access_ok() is noted with `Ensure that the range [addr, addr+size)
> is within the process's address space`. Does the range checked by
> __access_ok() on MIPS is [addr, addr+size]. So if we want to use
> access_ok(s, 1), should we modify __access_ok()? Or my misunderstanding?

you are right, I'm going to apply

https://patchwork.kernel.org/project/linux-mips/patch/20190209194718.1294-1-paul.bur...@mips.com/

to fix that.

> More importantly, the implementation of strnlen_user in lib/strnlen_user.c
> is noted `we hit the address space limit, and we still had more characters
> the caller would have wanted. That's 0.` Does it make sense? It is not
> achieved on MIPS when hit __ua_limit, if only access_ok(s, 1) is used.

see the comment in arch/mips/lib/strnlen_user.S

 * Note: for performance reasons we deliberately accept that a user may
 *   make strlen_user and strnlen_user access the first few KSEG0
 *   bytes.  There's nothing secret there.  On 64-bit accessing beyond
 *   the maximum is a tad hairier ...

for 32bit kernels strnlen_user could possibly access KSEG0 and will find
a 0 sooner or later. I don't see much problems there. For 64bit kernels
strnlen_user will stop inside user space as there will be nothing
mapped after __UA_LIMIT.

Thomas.

-- 
Crap can work. Given enough thrust pigs will fly, but it's not necessarily a
good idea.[ RFC1925, 2.3 ]


Re: [PATCH -next] MIPS: Alchemy: Use DEFINE_SPINLOCK() for spinlock

2021-04-12 Thread Thomas Bogendoerfer
On Sat, Mar 27, 2021 at 05:52:25PM +0800, Chen Lifu wrote:
> From: Lifu Chen 
> 
> spinlock can be initialized automatically with DEFINE_SPINLOCK()
> rather than explicitly calling spin_lock_init().
> 
> Reported-by: Hulk Robot 
> Signed-off-by: Lifu Chen 
> ---
>  arch/mips/alchemy/common/clock.c | 3 +--
>  1 file changed, 1 insertion(+), 2 deletions(-)

applied to mips-next.

Thomas.

-- 
Crap can work. Given enough thrust pigs will fly, but it's not necessarily a
good idea.[ RFC1925, 2.3 ]


Re: [PATCH] MIPS: generic: Update node names to avoid unit addresses

2021-04-12 Thread Thomas Bogendoerfer
On Fri, Apr 09, 2021 at 12:21:28PM -0700, Nathan Chancellor wrote:
> With the latest mkimage from U-Boot 2021.04, the generic defconfigs no
> longer build, failing with:
> 
> /usr/bin/mkimage: verify_header failed for FIT Image support with exit code 1
> 
> This is expected after the linked U-Boot commits because '@' is
> forbidden in the node names due to the way that libfdt treats nodes with
> the same prefix but different unit addresses.
> 
> Switch the '@' in the node name to '-'. Drop the unit addresses from the
> hash and kernel child nodes because there is only one node so they do
> not need to have a number to differentiate them.
> 
> Cc: sta...@vger.kernel.org
> Link: 
> https://source.denx.de/u-boot/u-boot/-/commit/79af75f7776fc20b0d7eb6afe1e27c00fdb4b9b4
> Link: 
> https://source.denx.de/u-boot/u-boot/-/commit/3f04db891a353f4b127ed57279279f851c6b4917
> Suggested-by: Simon Glass 
> Signed-off-by: Nathan Chancellor 
> ---
>  arch/mips/generic/board-boston.its.S   | 10 +-
>  arch/mips/generic/board-jaguar2.its.S  | 16 
>  arch/mips/generic/board-luton.its.S|  8 
>  arch/mips/generic/board-ni169445.its.S | 10 +-
>  arch/mips/generic/board-ocelot.its.S   | 20 ++--
>  arch/mips/generic/board-serval.its.S   |  8 
>  arch/mips/generic/board-xilfpga.its.S  | 10 +-
>  arch/mips/generic/vmlinux.its.S| 10 +-
>  8 files changed, 46 insertions(+), 46 deletions(-)

applied to mips-next.

Thomas.

-- 
Crap can work. Given enough thrust pigs will fly, but it's not necessarily a
good idea.[ RFC1925, 2.3 ]


Re: [PATCH v3] MIPS: add support for buggy MT7621S core detection

2021-04-12 Thread Thomas Bogendoerfer
On Wed, Apr 07, 2021 at 01:07:38PM -0700, Ilya Lipnitskiy wrote:
> Most MT7621 SoCs have 2 cores, which is detected and supported properly
> by CPS.
> 
> Unfortunately, MT7621 SoC has a less common S variant with only one core.
> On MT7621S, GCR_CONFIG still reports 2 cores, which leads to hangs when
> starting SMP. CPULAUNCH registers can be used in that case to detect the
> absence of the second core and override the GCR_CONFIG PCORES field.
> 
> Rework a long-standing OpenWrt patch to override the value of
> mips_cps_numcores on single-core MT7621 systems.
> 
> Tested on a dual-core MT7621 device (Ubiquiti ER-X) and a single-core
> MT7621 device (Netgear R6220).
> 
> Original 4.14 OpenWrt patch:
> Link: 
> https://git.openwrt.org/?p=openwrt/openwrt.git;a=commitdiff;h=4cdbc90a376dd0555201c1434a2081e055e9ceb7
> Current 5.10 OpenWrt patch:
> Link: 
> https://git.openwrt.org/?p=openwrt/openwrt.git;a=blob;f=target/linux/ramips/patches-5.10/320-mt7621-core-detect-hack.patch;h=c63f0f4c1ec742e24d8480e80553863744b58f6a;hb=10267e17299806f9885d086147878f6c492cb904
> 
> Suggested-by: Felix Fietkau 
> Signed-off-by: Ilya Lipnitskiy 
> ---
>  arch/mips/include/asm/mips-cps.h | 23 ++-
>  1 file changed, 22 insertions(+), 1 deletion(-)

applied to mips-next.

Thomas.

-- 
Crap can work. Given enough thrust pigs will fly, but it's not necessarily a
good idea.[ RFC1925, 2.3 ]


Re: [PATCH] MIPS: uaccess: Reduce number of nested macros

2021-04-12 Thread Thomas Bogendoerfer
On Thu, Apr 08, 2021 at 08:14:37PM +0200, Thomas Bogendoerfer wrote:
> Clean up macros even further after removal get_fs/set_fs.
> 
> Signed-off-by: Thomas Bogendoerfer 
> ---
>  arch/mips/include/asm/uaccess.h | 157 +++-
>  1 file changed, 71 insertions(+), 86 deletions(-)

applied to mips-next.

Thomas.

-- 
Crap can work. Given enough thrust pigs will fly, but it's not necessarily a
good idea.[ RFC1925, 2.3 ]


Re: [PATCH] MIPS: Fix strnlen_user access check

2021-04-12 Thread Thomas Bogendoerfer
On Mon, Apr 12, 2021 at 11:02:19AM +0800, Tiezhu Yang wrote:
> On 04/11/2021 07:04 PM, Jinyang He wrote:
> > Commit 04324f44cb69 ("MIPS: Remove get_fs/set_fs") brought a problem for
> > strnlen_user(). Jump out when checking access_ok() with condition that
> > (s + strlen(s)) < __UA_LIMIT <= (s + n). The old __strnlen_user_asm()
> > just checked (ua_limit & s) without checking (ua_limit & (s + n)).
> > Therefore, find strlen form s to __UA_LIMIT - 1 in that condition.
> > 
> > Signed-off-by: Jinyang He 
> > ---
> >   arch/mips/include/asm/uaccess.h | 11 +--
> >   1 file changed, 9 insertions(+), 2 deletions(-)
> > 
> > diff --git a/arch/mips/include/asm/uaccess.h 
> > b/arch/mips/include/asm/uaccess.h
> > index 91bc7fb..85ba0c8 100644
> > --- a/arch/mips/include/asm/uaccess.h
> > +++ b/arch/mips/include/asm/uaccess.h
> > @@ -630,8 +630,15 @@ static inline long strnlen_user(const char __user *s, 
> > long n)
> >   {
> > long res;
> > -   if (!access_ok(s, n))
> > -   return -0;
> > +   if (unlikely(n <= 0))
> > +   return 0;
> > +
> > +   if (!access_ok(s, n)) {
> > +   if (!access_ok(s, 0))
> > +   return 0;
> > +
> > +   n = __UA_LIMIT - (unsigned long)s - 1;
> > +   }
> > might_fault();
> > __asm__ __volatile__(
> 
> The following simple changes are OK to fix this issue?
> 
> diff --git a/arch/mips/include/asm/uaccess.h b/arch/mips/include/asm/uaccess.h
> index 91bc7fb..eafc99b 100644
> --- a/arch/mips/include/asm/uaccess.h
> +++ b/arch/mips/include/asm/uaccess.h
> @@ -630,8 +630,8 @@ static inline long strnlen_user(const char __user *s, 
> long n)
>  {
> long res;
> -   if (!access_ok(s, n))
> -   return -0;
> +   if (!access_ok(s, 1))
> +   return 0;
> might_fault();
> __asm__ __volatile__(

that's the fix I'd like to apply. Could someone send it as a formal
patch ? Thanks.

Thomas.

-- 
Crap can work. Given enough thrust pigs will fly, but it's not necessarily a
good idea.[ RFC1925, 2.3 ]


Re: [PATCH v2 1/1] kernel.h: Split out panic and oops helpers

2021-04-09 Thread Thomas Bogendoerfer
On Fri, Apr 09, 2021 at 01:02:50PM +0300, Andy Shevchenko wrote:
> kernel.h is being used as a dump for all kinds of stuff for a long time.
> Here is the attempt to start cleaning it up by splitting out panic and
> oops helpers.
> 
> There are several purposes of doing this:
> - dropping dependency in bug.h
> - dropping a loop by moving out panic_notifier.h
> - unload kernel.h from something which has its own domain
> 
> At the same time convert users tree-wide to use new headers, although
> for the time being include new header back to kernel.h to avoid twisted
> indirected includes for existing users.
> 
> Signed-off-by: Andy Shevchenko 
> Reviewed-by: Bjorn Andersson 
> Acked-by: Mike Rapoport 
> Acked-by: Corey Minyard 
> Acked-by: Christian Brauner 
> Acked-by: Arnd Bergmann 
> Acked-by: Kees Cook 
> Acked-by: Wei Liu 
> Acked-by: Rasmus Villemoes 
> Signed-off-by: Andrew Morton 
> ---
> v2:
>  - fixed all errors with allmodconfig on x86_64 (Andrew)
>  - checked with allyesconfig on x86_64
>  - additionally grepped source code for panic notifier list usage
>and converted all users
>  - elaborated commit message (Luis)
>  - collected given tags (incl. Andrew's SoB, see below)
> 
> I added Andrew's SoB since part of the fixes I took from him. Andrew,
> feel free to amend or tell me how you want me to do.
> 
>  arch/mips/kernel/relocate.c   |  1 +
>  arch/mips/sgi-ip22/ip22-reset.c   |  1 +
>  arch/mips/sgi-ip32/ip32-reset.c   |  1 +

Acked-by: Thomas Bogendoerfer 

-- 
Crap can work. Given enough thrust pigs will fly, but it's not necessarily a
good idea.[ RFC1925, 2.3 ]


Re: build failure of malta_qemu_32r6_defconfig

2021-04-09 Thread Thomas Bogendoerfer
On Thu, Apr 08, 2021 at 09:42:11AM +0800, YunQiang Su wrote:
> Sudip Mukherjee  于2021年4月8日周四 上午2:26写道:
> >
> > Hi Thomas,
> >
> > I was building v5.10.28 with malta_qemu_32r6_defconfig and noticed that
> > it fails to build, so tried next-20210407 to see if it has been fixed.
> > But linux-next also has the issue with gcc-10.
> >
> > The error is:
> >
> > ./arch/mips/include/asm/vdso/gettimeofday.h: In function 
> > '__vdso_clock_gettime':
> > ./arch/mips/include/asm/vdso/gettimeofday.h:103:2: error: the register 'lo' 
> > cannot be clobbered in 'asm' for the current target
> >   103 |  asm volatile(
> >   |  ^~~
> 
> this operation try to save lo and hi register, while they are not
> exisiting on r6.
> We are working on figure out a patch for it.

looks like there is already a patch in patchwork, which just needs
a workup:

https://patchwork.kernel.org/project/linux-mips/patch/20200801154401.4177009-1-romain.na...@gmail.com/

Thomas.

-- 
Crap can work. Given enough thrust pigs will fly, but it's not necessarily a
good idea.[ RFC1925, 2.3 ]


Re: [PATCH] MIPS: octeon: Add __raw_copy_[from|to|in]_user symbols

2021-04-09 Thread Thomas Bogendoerfer
On Fri, Apr 09, 2021 at 11:42:46AM +0300, Sergei Shtylyov wrote:
> Hello!
> 
> On 09.04.2021 0:48, Thomas Bogendoerfer wrote:
> 
> > Cavium Octeon has it's own memcpy implementation and also need the change
> 
>Its. :-)

applied (with typo fixed) to mips-next.

Thomas.

-- 
Crap can work. Given enough thrust pigs will fly, but it's not necessarily a
good idea.[ RFC1925, 2.3 ]


[PATCH] MIPS: octeon: Add __raw_copy_[from|to|in]_user symbols

2021-04-08 Thread Thomas Bogendoerfer
Cavium Octeon has it's own memcpy implementation and also need the change
done in commit 04324f44cb69 ("MIPS: Remove get_fs/set_fs").

Fixes: 04324f44cb69 ("MIPS: Remove get_fs/set_fs")
Reported-by: kernel test robot 
Signed-off-by: Thomas Bogendoerfer 
---
 arch/mips/cavium-octeon/octeon-memcpy.S | 8 ++--
 1 file changed, 6 insertions(+), 2 deletions(-)

diff --git a/arch/mips/cavium-octeon/octeon-memcpy.S 
b/arch/mips/cavium-octeon/octeon-memcpy.S
index 0a7c9834b81c..600d018cf354 100644
--- a/arch/mips/cavium-octeon/octeon-memcpy.S
+++ b/arch/mips/cavium-octeon/octeon-memcpy.S
@@ -150,8 +150,12 @@ LEAF(memcpy)   /* 
a0=dst a1=src a2=len */
 EXPORT_SYMBOL(memcpy)
movev0, dst /* return value */
 __memcpy:
-FEXPORT(__copy_user)
-EXPORT_SYMBOL(__copy_user)
+FEXPORT(__raw_copy_from_user)
+EXPORT_SYMBOL(__raw_copy_from_user)
+FEXPORT(__raw_copy_to_user)
+EXPORT_SYMBOL(__raw_copy_to_user)
+FEXPORT(__raw_copy_in_user)
+EXPORT_SYMBOL(__raw_copy_in_user)
/*
 * Note: dst & src may be unaligned, len may be 0
 * Temps
-- 
2.29.2



Re: [PATCH] MIPS: uaccess: Reduce number of nested macros

2021-04-08 Thread Thomas Bogendoerfer
On Thu, Apr 08, 2021 at 09:46:11PM +0200, Christoph Hellwig wrote:
> > +#define put_user(x, ptr)   \
> > +({ \
> > +   __typeof__(*(ptr)) __user *__p = (ptr); \
> > +   \
> > +   might_fault();  \
> > +   access_ok(__p, sizeof(*__p)) ?  \
> > +   __put_user((x), __p) :  \
> > +   -EFAULT;\
> 
> Why not merge this into a single line, which seems a little more
> readable:
> 
>   access_ok(__p, sizeof(*__p)) ? __put_user((x), __p) : -EFAULT;  \

I just copied the riscv version ;-) I'll make it one line before applying.

Thomas.

-- 
Crap can work. Given enough thrust pigs will fly, but it's not necessarily a
good idea.[ RFC1925, 2.3 ]


[PATCH] MIPS: uaccess: Reduce number of nested macros

2021-04-08 Thread Thomas Bogendoerfer
Clean up macros even further after removal get_fs/set_fs.

Signed-off-by: Thomas Bogendoerfer 
---
 arch/mips/include/asm/uaccess.h | 157 +++-
 1 file changed, 71 insertions(+), 86 deletions(-)

diff --git a/arch/mips/include/asm/uaccess.h b/arch/mips/include/asm/uaccess.h
index 91bc7fb7dca1..e0dedd47e4e6 100644
--- a/arch/mips/include/asm/uaccess.h
+++ b/arch/mips/include/asm/uaccess.h
@@ -102,8 +102,15 @@ static inline int __access_ok(const void __user *p, 
unsigned long size)
  *
  * Returns zero on success, or -EFAULT on error.
  */
-#define put_user(x,ptr) \
-   __put_user_check((x), (ptr), sizeof(*(ptr)))
+#define put_user(x, ptr)   \
+({ \
+   __typeof__(*(ptr)) __user *__p = (ptr); \
+   \
+   might_fault();  \
+   access_ok(__p, sizeof(*__p)) ?  \
+   __put_user((x), __p) :  \
+   -EFAULT;\
+})
 
 /*
  * get_user: - Get a simple variable from user space.
@@ -123,8 +130,15 @@ static inline int __access_ok(const void __user *p, 
unsigned long size)
  * Returns zero on success, or -EFAULT on error.
  * On error, the variable @x is set to zero.
  */
-#define get_user(x,ptr) \
-   __get_user_check((x), (ptr), sizeof(*(ptr)))
+#define get_user(x, ptr)   \
+({ \
+   const __typeof__(*(ptr)) __user *__p = (ptr);   \
+   \
+   might_fault();  \
+   access_ok(__p, sizeof(*__p)) ?  \
+   __get_user((x), __p) :  \
+   ((x) = 0, -EFAULT); \
+})
 
 /*
  * __put_user: - Write a simple value into user space, with less checking.
@@ -146,8 +160,32 @@ static inline int __access_ok(const void __user *p, 
unsigned long size)
  *
  * Returns zero on success, or -EFAULT on error.
  */
-#define __put_user(x,ptr) \
-   __put_user_nocheck((x), (ptr), sizeof(*(ptr)))
+#define __put_user(x, ptr) \
+({ \
+   __typeof__(*(ptr)) __user *__pu_ptr = (ptr);\
+   __typeof__(*(ptr)) __pu_val = (x);  \
+   int __pu_err = 0;   \
+   \
+   __chk_user_ptr(__pu_ptr);   \
+   switch (sizeof(*__pu_ptr)) {\
+   case 1: \
+   __put_data_asm(user_sb, __pu_ptr);  \
+   break;  \
+   case 2: \
+   __put_data_asm(user_sh, __pu_ptr);  \
+   break;  \
+   case 4: \
+   __put_data_asm(user_sw, __pu_ptr);  \
+   break;  \
+   case 8: \
+   __PUT_DW(user_sd, __pu_ptr);\
+   break;  \
+   default:\
+   BUILD_BUG();\
+   }   \
+   \
+   __pu_err;   \
+})
 
 /*
  * __get_user: - Get a simple variable from user space, with less checking.
@@ -170,8 +208,31 @@ static inline int __access_ok(const void __user *p, 
unsigned long size)
  * Returns zero on success, or -EFAULT on error.
  * On error, the variable @x is set to zero.
  */
-#define __get_user(x,ptr) \
-   __get_user_nocheck((x), (ptr), sizeof(*(ptr)))
+#define __get_user(x, ptr) \
+({ \
+   const __typeof__(*(ptr)) __user *__gu_ptr = (ptr);  \
+   int __gu_err = 0

Re: [PATCH] MIPS: Fix new sparse warning

2021-04-08 Thread Thomas Bogendoerfer
On Wed, Apr 07, 2021 at 01:03:48AM +0200, Thomas Bogendoerfer wrote:
> Commit 45deb5faeb9e ("MIPS: uaccess: Remove get_fs/set_fs call sites")
> caused a few new sparse warning, fix them.
> 
> Signed-off-by: Thomas Bogendoerfer 
> ---
>  arch/mips/kernel/access-helper.h | 7 ---
>  arch/mips/kernel/unaligned.c | 6 +++---
>  2 files changed, 7 insertions(+), 6 deletions(-)

applied to mips-next.

Thomas.

-- 
Crap can work. Given enough thrust pigs will fly, but it's not necessarily a
good idea.[ RFC1925, 2.3 ]


[PATCH] MIPS: Fix new sparse warning

2021-04-06 Thread Thomas Bogendoerfer
Commit 45deb5faeb9e ("MIPS: uaccess: Remove get_fs/set_fs call sites")
caused a few new sparse warning, fix them.

Signed-off-by: Thomas Bogendoerfer 
---
 arch/mips/kernel/access-helper.h | 7 ---
 arch/mips/kernel/unaligned.c | 6 +++---
 2 files changed, 7 insertions(+), 6 deletions(-)

diff --git a/arch/mips/kernel/access-helper.h b/arch/mips/kernel/access-helper.h
index dd5b502813b8..590388031503 100644
--- a/arch/mips/kernel/access-helper.h
+++ b/arch/mips/kernel/access-helper.h
@@ -4,15 +4,16 @@
 
 static inline int __get_addr(unsigned long *a, unsigned long *p, bool user)
 {
-   return user ? get_user(*a, p) : get_kernel_nofault(*a, p);
+   return user ? get_user(*a, (unsigned long __user *)p) :
+ get_kernel_nofault(*a, p);
 }
 
 static inline int __get_inst16(u16 *i, u16 *p, bool user)
 {
-   return user ? get_user(*i, p) : get_kernel_nofault(*i, p);
+   return user ? get_user(*i, (u16 __user *)p) : get_kernel_nofault(*i, p);
 }
 
 static inline int __get_inst32(u32 *i, u32 *p, bool user)
 {
-   return user ? get_user(*i, p) : get_kernel_nofault(*i, p);
+   return user ? get_user(*i, (u32 __user *)p) : get_kernel_nofault(*i, p);
 }
diff --git a/arch/mips/kernel/unaligned.c b/arch/mips/kernel/unaligned.c
index 1f3b20a8c377..df4b708c04a9 100644
--- a/arch/mips/kernel/unaligned.c
+++ b/arch/mips/kernel/unaligned.c
@@ -109,7 +109,7 @@ static u32 unaligned_action;
 extern void show_registers(struct pt_regs *regs);
 
 static void emulate_load_store_insn(struct pt_regs *regs,
-   void __user *addr, unsigned int __user *pc)
+   void __user *addr, unsigned int *pc)
 {
unsigned long origpc, orig31, value;
union mips_instruction insn;
@@ -1475,7 +1475,7 @@ static void emulate_load_store_MIPS16e(struct pt_regs 
*regs, void __user * addr)
 asmlinkage void do_ade(struct pt_regs *regs)
 {
enum ctx_state prev_state;
-   unsigned int __user *pc;
+   unsigned int *pc;
 
prev_state = exception_enter();
perf_sw_event(PERF_COUNT_SW_ALIGNMENT_FAULTS,
@@ -1526,7 +1526,7 @@ asmlinkage void do_ade(struct pt_regs *regs)
 
if (unaligned_action == UNALIGNED_ACTION_SHOW)
show_registers(regs);
-   pc = (unsigned int __user *)exception_epc(regs);
+   pc = (unsigned int *)exception_epc(regs);
 
emulate_load_store_insn(regs, (void __user *)regs->cp0_badvaddr, pc);
 
-- 
2.29.2



Re: [PATCH v4] MIPS: Add support for CONFIG_DEBUG_VIRTUAL

2021-04-06 Thread Thomas Bogendoerfer
On Tue, Mar 30, 2021 at 08:22:07PM -0700, Florian Fainelli wrote:
> Provide hooks to intercept bad usages of virt_to_phys() and
> __pa_symbol() throughout the kernel. To make this possible, we need to
> rename the current implement of virt_to_phys() into
> __virt_to_phys_nodebug() and wrap it around depending on
> CONFIG_DEBUG_VIRTUAL.
> 
> A similar thing is needed for __pa_symbol() which is now aliased to
> __phys_addr_symbol() whose implementation is either the direct return of
> RELOC_HIDE or goes through the debug version.
> 
> Signed-off-by: Florian Fainelli 
> ---
> Changes in v4:
> 
> - properly address sparse warning in arch/mips/kernel/vdso.c and
>   eliminate it entirely
> 
> Changes in v3:
> 
> - added missing SDPX license tag in physaddr.c
> 
> Changes in v2:
> - fixed sparse warning in arch/mips/kernel/vdso.c
> 
>  arch/mips/Kconfig|  1 +
>  arch/mips/include/asm/io.h   | 14 -
>  arch/mips/include/asm/page.h |  9 +-
>  arch/mips/kernel/vdso.c  |  5 ++--
>  arch/mips/mm/Makefile|  2 ++
>  arch/mips/mm/physaddr.c  | 56 
>  6 files changed, 83 insertions(+), 4 deletions(-)
>  create mode 100644 arch/mips/mm/physaddr.c

applied to mips-next.

Thomas.

-- 
Crap can work. Given enough thrust pigs will fly, but it's not necessarily a
good idea.[ RFC1925, 2.3 ]


Re: [PATCH v2 0/6] mips: bmips: fix and improve reboot nodes

2021-04-06 Thread Thomas Bogendoerfer
On Sun, Mar 14, 2021 at 05:43:45PM +0100, Álvaro Fernández Rojas wrote:
> These patches improve bmips bcm63xx device tree nodes.
> 
> v2: add missing BCM63268 patch.
> 
> Álvaro Fernández Rojas (6):
>   mips: bmips: fix syscon-reboot nodes
>   mips: bmips: bcm6328: populate device tree nodes
>   mips: bmips: bcm6358: populate device tree nodes
>   mips: bmips: bcm6362: populate device tree nodes
>   mips: bmips: bcm6368: populate device tree nodes
>   mips: bmips: bcm63268: populate device tree nodes
> 
>  arch/mips/boot/dts/brcm/bcm3368.dtsi  |   2 +-
>  arch/mips/boot/dts/brcm/bcm63268.dtsi | 132 +++---
>  arch/mips/boot/dts/brcm/bcm6328.dtsi  | 119 ---
>  arch/mips/boot/dts/brcm/bcm6358.dtsi  |  85 ++---
>  arch/mips/boot/dts/brcm/bcm6362.dtsi  | 129 ++---
>  arch/mips/boot/dts/brcm/bcm6368.dtsi  | 129 ++---
>  6 files changed, 530 insertions(+), 66 deletions(-)

series applied to mips-next.

Thomas.

-- 
Crap can work. Given enough thrust pigs will fly, but it's not necessarily a
good idea.[ RFC1925, 2.3 ]


Re: [PATCH v3 0/4] MIPS: Remove get_fs/set_fs

2021-04-06 Thread Thomas Bogendoerfer
On Thu, Apr 01, 2021 at 02:56:33PM +0200, Thomas Bogendoerfer wrote:
> This series replaces get_fs/set_fs and removes it from MIPS arch code.
> 
> Changes in v3:
> - use get_user/get_kernel_nofault for helper functions
> 
> Changes in v2:
> - added copy_from_kernel_nofault_allowed() for !EVA to restrict
>   access of __get/__put_kernel_nofault
> - replaced __get_data macro by helper functions
> - removed leftover set_fs calls in ftrace.c
> - further cleanup uaccess.h
> 
> Thomas Bogendoerfer (4):
>   MIPS: kernel: Remove not needed set_fs calls
>   MIPS: uaccess: Added __get/__put_kernel_nofault
>   MIPS: uaccess: Remove get_fs/set_fs call sites
>   MIPS: Remove get_fs/set_fs
> 
>  arch/mips/Kconfig   |   1 -
>  arch/mips/include/asm/processor.h   |   4 -
>  arch/mips/include/asm/thread_info.h |   6 -
>  arch/mips/include/asm/uaccess.h | 436 +++-
>  arch/mips/kernel/access-helper.h|  18 ++
>  arch/mips/kernel/asm-offsets.c  |   1 -
>  arch/mips/kernel/ftrace.c   |   8 -
>  arch/mips/kernel/process.c  |   2 -
>  arch/mips/kernel/scall32-o32.S  |   4 +-
>  arch/mips/kernel/traps.c| 105 +++
>  arch/mips/kernel/unaligned.c| 199 +
>  arch/mips/lib/memcpy.S  |  28 +-
>  arch/mips/lib/memset.S  |   3 -
>  arch/mips/lib/strncpy_user.S|  48 +--
>  arch/mips/lib/strnlen_user.S|  44 +--
>  arch/mips/mm/Makefile   |   4 +
>  arch/mips/mm/maccess.c  |  10 +
>  17 files changed, 357 insertions(+), 564 deletions(-)
>  create mode 100644 arch/mips/kernel/access-helper.h
>  create mode 100644 arch/mips/mm/maccess.c

series applied to mips-next.

Thomas.

-- 
Crap can work. Given enough thrust pigs will fly, but it's not necessarily a
good idea.[ RFC1925, 2.3 ]


Re: [PATCH] MIPS: fix memory reservation for non-usermem setups

2021-04-06 Thread Thomas Bogendoerfer
On Sat, Apr 03, 2021 at 07:02:13PM -0700, Ilya Lipnitskiy wrote:
> Hi Mike,
> 
> On Tue, Mar 16, 2021 at 11:33 PM Mike Rapoport  wrote:
> >
> > Hi Ilya,
> >
> > On Tue, Mar 16, 2021 at 10:10:09PM -0700, Ilya Lipnitskiy wrote:
> > > Hi Thomas,
> > >
> > > On Fri, Mar 12, 2021 at 7:19 AM Thomas Bogendoerfer
> > >  wrote:
> > > >
> > > > On Sun, Mar 07, 2021 at 11:40:30AM -0800, Ilya Lipnitskiy wrote:
> > > > > From: Tobias Wolf 
> > > > >
> > > > > Commit 67a3ba25aa95 ("MIPS: Fix incorrect mem=X@Y handling") 
> > > > > introduced a new
> > > > > issue for rt288x where "PHYS_OFFSET" is 0x0 but the calculated 
> > > > > "ramstart" is
> > > > > not. As the prerequisite of custom memory map has been removed, this 
> > > > > results
> > > > > in the full memory range of 0x0 - 0x800 to be marked as reserved 
> > > > > for this
> > > > > platform.
> > > >
> > > > and where is the problem here ?
> > > Turns out this was already attempted to be upstreamed - not clear why
> > > it wasn't merged. Context:
> > > https://lore.kernel.org/linux-mips/6504517.U6H5IhoIOn@loki/
> > >
> > > I hope the thread above helps you understand the problem.
> >
> > The memory initialization was a bit different then. Do you still see the
> > same problem?
> Thanks for asking. I obtained a RT2880 device and gave it a try. It
> hangs at boot without this patch, however selecting

can you provide debug logs with memblock=debug for both good and bad
kernels ? I'm curious what's the reason for failing allocation...

Thomas.

-- 
Crap can work. Given enough thrust pigs will fly, but it's not necessarily a
good idea.[ RFC1925, 2.3 ]


Re: [PATCH v3 0/4] MIPS: Remove get_fs/set_fs

2021-04-06 Thread Thomas Bogendoerfer
On Tue, Apr 06, 2021 at 09:24:43AM +0200, Christoph Hellwig wrote:
> Btw, there is a bunch of cleanups that would fit in nicely on top of
> this:
> 
>  - remove the unused __invoke_copy_from function

I've removed in the last patch before applying to mips-next.

>  - fold __get_user_check into get_user as it is the only caller
>  - fold __get_user_nocheck into __get_user as it is the only caller
>  - fold __put_user_check into put_user as it is the only caller
>  - fold __put_user_nocheck into __put_user as it is the only caller
>  - implement get_user in terms of __get_user to document the difference
>better and to remove __get_user_common
>  - implement put_user in terms of __put_user to document the difference
>better and to remove __get_user_common
>  - remove __put_user_unknown/__get_user_unknown and replace them with
>BUILD_BUG_ON()

I'll prepare a follow-up patch. Thank you for your cleanup hints.

Thomas.

-- 
Crap can work. Given enough thrust pigs will fly, but it's not necessarily a
good idea.[ RFC1925, 2.3 ]


Re: [PATCH RFC] MIPS: Loongson64: Use _CACHE_UNCACHED instead of _CACHE_UNCACHED_ACCELERATED

2021-04-06 Thread Thomas Bogendoerfer
On Tue, Apr 06, 2021 at 05:25:12PM +0800, Tiezhu Yang wrote:
> Loongson64 processors have a writecombine issue that maybe failed to
> write back framebuffer used with ATI Radeon or AMD GPU at times, after
> commit 8a08e50cee66 ("drm: Permit video-buffers writecombine mapping
> for MIPS"), there exists some errors such as blurred screen and lockup,
> and so on.
> 
> [   60.958721] radeon :03:00.0: ring 0 stalled for more than 10079msec
> [   60.965315] radeon :03:00.0: GPU lockup (current fence id 
> 0x0112 last fence id 0x011d on ring 0)
> [   60.976525] radeon :03:00.0: ring 3 stalled for more than 10086msec
> [   60.983156] radeon :03:00.0: GPU lockup (current fence id 
> 0x0374 last fence id 0x03a8 on ring 3)
> 
> As discussed earlier [1], it might be better to disable writecombine
> on the CPU detection side because the root cause is unknown now.
> 
> Actually, this patch is a temporary solution to just make it work well,
> it is not a proper and final solution, I hope someone will have a better
> solution to fix this issue in the future.
> 
> [1] https://lore.kernel.org/patchwork/patch/1285542/
> 
> Signed-off-by: Tiezhu Yang 
> ---
> 
> Hi Thomas,
> 
> If you are OK with this change, could you please apply it
> to mips-next? Then, no need to do this change manually every
> time when update the mainline kernel.

looks good to me, applied to mips-next.

Thomas.

-- 
Crap can work. Given enough thrust pigs will fly, but it's not necessarily a
good idea.[ RFC1925, 2.3 ]


Re: [PATCH] MIPS: ralink: rt288x: select MIPS_AUTO_PFN_OFFSET

2021-04-06 Thread Thomas Bogendoerfer
On Sat, Apr 03, 2021 at 07:11:26PM -0700, Ilya Lipnitskiy wrote:
> RT288X systems may have a non-zero ramstart causing problems with memory
> reservations and boot hangs, as well as messages like:
>   Wasting 1048576 bytes for tracking 32768 unused pages
> 
> Both are alleviated by selecting MIPS_AUTO_PFN_OFFSET for such
> platforms.
> 
> Tested on a Belkin F5D8235 v1 RT2880 device.
> 
> Link: 
> https://lore.kernel.org/linux-mips/20180820233111.xww5232dxbuouf4n@pburton-laptop/
> 
> Signed-off-by: Ilya Lipnitskiy 
> Cc: Mike Rapoport 
> ---
>  arch/mips/ralink/Kconfig | 1 +
>  1 file changed, 1 insertion(+)

applied to mips-next.

Thomas.

-- 
Crap can work. Given enough thrust pigs will fly, but it's not necessarily a
good idea.[ RFC1925, 2.3 ]


Re: [PATCH 6/9] mips: netlogic: Use irq_domain_simple_ops for XLP PIC

2021-04-06 Thread Thomas Bogendoerfer
On Tue, Apr 06, 2021 at 10:35:54AM +0100, Marc Zyngier wrote:
> Use the generic irq_domain_simple_ops structure instead of
> a home-grown one.
> 
> Signed-off-by: Marc Zyngier 
> ---
>  arch/mips/netlogic/common/irq.c | 6 +-
>  1 file changed, 1 insertion(+), 5 deletions(-)

Acked-by: Thomas Bogendoerfer 

-- 
Crap can work. Given enough thrust pigs will fly, but it's not necessarily a
good idea.[ RFC1925, 2.3 ]


  1   2   3   4   5   6   7   8   9   10   >