+ while(!(mii_reg & 0x0020) && timeout--)
+ {
+ regstat=mk_mii_read(MII_BMSR);
+ regstat |= fep->phy_addr <<23;
+ mii_reg = mii_send_receive(fep->fip,regstat);
+ }
+
+ mii_parse_sr(mii_reg, dev);
+}
+
+static void mii_parse_dm9161_scsr(uint mii_reg, struct net_device * dev)
+{
+ volatile struct fcc_enet_private *fep = dev->priv;
+ uint s = fep->phy_status;
+
+ s &= ~(PHY_STAT_SPMASK);
+ switch((mii_reg >>12) & 0xf) {
+ case 1:
+ {
+ s |= PHY_STAT_10HDX;
+ printk("10BaseT Half Duplex\n");
+ break;
+ }
+ case 2:
+ {
+ s |= PHY_STAT_10FDX;
+ printk("10BaseT Full Duplex\n");
+ break;
+ }
+ case 4:
+ {
+ s |= PHY_STAT_100HDX;
+ printk("100BaseT Half Duplex\n");
+ break;
+ }
+ case 8:
+ {
+ s |= PHY_STAT_100FDX;
+ printk("100BaseT Full Duplex\n");
+ break;
+ }
+ }
+
+ fep->phy_status = s;
+
+}
+
+static void mii_dm9161_wait(uint mii_reg, struct net_device *dev)
+{
+ int timeout = HZ;
+
+ /* Davicom takes a bit to come up after a reset,
+ * so wait here for a bit */
+ schedule_timeout_uninterruptible(timeout);
+}
+
+static phy_info_t phy_info_dm9161 = {
+ 0x00181b88,
+ "Davicom DM9161E",
+ (const phy_cmd_t[]) { /* config */
+ { mk_mii_write(MII_BMCR, MIIM_DM9161_CR_STOP), NULL},
+ /* Do not bypass the scrambler/descrambler */
+ { mk_mii_write(MIIM_DM9161_SCR, MIIM_DM9161_SCR_INIT), NULL},
+ /* Configure 10BTCSR register */
+ { mk_mii_write(MIIM_DM9161_10BTCSR, MIIM_DM9161_10BTCSR_INIT),NULL},
+ /* Configure some basic stuff */
+ { mk_mii_write(MII_BMCR, 0x1000), NULL},
+ { mk_mii_read(MII_BMCR), mii_parse_cr },
+ { mk_mii_read(MII_ADVERTISE), mii_parse_anar },
+ { mk_mii_end,}
+ },
+ (const phy_cmd_t[]) { /* startup */
+ /* Restart Auto Negotiation */
+ { mk_mii_write(MII_BMCR, MIIM_DM9161_CR_RSTAN), NULL},
+ /* Status is read once to clear old link state */
+ { mk_mii_read(MII_BMSR), mii_dm9161_wait},
+ /* Auto-negotiate */
+ { mk_mii_read(MII_BMSR), mii_parse_dm9161_sr},
+ /* Read the status */
+ { mk_mii_read(MIIM_DM9161_SCSR), mii_parse_dm9161_scsr},
+ /* Clear any pending interrupts */
+ { mk_mii_read(MIIM_DM9161_INTR), NULL},
+ /* Enable Interrupts */
+ { mk_mii_write(MIIM_DM9161_INTR, MIIM_DM9161_INTR_INIT), NULL},
+ { mk_mii_end,}
+ },
+ (const phy_cmd_t[]) { /* ack_int */
+ { mk_mii_read(MIIM_DM9161_INTR), NULL},
+#if 0
+ { mk_mii_read(MII_BMSR), NULL},
+ { mk_mii_read(MII_BMSR), mii_parse_dm9161_sr},
+ { mk_mii_read(MIIM_DM9161_SCSR), mii_parse_dm9161_scsr},
+#endif
+ { mk_mii_end,}
+ },
+ (const phy_cmd_t[]) { /* shutdown */
+ { mk_mii_read(MIIM_DM9161_INTR),NULL},
+ { mk_mii_write(MIIM_DM9161_INTR, MIIM_DM9161_INTR_STOP), NULL},
+ { mk_mii_end,}
+ },
+};
+#endif /* CONFIG_FCC_DM9161 */