static int sel_phy_reg_page(struct ti_lynx *lynx, int page) { int reg; if (page > 7) { PRINT(KERN_ERR, lynx->id, "%s: PHY page %d out of range", __FUNCTION__, page); return -1; } reg = get_phy_reg(lynx, 7); if (reg != -1) { reg &= 0x1f; reg |= (page << 5); set_phy_reg(lynx, 7, reg); return 0; } else { return -1; } }
/*********************************** * IEEE-1394 functionality section * ***********************************/ static int get_phy_reg(struct ti_lynx *lynx, int addr) { int retval; int i = 0; unsigned long flags; if (addr > 15) { PRINT(KERN_ERR, lynx->id, "%s: PHY register address %d out of range", __FUNCTION__, addr); return -1; } spin_lock_irqsave(&lynx->phy_reg_lock, flags); reg_write(lynx, LINK_PHY, LINK_PHY_READ | LINK_PHY_ADDR(addr)); do { retval = reg_read(lynx, LINK_PHY); if (i > 10000) { PRINT(KERN_ERR, lynx->id, "%s: runaway loop, aborting", __FUNCTION__); retval = -1; break; } i++; } while ((retval & 0xf00) != LINK_PHY_RADDR(addr)); reg_write(lynx, LINK_INT_STATUS, LINK_INT_PHY_REG_RCVD); spin_unlock_irqrestore(&lynx->phy_reg_lock, flags); if (retval != -1) { return retval & 0xff; } else { return -1; } } static int set_phy_reg(struct ti_lynx *lynx, int addr, int val) { unsigned long flags; if (addr > 15) { PRINT(KERN_ERR, lynx->id, "%s: PHY register address %d out of range", __FUNCTION__, addr); return -1; } if (val > 0xff) { PRINT(KERN_ERR, lynx->id, "%s: PHY register value %d out of range", __FUNCTION__, val); return -1; } spin_lock_irqsave(&lynx->phy_reg_lock, flags); reg_write(lynx, LINK_PHY, LINK_PHY_WRITE | LINK_PHY_ADDR(addr) | LINK_PHY_WDATA(val)); spin_unlock_irqrestore(&lynx->phy_reg_lock, flags); return 0; } static int sel_phy_reg_page(struct ti_lynx *lynx, int page) { int reg; if (page > 7) { PRINT(KERN_ERR, lynx->id, "%s: PHY page %d out of range", __FUNCTION__, page); return -1; } reg = get_phy_reg(lynx, 7); if (reg != -1) { reg &= 0x1f; reg |= (page << 5); set_phy_reg(lynx, 7, reg); return 0; } else { return -1; } } #if 0 /* not needed at this time */ static int sel_phy_reg_port(struct ti_lynx *lynx, int port) { int reg; if (port > 15) { PRINT(KERN_ERR, lynx->id, "%s: PHY port %d out of range", __FUNCTION__, port); return -1; } reg = get_phy_reg(lynx, 7); if (reg != -1) { reg &= 0xf0; reg |= port; set_phy_reg(lynx, 7, reg); return 0; } else { return -1; } }
int mdio_main(int argc, char *argv[]) #endif { int ret; int i; /* test related */ uint16_t phy_id; uint16_t reg_num; uint16_t val_in; uint16_t val_out; /*--- SETUP --------------------------------------------------------------*/ if (argc == 1) { printf("usage:\n"); printf("\n"); printf(" %s phy_id reg_no -- read register\n", argv[0]); printf(" %s phy_id reg_no value -- write register\n", argv[0]); printf("\n"); return -1; } initialize_socket(); if (argc == 4) /* Write to register */ { phy_id = strtol(argv[1], NULL, 16); reg_num = strtol(argv[2], NULL, 16); val_in = strtol(argv[3], NULL, 16); ret = set_phy_reg(phy_id, reg_num, val_in); if (ret != 0) { printf("%s() returned %d\n", "set_phy_reg", ret); } } else if (argc == 3) /* Read from register */ { phy_id = strtol(argv[1], NULL, 16); reg_num = strtol(argv[2], NULL, 16); ret = get_phy_reg(phy_id, reg_num, &val_out); if (ret != 0) { printf("%s() returned %d\n", "get_phy_reg", ret); } else { printf("0x%4x\n", val_out); } } else if (argc == 2) { phy_id = strtol(argv[1], NULL, 16); for (i = 0; i < 32; i++) { ret = get_phy_reg(phy_id, i, &val_out); printf("phy[%d][%d] = 0x%4x\n", phy_id, i, val_out); } } else { /* Read the PHY address */ phy_id = get_phy_id(); if (phy_id < 1) { /* failed (can not be negative) */ printf("getting phy id failed\n"); } else { printf("phy_id = %d\n", phy_id); } } return 0; }