* Re: [PATCH net-next] net: remove unnecessary return's
From: Stephen Hemminger @ 2014-02-13 16:02 UTC (permalink / raw)
To: Joe Perches; +Cc: David Miller, netdev, Julia Lawall
In-Reply-To: <1392273125.2214.25.camel@joe-AO722>
On Wed, 12 Feb 2014 22:32:05 -0800
Joe Perches <joe@perches.com> wrote:
> On Wed, 2014-02-12 at 20:51 -0800, Stephen Hemminger wrote:
> > One of my pet coding style peeves is the practice of
> > adding extra return; at the end of function.
> > Kill several instances of this in network code.
> > I suppose some coccinelle wizardy could do this automatically.
>
> Maybe, but grep version 2.5.4 will show most of them.
>
> $ grep-2.5.4 -rP --include=*.[ch] "return;\n}" *
> [...]
>
> Fixing them has to make sure that there's no
> label before the close brace.
>
> gcc has to have a statement before the close brace
> of a void return after a label.
>
> label:
> }
>
> must be:
>
> label:
> ;
> }
>
> to compile.
>
My method was to use:
find . -name '*.c' | xargs grep -Pzo '(?s)^(\s*)\Nreturn;.}'
Then ignore cases where it was done for final label and where return
was alone in stub function.
^ permalink raw reply
* Re: [PATCH 08/14] net: axienet: Removed checkpatch errors/warnings
From: Joe Perches @ 2014-02-13 15:51 UTC (permalink / raw)
To: Michal Simek
Cc: netdev, Srikanth Thokala, Srikanth Thokala, Michal Simek,
Anirudha Sarangi, John Linn, linux-arm-kernel, linux-kernel
In-Reply-To: <ff5b1f6a-a6a7-405c-9e83-59ad33852b93@TX2EHSMHS044.ehs.local>
On Thu, 2014-02-13 at 08:19 +0100, Michal Simek wrote:
> On 02/13/2014 01:31 AM, Joe Perches wrote:
> > On Wed, 2014-02-12 at 16:55 +0100, Michal Simek wrote:
Hi again Michal.
> >> + netdev_warn(lp->ndev,
> >> + "Could not find clock ethernet controller property.");
> >
> > here too. (and alignment)
>
> This is problematic. I would like to keep 80 char limits and keeping
> this align just break it. That's why I was using tab alignment.
> Probably the solution is just to shorten message.
(overly long, tiresomely trivial stuff below)
Your choice. I'm not an 80 column zealot but
please don't shorten the message just to fit
80 columns if it impacts intelligibility.
Generally, I'd write this something like:
netdev_warn(lp->ndev,
"Could not find clock ethernet controller property\n");
(without the period) which is 83 columns.
checkpatch makes exceptions for 80 column line
length maximums for format strings.
I've no real issue if you indent it back one.
fyi: this is 77 columns
netdev_warn(lp->ndev,
"No clock ethernet controller property found\n");
About the message itself.
You dropped the "axienet_mdio_setup" function name.
I believe the dmesg output will look something like:
xilinx_temac 0000:01:00.0 (unregistered net_device): Could not find clock ethernet controller property.
xilinx_temac 0000:01:00.0 (unregistered net_device): Setting MDIO clock divisor to default 29
Because these 2 messages are effectively linked,
my preference would be to emit them on a single line,
Something like:
xilinx_temac 0000:01:00.0 (unregistered net_device): of_get_property("clock-frequency") not found - setting MDIO clock divisor to default 29
or
netdev_warn(lp->ndev,
"of_get_property(\"clock-frequency\") not found - setting MDIO clock divisor to default %u\n",
DEFAULT_CLOCK_DIVISOR);
^ permalink raw reply
* Re: RFC: bridge get fdb by bridge device
From: Jamal Hadi Salim @ 2014-02-13 15:37 UTC (permalink / raw)
To: John Fastabend
Cc: vyasevic, netdev@vger.kernel.org, Stephen Hemminger,
Scott Feldman
In-Reply-To: <52FBC282.6020301@intel.com>
On 02/12/14 13:50, John Fastabend wrote:
> On 2/11/2014 1:04 PM, Jamal Hadi Salim wrote:
>
> Because it is not the same type of object as the software bridge.
> Most notably it doesn't do learning.
This kept nagging at me.
Learning is optional for a bridge. So is flooding.
I think we got this right in recent kernels.
cheers,
jamal
^ permalink raw reply
* Re: [PATCH next resend] tcp: use zero-window when free_space is low
From: Florian Westphal @ 2014-02-13 15:34 UTC (permalink / raw)
To: Eric Dumazet; +Cc: Florian Westphal, netdev, Neal Cardwell, Yuchung Cheng
In-Reply-To: <1392303499.1752.19.camel@edumazet-glaptop2.roam.corp.google.com>
Eric Dumazet <eric.dumazet@gmail.com> wrote:
> Do we have one SNMP counter tracking number of time we took the decision
> to send a 0 window ?
No.
> Would you mind waiting we run our packetdrill tests before acknowledging
> this patch, because I suspect this might have some impact ?
Of course not. I am very happy that you folks have these kinds of tests
and are willing to double-check. Take all time you need, there is no
need to haste.
Many Thanks Eric.
Do you think it makes sense to add counters for this?
The caveat is that decision to send 0 window doesn't mean we end
up sending one, since we cannot shrink already offered window.
static u16 tcp_select_window(struct sock *sk)
{
struct tcp_sock *tp = tcp_sk(sk);
u32 cur_win = tcp_receive_window(tp);
u32 new_win = __tcp_select_window(sk);
/* Never shrink the offered window */
if (new_win < cur_win) {
Would you add SNMP counter for '__tcp_select_window() wants 0 window'
or for 'tcp_select_window() does pick 0 window' ?
[ or even different counters for both ? ]
Cheers,
Florian
^ permalink raw reply
* RE: [PATCH net,v3] hyperv: Fix the carrier status setting
From: Haiyang Zhang @ 2014-02-13 15:04 UTC (permalink / raw)
To: Jason Wang, davem@davemloft.net, netdev@vger.kernel.org
Cc: driverdev-devel@linuxdriverproject.org, olaf@aepfle.de,
linux-kernel@vger.kernel.org
In-Reply-To: <52FC4147.7060803@redhat.com>
> -----Original Message-----
> From: Jason Wang [mailto:jasowang@redhat.com]
> Sent: Wednesday, February 12, 2014 10:52 PM
> To: Haiyang Zhang; davem@davemloft.net; netdev@vger.kernel.org
> Cc: KY Srinivasan; olaf@aepfle.de; linux-kernel@vger.kernel.org; driverdev-
> devel@linuxdriverproject.org
> Subject: Re: [PATCH net,v3] hyperv: Fix the carrier status setting
>
> On 02/13/2014 08:54 AM, Haiyang Zhang wrote:
> > Without this patch, the "cat /sys/class/net/ethN/operstate" shows
> > "unknown", and "ethtool ethN" shows "Link detected: yes", when VM
> > boots up with or without vNIC connected.
> >
> > This patch fixed the problem.
> >
> > Signed-off-by: Haiyang Zhang <haiyangz@microsoft.com>
> > Reviewed-by: K. Y. Srinivasan <kys@microsoft.com>
> > ---
> > drivers/net/hyperv/netvsc_drv.c | 53
> ++++++++++++++++++++++++++++-----------
> > 1 files changed, 38 insertions(+), 15 deletions(-)
> >
> > diff --git a/drivers/net/hyperv/netvsc_drv.c
> > b/drivers/net/hyperv/netvsc_drv.c index 7756118..7141a19 100644
> > --- a/drivers/net/hyperv/netvsc_drv.c
> > +++ b/drivers/net/hyperv/netvsc_drv.c
> > @@ -88,8 +88,12 @@ static int netvsc_open(struct net_device *net) {
> > struct net_device_context *net_device_ctx = netdev_priv(net);
> > struct hv_device *device_obj = net_device_ctx->device_ctx;
> > + struct netvsc_device *nvdev;
> > + struct rndis_device *rdev;
> > int ret = 0;
> >
> > + netif_carrier_off(net);
> > +
> > /* Open up the device */
> > ret = rndis_filter_open(device_obj);
> > if (ret != 0) {
> > @@ -99,6 +103,11 @@ static int netvsc_open(struct net_device *net)
> >
> > netif_start_queue(net);
> >
> > + nvdev = hv_get_drvdata(device_obj);
> > + rdev = nvdev->extension;
> > + if (!rdev->link_state)
> > + netif_carrier_on(net);
> > +
>
> Maybe you can just schedule the work here and then you can drop the
> rtnl_lock in netvsc_link_change() ?
The rtnl_lock will still be necessary in the netvsc_link_change(), because
we want to prevent it getting wrong rdev pointer when netvsc_change_mtu
is removing/adding rndis device.
> > +
> > + if (notify)
> > + netdev_notify_peers(net);
> > }
> >
>
> Looks like this forces arp_notify here. Is it expected?
Yes, this is expected. It's required after live migration.
Thanks,
- Haiyang
^ permalink raw reply
* Re: [PATCH next resend] tcp: use zero-window when free_space is low
From: Eric Dumazet @ 2014-02-13 14:58 UTC (permalink / raw)
To: Florian Westphal; +Cc: netdev, Neal Cardwell, Yuchung Cheng
In-Reply-To: <1392292350-28800-1-git-send-email-fw@strlen.de>
On Thu, 2014-02-13 at 12:52 +0100, Florian Westphal wrote:
> Currently the kernel tries to announce a zero window when free_space
> is below the current receiver mss estimate.
>
> When a sender is transmitting small packets and reader consumes data
> slowly (or not at all), receiver might be unable to shrink the receive
> win because
>
> a) we cannot withdraw already-commited receive window, and,
> b) we have to round the current rwin up to a multiple of the wscale
> factor, else we would shrink the current window.
>
> This causes the receive buffer to fill up until the rmem limit is hit.
> When this happens, we start dropping packets.
>
> Moreover, tcp_clamp_window may continue to grow sk_rcvbuf towards rmem[2]
> even if socket is not being read from.
>
> As we cannot avoid the "current_win is rounded up to multiple of mss"
> issue [we would violate a) above] at least try to prevent the receive buf
> growth towards tcp_rmem[2] limit by attempting to move to zero-window
> announcement when free_space becomes less than 1/16 of the current
> allowed receive buffer maximum. If tcp_rmem[2] is large, this will
> increase our chances to get a zero-window announcement out in time.
>
> Reproducer:
> On server:
> $ nc -l -p 12345
> <suspend it: CTRL-Z>
>
> Client:
> #!/usr/bin/env python
> import socket
> import time
>
> sock = socket.socket()
> sock.setsockopt(socket.IPPROTO_TCP, socket.TCP_NODELAY, 1)
> sock.connect(("192.168.4.1", 12345));
> while True:
> sock.send('A' * 23)
> time.sleep(0.005)
>
>
> socket buffer on server-side will grow until tcp_rmem[2] is hit,
> at which point the client rexmits data until -EDTIMEOUT:
>
> tcp_data_queue invokes tcp_try_rmem_schedule which will call
> tcp_prune_queue which calls tcp_clamp_window(). And that function will
> grow sk->sk_rcvbuf up until it eventually hits tcp_rmem[2].
>
> Cc: Neal Cardwell <ncardwell@google.com>
> Cc: Eric Dumazet <eric.dumazet@gmail.com>
> Cc: Yuchung Cheng <ycheng@google.com>
> Signed-off-by: Florian Westphal <fw@strlen.de>
> ---
> V1 of this patch was deferred, resending to get discussion going again.
> Changes since v1:
> - add reproducer to commit message
>
> Unfortunately I couldn't come up with something that has no magic
> ('allowed >> 4') value. I chose >>4 (1/16th) because it didn't cause
> tput limitations in my 'full-mss-sized, steady state' netcat tests.
>
> Maybe someone has better idea?
Thanks a lot Florian looking at this.
Do we have one SNMP counter tracking number of time we took the decision
to send a 0 window ?
Would you mind waiting we run our packetdrill tests before acknowledging
this patch, because I suspect this might have some impact ?
Thanks !
^ permalink raw reply
* [PATCH v3 1/3] net:phy:dp83640: Program pulsewidth2 values of perout triggers 0 and 1
From: Stefan Sørensen @ 2014-02-13 14:35 UTC (permalink / raw)
To: richardcochran, grant.likely, robh+dt, mark.rutland, devicetree,
linux-kernel, netdev
Cc: Stefan Sørensen
In-Reply-To: <1392302129-24947-1-git-send-email-stefan.sorensen@spectralink.com>
Periodic output triggers 0 and 1 of the dp83640 has a programmable
duty-cycle which is controlled by the Pulsewidth2 field of the trigger
data register. This field is not documented in the datasheet, but it
is described in the "PHYTER Software Development Guide" section
3.1.4.1. Failing to set the field can result in unstable/no trigger
output.
This patch add programming of the Pulsewidth2 field, setting it to the
same value as the Pulsewidth field for a 50% duty cycle.
Signed-off-by: Stefan Sørensen <stefan.sorensen@spectralink.com>
---
drivers/net/phy/dp83640.c | 5 +++++
1 file changed, 5 insertions(+)
diff --git a/drivers/net/phy/dp83640.c b/drivers/net/phy/dp83640.c
index 5ff221d..a370814 100644
--- a/drivers/net/phy/dp83640.c
+++ b/drivers/net/phy/dp83640.c
@@ -312,6 +312,11 @@ static void periodic_output(struct dp83640_clock *clock,
ext_write(0, phydev, PAGE4, PTP_TDR, sec >> 16); /* sec[31:16] */
ext_write(0, phydev, PAGE4, PTP_TDR, period & 0xffff); /* ns[15:0] */
ext_write(0, phydev, PAGE4, PTP_TDR, period >> 16); /* ns[31:16] */
+ /* Triggers 0 and 1 has programmable pulsewidth2 */
+ if (trigger == 0 || trigger == 1) {
+ ext_write(0, phydev, PAGE4, PTP_TDR, period & 0xffff);
+ ext_write(0, phydev, PAGE4, PTP_TDR, period >> 16);
+ }
/*enable trigger*/
val &= ~TRIG_LOAD;
--
1.8.5.3
^ permalink raw reply related
* [PATCH v3 0/3] dp83640: Get pin and master/slave configuration from DT
From: Stefan Sørensen @ 2014-02-13 14:35 UTC (permalink / raw)
To: richardcochran, grant.likely, robh+dt, mark.rutland, devicetree,
linux-kernel, netdev
Cc: Stefan Sørensen
This patch series add DT configuration to the DP83640 PHY driver and makes
the configuration of periodic output pins dynamic.
Changes since v2:
- Add patch to properly configure perout triggers 0+1
- Keep extts and perout numbers separate
- Shorten pr_err lines
Changes since v1:
- Add bindings documentation
- Keep module parameters
- Rename gpio->pin
- Split patch into DT part and dynamic periodic output support
Stefan Sørensen (3):
net:phy:dp83640: Program pulsewidth2 values of perout triggers 0 and 1
net:phy:dp83640: Support a configurable number of periodic outputs
net:phy:dp83640: Get pin and master/slave configuration from DT
Documentation/devicetree/bindings/net/dp83640.txt | 29 ++++
drivers/net/phy/dp83640.c | 199 +++++++++++++++-------
2 files changed, 170 insertions(+), 58 deletions(-)
create mode 100644 Documentation/devicetree/bindings/net/dp83640.txt
--
1.8.5.3
^ permalink raw reply
* [PATCH v3 3/3] net:phy:dp83640: Get pin and master/slave configuration from DT
From: Stefan Sørensen @ 2014-02-13 14:35 UTC (permalink / raw)
To: richardcochran, grant.likely, robh+dt, mark.rutland, devicetree,
linux-kernel, netdev
Cc: Stefan Sørensen
In-Reply-To: <1392302129-24947-1-git-send-email-stefan.sorensen@spectralink.com>
This patch adds configuration of the periodic output and external timestamp
pins available on the dp83640 family of PHYs. It also configures the
master/slave relationship in a group of PHYs on the same MDIO bus and the pins
used for clock calibration in the group.
The configuration is retrieved from DT through the properties
dp83640,slave
dp83640,calibrate-pin
dp83640,perout-pins
dp83640,extts-pins
The configuration module parameters are retained as fallback for the non-DT
case.
Since the pin configuration is now stored for each clock device, groups of
devices on different mdio busses can now have different pin configurations.
Signed-off-by: Stefan Sørensen <stefan.sorensen@spectralink.com>
---
Documentation/devicetree/bindings/net/dp83640.txt | 29 +++++
drivers/net/phy/dp83640.c | 139 ++++++++++++++++++----
2 files changed, 143 insertions(+), 25 deletions(-)
create mode 100644 Documentation/devicetree/bindings/net/dp83640.txt
diff --git a/Documentation/devicetree/bindings/net/dp83640.txt b/Documentation/devicetree/bindings/net/dp83640.txt
new file mode 100644
index 0000000..b9a57c0
--- /dev/null
+++ b/Documentation/devicetree/bindings/net/dp83640.txt
@@ -0,0 +1,29 @@
+Required properties for the National DP83640 ethernet phy:
+
+- compatible : Must contain "national,dp83640"
+
+Optional properties:
+
+- dp83640,slave: If present, this phy will be slave to another dp83640
+ on the same mdio bus.
+- dp83640,perout-pins : List of the pin pins used for periodic output
+ triggers.
+- dp83640,extts-pins : List of the pin pins used for external event
+ timestamping.
+- dp83640,calibrate-pin : The pin used for master/slave calibration.
+
+Example:
+
+ ethernet-phy@1 {
+ compatible = "national,dp83640", "ethernet-phy-ieee802.3-c22";
+ reg = <1>;
+ dp83640,perout-pins = <2>;
+ dp83640,extts-pins = <3 4 8 9 10 11>;
+ dp83640,calibrate-pin = <1>;
+ };
+
+ ethernet-phy@2 {
+ compatible = "national,dp83640", "ethernet-phy-ieee802.3-c22";
+ reg = <2>;
+ dp83640,slave;
+ };
diff --git a/drivers/net/phy/dp83640.c b/drivers/net/phy/dp83640.c
index 28a6e1d..077bdc2 100644
--- a/drivers/net/phy/dp83640.c
+++ b/drivers/net/phy/dp83640.c
@@ -30,6 +30,7 @@
#include <linux/phy.h>
#include <linux/ptp_classify.h>
#include <linux/ptp_clock_kernel.h>
+#include <linux/of_device.h>
#include "dp83640_reg.h"
@@ -120,6 +121,8 @@ struct dp83640_private {
/* queues of incoming and outgoing packets */
struct sk_buff_head rx_queue;
struct sk_buff_head tx_queue;
+ /* is this phyter a slave */
+ bool slave;
};
struct dp83640_clock {
@@ -141,6 +144,7 @@ struct dp83640_clock {
struct list_head phylist;
/* reference to our PTP hardware clock */
struct ptp_clock *ptp_clock;
+ u32 perout_pins[N_EXT], extts_pins[N_EXT], calibrate_pin;
};
@@ -264,7 +268,7 @@ static void periodic_output(struct dp83640_clock *clock,
u32 sec, nsec, period;
u16 gpio, ptp_trig, val;
- gpio = on ? perout_pins[trigger] : 0;
+ gpio = on ? clock->perout_pins[trigger] : 0;
ptp_trig = TRIG_WR |
(trigger & TRIG_CSEL_MASK) << TRIG_CSEL_SHIFT |
@@ -435,12 +439,12 @@ static int ptp_dp83640_enable(struct ptp_clock_info *ptp,
switch (rq->type) {
case PTP_CLK_REQ_EXTTS:
index = rq->extts.index;
- if (index < 0 || index >= n_ext_ts)
+ if (index < 0 || index >= clock->caps.n_ext_ts)
return -EINVAL;
event_num = index;
evnt = EVNT_WR | (event_num & EVNT_SEL_MASK) << EVNT_SEL_SHIFT;
if (on) {
- gpio_num = extts_pins[index];
+ gpio_num = clock->extts_pins[index];
evnt |= (gpio_num & EVNT_GPIO_MASK) << EVNT_GPIO_SHIFT;
if (rq->extts.flags & PTP_FALLING_EDGE)
evnt |= EVNT_FALL;
@@ -452,7 +456,7 @@ static int ptp_dp83640_enable(struct ptp_clock_info *ptp,
case PTP_CLK_REQ_PEROUT:
index = rq->perout.index;
- if (index < 0 || index >= n_per_out)
+ if (index < 0 || index >= clock->caps.n_per_out)
return -EINVAL;
periodic_output(clock, rq, index, on);
return 0;
@@ -573,7 +577,7 @@ static void recalibrate(struct dp83640_clock *clock)
*/
evnt = EVNT_WR | EVNT_RISE | EVNT_SINGLE;
evnt |= (trigger & EVNT_SEL_MASK) << EVNT_SEL_SHIFT;
- evnt |= (calibrate_pin & EVNT_GPIO_MASK) << EVNT_GPIO_SHIFT;
+ evnt |= (clock->calibrate_pin & EVNT_GPIO_MASK) << EVNT_GPIO_SHIFT;
list_for_each(this, &clock->phylist) {
tmp = list_entry(this, struct dp83640_private, list);
@@ -586,7 +590,7 @@ static void recalibrate(struct dp83640_clock *clock)
*/
ptp_trig = TRIG_WR | TRIG_IF_LATE | TRIG_PULSE;
ptp_trig |= (trigger & TRIG_CSEL_MASK) << TRIG_CSEL_SHIFT;
- ptp_trig |= (calibrate_pin & TRIG_GPIO_MASK) << TRIG_GPIO_SHIFT;
+ ptp_trig |= (clock->calibrate_pin & TRIG_GPIO_MASK) << TRIG_GPIO_SHIFT;
ext_write(0, master, PAGE5, PTP_TRIG, ptp_trig);
/* load trigger */
@@ -691,7 +695,7 @@ static int decode_evnt(struct dp83640_private *dp83640,
event.type = PTP_CLOCK_EXTTS;
event.timestamp = phy2txts(&dp83640->edata);
- for (i = 0; i < n_ext_ts; i++) {
+ for (i = 0; i < dp83640->clock->caps.n_ext_ts; i++) {
if (ext_status & exts_chan_to_edata(i)) {
event.index = i;
ptp_clock_event(dp83640->clock->ptp_clock, &event);
@@ -893,12 +897,11 @@ static void dp83640_clock_init(struct dp83640_clock *clock, struct mii_bus *bus)
mutex_init(&clock->extreg_lock);
mutex_init(&clock->clock_lock);
INIT_LIST_HEAD(&clock->phylist);
+ clock->calibrate_pin = -1;
clock->caps.owner = THIS_MODULE;
sprintf(clock->caps.name, "dp83640 timer");
clock->caps.max_adj = 1953124;
clock->caps.n_alarm = 0;
- clock->caps.n_ext_ts = n_ext_ts;
- clock->caps.n_per_out = n_per_out;
clock->caps.pps = 0;
clock->caps.adjfreq = ptp_dp83640_adjfreq;
clock->caps.adjtime = ptp_dp83640_adjtime;
@@ -911,18 +914,6 @@ static void dp83640_clock_init(struct dp83640_clock *clock, struct mii_bus *bus)
get_device(&bus->dev);
}
-static int choose_this_phy(struct dp83640_clock *clock,
- struct phy_device *phydev)
-{
- if (chosen_phy == -1 && !clock->chosen)
- return 1;
-
- if (chosen_phy == phydev->addr)
- return 1;
-
- return 0;
-}
-
static struct dp83640_clock *dp83640_clock_get(struct dp83640_clock *clock)
{
if (clock)
@@ -968,6 +959,86 @@ static void dp83640_clock_put(struct dp83640_clock *clock)
mutex_unlock(&clock->clock_lock);
}
+#ifdef CONFIG_OF
+static int dp83640_probe_dt(struct device_node *node,
+ struct dp83640_private *dp83640)
+{
+ struct dp83640_clock *clock = dp83640->clock;
+ struct property *prop;
+ int err, proplen, n_cal = 0;
+
+ dp83640->slave = of_property_read_bool(node, "dp83640,slave");
+ if (!dp83640->slave && clock->chosen) {
+ pr_err("More then one dp83640 master on the same bus");
+ return -EINVAL;
+ }
+
+ prop = of_find_property(node, "dp83640,calibrate-pin", &proplen);
+ if (prop) {
+ if (dp83640->slave) {
+ pr_err("dp83640 slave cannot have calibrate pin");
+ return -EINVAL;
+ }
+ of_property_read_u32(node, "dp83640,calibrate-pin",
+ &clock->calibrate_pin);
+ n_cal = 1;
+ }
+
+ prop = of_find_property(node, "dp83640,perout-pins", &proplen);
+ if (prop) {
+ if (dp83640->slave) {
+ pr_err("dp83640 slave cannot have perout pins");
+ return -EINVAL;
+ }
+
+ clock->caps.n_per_out = proplen / sizeof(u32);
+ if (clock->caps.n_per_out + n_cal > N_EXT) {
+ pr_err("Too many dp83640,perout-pins");
+ return -EINVAL;
+ }
+ err = of_property_read_u32_array(node, "dp83640,perout-pins",
+ clock->perout_pins,
+ clock->caps.n_per_out);
+ if (err < 0)
+ return err;
+ }
+
+ prop = of_find_property(node, "dp83640,extts-pins", &proplen);
+ if (prop) {
+ if (dp83640->slave) {
+ pr_err("dp83640 slave cannot have extts pins");
+ return -EINVAL;
+ }
+
+ clock->caps.n_ext_ts = proplen / sizeof(u32);
+ if (clock->caps.n_ext_ts + n_cal > N_EXT) {
+ pr_err("Too many dp83640,extts-pins");
+ return -EINVAL;
+ }
+ err = of_property_read_u32_array(node, "dp83640,extts-pins",
+ clock->extts_pins,
+ clock->caps.n_ext_ts);
+ if (err < 0)
+ return err;
+ }
+
+ return 0;
+}
+
+static const struct of_device_id dp83640_of_match_table[] = {
+ { .compatible = "national,dp83640", },
+ { },
+};
+MODULE_DEVICE_TABLE(of, dp83640_of_match_table);
+#else
+
+static inline int dp83640_probe_dt(struct device_node *node,
+ struct dp83640_private *dp83640)
+{
+ return 0;
+}
+#endif
+
static int dp83640_probe(struct phy_device *phydev)
{
struct dp83640_clock *clock;
@@ -985,7 +1056,24 @@ static int dp83640_probe(struct phy_device *phydev)
if (!dp83640)
goto no_memory;
+ dp83640->clock = clock;
dp83640->phydev = phydev;
+
+ if (phydev->dev.of_node) {
+ err = dp83640_probe_dt(phydev->dev.of_node, dp83640);
+ if (err)
+ return err;
+ } else {
+ clock->calibrate_pin = calibrate_pin;
+ memcpy(clock->perout_pins, perout_pins,
+ sizeof(clock->perout_pins));
+ memcpy(clock->extts_pins, extts_pins,
+ sizeof(clock->extts_pins));
+ if (clock->chosen ||
+ (chosen_phy != -1 && phydev->addr != chosen_phy))
+ dp83640->slave = true;
+ }
+
INIT_WORK(&dp83640->ts_work, rx_timestamp_work);
INIT_LIST_HEAD(&dp83640->rxts);
@@ -999,9 +1087,7 @@ static int dp83640_probe(struct phy_device *phydev)
skb_queue_head_init(&dp83640->rx_queue);
skb_queue_head_init(&dp83640->tx_queue);
- dp83640->clock = clock;
-
- if (choose_this_phy(clock, phydev)) {
+ if (!dp83640->slave) {
clock->chosen = dp83640;
clock->ptp_clock = ptp_clock_register(&clock->caps, &phydev->dev);
if (IS_ERR(clock->ptp_clock)) {
@@ -1353,7 +1439,10 @@ static struct phy_driver dp83640_driver = {
.hwtstamp = dp83640_hwtstamp,
.rxtstamp = dp83640_rxtstamp,
.txtstamp = dp83640_txtstamp,
- .driver = {.owner = THIS_MODULE,}
+ .driver = {
+ .owner = THIS_MODULE,
+ .of_match_table = of_match_ptr(dp83640_of_match_table),
+ }
};
static int __init dp83640_init(void)
--
1.8.5.3
^ permalink raw reply related
* [PATCH v3 2/3] net:phy:dp83640: Support a configurable number of periodic outputs
From: Stefan Sørensen @ 2014-02-13 14:35 UTC (permalink / raw)
To: richardcochran, grant.likely, robh+dt, mark.rutland, devicetree,
linux-kernel, netdev
Cc: Stefan Sørensen
In-Reply-To: <1392302129-24947-1-git-send-email-stefan.sorensen@spectralink.com>
The driver is currently limited to a single periodic output. This patch makes
the number of peridodic output dynamic by dropping the gpio_tab module
parameter and adding calibrate_pin, perout_pins, and extts_pins parameters.
Signed-off-by: Stefan Sørensen <stefan.sorensen@spectralink.com>
---
drivers/net/phy/dp83640.c | 73 ++++++++++++++++++++---------------------------
1 file changed, 31 insertions(+), 42 deletions(-)
diff --git a/drivers/net/phy/dp83640.c b/drivers/net/phy/dp83640.c
index a370814..28a6e1d 100644
--- a/drivers/net/phy/dp83640.c
+++ b/drivers/net/phy/dp83640.c
@@ -38,15 +38,12 @@
#define LAYER4 0x02
#define LAYER2 0x01
#define MAX_RXTS 64
-#define N_EXT_TS 6
+#define N_EXT 8
#define PSF_PTPVER 2
#define PSF_EVNT 0x4000
#define PSF_RX 0x2000
#define PSF_TX 0x1000
-#define EXT_EVENT 1
-#define CAL_EVENT 7
#define CAL_TRIGGER 7
-#define PER_TRIGGER 6
#define MII_DP83640_MICR 0x11
#define MII_DP83640_MISR 0x12
@@ -146,32 +143,24 @@ struct dp83640_clock {
struct ptp_clock *ptp_clock;
};
-/* globals */
-
-enum {
- CALIBRATE_GPIO,
- PEROUT_GPIO,
- EXTTS0_GPIO,
- EXTTS1_GPIO,
- EXTTS2_GPIO,
- EXTTS3_GPIO,
- EXTTS4_GPIO,
- EXTTS5_GPIO,
- GPIO_TABLE_SIZE
-};
static int chosen_phy = -1;
-static ushort gpio_tab[GPIO_TABLE_SIZE] = {
- 1, 2, 3, 4, 8, 9, 10, 11
-};
+static int calibrate_pin = 1;
+static int perout_pins[N_EXT] = {2};
+static int n_per_out = 1;
+static int extts_pins[N_EXT] = {3, 4, 8, 9, 10, 11};
+static int n_ext_ts = 6;
module_param(chosen_phy, int, 0444);
-module_param_array(gpio_tab, ushort, NULL, 0444);
+module_param(calibrate_pin, int, 0444);
+module_param_array(perout_pins, int, &n_per_out, 0444);
+module_param_array(extts_pins, int, &n_ext_ts, 0444);
MODULE_PARM_DESC(chosen_phy, \
"The address of the PHY to use for the ancillary clock features");
-MODULE_PARM_DESC(gpio_tab, \
- "Which GPIO line to use for which purpose: cal,perout,extts1,...,extts6");
+MODULE_PARM_DESC(calibrate_pin, "Which pin to use for calibration");
+MODULE_PARM_DESC(perout_pins, "Which pins to use for periodic output");
+MODULE_PARM_DESC(extts_pins, "Which pins to use for external timestamping");
/* a list of clocks and a mutex to protect it */
static LIST_HEAD(phyter_clocks);
@@ -267,15 +256,15 @@ static u64 phy2txts(struct phy_txts *p)
}
static void periodic_output(struct dp83640_clock *clock,
- struct ptp_clock_request *clkreq, bool on)
+ struct ptp_clock_request *clkreq, int trigger,
+ bool on)
{
struct dp83640_private *dp83640 = clock->chosen;
struct phy_device *phydev = dp83640->phydev;
u32 sec, nsec, period;
- u16 gpio, ptp_trig, trigger, val;
+ u16 gpio, ptp_trig, val;
- gpio = on ? gpio_tab[PEROUT_GPIO] : 0;
- trigger = PER_TRIGGER;
+ gpio = on ? perout_pins[trigger] : 0;
ptp_trig = TRIG_WR |
(trigger & TRIG_CSEL_MASK) << TRIG_CSEL_SHIFT |
@@ -446,12 +435,12 @@ static int ptp_dp83640_enable(struct ptp_clock_info *ptp,
switch (rq->type) {
case PTP_CLK_REQ_EXTTS:
index = rq->extts.index;
- if (index < 0 || index >= N_EXT_TS)
+ if (index < 0 || index >= n_ext_ts)
return -EINVAL;
- event_num = EXT_EVENT + index;
+ event_num = index;
evnt = EVNT_WR | (event_num & EVNT_SEL_MASK) << EVNT_SEL_SHIFT;
if (on) {
- gpio_num = gpio_tab[EXTTS0_GPIO + index];
+ gpio_num = extts_pins[index];
evnt |= (gpio_num & EVNT_GPIO_MASK) << EVNT_GPIO_SHIFT;
if (rq->extts.flags & PTP_FALLING_EDGE)
evnt |= EVNT_FALL;
@@ -462,9 +451,10 @@ static int ptp_dp83640_enable(struct ptp_clock_info *ptp,
return 0;
case PTP_CLK_REQ_PEROUT:
- if (rq->perout.index != 0)
+ index = rq->perout.index;
+ if (index < 0 || index >= n_per_out)
return -EINVAL;
- periodic_output(clock, rq, on);
+ periodic_output(clock, rq, index, on);
return 0;
default:
@@ -557,10 +547,9 @@ static void recalibrate(struct dp83640_clock *clock)
struct list_head *this;
struct dp83640_private *tmp;
struct phy_device *master = clock->chosen->phydev;
- u16 cal_gpio, cfg0, evnt, ptp_trig, trigger, val;
+ u16 cfg0, evnt, ptp_trig, trigger, val;
trigger = CAL_TRIGGER;
- cal_gpio = gpio_tab[CALIBRATE_GPIO];
mutex_lock(&clock->extreg_lock);
@@ -583,8 +572,8 @@ static void recalibrate(struct dp83640_clock *clock)
* enable an event timestamp
*/
evnt = EVNT_WR | EVNT_RISE | EVNT_SINGLE;
- evnt |= (CAL_EVENT & EVNT_SEL_MASK) << EVNT_SEL_SHIFT;
- evnt |= (cal_gpio & EVNT_GPIO_MASK) << EVNT_GPIO_SHIFT;
+ evnt |= (trigger & EVNT_SEL_MASK) << EVNT_SEL_SHIFT;
+ evnt |= (calibrate_pin & EVNT_GPIO_MASK) << EVNT_GPIO_SHIFT;
list_for_each(this, &clock->phylist) {
tmp = list_entry(this, struct dp83640_private, list);
@@ -597,7 +586,7 @@ static void recalibrate(struct dp83640_clock *clock)
*/
ptp_trig = TRIG_WR | TRIG_IF_LATE | TRIG_PULSE;
ptp_trig |= (trigger & TRIG_CSEL_MASK) << TRIG_CSEL_SHIFT;
- ptp_trig |= (cal_gpio & TRIG_GPIO_MASK) << TRIG_GPIO_SHIFT;
+ ptp_trig |= (calibrate_pin & TRIG_GPIO_MASK) << TRIG_GPIO_SHIFT;
ext_write(0, master, PAGE5, PTP_TRIG, ptp_trig);
/* load trigger */
@@ -661,7 +650,7 @@ static void recalibrate(struct dp83640_clock *clock)
static inline u16 exts_chan_to_edata(int ch)
{
- return 1 << ((ch + EXT_EVENT) * 2);
+ return 1 << ((ch) * 2);
}
static int decode_evnt(struct dp83640_private *dp83640,
@@ -695,14 +684,14 @@ static int decode_evnt(struct dp83640_private *dp83640,
parsed = words + 2;
} else {
parsed = words + 1;
- i = ((ests >> EVNT_NUM_SHIFT) & EVNT_NUM_MASK) - EXT_EVENT;
+ i = ((ests >> EVNT_NUM_SHIFT) & EVNT_NUM_MASK);
ext_status = exts_chan_to_edata(i);
}
event.type = PTP_CLOCK_EXTTS;
event.timestamp = phy2txts(&dp83640->edata);
- for (i = 0; i < N_EXT_TS; i++) {
+ for (i = 0; i < n_ext_ts; i++) {
if (ext_status & exts_chan_to_edata(i)) {
event.index = i;
ptp_clock_event(dp83640->clock->ptp_clock, &event);
@@ -908,8 +897,8 @@ static void dp83640_clock_init(struct dp83640_clock *clock, struct mii_bus *bus)
sprintf(clock->caps.name, "dp83640 timer");
clock->caps.max_adj = 1953124;
clock->caps.n_alarm = 0;
- clock->caps.n_ext_ts = N_EXT_TS;
- clock->caps.n_per_out = 1;
+ clock->caps.n_ext_ts = n_ext_ts;
+ clock->caps.n_per_out = n_per_out;
clock->caps.pps = 0;
clock->caps.adjfreq = ptp_dp83640_adjfreq;
clock->caps.adjtime = ptp_dp83640_adjtime;
--
1.8.5.3
^ permalink raw reply related
* [PATCH v3 0/3] dp83640: Get pin and master/slave configuration from DT
From: Stefan Sørensen @ 2014-02-13 14:35 UTC (permalink / raw)
To: richardcochran, grant.likely, robh+dt, mark.rutland, devicetree,
linux-kernel, netdev
Cc: Stefan Sørensen
In-Reply-To: <1392302129-24947-1-git-send-email-stefan.sorensen@spectralink.com>
This patch series add DT configuration to the DP83640 PHY driver and makes
the configuration of periodic output pins dynamic.
Changes since v2:
- Add patch to properly configure perout triggers 0+1
- Keep extts and perout numbers separate
- Shorten pr_err lines
Changes since v1:
- Add bindings documentation
- Keep module parameters
- Rename gpio->pin
- Split patch into DT part and dynamic periodic output support
Stefan Sørensen (3):
net:phy:dp83640: Program pulsewidth2 values of perout triggers 0 and 1
net:phy:dp83640: Support a configurable number of periodic outputs
net:phy:dp83640: Get pin and master/slave configuration from DT
Documentation/devicetree/bindings/net/dp83640.txt | 29 ++++
drivers/net/phy/dp83640.c | 199 +++++++++++++++-------
2 files changed, 170 insertions(+), 58 deletions(-)
create mode 100644 Documentation/devicetree/bindings/net/dp83640.txt
--
1.8.5.3
^ permalink raw reply
* [PATCH v3 3/3] net:phy:dp83640: Get pin and master/slave configuration from DT
From: Stefan Sørensen @ 2014-02-13 14:35 UTC (permalink / raw)
To: richardcochran, grant.likely, robh+dt, mark.rutland, devicetree,
linux-kernel, netdev
Cc: Stefan Sørensen
In-Reply-To: <1392302129-24947-1-git-send-email-stefan.sorensen@spectralink.com>
This patch adds configuration of the periodic output and external timestamp
pins available on the dp83640 family of PHYs. It also configures the
master/slave relationship in a group of PHYs on the same MDIO bus and the pins
used for clock calibration in the group.
The configuration is retrieved from DT through the properties
dp83640,slave
dp83640,calibrate-pin
dp83640,perout-pins
dp83640,extts-pins
The configuration module parameters are retained as fallback for the non-DT
case.
Since the pin configuration is now stored for each clock device, groups of
devices on different mdio busses can now have different pin configurations.
Signed-off-by: Stefan Sørensen <stefan.sorensen@spectralink.com>
---
Documentation/devicetree/bindings/net/dp83640.txt | 29 +++++
drivers/net/phy/dp83640.c | 139 ++++++++++++++++++----
2 files changed, 143 insertions(+), 25 deletions(-)
create mode 100644 Documentation/devicetree/bindings/net/dp83640.txt
diff --git a/Documentation/devicetree/bindings/net/dp83640.txt b/Documentation/devicetree/bindings/net/dp83640.txt
new file mode 100644
index 0000000..b9a57c0
--- /dev/null
+++ b/Documentation/devicetree/bindings/net/dp83640.txt
@@ -0,0 +1,29 @@
+Required properties for the National DP83640 ethernet phy:
+
+- compatible : Must contain "national,dp83640"
+
+Optional properties:
+
+- dp83640,slave: If present, this phy will be slave to another dp83640
+ on the same mdio bus.
+- dp83640,perout-pins : List of the pin pins used for periodic output
+ triggers.
+- dp83640,extts-pins : List of the pin pins used for external event
+ timestamping.
+- dp83640,calibrate-pin : The pin used for master/slave calibration.
+
+Example:
+
+ ethernet-phy@1 {
+ compatible = "national,dp83640", "ethernet-phy-ieee802.3-c22";
+ reg = <1>;
+ dp83640,perout-pins = <2>;
+ dp83640,extts-pins = <3 4 8 9 10 11>;
+ dp83640,calibrate-pin = <1>;
+ };
+
+ ethernet-phy@2 {
+ compatible = "national,dp83640", "ethernet-phy-ieee802.3-c22";
+ reg = <2>;
+ dp83640,slave;
+ };
diff --git a/drivers/net/phy/dp83640.c b/drivers/net/phy/dp83640.c
index 28a6e1d..077bdc2 100644
--- a/drivers/net/phy/dp83640.c
+++ b/drivers/net/phy/dp83640.c
@@ -30,6 +30,7 @@
#include <linux/phy.h>
#include <linux/ptp_classify.h>
#include <linux/ptp_clock_kernel.h>
+#include <linux/of_device.h>
#include "dp83640_reg.h"
@@ -120,6 +121,8 @@ struct dp83640_private {
/* queues of incoming and outgoing packets */
struct sk_buff_head rx_queue;
struct sk_buff_head tx_queue;
+ /* is this phyter a slave */
+ bool slave;
};
struct dp83640_clock {
@@ -141,6 +144,7 @@ struct dp83640_clock {
struct list_head phylist;
/* reference to our PTP hardware clock */
struct ptp_clock *ptp_clock;
+ u32 perout_pins[N_EXT], extts_pins[N_EXT], calibrate_pin;
};
@@ -264,7 +268,7 @@ static void periodic_output(struct dp83640_clock *clock,
u32 sec, nsec, period;
u16 gpio, ptp_trig, val;
- gpio = on ? perout_pins[trigger] : 0;
+ gpio = on ? clock->perout_pins[trigger] : 0;
ptp_trig = TRIG_WR |
(trigger & TRIG_CSEL_MASK) << TRIG_CSEL_SHIFT |
@@ -435,12 +439,12 @@ static int ptp_dp83640_enable(struct ptp_clock_info *ptp,
switch (rq->type) {
case PTP_CLK_REQ_EXTTS:
index = rq->extts.index;
- if (index < 0 || index >= n_ext_ts)
+ if (index < 0 || index >= clock->caps.n_ext_ts)
return -EINVAL;
event_num = index;
evnt = EVNT_WR | (event_num & EVNT_SEL_MASK) << EVNT_SEL_SHIFT;
if (on) {
- gpio_num = extts_pins[index];
+ gpio_num = clock->extts_pins[index];
evnt |= (gpio_num & EVNT_GPIO_MASK) << EVNT_GPIO_SHIFT;
if (rq->extts.flags & PTP_FALLING_EDGE)
evnt |= EVNT_FALL;
@@ -452,7 +456,7 @@ static int ptp_dp83640_enable(struct ptp_clock_info *ptp,
case PTP_CLK_REQ_PEROUT:
index = rq->perout.index;
- if (index < 0 || index >= n_per_out)
+ if (index < 0 || index >= clock->caps.n_per_out)
return -EINVAL;
periodic_output(clock, rq, index, on);
return 0;
@@ -573,7 +577,7 @@ static void recalibrate(struct dp83640_clock *clock)
*/
evnt = EVNT_WR | EVNT_RISE | EVNT_SINGLE;
evnt |= (trigger & EVNT_SEL_MASK) << EVNT_SEL_SHIFT;
- evnt |= (calibrate_pin & EVNT_GPIO_MASK) << EVNT_GPIO_SHIFT;
+ evnt |= (clock->calibrate_pin & EVNT_GPIO_MASK) << EVNT_GPIO_SHIFT;
list_for_each(this, &clock->phylist) {
tmp = list_entry(this, struct dp83640_private, list);
@@ -586,7 +590,7 @@ static void recalibrate(struct dp83640_clock *clock)
*/
ptp_trig = TRIG_WR | TRIG_IF_LATE | TRIG_PULSE;
ptp_trig |= (trigger & TRIG_CSEL_MASK) << TRIG_CSEL_SHIFT;
- ptp_trig |= (calibrate_pin & TRIG_GPIO_MASK) << TRIG_GPIO_SHIFT;
+ ptp_trig |= (clock->calibrate_pin & TRIG_GPIO_MASK) << TRIG_GPIO_SHIFT;
ext_write(0, master, PAGE5, PTP_TRIG, ptp_trig);
/* load trigger */
@@ -691,7 +695,7 @@ static int decode_evnt(struct dp83640_private *dp83640,
event.type = PTP_CLOCK_EXTTS;
event.timestamp = phy2txts(&dp83640->edata);
- for (i = 0; i < n_ext_ts; i++) {
+ for (i = 0; i < dp83640->clock->caps.n_ext_ts; i++) {
if (ext_status & exts_chan_to_edata(i)) {
event.index = i;
ptp_clock_event(dp83640->clock->ptp_clock, &event);
@@ -893,12 +897,11 @@ static void dp83640_clock_init(struct dp83640_clock *clock, struct mii_bus *bus)
mutex_init(&clock->extreg_lock);
mutex_init(&clock->clock_lock);
INIT_LIST_HEAD(&clock->phylist);
+ clock->calibrate_pin = -1;
clock->caps.owner = THIS_MODULE;
sprintf(clock->caps.name, "dp83640 timer");
clock->caps.max_adj = 1953124;
clock->caps.n_alarm = 0;
- clock->caps.n_ext_ts = n_ext_ts;
- clock->caps.n_per_out = n_per_out;
clock->caps.pps = 0;
clock->caps.adjfreq = ptp_dp83640_adjfreq;
clock->caps.adjtime = ptp_dp83640_adjtime;
@@ -911,18 +914,6 @@ static void dp83640_clock_init(struct dp83640_clock *clock, struct mii_bus *bus)
get_device(&bus->dev);
}
-static int choose_this_phy(struct dp83640_clock *clock,
- struct phy_device *phydev)
-{
- if (chosen_phy == -1 && !clock->chosen)
- return 1;
-
- if (chosen_phy == phydev->addr)
- return 1;
-
- return 0;
-}
-
static struct dp83640_clock *dp83640_clock_get(struct dp83640_clock *clock)
{
if (clock)
@@ -968,6 +959,86 @@ static void dp83640_clock_put(struct dp83640_clock *clock)
mutex_unlock(&clock->clock_lock);
}
+#ifdef CONFIG_OF
+static int dp83640_probe_dt(struct device_node *node,
+ struct dp83640_private *dp83640)
+{
+ struct dp83640_clock *clock = dp83640->clock;
+ struct property *prop;
+ int err, proplen, n_cal = 0;
+
+ dp83640->slave = of_property_read_bool(node, "dp83640,slave");
+ if (!dp83640->slave && clock->chosen) {
+ pr_err("More then one dp83640 master on the same bus");
+ return -EINVAL;
+ }
+
+ prop = of_find_property(node, "dp83640,calibrate-pin", &proplen);
+ if (prop) {
+ if (dp83640->slave) {
+ pr_err("dp83640 slave cannot have calibrate pin");
+ return -EINVAL;
+ }
+ of_property_read_u32(node, "dp83640,calibrate-pin",
+ &clock->calibrate_pin);
+ n_cal = 1;
+ }
+
+ prop = of_find_property(node, "dp83640,perout-pins", &proplen);
+ if (prop) {
+ if (dp83640->slave) {
+ pr_err("dp83640 slave cannot have perout pins");
+ return -EINVAL;
+ }
+
+ clock->caps.n_per_out = proplen / sizeof(u32);
+ if (clock->caps.n_per_out + n_cal > N_EXT) {
+ pr_err("Too many dp83640,perout-pins");
+ return -EINVAL;
+ }
+ err = of_property_read_u32_array(node, "dp83640,perout-pins",
+ clock->perout_pins,
+ clock->caps.n_per_out);
+ if (err < 0)
+ return err;
+ }
+
+ prop = of_find_property(node, "dp83640,extts-pins", &proplen);
+ if (prop) {
+ if (dp83640->slave) {
+ pr_err("dp83640 slave cannot have extts pins");
+ return -EINVAL;
+ }
+
+ clock->caps.n_ext_ts = proplen / sizeof(u32);
+ if (clock->caps.n_ext_ts + n_cal > N_EXT) {
+ pr_err("Too many dp83640,extts-pins");
+ return -EINVAL;
+ }
+ err = of_property_read_u32_array(node, "dp83640,extts-pins",
+ clock->extts_pins,
+ clock->caps.n_ext_ts);
+ if (err < 0)
+ return err;
+ }
+
+ return 0;
+}
+
+static const struct of_device_id dp83640_of_match_table[] = {
+ { .compatible = "national,dp83640", },
+ { },
+};
+MODULE_DEVICE_TABLE(of, dp83640_of_match_table);
+#else
+
+static inline int dp83640_probe_dt(struct device_node *node,
+ struct dp83640_private *dp83640)
+{
+ return 0;
+}
+#endif
+
static int dp83640_probe(struct phy_device *phydev)
{
struct dp83640_clock *clock;
@@ -985,7 +1056,24 @@ static int dp83640_probe(struct phy_device *phydev)
if (!dp83640)
goto no_memory;
+ dp83640->clock = clock;
dp83640->phydev = phydev;
+
+ if (phydev->dev.of_node) {
+ err = dp83640_probe_dt(phydev->dev.of_node, dp83640);
+ if (err)
+ return err;
+ } else {
+ clock->calibrate_pin = calibrate_pin;
+ memcpy(clock->perout_pins, perout_pins,
+ sizeof(clock->perout_pins));
+ memcpy(clock->extts_pins, extts_pins,
+ sizeof(clock->extts_pins));
+ if (clock->chosen ||
+ (chosen_phy != -1 && phydev->addr != chosen_phy))
+ dp83640->slave = true;
+ }
+
INIT_WORK(&dp83640->ts_work, rx_timestamp_work);
INIT_LIST_HEAD(&dp83640->rxts);
@@ -999,9 +1087,7 @@ static int dp83640_probe(struct phy_device *phydev)
skb_queue_head_init(&dp83640->rx_queue);
skb_queue_head_init(&dp83640->tx_queue);
- dp83640->clock = clock;
-
- if (choose_this_phy(clock, phydev)) {
+ if (!dp83640->slave) {
clock->chosen = dp83640;
clock->ptp_clock = ptp_clock_register(&clock->caps, &phydev->dev);
if (IS_ERR(clock->ptp_clock)) {
@@ -1353,7 +1439,10 @@ static struct phy_driver dp83640_driver = {
.hwtstamp = dp83640_hwtstamp,
.rxtstamp = dp83640_rxtstamp,
.txtstamp = dp83640_txtstamp,
- .driver = {.owner = THIS_MODULE,}
+ .driver = {
+ .owner = THIS_MODULE,
+ .of_match_table = of_match_ptr(dp83640_of_match_table),
+ }
};
static int __init dp83640_init(void)
--
1.8.5.3
^ permalink raw reply related
* [PATCH v3 2/3] net:phy:dp83640: Support a configurable number of periodic outputs
From: Stefan Sørensen @ 2014-02-13 14:35 UTC (permalink / raw)
To: richardcochran, grant.likely, robh+dt, mark.rutland, devicetree,
linux-kernel, netdev
Cc: Stefan Sørensen
In-Reply-To: <1392302129-24947-1-git-send-email-stefan.sorensen@spectralink.com>
The driver is currently limited to a single periodic output. This patch makes
the number of peridodic output dynamic by dropping the gpio_tab module
parameter and adding calibrate_pin, perout_pins, and extts_pins parameters.
Signed-off-by: Stefan Sørensen <stefan.sorensen@spectralink.com>
---
drivers/net/phy/dp83640.c | 73 ++++++++++++++++++++---------------------------
1 file changed, 31 insertions(+), 42 deletions(-)
diff --git a/drivers/net/phy/dp83640.c b/drivers/net/phy/dp83640.c
index a370814..28a6e1d 100644
--- a/drivers/net/phy/dp83640.c
+++ b/drivers/net/phy/dp83640.c
@@ -38,15 +38,12 @@
#define LAYER4 0x02
#define LAYER2 0x01
#define MAX_RXTS 64
-#define N_EXT_TS 6
+#define N_EXT 8
#define PSF_PTPVER 2
#define PSF_EVNT 0x4000
#define PSF_RX 0x2000
#define PSF_TX 0x1000
-#define EXT_EVENT 1
-#define CAL_EVENT 7
#define CAL_TRIGGER 7
-#define PER_TRIGGER 6
#define MII_DP83640_MICR 0x11
#define MII_DP83640_MISR 0x12
@@ -146,32 +143,24 @@ struct dp83640_clock {
struct ptp_clock *ptp_clock;
};
-/* globals */
-
-enum {
- CALIBRATE_GPIO,
- PEROUT_GPIO,
- EXTTS0_GPIO,
- EXTTS1_GPIO,
- EXTTS2_GPIO,
- EXTTS3_GPIO,
- EXTTS4_GPIO,
- EXTTS5_GPIO,
- GPIO_TABLE_SIZE
-};
static int chosen_phy = -1;
-static ushort gpio_tab[GPIO_TABLE_SIZE] = {
- 1, 2, 3, 4, 8, 9, 10, 11
-};
+static int calibrate_pin = 1;
+static int perout_pins[N_EXT] = {2};
+static int n_per_out = 1;
+static int extts_pins[N_EXT] = {3, 4, 8, 9, 10, 11};
+static int n_ext_ts = 6;
module_param(chosen_phy, int, 0444);
-module_param_array(gpio_tab, ushort, NULL, 0444);
+module_param(calibrate_pin, int, 0444);
+module_param_array(perout_pins, int, &n_per_out, 0444);
+module_param_array(extts_pins, int, &n_ext_ts, 0444);
MODULE_PARM_DESC(chosen_phy, \
"The address of the PHY to use for the ancillary clock features");
-MODULE_PARM_DESC(gpio_tab, \
- "Which GPIO line to use for which purpose: cal,perout,extts1,...,extts6");
+MODULE_PARM_DESC(calibrate_pin, "Which pin to use for calibration");
+MODULE_PARM_DESC(perout_pins, "Which pins to use for periodic output");
+MODULE_PARM_DESC(extts_pins, "Which pins to use for external timestamping");
/* a list of clocks and a mutex to protect it */
static LIST_HEAD(phyter_clocks);
@@ -267,15 +256,15 @@ static u64 phy2txts(struct phy_txts *p)
}
static void periodic_output(struct dp83640_clock *clock,
- struct ptp_clock_request *clkreq, bool on)
+ struct ptp_clock_request *clkreq, int trigger,
+ bool on)
{
struct dp83640_private *dp83640 = clock->chosen;
struct phy_device *phydev = dp83640->phydev;
u32 sec, nsec, period;
- u16 gpio, ptp_trig, trigger, val;
+ u16 gpio, ptp_trig, val;
- gpio = on ? gpio_tab[PEROUT_GPIO] : 0;
- trigger = PER_TRIGGER;
+ gpio = on ? perout_pins[trigger] : 0;
ptp_trig = TRIG_WR |
(trigger & TRIG_CSEL_MASK) << TRIG_CSEL_SHIFT |
@@ -446,12 +435,12 @@ static int ptp_dp83640_enable(struct ptp_clock_info *ptp,
switch (rq->type) {
case PTP_CLK_REQ_EXTTS:
index = rq->extts.index;
- if (index < 0 || index >= N_EXT_TS)
+ if (index < 0 || index >= n_ext_ts)
return -EINVAL;
- event_num = EXT_EVENT + index;
+ event_num = index;
evnt = EVNT_WR | (event_num & EVNT_SEL_MASK) << EVNT_SEL_SHIFT;
if (on) {
- gpio_num = gpio_tab[EXTTS0_GPIO + index];
+ gpio_num = extts_pins[index];
evnt |= (gpio_num & EVNT_GPIO_MASK) << EVNT_GPIO_SHIFT;
if (rq->extts.flags & PTP_FALLING_EDGE)
evnt |= EVNT_FALL;
@@ -462,9 +451,10 @@ static int ptp_dp83640_enable(struct ptp_clock_info *ptp,
return 0;
case PTP_CLK_REQ_PEROUT:
- if (rq->perout.index != 0)
+ index = rq->perout.index;
+ if (index < 0 || index >= n_per_out)
return -EINVAL;
- periodic_output(clock, rq, on);
+ periodic_output(clock, rq, index, on);
return 0;
default:
@@ -557,10 +547,9 @@ static void recalibrate(struct dp83640_clock *clock)
struct list_head *this;
struct dp83640_private *tmp;
struct phy_device *master = clock->chosen->phydev;
- u16 cal_gpio, cfg0, evnt, ptp_trig, trigger, val;
+ u16 cfg0, evnt, ptp_trig, trigger, val;
trigger = CAL_TRIGGER;
- cal_gpio = gpio_tab[CALIBRATE_GPIO];
mutex_lock(&clock->extreg_lock);
@@ -583,8 +572,8 @@ static void recalibrate(struct dp83640_clock *clock)
* enable an event timestamp
*/
evnt = EVNT_WR | EVNT_RISE | EVNT_SINGLE;
- evnt |= (CAL_EVENT & EVNT_SEL_MASK) << EVNT_SEL_SHIFT;
- evnt |= (cal_gpio & EVNT_GPIO_MASK) << EVNT_GPIO_SHIFT;
+ evnt |= (trigger & EVNT_SEL_MASK) << EVNT_SEL_SHIFT;
+ evnt |= (calibrate_pin & EVNT_GPIO_MASK) << EVNT_GPIO_SHIFT;
list_for_each(this, &clock->phylist) {
tmp = list_entry(this, struct dp83640_private, list);
@@ -597,7 +586,7 @@ static void recalibrate(struct dp83640_clock *clock)
*/
ptp_trig = TRIG_WR | TRIG_IF_LATE | TRIG_PULSE;
ptp_trig |= (trigger & TRIG_CSEL_MASK) << TRIG_CSEL_SHIFT;
- ptp_trig |= (cal_gpio & TRIG_GPIO_MASK) << TRIG_GPIO_SHIFT;
+ ptp_trig |= (calibrate_pin & TRIG_GPIO_MASK) << TRIG_GPIO_SHIFT;
ext_write(0, master, PAGE5, PTP_TRIG, ptp_trig);
/* load trigger */
@@ -661,7 +650,7 @@ static void recalibrate(struct dp83640_clock *clock)
static inline u16 exts_chan_to_edata(int ch)
{
- return 1 << ((ch + EXT_EVENT) * 2);
+ return 1 << ((ch) * 2);
}
static int decode_evnt(struct dp83640_private *dp83640,
@@ -695,14 +684,14 @@ static int decode_evnt(struct dp83640_private *dp83640,
parsed = words + 2;
} else {
parsed = words + 1;
- i = ((ests >> EVNT_NUM_SHIFT) & EVNT_NUM_MASK) - EXT_EVENT;
+ i = ((ests >> EVNT_NUM_SHIFT) & EVNT_NUM_MASK);
ext_status = exts_chan_to_edata(i);
}
event.type = PTP_CLOCK_EXTTS;
event.timestamp = phy2txts(&dp83640->edata);
- for (i = 0; i < N_EXT_TS; i++) {
+ for (i = 0; i < n_ext_ts; i++) {
if (ext_status & exts_chan_to_edata(i)) {
event.index = i;
ptp_clock_event(dp83640->clock->ptp_clock, &event);
@@ -908,8 +897,8 @@ static void dp83640_clock_init(struct dp83640_clock *clock, struct mii_bus *bus)
sprintf(clock->caps.name, "dp83640 timer");
clock->caps.max_adj = 1953124;
clock->caps.n_alarm = 0;
- clock->caps.n_ext_ts = N_EXT_TS;
- clock->caps.n_per_out = 1;
+ clock->caps.n_ext_ts = n_ext_ts;
+ clock->caps.n_per_out = n_per_out;
clock->caps.pps = 0;
clock->caps.adjfreq = ptp_dp83640_adjfreq;
clock->caps.adjtime = ptp_dp83640_adjtime;
--
1.8.5.3
^ permalink raw reply related
* [PATCH v3 1/3] net:phy:dp83640: Program pulsewidth2 values of perout triggers 0 and 1
From: Stefan Sørensen @ 2014-02-13 14:35 UTC (permalink / raw)
To: richardcochran, grant.likely, robh+dt, mark.rutland, devicetree,
linux-kernel, netdev
Cc: Stefan Sørensen
In-Reply-To: <1392302129-24947-1-git-send-email-stefan.sorensen@spectralink.com>
Periodic output triggers 0 and 1 of the dp83640 has a programmable
duty-cycle which is controlled by the Pulsewidth2 field of the trigger
data register. This field is not documented in the datasheet, but it
is described in the "PHYTER Software Development Guide" section
3.1.4.1. Failing to set the field can result in unstable/no trigger
output.
This patch add programming of the Pulsewidth2 field, setting it to the
same value as the Pulsewidth field for a 50% duty cycle.
Signed-off-by: Stefan Sørensen <stefan.sorensen@spectralink.com>
---
drivers/net/phy/dp83640.c | 5 +++++
1 file changed, 5 insertions(+)
diff --git a/drivers/net/phy/dp83640.c b/drivers/net/phy/dp83640.c
index 5ff221d..a370814 100644
--- a/drivers/net/phy/dp83640.c
+++ b/drivers/net/phy/dp83640.c
@@ -312,6 +312,11 @@ static void periodic_output(struct dp83640_clock *clock,
ext_write(0, phydev, PAGE4, PTP_TDR, sec >> 16); /* sec[31:16] */
ext_write(0, phydev, PAGE4, PTP_TDR, period & 0xffff); /* ns[15:0] */
ext_write(0, phydev, PAGE4, PTP_TDR, period >> 16); /* ns[31:16] */
+ /* Triggers 0 and 1 has programmable pulsewidth2 */
+ if (trigger == 0 || trigger == 1) {
+ ext_write(0, phydev, PAGE4, PTP_TDR, period & 0xffff);
+ ext_write(0, phydev, PAGE4, PTP_TDR, period >> 16);
+ }
/*enable trigger*/
val &= ~TRIG_LOAD;
--
1.8.5.3
^ permalink raw reply related
* Re: [PATCH net-next 2/2] bonding: remove the redundant judgements for bond_option_queue_id_set()
From: Jiri Pirko @ 2014-02-13 14:30 UTC (permalink / raw)
To: Ding Tianhong; +Cc: fubar, vfalico, andy, davem, netdev
In-Reply-To: <1392188330-17208-3-git-send-email-dingtianhong@huawei.com>
Wed, Feb 12, 2014 at 07:58:50AM CET, dingtianhong@huawei.com wrote:
>The dev_valid_name() will check the buffer length for input name, no need to
>check it twice.
>
>Cc: Jay Vosburgh <fubar@us.ibm.com>
>Cc: Veaceslav Falico <vfalico@redhat.com>
>Cc: Andy Gospodarek <andy@greyhouse.net>
>Signed-off-by: Ding Tianhong <dingtianhong@huawei.com>
Reviewed-by: Jiri Pirko <jiri@resnulli.us>
^ permalink raw reply
* Re: [PATCH net-next 1/2] bonding: remove the redundant judgements for bond_set_mac_address()
From: Jiri Pirko @ 2014-02-13 14:29 UTC (permalink / raw)
To: Ding Tianhong; +Cc: fubar, vfalico, andy, davem, netdev
In-Reply-To: <1392188330-17208-2-git-send-email-dingtianhong@huawei.com>
Wed, Feb 12, 2014 at 07:58:49AM CET, dingtianhong@huawei.com wrote:
>The dev_set_mac_address() will check the dev->netdev_ops->ndo_set_mac_address,
>so no need to check it in bond_set_mac_address().
>
>Cc: Jay Vosburgh <fubar@us.ibm.com>
>Cc: Veaceslav Falico <vfalico@redhat.com>
>Cc: Andy Gospodarek <andy@greyhouse.net>
>Signed-off-by: Ding Tianhong <dingtianhong@huawei.com>
Reviewed-by: Jiri Pirko <jiri@resnulli.us>
^ permalink raw reply
* [PATCH] net:phy:dp83640: Move all HW initialization to dp83640_config_init
From: Stefan Sørensen @ 2014-02-13 14:26 UTC (permalink / raw)
To: richardcochran, netdev; +Cc: Stefan Sørensen
phy_init_hw not does a full PHY reset after the driver probe has
finished, so any hw initialization done in the probe will be lost.
Part of the timestamping functionality of the dp83640 is set up in the
probe and with that lost, enabling timestamping will cause a PHY
lockup, requiring a hard reset / power cycle to recover.
This patch moves all the HW initialization in dp83640_probe to
dp83640_config_init.
Signed-off-by: Stefan Sørensen <stefan.sorensen@spectralink.com>
---
drivers/net/phy/dp83640.c | 13 ++++++++-----
1 file changed, 8 insertions(+), 5 deletions(-)
diff --git a/drivers/net/phy/dp83640.c b/drivers/net/phy/dp83640.c
index 0de863c..5ff221d 100644
--- a/drivers/net/phy/dp83640.c
+++ b/drivers/net/phy/dp83640.c
@@ -1017,11 +1017,6 @@ static int dp83640_probe(struct phy_device *phydev)
} else
list_add_tail(&dp83640->list, &clock->phylist);
- if (clock->chosen && !list_empty(&clock->phylist))
- recalibrate(clock);
- else
- enable_broadcast(dp83640->phydev, clock->page, 1);
-
dp83640_clock_put(clock);
return 0;
@@ -1074,6 +1069,14 @@ static void dp83640_remove(struct phy_device *phydev)
static int dp83640_config_init(struct phy_device *phydev)
{
+ struct dp83640_private *dp83640 = phydev->priv;
+ struct dp83640_clock *clock = dp83640->clock;
+
+ if (clock->chosen && !list_empty(&clock->phylist))
+ recalibrate(clock);
+ else
+ enable_broadcast(phydev, clock->page, 1);
+
enable_status_frames(phydev, true);
ext_write(0, phydev, PAGE4, PTP_CTL, PTP_ENABLE);
return 0;
--
1.8.5.3
^ permalink raw reply related
* [PATCH v2] net:cpsw: Pass unhandled ioctl's on to generic phy ioctl
From: Stefan Sørensen @ 2014-02-13 14:26 UTC (permalink / raw)
To: mugunthanvnm, davem, netdev; +Cc: Stefan Sørensen
This patch allows the use of a generic timestamping phy connected
to the cpsw if CPTS support is not enabled. This also adds support
of the SIOCGMIIREG and SIOCSMIIREG, and moves handling of SIOCGMIIPHY
to the generic driver.
Signed-off-by: Stefan Sørensen <stefan.sorensen@spectralink.com>
---
Changes since v1:
- Remove SIOCGMIIPHY from cpsw
- Mention that SIOCGMIIREG and SIOCSMIIREG support is gained
drivers/net/ethernet/ti/cpsw.c | 10 +++-------
1 file changed, 3 insertions(+), 7 deletions(-)
diff --git a/drivers/net/ethernet/ti/cpsw.c b/drivers/net/ethernet/ti/cpsw.c
index 1d860ce..6ecea1d 100644
--- a/drivers/net/ethernet/ti/cpsw.c
+++ b/drivers/net/ethernet/ti/cpsw.c
@@ -1471,7 +1471,6 @@ static int cpsw_hwtstamp_get(struct net_device *dev, struct ifreq *ifr)
static int cpsw_ndo_ioctl(struct net_device *dev, struct ifreq *req, int cmd)
{
struct cpsw_priv *priv = netdev_priv(dev);
- struct mii_ioctl_data *data = if_mii(req);
int slave_no = cpsw_slave_index(priv);
if (!netif_running(dev))
@@ -1484,14 +1483,11 @@ static int cpsw_ndo_ioctl(struct net_device *dev, struct ifreq *req, int cmd)
case SIOCGHWTSTAMP:
return cpsw_hwtstamp_get(dev, req);
#endif
- case SIOCGMIIPHY:
- data->phy_id = priv->slaves[slave_no].phy->addr;
- break;
- default:
- return -ENOTSUPP;
}
- return 0;
+ if (!priv->slaves[slave_no].phy)
+ return -EINVAL;
+ return phy_mii_ioctl(priv->slaves[slave_no].phy, req, cmd);
}
static void cpsw_ndo_tx_timeout(struct net_device *ndev)
--
1.8.5.3
^ permalink raw reply related
* Re: [PATCH v2 2/2] dp83640: Get pin and master/slave configuration from DT
From: Stefan Sørensen @ 2014-02-13 14:23 UTC (permalink / raw)
To: Richard Cochran
Cc: grant.likely, robh+dt, mark.rutland, netdev, linux-kernel,
devicetree
In-Reply-To: <20140211201917.GB4254@netboy>
On Tue, 2014-02-11 at 21:19 +0100, Richard Cochran wrote:
> > +- dp83640,slave: If present, this phy will be slave to another dp83640
> > + on the same mdio bus.
>
> Wouldn't it be more natural to have one "dp83640,master" property
> rather than multiple slave properties?
I wanted to keep the common case of a single phy simple, i.e. no need to
specify any master/slave properties.
> Most of these pr_err lines are a bit _way_ too long for coding style.
I will fix that in the next version.
Stefan
^ permalink raw reply
* Re: [PATCH v2 1/2] dp83640: Support a configurable number of periodic outputs
From: Stefan Sørensen @ 2014-02-13 14:21 UTC (permalink / raw)
To: Richard Cochran
Cc: grant.likely, robh+dt, mark.rutland, netdev, linux-kernel,
devicetree
In-Reply-To: <20140211200922.GA4254@netboy>
On Tue, 2014-02-11 at 21:09 +0100, Richard Cochran wrote:
> > -#define EXT_EVENT 1
>
> Regarding this EXT_EVENT thing ...
>
> > @@ -430,12 +419,12 @@ static int ptp_dp83640_enable(struct ptp_clock_info *ptp,
> > switch (rq->type) {
> > case PTP_CLK_REQ_EXTTS:
> > index = rq->extts.index;
> > - if (index < 0 || index >= N_EXT_TS)
> > + if (index < 0 || index >= n_ext_ts)
> > return -EINVAL;
> > - event_num = EXT_EVENT + index;
> > + event_num = index;
>
> there was a mapping between the "event numbers" and the external time
> stamp channels. I don't remember off the top of my head why this these
> two differ by one, but there was a good reason.
I haven't seen anything in the documentation regarding this, output
triggers 0 and 1 are special, but the events should all behave the same.
Could be be a mixup between events and pins? Pin0 means disable the
event.
> Are you sure this is still working with this change?
It has been running with event 0 in one of our products for at least the
last 3 months....
> I am especially wondering about the event decoding here:
>
> > @@ -642,7 +631,7 @@ static void recalibrate(struct dp83640_clock *clock)
> >
> > static inline u16 exts_chan_to_edata(int ch)
> > {
> > - return 1 << ((ch + EXT_EVENT) * 2);
> > + return 1 << ((ch) * 2);
> > }
>
> Maybe I am just paranoid, but can you remind me how these event
> numbers are supposed to work, before and after the change?
The mapping was hardcoded to map events 0-5 to event channels 1-6, the
periodic output trigger at channel 6 and the calibration event+trigger
both at channel 7.
The patch will (at least in v3 that I will post shortly) change both the
event and trigger mapping to a direct mapping and keep the calibration
at channel 7.
Stefan
^ permalink raw reply
* Re: [PATCH] drivers: net: cpsw: fix buggy loop condition
From: Mugunthan V N @ 2014-02-13 14:14 UTC (permalink / raw)
To: Heiko Schocher, linux-arm-kernel
Cc: David S. Miller, Sebastian Siewior, Daniel Mack, Felipe Balbi,
Markus Pargmann, netdev, linux-kernel
In-Reply-To: <1392299247-16917-1-git-send-email-hs@denx.de>
On Thursday 13 February 2014 07:17 PM, Heiko Schocher wrote:
> commit:
> From 0cd8f9cc0654c06adde353c6532114c5f53a18e8 Mon Sep 17 00:00:00 2001
> From: Mugunthan V N <mugunthanvnm@ti.com>
> Date: Thu, 23 Jan 2014 00:03:12 +0530
> Subject: [PATCH] drivers: net: cpsw: enable promiscuous mode support
>
> Enable promiscuous mode support for CPSW.
>
> Introduced a crash on an am335x based board (similiar to am335x-evm).
> Reason is buggy end condition in for loop in cpsw_set_promiscious()
>
> for (i = 0; i <= priv->data.slaves; i++)
>
> should be
>
> for (i = 0; i < priv->data.slaves; i++)
>
> Fix this ...
>
> Signed-off-by: Heiko Schocher <hs@denx.de>
> Cc: Mugunthan V N <mugunthanvnm@ti.com>
> Cc: David S. Miller <davem@davemloft.net>
> Cc: Sebastian Siewior <bigeasy@linutronix.de>
> Cc: Daniel Mack <zonque@gmail.com>
> Cc: Felipe Balbi <balbi@ti.com>
> Cc: Markus Pargmann <mpa@pengutronix.de>
> Cc: netdev@vger.kernel.org
> Cc: linux-kernel@vger.kernel.org
Ah, it's copy paste error, thanks for the fix.
Acked-by: Mugunthan V N <mugunthanvnm@ti.com>
Regards
Mugunthan V N
^ permalink raw reply
* Re: [PATCH] net: cpsw: catch of_get_phy_mode failing and propagate error
From: Mugunthan V N @ 2014-02-13 14:11 UTC (permalink / raw)
To: Uwe Kleine-König, netdev; +Cc: kernel, David S. Miller
In-Reply-To: <1392244402-24823-1-git-send-email-u.kleine-koenig@pengutronix.de>
On Thursday 13 February 2014 04:03 AM, Uwe Kleine-König wrote:
> It's wrong if the device tree doesn't provide a phy-mode property for
> the cpsw slaves as it is documented to be required in
> Documentation/devicetree/bindings/net/cpsw.txt.
>
> Anyhow it's nice to catch that problem, still more as it used to work
> without this property up to commit 388367a5a9fb (drivers: net: cpsw: use
> cpsw-phy-sel driver to configure phy mode) which is in v3.13-rc1.
>
> Signed-off-by: Uwe Kleine-König <u.kleine-koenig@pengutronix.de>
Good catch
Acked-by: Mugunthan V N <mugunthanvnm@ti.com>
Regards
Mugunthan V N
^ permalink raw reply
* [PATCH] drivers: net: cpsw: fix buggy loop condition
From: Heiko Schocher @ 2014-02-13 13:47 UTC (permalink / raw)
To: linux-arm-kernel
Cc: Heiko Schocher, Mugunthan V N, David S. Miller, Sebastian Siewior,
Daniel Mack, Felipe Balbi, Markus Pargmann, netdev, linux-kernel
commit:
>From 0cd8f9cc0654c06adde353c6532114c5f53a18e8 Mon Sep 17 00:00:00 2001
From: Mugunthan V N <mugunthanvnm@ti.com>
Date: Thu, 23 Jan 2014 00:03:12 +0530
Subject: [PATCH] drivers: net: cpsw: enable promiscuous mode support
Enable promiscuous mode support for CPSW.
Introduced a crash on an am335x based board (similiar to am335x-evm).
Reason is buggy end condition in for loop in cpsw_set_promiscious()
for (i = 0; i <= priv->data.slaves; i++)
should be
for (i = 0; i < priv->data.slaves; i++)
Fix this ...
Signed-off-by: Heiko Schocher <hs@denx.de>
Cc: Mugunthan V N <mugunthanvnm@ti.com>
Cc: David S. Miller <davem@davemloft.net>
Cc: Sebastian Siewior <bigeasy@linutronix.de>
Cc: Daniel Mack <zonque@gmail.com>
Cc: Felipe Balbi <balbi@ti.com>
Cc: Markus Pargmann <mpa@pengutronix.de>
Cc: netdev@vger.kernel.org
Cc: linux-kernel@vger.kernel.org
---
complete crash dump
[ 4.986544] Unable to handle kernel NULL pointer dereference at virtual address 00000120
[ 4.995056] pgd = c0004000
[ 4.997906] [00000120] *pgd=00000000
[ 5.001723] Internal error: Oops: 5 [#1] SMP ARM
[ 5.006560] Modules linked in:
[ 5.009773] CPU: 0 PID: 1 Comm: swapper/0 Not tainted 3.14.0-rc1-01621-ga10cd7e-dirty #9
[ 5.018243] task: c607b540 ti: c607c000 task.ti: c607c000
[ 5.023914] PC is at cpsw_set_promiscious+0x1d8/0x2a4
[ 5.029204] LR is at cpsw_set_promiscious+0x1c0/0x2a4
[ 5.034494] pc : [<c0407c18>] lr : [<c0407c00>] psr: 60000113
[ 5.034494] sp : c607dd88 ip : c0984ab8 fp : c085c7cc
[ 5.046506] r10: 00000024 r9 : c64b31d8 r8 : 00000003
[ 5.051974] r7 : 00000000 r6 : c64ad800 r5 : c64b3080 r4 : 00000000
[ 5.058806] r3 : 00000003 r2 : c64b3190 r1 : 00000002 r0 : 00000000
[ 5.065641] Flags: nZCv IRQs on FIQs on Mode SVC_32 ISA ARM Segment kernel
[ 5.073291] Control: 10c5387d Table: 80004019 DAC: 00000017
[ 5.079303] Process swapper/0 (pid: 1, stack limit = 0xc607c248)
[ 5.085592] Stack: (0xc607dd88 to 0xc607e000)
[ 5.090158] dd80: c64ad800 c05ff710 00000000 00000000 00000000 00001002
[ 5.098722] dda0: 0000016b c0409c44 00000000 00000000 c64ad800 c05ff710 00000000 00000000
[ 5.107287] ddc0: 00000000 00001002 0000016b c04cd8cc c64ad964 c64ad800 c64ad82c c04cd920
[ 5.115850] dde0: 00001003 c64ad800 c05ff710 c04cd9f0 00000000 c64ad800 00001002 c64ad800
[ 5.124414] de00: 00001003 00000001 00001002 c04cdc58 c64ad800 00000128 00001002 c08fe840
[ 5.132979] de20: 00000000 c04cdd58 c64ad800 00000003 c085c7e0 c08fe840 c085c7cc c0847ce8
[ 5.141543] de40: 00000000 c058fbf4 c607b540 c5b17cd0 c5b131c8 00000000 12400000 c02a1558
[ 5.150105] de60: c5b17d0c 00000000 00000002 00000000 00000000 00000000 00000002 00000000
[ 5.158669] de80: c05185b4 c00873ac 00000002 00000000 00000000 c05185b4 00000000 c607c030
[ 5.167233] dea0: c607c008 60000113 c08f79c0 c0901610 00000007 c090bdc0 c090bdc0 c08459c8
[ 5.175798] dec0: c0901610 00000007 c090bdc0 c08615ac 00000007 c090bdc0 c090bdc0 c0847b58
[ 5.184362] dee0: 000000bd c607c030 00000000 c0008918 00000004 c08bfa30 c08bfa30 60000113
[ 5.192926] df00: c0089d00 00000000 c08bfa2c 00000000 00000000 c0590db0 00000002 c607c000
[ 5.201489] df20: c7eff36d c05dd514 000000bd c005df1c c07d1ed4 00000007 c7eff419 00000007
[ 5.210054] df40: 60000113 c08615ac 00000007 c090bdc0 c090bdc0 c080450c 000000bd c084d950
[ 5.218620] df60: c084d948 c0804c1c 00000007 00000007 c080450c dfdedeff fcdfffff c7dd9ec0
[ 5.227183] df80: c607c018 00000000 c058668c 00000000 00000000 00000000 00000000 00000000
[ 5.235747] dfa0: 00000000 c0586694 00000000 c000e548 00000000 00000000 00000000 00000000
[ 5.244310] dfc0: 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000
[ 5.252873] dfe0: 00000000 00000000 00000000 00000000 00000013 00000000 fffff6f7 7ffeefbf
[ 5.261448] [<c0407c18>] (cpsw_set_promiscious) from [<c0409c44>] (cpsw_ndo_set_rx_mode+0x20/0xf8)
[ 5.270841] [<c0409c44>] (cpsw_ndo_set_rx_mode) from [<c04cd8cc>] (__dev_set_rx_mode+0x5c/0x94)
[ 5.279952] [<c04cd8cc>] (__dev_set_rx_mode) from [<c04cd920>] (dev_set_rx_mode+0x1c/0x28)
[ 5.288609] [<c04cd920>] (dev_set_rx_mode) from [<c04cd9f0>] (__dev_open+0xc4/0x110)
[ 5.296720] [<c04cd9f0>] (__dev_open) from [<c04cdc58>] (__dev_change_flags+0x88/0x170)
[ 5.305102] [<c04cdc58>] (__dev_change_flags) from [<c04cdd58>] (dev_change_flags+0x18/0x48)
[ 5.313945] [<c04cdd58>] (dev_change_flags) from [<c0847ce8>] (ip_auto_config+0x190/0x110c)
[ 5.322697] [<c0847ce8>] (ip_auto_config) from [<c0008918>] (do_one_initcall+0xe8/0x148)
[ 5.331190] [<c0008918>] (do_one_initcall) from [<c0804c1c>] (kernel_init_freeable+0x104/0x1c8)
[ 5.340316] [<c0804c1c>] (kernel_init_freeable) from [<c0586694>] (kernel_init+0x8/0x118)
[ 5.348890] [<c0586694>] (kernel_init) from [<c000e548>] (ret_from_fork+0x14/0x2c)
[ 5.356821] Code: e0829009 e2888001 e5990018 e1a03008 (e5900120)
[ 5.363291] ---[ end trace ba29586f1d312ca3 ]---
[ 5.369343] Kernel panic - not syncing: Fatal exception in interrupt
[ 5.376005] drm_kms_helper: panic occurred, switching back to text console
---
drivers/net/ethernet/ti/cpsw.c | 6 +++---
1 file changed, 3 insertions(+), 3 deletions(-)
diff --git a/drivers/net/ethernet/ti/cpsw.c b/drivers/net/ethernet/ti/cpsw.c
index bde63e3..34b4262 100644
--- a/drivers/net/ethernet/ti/cpsw.c
+++ b/drivers/net/ethernet/ti/cpsw.c
@@ -554,7 +554,7 @@ static void cpsw_set_promiscious(struct net_device *ndev, bool enable)
* common for both the interface as the interface shares
* the same hardware resource.
*/
- for (i = 0; i <= priv->data.slaves; i++)
+ for (i = 0; i < priv->data.slaves; i++)
if (priv->slaves[i].ndev->flags & IFF_PROMISC)
flag = true;
@@ -578,7 +578,7 @@ static void cpsw_set_promiscious(struct net_device *ndev, bool enable)
unsigned long timeout = jiffies + HZ;
/* Disable Learn for all ports */
- for (i = 0; i <= priv->data.slaves; i++) {
+ for (i = 0; i < priv->data.slaves; i++) {
cpsw_ale_control_set(ale, i,
ALE_PORT_NOLEARN, 1);
cpsw_ale_control_set(ale, i,
@@ -606,7 +606,7 @@ static void cpsw_set_promiscious(struct net_device *ndev, bool enable)
cpsw_ale_control_set(ale, 0, ALE_P0_UNI_FLOOD, 0);
/* Enable Learn for all ports */
- for (i = 0; i <= priv->data.slaves; i++) {
+ for (i = 0; i < priv->data.slaves; i++) {
cpsw_ale_control_set(ale, i,
ALE_PORT_NOLEARN, 0);
cpsw_ale_control_set(ale, i,
--
1.8.3.1
^ permalink raw reply related
* Re: RFC: bridge get fdb by bridge device
From: Jamal Hadi Salim @ 2014-02-13 12:50 UTC (permalink / raw)
To: John Fastabend
Cc: vyasevic, netdev@vger.kernel.org, Stephen Hemminger,
Scott Feldman
In-Reply-To: <52FBC282.6020301@intel.com>
On 02/12/14 13:50, John Fastabend wrote:
>
> Just to wrap things up in one email. Changing between VEB and VEPA
> modes already triggers an event. So management applications can listen
> for this.
>
Ok - reasonable.
> And I can send out a patch to add a flag to hardware bridge devices
> I'll likely get to it next week sometime unless someone beats me
> to it.
>
You understand this better - so i will wait.
I'll send an updated version of the patch this weekend
now that net-next is open.
>
> Sure, IEEE802.1Q would call these edge relays.
>
Ok, so what older kids used to call "repeaters".
The more i think about it, the more it looks like this is
still a bridge and we have a bridgeport mode as VEPA vs VEB.
IOW, as you said - you can have a bridge with mix and match of
VEB/VEPA. We can easily add such a feature to the software bridge
as well. It sounds simple and useful enough.
>
> Because it is not the same type of object as the software bridge.
> Most notably it doesn't do learning. If anything its more like a
> macvlan device and we could just as easily tag it IFF_MACVLAN. So
> because it doesn't really match 1:1 with either of those object I
> would just presume give its own flag. Userspace can always create
> a small macro call it is_bridge_like() and check for any of the
> handful of bridge like objects.
>
I think VEB/VEP may be somehow covering the "port" aspect.
The challenge is what to call "eth0 when running in SRIOV"
>>>
>>> # ip link set dev bridge0 master bridge1
>>> RTNETLINK answers: Too many levels of symbolic links
>>>
>>
>> pourquoi? If the original rationale was to limit the
>> broadcast domain scope it sounds strange that a bridge in
>> the form a macvlan is allowed.
>>
>
> Agreed. But there it is.
>
I am sure someone knows why - Stephen?
cheers,
jamal
^ permalink raw reply
* Re: [PATCH v3 2/2] sctp: optimize the sctp_sysctl_net_register
From: Neil Horman @ 2014-02-13 12:44 UTC (permalink / raw)
To: Wang Weidong; +Cc: davem, vyasevich, dborkman, sergei.shtylyov, netdev
In-Reply-To: <52FC1D9D.3090500@huawei.com>
On Thu, Feb 13, 2014 at 09:19:25AM +0800, Wang Weidong wrote:
> On 2014/2/12 19:53, Neil Horman wrote:
> > On Wed, Feb 12, 2014 at 09:44:44AM +0800, Wang Weidong wrote:
> >> Here, when the net is init_net, we needn't to kmemdup the ctl_table
> >> again. So add a check for net. Also we can save some memory.
> >>
> >> Signed-off-by: Wang Weidong <wangweidong1@huawei.com>
> >> ---
> >> net/sctp/sysctl.c | 17 ++++++++++-------
> >> 1 file changed, 10 insertions(+), 7 deletions(-)
> >>
> >> diff --git a/net/sctp/sysctl.c b/net/sctp/sysctl.c
> >> index d354de5..35c8923 100644
> >> --- a/net/sctp/sysctl.c
> >> +++ b/net/sctp/sysctl.c
> >> @@ -402,15 +402,18 @@ static int proc_sctp_do_rto_max(struct ctl_table *ctl, int write,
> >>
> >> int sctp_sysctl_net_register(struct net *net)
> >> {
> >> - struct ctl_table *table;
> >> - int i;
> >> + struct ctl_table *table = sctp_net_table;
> >> +
> >> + if (!net_eq(net, &init_net)) {
> >> + int i;
> >>
> >> - table = kmemdup(sctp_net_table, sizeof(sctp_net_table), GFP_KERNEL);
> >> - if (!table)
> >> - return -ENOMEM;
> >> + table = kmemdup(sctp_net_table, sizeof(sctp_net_table), GFP_KERNEL);
> >> + if (!table)
> >> + return -ENOMEM;
> >>
> >> - for (i = 0; table[i].data; i++)
> >> - table[i].data += (char *)(&net->sctp) - (char *)&init_net.sctp;
> >> + for (i = 0; table[i].data; i++)
> >> + table[i].data += (char *)(&net->sctp) - (char *)&init_net.sctp;
> >> + }
> >>
> > In the first version of this patch you complained about a lockdep issue. Did
> > you figure out what that was, and if it related to these changes?
> >
> > Neil
> >
> >
> Hi Neil,
>
> The lockdep issue doesn't relate to these changes. I should send it
> by the another email. Sorry for confusing you.
>
> Regards
> Wang
>
Then you probably don't need to mention it in the same note that you're
proposing changes.
Acked-by: Neil Horman <nhorman@tuxdriver.com>
^ permalink raw reply
page: next (older) | prev (newer) | latest
- recent:[subjects (threaded)|topics (new)|topics (active)]
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox