Commit cbd19d09 authored by Jakub Kicinski's avatar Jakub Kicinski

Merge branch 'IXP4xx-networking-cleanups'

Linus Walleij says:

====================
IXP4xx networking cleanups

This is a patch series which jams together Arnds and mine
cleanups for the IXP4xx networking.

I also have patches for device tree support but that
requires more elaborate work, this series is some of
mine and some of Arnds patches that is a good foundation
for his multiplatform work and my device tree work.

These are for application to the networking tree so
that can be taken in one separate sweep.

I have tested the patches for a bit using zeroday builds
and some boots on misc IXP4xx devices and haven't run
into any major problems. We might find some new stuff
as a result from the new compiler coverage.

I had to depromote enabling compiler coverage at one
point in the v2 set because it depended on other patches
making the code more generic.

The change in v3 was simply dropping one offending
patch hardcoding base addresses into the driver.

The change in v4 drops a stable@ tag that was
unnecessary.

This v5 is a rebase of the v4 patch set on top of
net-next.
====================
Signed-off-by: default avatarJakub Kicinski <kuba@kernel.org>
parents a442c2c3 e45d0fad
......@@ -132,6 +132,22 @@ static struct platform_device fsg_leds = {
};
/* Built-in 10/100 Ethernet MAC interfaces */
static struct resource fsg_eth_npeb_resources[] = {
{
.start = IXP4XX_EthB_BASE_PHYS,
.end = IXP4XX_EthB_BASE_PHYS + 0x0fff,
.flags = IORESOURCE_MEM,
},
};
static struct resource fsg_eth_npec_resources[] = {
{
.start = IXP4XX_EthC_BASE_PHYS,
.end = IXP4XX_EthC_BASE_PHYS + 0x0fff,
.flags = IORESOURCE_MEM,
},
};
static struct eth_plat_info fsg_plat_eth[] = {
{
.phy = 5,
......@@ -151,12 +167,16 @@ static struct platform_device fsg_eth[] = {
.dev = {
.platform_data = fsg_plat_eth,
},
.num_resources = ARRAY_SIZE(fsg_eth_npeb_resources),
.resource = fsg_eth_npeb_resources,
}, {
.name = "ixp4xx_eth",
.id = IXP4XX_ETH_NPEC,
.dev = {
.platform_data = fsg_plat_eth + 1,
},
.num_resources = ARRAY_SIZE(fsg_eth_npec_resources),
.resource = fsg_eth_npec_resources,
}
};
......
......@@ -11,6 +11,7 @@
#include <linux/irq.h>
#include <linux/kernel.h>
#include <linux/pci.h>
#include <linux/platform_data/wan_ixp4xx_hss.h>
#include <linux/serial_8250.h>
#include <asm/mach-types.h>
#include <asm/mach/arch.h>
......@@ -272,6 +273,22 @@ static struct platform_device device_uarts = {
/* Built-in 10/100 Ethernet MAC interfaces */
static struct resource eth_npeb_resources[] = {
{
.start = IXP4XX_EthB_BASE_PHYS,
.end = IXP4XX_EthB_BASE_PHYS + 0x0fff,
.flags = IORESOURCE_MEM,
},
};
static struct resource eth_npec_resources[] = {
{
.start = IXP4XX_EthC_BASE_PHYS,
.end = IXP4XX_EthC_BASE_PHYS + 0x0fff,
.flags = IORESOURCE_MEM,
},
};
static struct eth_plat_info eth_plat[] = {
{
.phy = 0,
......@@ -289,10 +306,14 @@ static struct platform_device device_eth_tab[] = {
.name = "ixp4xx_eth",
.id = IXP4XX_ETH_NPEB,
.dev.platform_data = eth_plat,
.num_resources = ARRAY_SIZE(eth_npeb_resources),
.resource = eth_npeb_resources,
}, {
.name = "ixp4xx_eth",
.id = IXP4XX_ETH_NPEC,
.dev.platform_data = eth_plat + 1,
.num_resources = ARRAY_SIZE(eth_npec_resources),
.resource = eth_npec_resources,
}
};
......@@ -405,6 +426,9 @@ static void __init gmlr_init(void)
if (hw_bits & CFG_HW_HAS_HSS1)
device_tab[devices++] = &device_hss_tab[1]; /* max index 5 */
hss_plat[0].timer_freq = ixp4xx_timer_freq;
hss_plat[1].timer_freq = ixp4xx_timer_freq;
gpio_request(GPIO_SCL, "SCL/clock");
gpio_request(GPIO_SDA, "SDA/data");
gpio_request(GPIO_STR, "strobe");
......
......@@ -15,6 +15,7 @@
#ifndef __ASSEMBLY__
#include <linux/reboot.h>
#include <linux/platform_data/eth_ixp4xx.h>
#include <asm/types.h>
......@@ -92,27 +93,6 @@ struct ixp4xx_pata_data {
void __iomem *cs1;
};
#define IXP4XX_ETH_NPEA 0x00
#define IXP4XX_ETH_NPEB 0x10
#define IXP4XX_ETH_NPEC 0x20
/* Information about built-in Ethernet MAC interfaces */
struct eth_plat_info {
u8 phy; /* MII PHY ID, 0 - 31 */
u8 rxq; /* configurable, currently 0 - 31 only */
u8 txreadyq;
u8 hwaddr[6];
};
/* Information about built-in HSS (synchronous serial) interfaces */
struct hss_plat_info {
int (*set_clock)(int port, unsigned int clock_type);
int (*open)(int port, void *pdev,
void (*set_carrier_cb)(void *pdev, int carrier));
void (*close)(int port, void *pdev);
u8 txreadyq;
};
/*
* Frequency of clock used for primary clocksource
*/
......
......@@ -187,6 +187,22 @@ static struct platform_device ixdp425_uart = {
};
/* Built-in 10/100 Ethernet MAC interfaces */
static struct resource ixp425_npeb_resources[] = {
{
.start = IXP4XX_EthB_BASE_PHYS,
.end = IXP4XX_EthB_BASE_PHYS + 0x0fff,
.flags = IORESOURCE_MEM,
},
};
static struct resource ixp425_npec_resources[] = {
{
.start = IXP4XX_EthC_BASE_PHYS,
.end = IXP4XX_EthC_BASE_PHYS + 0x0fff,
.flags = IORESOURCE_MEM,
},
};
static struct eth_plat_info ixdp425_plat_eth[] = {
{
.phy = 0,
......@@ -204,10 +220,14 @@ static struct platform_device ixdp425_eth[] = {
.name = "ixp4xx_eth",
.id = IXP4XX_ETH_NPEB,
.dev.platform_data = ixdp425_plat_eth,
.num_resources = ARRAY_SIZE(ixp425_npeb_resources),
.resource = ixp425_npeb_resources,
}, {
.name = "ixp4xx_eth",
.id = IXP4XX_ETH_NPEC,
.dev.platform_data = ixdp425_plat_eth + 1,
.num_resources = ARRAY_SIZE(ixp425_npec_resources),
.resource = ixp425_npec_resources,
}
};
......
......@@ -165,6 +165,14 @@ static struct platform_device nas100d_uart = {
};
/* Built-in 10/100 Ethernet MAC interfaces */
static struct resource nas100d_eth_resources[] = {
{
.start = IXP4XX_EthB_BASE_PHYS,
.end = IXP4XX_EthB_BASE_PHYS + 0x0fff,
.flags = IORESOURCE_MEM,
},
};
static struct eth_plat_info nas100d_plat_eth[] = {
{
.phy = 0,
......@@ -178,6 +186,8 @@ static struct platform_device nas100d_eth[] = {
.name = "ixp4xx_eth",
.id = IXP4XX_ETH_NPEB,
.dev.platform_data = nas100d_plat_eth,
.num_resources = ARRAY_SIZE(nas100d_eth_resources),
.resource = nas100d_eth_resources,
}
};
......
......@@ -185,6 +185,14 @@ static struct platform_device nslu2_uart = {
};
/* Built-in 10/100 Ethernet MAC interfaces */
static struct resource nslu2_eth_resources[] = {
{
.start = IXP4XX_EthB_BASE_PHYS,
.end = IXP4XX_EthB_BASE_PHYS + 0x0fff,
.flags = IORESOURCE_MEM,
},
};
static struct eth_plat_info nslu2_plat_eth[] = {
{
.phy = 1,
......@@ -198,6 +206,8 @@ static struct platform_device nslu2_eth[] = {
.name = "ixp4xx_eth",
.id = IXP4XX_ETH_NPEB,
.dev.platform_data = nslu2_plat_eth,
.num_resources = ARRAY_SIZE(nslu2_eth_resources),
.resource = nslu2_eth_resources,
}
};
......
......@@ -170,6 +170,22 @@ static struct platform_device mic256_leds = {
};
/* Built-in 10/100 Ethernet MAC interfaces */
static struct resource ixp425_npeb_resources[] = {
{
.start = IXP4XX_EthB_BASE_PHYS,
.end = IXP4XX_EthB_BASE_PHYS + 0x0fff,
.flags = IORESOURCE_MEM,
},
};
static struct resource ixp425_npec_resources[] = {
{
.start = IXP4XX_EthC_BASE_PHYS,
.end = IXP4XX_EthC_BASE_PHYS + 0x0fff,
.flags = IORESOURCE_MEM,
},
};
static struct eth_plat_info ixdp425_plat_eth[] = {
{
.phy = 0,
......@@ -187,10 +203,14 @@ static struct platform_device ixdp425_eth[] = {
.name = "ixp4xx_eth",
.id = IXP4XX_ETH_NPEB,
.dev.platform_data = ixdp425_plat_eth,
.num_resources = ARRAY_SIZE(ixp425_npeb_resources),
.resource = ixp425_npeb_resources,
}, {
.name = "ixp4xx_eth",
.id = IXP4XX_ETH_NPEC,
.dev.platform_data = ixdp425_plat_eth + 1,
.num_resources = ARRAY_SIZE(ixp425_npec_resources),
.resource = ixp425_npec_resources,
},
};
......
......@@ -124,6 +124,22 @@ static struct platform_device vulcan_uart = {
.num_resources = ARRAY_SIZE(vulcan_uart_resources),
};
static struct resource vulcan_npeb_resources[] = {
{
.start = IXP4XX_EthB_BASE_PHYS,
.end = IXP4XX_EthB_BASE_PHYS + 0x0fff,
.flags = IORESOURCE_MEM,
},
};
static struct resource vulcan_npec_resources[] = {
{
.start = IXP4XX_EthC_BASE_PHYS,
.end = IXP4XX_EthC_BASE_PHYS + 0x0fff,
.flags = IORESOURCE_MEM,
},
};
static struct eth_plat_info vulcan_plat_eth[] = {
[0] = {
.phy = 0,
......@@ -144,6 +160,8 @@ static struct platform_device vulcan_eth[] = {
.dev = {
.platform_data = &vulcan_plat_eth[0],
},
.num_resources = ARRAY_SIZE(vulcan_npeb_resources),
.resource = vulcan_npeb_resources,
},
[1] = {
.name = "ixp4xx_eth",
......@@ -151,6 +169,8 @@ static struct platform_device vulcan_eth[] = {
.dev = {
.platform_data = &vulcan_plat_eth[1],
},
.num_resources = ARRAY_SIZE(vulcan_npec_resources),
.resource = vulcan_npec_resources,
},
};
......
......@@ -27,4 +27,18 @@ config IXP4XX_ETH
Say Y here if you want to use built-in Ethernet ports
on IXP4xx processor.
config PTP_1588_CLOCK_IXP46X
tristate "Intel IXP46x as PTP clock"
depends on IXP4XX_ETH
depends on PTP_1588_CLOCK
default y
help
This driver adds support for using the IXP46X as a PTP
clock. This clock is only useful if your PTP programs are
getting hardware time stamps on the PTP Ethernet packets
using the SO_TIMESTAMPING API.
To compile this driver as a module, choose M here: the module
will be called ptp_ixp46x.
endif # NET_VENDOR_XSCALE
......@@ -4,3 +4,4 @@
#
obj-$(CONFIG_IXP4XX_ETH) += ixp4xx_eth.o
obj-$(CONFIG_PTP_1588_CLOCK_IXP46X) += ptp_ixp46x.o
This diff is collapsed.
......@@ -15,7 +15,8 @@
#include <linux/module.h>
#include <linux/ptp_clock_kernel.h>
#include <mach/ixp46x_ts.h>
#include "ixp46x_ts.h"
#define DRIVER "ptp_ixp46x"
#define N_EXT_TS 2
......
......@@ -315,7 +315,8 @@ config DSCC4_PCI_RST
config IXP4XX_HSS
tristate "Intel IXP4xx HSS (synchronous serial port) support"
depends on HDLC && ARM && ARCH_IXP4XX && IXP4XX_NPE && IXP4XX_QMGR
depends on HDLC && IXP4XX_NPE && IXP4XX_QMGR
depends on ARCH_IXP4XX
help
Say Y here if you want to use built-in HSS ports
on IXP4xx processor.
......
......@@ -17,6 +17,7 @@
#include <linux/io.h>
#include <linux/kernel.h>
#include <linux/platform_device.h>
#include <linux/platform_data/wan_ixp4xx_hss.h>
#include <linux/poll.h>
#include <linux/slab.h>
#include <linux/soc/ixp4xx/npe.h>
......@@ -258,7 +259,7 @@ struct port {
struct hss_plat_info *plat;
buffer_t *rx_buff_tab[RX_DESCS], *tx_buff_tab[TX_DESCS];
struct desc *desc_tab; /* coherent */
u32 desc_tab_phys;
dma_addr_t desc_tab_phys;
unsigned int id;
unsigned int clock_type, clock_rate, loopback;
unsigned int initialized, carrier;
......@@ -858,7 +859,7 @@ static int hss_hdlc_xmit(struct sk_buff *skb, struct net_device *dev)
dev->stats.tx_dropped++;
return NETDEV_TX_OK;
}
memcpy_swab32(mem, (u32 *)((int)skb->data & ~3), bytes / 4);
memcpy_swab32(mem, (u32 *)((uintptr_t)skb->data & ~3), bytes / 4);
dev_kfree_skb(skb);
#endif
......@@ -1182,14 +1183,14 @@ static int hss_hdlc_attach(struct net_device *dev, unsigned short encoding,
}
}
static u32 check_clock(u32 rate, u32 a, u32 b, u32 c,
static u32 check_clock(u32 timer_freq, u32 rate, u32 a, u32 b, u32 c,
u32 *best, u32 *best_diff, u32 *reg)
{
/* a is 10-bit, b is 10-bit, c is 12-bit */
u64 new_rate;
u32 new_diff;
new_rate = ixp4xx_timer_freq * (u64)(c + 1);
new_rate = timer_freq * (u64)(c + 1);
do_div(new_rate, a * (c + 1) + b + 1);
new_diff = abs((u32)new_rate - rate);
......@@ -1201,40 +1202,43 @@ static u32 check_clock(u32 rate, u32 a, u32 b, u32 c,
return new_diff;
}
static void find_best_clock(u32 rate, u32 *best, u32 *reg)
static void find_best_clock(u32 timer_freq, u32 rate, u32 *best, u32 *reg)
{
u32 a, b, diff = 0xFFFFFFFF;
a = ixp4xx_timer_freq / rate;
a = timer_freq / rate;
if (a > 0x3FF) { /* 10-bit value - we can go as slow as ca. 65 kb/s */
check_clock(rate, 0x3FF, 1, 1, best, &diff, reg);
check_clock(timer_freq, rate, 0x3FF, 1, 1, best, &diff, reg);
return;
}
if (a == 0) { /* > 66.666 MHz */
a = 1; /* minimum divider is 1 (a = 0, b = 1, c = 1) */
rate = ixp4xx_timer_freq;
rate = timer_freq;
}
if (rate * a == ixp4xx_timer_freq) { /* don't divide by 0 later */
check_clock(rate, a - 1, 1, 1, best, &diff, reg);
if (rate * a == timer_freq) { /* don't divide by 0 later */
check_clock(timer_freq, rate, a - 1, 1, 1, best, &diff, reg);
return;
}
for (b = 0; b < 0x400; b++) {
u64 c = (b + 1) * (u64)rate;
do_div(c, ixp4xx_timer_freq - rate * a);
do_div(c, timer_freq - rate * a);
c--;
if (c >= 0xFFF) { /* 12-bit - no need to check more 'b's */
if (b == 0 && /* also try a bit higher rate */
!check_clock(rate, a - 1, 1, 1, best, &diff, reg))
!check_clock(timer_freq, rate, a - 1, 1, 1, best,
&diff, reg))
return;
check_clock(rate, a, b, 0xFFF, best, &diff, reg);
check_clock(timer_freq, rate, a, b, 0xFFF, best,
&diff, reg);
return;
}
if (!check_clock(rate, a, b, c, best, &diff, reg))
if (!check_clock(timer_freq, rate, a, b, c, best, &diff, reg))
return;
if (!check_clock(rate, a, b, c + 1, best, &diff, reg))
if (!check_clock(timer_freq, rate, a, b, c + 1, best, &diff,
reg))
return;
}
}
......@@ -1285,8 +1289,9 @@ static int hss_hdlc_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd)
port->clock_type = clk; /* Update settings */
if (clk == CLOCK_INT)
find_best_clock(new_line.clock_rate, &port->clock_rate,
&port->clock_reg);
find_best_clock(port->plat->timer_freq,
new_line.clock_rate,
&port->clock_rate, &port->clock_reg);
else {
port->clock_rate = 0;
port->clock_reg = CLK42X_SPEED_2048KHZ;
......
......@@ -56,20 +56,6 @@ config PTP_1588_CLOCK_QORIQ
To compile this driver as a module, choose M here: the module
will be called ptp-qoriq.
config PTP_1588_CLOCK_IXP46X
tristate "Intel IXP46x as PTP clock"
depends on IXP4XX_ETH
depends on PTP_1588_CLOCK
default y
help
This driver adds support for using the IXP46X as a PTP
clock. This clock is only useful if your PTP programs are
getting hardware time stamps on the PTP Ethernet packets
using the SO_TIMESTAMPING API.
To compile this driver as a module, choose M here: the module
will be called ptp_ixp46x.
comment "Enable PHYLIB and NETWORK_PHY_TIMESTAMPING to see the additional clocks."
depends on PHYLIB=n || NETWORK_PHY_TIMESTAMPING=n
......
......@@ -7,7 +7,6 @@ ptp-y := ptp_clock.o ptp_chardev.o ptp_sysfs.o
obj-$(CONFIG_PTP_1588_CLOCK) += ptp.o
obj-$(CONFIG_PTP_1588_CLOCK_DTE) += ptp_dte.o
obj-$(CONFIG_PTP_1588_CLOCK_INES) += ptp_ines.o
obj-$(CONFIG_PTP_1588_CLOCK_IXP46X) += ptp_ixp46x.o
obj-$(CONFIG_PTP_1588_CLOCK_PCH) += ptp_pch.o
obj-$(CONFIG_PTP_1588_CLOCK_KVM) += ptp_kvm.o
obj-$(CONFIG_PTP_1588_CLOCK_QORIQ) += ptp-qoriq.o
......
/* SPDX-License-Identifier: GPL-2.0 */
#ifndef __PLATFORM_DATA_ETH_IXP4XX
#define __PLATFORM_DATA_ETH_IXP4XX
#include <linux/types.h>
#define IXP4XX_ETH_NPEA 0x00
#define IXP4XX_ETH_NPEB 0x10
#define IXP4XX_ETH_NPEC 0x20
/* Information about built-in Ethernet MAC interfaces */
struct eth_plat_info {
u8 phy; /* MII PHY ID, 0 - 31 */
u8 rxq; /* configurable, currently 0 - 31 only */
u8 txreadyq;
u8 hwaddr[6];
};
#endif
/* SPDX-License-Identifier: GPL-2.0 */
#ifndef __PLATFORM_DATA_WAN_IXP4XX_HSS_H
#define __PLATFORM_DATA_WAN_IXP4XX_HSS_H
#include <linux/types.h>
/* Information about built-in HSS (synchronous serial) interfaces */
struct hss_plat_info {
int (*set_clock)(int port, unsigned int clock_type);
int (*open)(int port, void *pdev,
void (*set_carrier_cb)(void *pdev, int carrier));
void (*close)(int port, void *pdev);
u8 txreadyq;
u32 timer_freq;
};
#endif
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment