#include <linux/etherdevice.h>
#include <linux/platform_device.h>
#include <linux/serial_8250.h>
+#include <linux/clk.h>
#include <asm/mach-ath79/ath79.h>
#include <asm/mach-ath79/ar71xx_regs.h>
iounmap(base);
}
+static unsigned long ar934x_get_mdio_ref_clock(void)
+{
+ void __iomem *base;
+ unsigned long ret;
+ u32 t;
+
+ base = ioremap(AR71XX_PLL_BASE, AR71XX_PLL_SIZE);
+
+ ret = 0;
+ t = __raw_readl(base + AR934X_PLL_SWITCH_CLOCK_CONTROL_REG);
+ if (t & AR934X_PLL_SWITCH_CLOCK_CONTROL_MDIO_CLK_SEL) {
+ ret = 100 * 1000 * 1000;
+ } else {
+ struct clk *clk;
+
+ clk = clk_get(NULL, "ref");
+ if (!IS_ERR(clk))
+ ret = clk_get_rate(clk);
+ }
+
+ iounmap(base);
+
+ return ret;
+}
+
void __init ath79_register_mdio(unsigned int id, u32 phy_mask)
{
struct platform_device *mdio_dev;
case ATH79_SOC_AR9341:
case ATH79_SOC_AR9342:
case ATH79_SOC_AR9344:
+ if (id == 1) {
+ mdio_data->builtin_switch = 1;
+ mdio_data->ref_clock = ar934x_get_mdio_ref_clock();
+ mdio_data->mdio_clock = 6250000;
+ }
+ mdio_data->is_ar934x = 1;
+ break;
case ATH79_SOC_QCA9558:
if (id == 1)
mdio_data->builtin_switch = 1;
case ATH79_SOC_AR9341:
case ATH79_SOC_AR9342:
case ATH79_SOC_AR9344:
- case ATH79_SOC_QCA9558:
switch (pdata->phy_if_mode) {
case PHY_INTERFACE_MODE_MII:
case PHY_INTERFACE_MODE_GMII:
}
break;
+ case ATH79_SOC_QCA9558:
+ switch (pdata->phy_if_mode) {
+ case PHY_INTERFACE_MODE_MII:
+ case PHY_INTERFACE_MODE_RGMII:
+ case PHY_INTERFACE_MODE_SGMII:
+ break;
+ default:
+ return -EINVAL;
+ }
+ break;
+
default:
BUG();
}
break;
case ATH79_SOC_AR7242:
+ /* FIXME */
+
+ case ATH79_SOC_AR9341:
+ case ATH79_SOC_AR9342:
+ case ATH79_SOC_AR9344:
switch (pdata->phy_if_mode) {
- case PHY_INTERFACE_MODE_RGMII:
+ case PHY_INTERFACE_MODE_MII:
+ case PHY_INTERFACE_MODE_GMII:
break;
default:
- /* Other PHY modes are not tested yet. */
return -EINVAL;
}
break;
- case ATH79_SOC_AR9341:
- case ATH79_SOC_AR9342:
- case ATH79_SOC_AR9344:
case ATH79_SOC_QCA9558:
switch (pdata->phy_if_mode) {
case PHY_INTERFACE_MODE_MII:
- case PHY_INTERFACE_MODE_GMII:
+ case PHY_INTERFACE_MODE_RGMII:
+ case PHY_INTERFACE_MODE_SGMII:
break;
default:
return -EINVAL;
iounmap(base);
}
+void __init ath79_setup_ar934x_eth_cfg(u32 mask)
+{
+ void __iomem *base;
+ u32 t;
+
+ base = ioremap(AR934X_GMAC_BASE, AR934X_GMAC_SIZE);
+
+ t = __raw_readl(base + AR934X_GMAC_REG_ETH_CFG);
+
+ t &= ~(AR934X_ETH_CFG_RGMII_GMAC0 |
+ AR934X_ETH_CFG_MII_GMAC0 |
+ AR934X_ETH_CFG_GMII_GMAC0 |
+ AR934X_ETH_CFG_SW_ONLY_MODE |
+ AR934X_ETH_CFG_SW_PHY_SWAP);
+
+ t |= mask;
+
+ __raw_writel(t, base + AR934X_GMAC_REG_ETH_CFG);
+ /* flush write */
+ __raw_readl(base + AR934X_GMAC_REG_ETH_CFG);
+
+ iounmap(base);
+}
+
static int ath79_eth_instance __initdata;
void __init ath79_register_eth(unsigned int id)
{
switch (pdata->phy_if_mode) {
case PHY_INTERFACE_MODE_GMII:
case PHY_INTERFACE_MODE_RGMII:
+ case PHY_INTERFACE_MODE_SGMII:
if (!pdata->has_gbit) {
printk(KERN_ERR "ar71xx: no gbit available on eth%d\n",
id);
case ATH79_SOC_AR9341:
case ATH79_SOC_AR9342:
case ATH79_SOC_AR9344:
- case ATH79_SOC_QCA9558:
if (id == 0)
pdata->mii_bus_dev = &ath79_mdio0_device.dev;
else
pdata->mii_bus_dev = &ath79_mdio1_device.dev;
break;
+ case ATH79_SOC_QCA9558:
+ /* don't assign any MDIO device by default */
+ break;
+
default:
pdata->mii_bus_dev = &ath79_mdio0_device.dev;
break;
{
int t;
- if (!is_valid_ether_addr(src)) {
+ if (!dst)
+ return;
+
+ if (!src || !is_valid_ether_addr(src)) {
memset(dst, '\0', ETH_ALEN);
return;
}
{
int i;
- if (!is_valid_ether_addr(src)) {
+ if (!dst)
+ return;
+
+ if (!src || !is_valid_ether_addr(src)) {
memset(dst, '\0', ETH_ALEN);
return;
}