Skip to content

Commit

Permalink
rswitch: Fix PHY station management clock setting
Browse files Browse the repository at this point in the history
Fix the MPIC.PSMCS value following the programming example in the
section 6.4.2 Management Data Clock (MDC) Setting, Ethernet MAC IP,
S4 Hardware User Manual Rev.1.00.

The value is calculated by
    MPIC.PSMCS = clk[MHz] / (MDC frequency[MHz] * 2) - 1
with the input clock frequency from clk_get_rate() and MDC frequency
of 2.5MHz. Otherwise, this driver cannot communicate PHYs on the R-Car
S4 Starter Kit board.

Fixes: 3590918 ("net: ethernet: renesas: Add support for "Ethernet Switch"")
Reported-by: Tam Nguyen <tam.nguyen.xa@renesas.com>
Signed-off-by: Yoshihiro Shimoda <yoshihiro.shimoda.uh@renesas.com>
Tested-by: Kuninori Morimoto <kuninori.morimoto.gx@renesas.com>
Reviewed-by: Andrew Lunn <andrew@lunn.ch>
Link: https://lore.kernel.org/r/20230926123054.3976752-1-yoshihiro.shimoda.uh@renesas.com
Signed-off-by: Jakub Kicinski <kuba@kernel.org>
  • Loading branch information
Yoshihiro Shimoda authored and Jakub Kicinski committed Oct 3, 2023
1 parent dfc7f7a commit a0c55bb
Show file tree
Hide file tree
Showing 2 changed files with 14 additions and 1 deletion.
13 changes: 12 additions & 1 deletion drivers/net/ethernet/renesas/rswitch.c
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
* Copyright (C) 2022 Renesas Electronics Corporation
*/

#include <linux/clk.h>
#include <linux/dma-mapping.h>
#include <linux/err.h>
#include <linux/etherdevice.h>
Expand Down Expand Up @@ -1049,7 +1050,7 @@ static void rswitch_rmac_setting(struct rswitch_etha *etha, const u8 *mac)
static void rswitch_etha_enable_mii(struct rswitch_etha *etha)
{
rswitch_modify(etha->addr, MPIC, MPIC_PSMCS_MASK | MPIC_PSMHT_MASK,
MPIC_PSMCS(0x05) | MPIC_PSMHT(0x06));
MPIC_PSMCS(etha->psmcs) | MPIC_PSMHT(0x06));
rswitch_modify(etha->addr, MPSM, 0, MPSM_MFF_C45);
}

Expand Down Expand Up @@ -1693,6 +1694,12 @@ static void rswitch_etha_init(struct rswitch_private *priv, int index)
etha->index = index;
etha->addr = priv->addr + RSWITCH_ETHA_OFFSET + index * RSWITCH_ETHA_SIZE;
etha->coma_addr = priv->addr;

/* MPIC.PSMCS = (clk [MHz] / (MDC frequency [MHz] * 2) - 1.
* Calculating PSMCS value as MDC frequency = 2.5MHz. So, multiply
* both the numerator and the denominator by 10.
*/
etha->psmcs = clk_get_rate(priv->clk) / 100000 / (25 * 2) - 1;
}

static int rswitch_device_alloc(struct rswitch_private *priv, int index)
Expand Down Expand Up @@ -1900,6 +1907,10 @@ static int renesas_eth_sw_probe(struct platform_device *pdev)
return -ENOMEM;
spin_lock_init(&priv->lock);

priv->clk = devm_clk_get(&pdev->dev, NULL);
if (IS_ERR(priv->clk))
return PTR_ERR(priv->clk);

attr = soc_device_match(rswitch_soc_no_speed_change);
if (attr)
priv->etha_no_runtime_change = true;
Expand Down
2 changes: 2 additions & 0 deletions drivers/net/ethernet/renesas/rswitch.h
Original file line number Diff line number Diff line change
Expand Up @@ -915,6 +915,7 @@ struct rswitch_etha {
bool external_phy;
struct mii_bus *mii;
phy_interface_t phy_interface;
u32 psmcs;
u8 mac_addr[MAX_ADDR_LEN];
int link;
int speed;
Expand Down Expand Up @@ -1012,6 +1013,7 @@ struct rswitch_private {
struct rswitch_mfwd mfwd;

spinlock_t lock; /* lock interrupt registers' control */
struct clk *clk;

bool etha_no_runtime_change;
bool gwca_halt;
Expand Down

0 comments on commit a0c55bb

Please sign in to comment.