+ mutex_unlock(&priv->reg_mutex);
+ return 0;
+}
+
+static int
+ar8316_hw_init(struct ar8216_priv *priv) {
+ static int initialized;
+ int i;
+ u32 val;
+ struct mii_bus *bus;
+
+ if (initialized)
+ return 0;
+
+ val = priv->read(priv, 0x8);
+
+ if (priv->phy->interface == PHY_INTERFACE_MODE_RGMII) {
+ /* value taken from Ubiquiti RouterStation Pro */
+ if (val == 0x81461bea) {
+ /* switch already intialized by bootloader */
+ initialized = true;
+ return 0;
+ }
+ priv->write(priv, 0x8, 0x81461bea);
+ } else if (priv->phy->interface == PHY_INTERFACE_MODE_GMII) {
+ /* value taken from AVM Fritz!Box 7390 sources */
+ if (val == 0x010e5b71) {
+ /* switch already initialized by bootloader */
+ initialized = true;
+ return 0;
+ }
+ priv->write(priv, 0x8, 0x010e5b71);
+ } else {
+ /* no known value for phy interface */
+ printk(KERN_ERR "ar8316: unsupported mii mode: %d.\n",
+ priv->phy->interface);
+ return -EINVAL;
+ }
+
+ /* standard atheros magic */
+ priv->write(priv, 0x38, 0xc000050e);
+
+ /* Initialize the ports */
+ bus = priv->phy->bus;
+ for (i = 0; i < 5; i++) {
+ if ((i == 4) &&
+ priv->phy->interface == PHY_INTERFACE_MODE_RGMII) {
+ /* work around for phy4 rgmii mode */
+ bus->write(bus, i, MII_ATH_DBG_ADDR, 0x12);
+ bus->write(bus, i, MII_ATH_DBG_DATA, 0x480c);
+ /* rx delay */
+ bus->write(bus, i, MII_ATH_DBG_ADDR, 0x0);
+ bus->write(bus, i, MII_ATH_DBG_DATA, 0x824e);
+ /* tx delay */
+ bus->write(bus, i, MII_ATH_DBG_ADDR, 0x5);
+ bus->write(bus, i, MII_ATH_DBG_DATA, 0x3d47);
+ msleep(1000);
+ }