Ejemplo n.º 1
0
static u32 get_phy_productid(struct ti_lynx *lynx)
{
    u32 id = 0;
    sel_phy_reg_page(lynx, 1);
    id |= (get_phy_reg(lynx, 13) << 16);
    id |= (get_phy_reg(lynx, 14) << 8);
    id |= get_phy_reg(lynx, 15);
    PRINT(KERN_INFO, lynx->id, "PHY product id 0x%06x", id);
    return id;
}
Ejemplo n.º 2
0
static u32 get_phy_vendorid(struct ti_lynx *lynx)
{
    u32 pvid = 0;
    sel_phy_reg_page(lynx, 1);
    pvid |= (get_phy_reg(lynx, 10) << 16);
    pvid |= (get_phy_reg(lynx, 11) << 8);
    pvid |= get_phy_reg(lynx, 12);
    PRINT(KERN_INFO, lynx->id, "PHY vendor id 0x%06x", pvid);
    return pvid;
}
Ejemplo n.º 3
0
static quadlet_t generate_own_selfid(struct ti_lynx *lynx,
                                     struct hpsb_host *host)
{
    quadlet_t lsid;
    char phyreg[7];
    int i;

    phyreg[0] = lynx->phy_reg0;
    for (i = 1; i < 7; i++) {
        phyreg[i] = get_phy_reg(lynx, i);
    }

    /* FIXME? We assume a TSB21LV03A phy here.  This code doesn't support
       more than 3 ports on the PHY anyway. */

    lsid = 0x80400000 | ((phyreg[0] & 0xfc) << 22);
    lsid |= (phyreg[1] & 0x3f) << 16; /* gap count */
    lsid |= (phyreg[2] & 0xc0) << 8; /* max speed */
    if (!hpsb_disable_irm)
        lsid |= (phyreg[6] & 0x01) << 11; /* contender (phy dependent) */
    /* lsid |= 1 << 11; *//* set contender (hack) */
    lsid |= (phyreg[6] & 0x10) >> 3; /* initiated reset */

    for (i = 0; i < (phyreg[2] & 0xf); i++) { /* ports */
        if (phyreg[3 + i] & 0x4) {
            lsid |= (((phyreg[3 + i] & 0x8) | 0x10) >> 3)
                    << (6 - i*2);
        } else {
Ejemplo n.º 4
0
/***********************************
 * 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;
    }
}
Ejemplo n.º 5
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;
    }
}
Ejemplo n.º 6
0
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;
}