/* ZMII only supports MII, RMII and SMII * we also support autodetection for backward compatibility
*/ staticinlineint zmii_valid_mode(int mode)
{ return mode == PHY_INTERFACE_MODE_MII ||
mode == PHY_INTERFACE_MODE_RMII ||
mode == PHY_INTERFACE_MODE_SMII ||
mode == PHY_INTERFACE_MODE_NA;
}
staticinlineconstchar *zmii_mode_name(int mode)
{ switch (mode) { case PHY_INTERFACE_MODE_MII: return"MII"; case PHY_INTERFACE_MODE_RMII: return"RMII"; case PHY_INTERFACE_MODE_SMII: return"SMII"; default:
BUG();
}
}
staticinline u32 zmii_mode_mask(int mode, int input)
{ switch (mode) { case PHY_INTERFACE_MODE_MII: return ZMII_FER_MII(input); case PHY_INTERFACE_MODE_RMII: return ZMII_FER_RMII(input); case PHY_INTERFACE_MODE_SMII: return ZMII_FER_SMII(input); default: return 0;
}
}
int zmii_attach(struct platform_device *ofdev, int input,
phy_interface_t *mode)
{ struct zmii_instance *dev = platform_get_drvdata(ofdev); struct zmii_regs __iomem *p = dev->base;
ZMII_DBG(dev, "init(%d, %d)" NL, input, *mode);
if (!zmii_valid_mode(*mode)) { /* Probably an EMAC connected to RGMII, * but it still may need ZMII for MDIO so * we don't fail here.
*/
dev->users++; return 0;
}
mutex_lock(&dev->lock);
/* Autodetect ZMII mode if not specified. * This is only for backward compatibility with the old driver. * Please, always specify PHY mode in your board port to avoid * any surprises.
*/ if (dev->mode == PHY_INTERFACE_MODE_NA) { if (*mode == PHY_INTERFACE_MODE_NA) {
u32 r = dev->fer_save;
ZMII_DBG(dev, "autodetecting mode, FER = 0x%08x" NL, r);
if (r & (ZMII_FER_MII(0) | ZMII_FER_MII(1)))
dev->mode = PHY_INTERFACE_MODE_MII; elseif (r & (ZMII_FER_RMII(0) | ZMII_FER_RMII(1)))
dev->mode = PHY_INTERFACE_MODE_RMII; else
dev->mode = PHY_INTERFACE_MODE_SMII;
} else {
dev->mode = *mode;
}
printk(KERN_NOTICE "%pOF: bridge in %s mode\n",
ofdev->dev.of_node,
zmii_mode_name(dev->mode));
} else { /* All inputs must use the same mode */ if (*mode != PHY_INTERFACE_MODE_NA && *mode != dev->mode) {
printk(KERN_ERR "%pOF: invalid mode %d specified for input %d\n",
ofdev->dev.of_node, *mode, input);
mutex_unlock(&dev->lock); return -EINVAL;
}
}
/* Report back correct PHY mode, * it may be used during PHY initialization.
*/
*mode = dev->mode;
hdr->version = 0;
hdr->index = 0; /* for now, are there chips with more than one * zmii ? if yes, then we'll add a cell_index * like we do for emac
*/
memcpy_fromio(regs, dev->base, sizeof(struct zmii_regs)); return regs + 1;
}
staticint zmii_probe(struct platform_device *ofdev)
{ struct zmii_instance *dev; int err;
dev = devm_kzalloc(&ofdev->dev, sizeof(struct zmii_instance),
GFP_KERNEL); if (!dev) return -ENOMEM;
err = devm_mutex_init(&ofdev->dev, &dev->lock); if (err) return err;
Die Informationen auf dieser Webseite wurden
nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit,
noch Qualität der bereit gestellten Informationen zugesichert.
Bemerkung:
Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.