⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 vsc8601_phy.c

📁 linux下atheros的ag7100驱动
💻 C
📖 第 1 页 / 共 3 页
字号:
  vsc8601_phy_rmw_gige_ctrl(unit, phy_addr, 7<<13, 4<<13);}CEXTERN void vsc8601_phy_set_gige_test_master(int unit, uint32_t phy_addr) {  vsc8601_phy_rmw_gige_ctrl(unit, phy_addr, 3<<11, 3<<11);}CEXTERN void vsc8601_phy_set_gige_test_slave(int unit, uint32_t phy_addr) {  vsc8601_phy_rmw_gige_ctrl(unit, phy_addr, 3<<11, 2<<11);}CEXTERN void vsc8601_phy_set_gige_multiport(int unit, uint32_t phy_addr, int onOff) {  uint32_t   val = onOff ? 1<<10 : 0;	    vsc8601_phy_rmw_gige_ctrl(unit, phy_addr, 1<<10, val);}CEXTERN uint16_tvsc8601_phy_get_speed(uint16_t unit, uint16_t phy_addr){  uint16_t speed = (vsc8601_phy_read_aux_ctrl_status(unit, phy_addr) >> 3) & 3;    switch(speed) {  case 0:    return AG7100_PHY_SPEED_10T;  case 1:    return AG7100_PHY_SPEED_100TX;  case 2:    return AG7100_PHY_SPEED_1000T;  default:    printk(MODULE_NAME": unkown speed read!\n");    return 0;  }}static void vsc8601_phy_setup_generic(uint16_t unit, uint16_t phy_addr){  vsc8601_phy_mii_set_duplex(unit, phy_addr, 1);#ifdef CONFIG_AR9100/* Temporary phy settings for 1000Mpbs mode */ ag7100_mii_write(unit, phy_addr, 0x1f,  0x1); ag7100_mii_write(unit, phy_addr, 0x1c,  0x3000); ag7100_mii_write(unit, phy_addr, 0x1f,  0x0);#endif}static voidvsc8601_phy_setup_atheros_f1e(uint16_t unit, uint16_t phy_addr){  /* delay tx_clk */  ag7100_mii_write(unit, phy_addr, 0x1D, 0x5);  ag7100_mii_write(unit, phy_addr, 0x1E, 0x100);    /* what else????? */}static void vsc8601_phy_setup_vsc8601_Rev_A(uint16_t unit, uint16_t phy_addr){  uint16_t uu;    /* Weird patch in vsc86-1 datasheet Errata */    ag7100_mii_write(unit, phy_addr, 31, 0x52b5);  ag7100_mii_write(unit, phy_addr, 16, 0xaf8a);    uu=ag7100_mii_read(unit, phy_addr, 18);  ag7100_mii_write(unit, phy_addr, 18, uu);  uu=ag7100_mii_read(unit, phy_addr, 17);  uu&=~0x000c;  uu|= 0x0008;  ag7100_mii_write(unit, phy_addr, 17, uu);  ag7100_mii_write(unit, phy_addr, 16, 0x8f8a);  ag7100_mii_write(unit, phy_addr, 16, 0xaf86);  uu=ag7100_mii_read(unit, phy_addr, 18);  uu&=~0x000c;  uu|= 0x0008;  ag7100_mii_write(unit, phy_addr, 18, uu);  uu=ag7100_mii_read(unit, phy_addr, 17);  ag7100_mii_write(unit, phy_addr, 17, uu);  ag7100_mii_write(unit, phy_addr, 16, 0x8f86);  ag7100_mii_write(unit, phy_addr, 16, 0xaf82);  uu=ag7100_mii_read(unit, phy_addr, 18);  ag7100_mii_write(unit, phy_addr, 18, uu);  uu=ag7100_mii_read(unit, phy_addr, 17);  uu&=~0x0180;  uu|= 0x0100;  ag7100_mii_write(unit, phy_addr, 17, uu);  ag7100_mii_write(unit, phy_addr, 16, 0x8f82);  ag7100_mii_write(unit, phy_addr, 31, 0);  /* Set Skew */  vsc8601_phy_rmw_ex_crtl_set_1(unit, phy_addr, 1<<8, 1<<8);}static void vsc8601_phy_setup_vsc8601_Rev_B(uint16_t unit, uint16_t phy_addr){  /* Set Skew */  vsc8601_phy_rmw_ex_crtl_set_1(unit, phy_addr, 1<<8, 1<<8);}CEXTERN intvsc8601_phy_discover_and_setup_phy(int unit){  uint16_t phy_addr;  uint16_t unit_cnt;    unit_cnt=0;  nmbr_phys=0;  for (phy_addr=0; phy_addr<31; phy_addr++) {    uint16_t id1 = vsc8601_phy_mii_read_id1(unit, phy_addr);    uint32_t id2 = vsc8601_phy_mii_read_id2(unit, phy_addr);    uint32_t id  = id1<<16 | id2;    uint32_t id_sav = 0;    uint16_t phy_status = 0;        if (id1 > 0 && id1 < 0x7ff) {      vsc8601_phy_mii_soft_reset( unit, phy_addr );      phy_status=vsc8601_phy_mii_read_mode_status(unit, phy_addr);         printk(MODULE_NAME": Found %d  unit %d:%d  phy_addr: %d  id: %08x\n",		     nmbr_phys, unit, unit_cnt, phy_addr, id);            phy_info[nmbr_phys].id=id;      phy_info[nmbr_phys].phy_addr=phy_addr;      phy_info[nmbr_phys].mac_unit=unit_cnt;      phy_info[nmbr_phys].is_enet_port=0;      if (id != id_sav) {	switch(id) {	case 0x00070420:	  printk(MODULE_NAME": PHY is Vitesse VSC8601 Rev A\n");	  vsc8601_phy_setup_vsc8601_Rev_A(unit, phy_addr);	  vsc8601_phy_setup_generic(unit, phy_addr);	  phy_info[nmbr_phys].is_enet_port=1;	  unit_cnt++;	  break;	case 0x00070421:	  printk(MODULE_NAME": PHY is Vitesse VSC8601 Rev B\n");	  vsc8601_phy_setup_vsc8601_Rev_B(unit, phy_addr);	  vsc8601_phy_setup_generic(unit, phy_addr);	  phy_info[nmbr_phys].is_enet_port=1;	  unit_cnt++;	  break;	case 0x000fc413:	  printk(MODULE_NAME": PHY is Vitesse VSC8201 Phy\n");	  vsc8601_phy_setup_generic(unit, phy_addr);	  phy_info[nmbr_phys].is_enet_port=1;	  unit_cnt++;	  break;        case 0x02430d80:          printk(MODULE_NAME": PHY is ICPlus IP175B Switch\n");          vsc8601_phy_setup_generic(unit, phy_addr);          phy_info[nmbr_phys].is_enet_port=1;          unit_cnt++;          break;	case 0x004dd04e:	  printk(MODULE_NAME": PHY is an Atheros F1E\n");	  vsc8601_phy_setup_atheros_f1e(unit, phy_addr);	  vsc8601_phy_setup_generic(unit, phy_addr);	  phy_info[nmbr_phys].is_enet_port=1;	  unit_cnt++;	  break;	  	default:	  printk(MODULE_NAME": PHY is unknown, using generic IEEE interface\n");	  vsc8601_phy_setup_generic(unit, phy_addr);	  phy_info[nmbr_phys].is_enet_port=1;	  unit_cnt++;	  break;	}	id_sav=id;      }      nmbr_phys++;    }  }  if (nmbr_phys == 0) {    printk(MODULE_NAME": no PHY IDs found \n");    return 1;  }  if (unit_cnt == 0) {    printk(MODULE_NAME": no PHY IDs assigned to unit\n");    return 1;  }  return 0;}CEXTERN intvsc8601_phy_print_status_raw(uint16_t unit, uint16_t phy_addr){ #if ( VERBOSE > 1 )  /* Generic IEEE */  uint16_t mc  = vsc8601_phy_mii_read_mode_ctrl            (unit, phy_addr);  uint16_t ms  = vsc8601_phy_mii_read_mode_status          (unit, phy_addr);  uint16_t id1 = vsc8601_phy_mii_read_id1                  (unit, phy_addr);  uint32_t id2 = vsc8601_phy_mii_read_id2                  (unit, phy_addr);  uint32_t id  = id1<<16 | id2;  uint16_t rec = vsc8601_phy_read_rx_error_count           (unit, phy_addr);  uint16_t fcc = vsc8601_phy_read_false_carrier_count      (unit, phy_addr);  uint16_t dc  = vsc8601_phy_read_disconnect_count         (unit, phy_addr);  uint16_t cs1 = vsc8601_phy_read_ex_crtl_set_1            (unit, phy_addr);  uint16_t cs2 = vsc8601_phy_read_ex_crtl_set_2            (unit, phy_addr);  uint16_t im  = vsc8601_phy_read_irq_msk                  (unit, phy_addr);  uint16_t is  = vsc8601_phy_read_irq_status               (unit, phy_addr);  uint16_t acs = vsc8601_phy_read_aux_ctrl_status          (unit, phy_addr);  uint16_t dss = vsc8601_phy_read_delay_skew_status        (unit, phy_addr);  printk(MODULE_NAME": unit %d  phy_addr %d\n", unit, phy_addr);  vsc8601_phy_mii_print_mode_ctrl(mc);  vsc8601_phy_mii_print_mode_status(ms);  printk(MODULE_NAME":  id1             (02 )=%02x\n", id1 & 0xff);  printk(MODULE_NAME":  id2             (03 )=%02x\n", id2 & 0xff);  printk(MODULE_NAME":  rcv-error       (19 )=%04x\n", rec & 0xff);  printk(MODULE_NAME":  false-carrier   (20 )=%04x\n", fcc & 0xff);  printk(MODULE_NAME":  disconnect_cnt  (21 )=%04x\n", dc  & 0xff);  vsc8601_phy_mii_print_ex_ctrl_set_1(cs1);  printk(MODULE_NAME":  ex_crtl_set_2   (24 )=%04x\n", cs2);  printk(MODULE_NAME":  irq_msk         (25 )=%04x\n", im);  vsc8601_phy_mii_print_irq_status(is);  vsc8601_phy_mii_print_aux_ctrl_status(acs);  vsc8601_phy_mii_print_delay_skew_status(dss);   /* Chip specific */  switch( id ) {  case 0x00070420:    {      uint16_t cgc = vsc8601_phy_read_crc_good_counter         (unit, phy_addr);      uint16_t mcr = vsc8601_phy_read_mac_resistor_calibration (unit, phy_addr);      uint16_t cs5 = vsc8601_phy_read_ex_crtl_set_5            (unit, phy_addr);      uint16_t skc = vsc8601_phy_read_skew_ctrl                (unit, phy_addr);      uint16_t ep1 = vsc8601_phy_read_epg_1                    (unit, phy_addr);      uint16_t ep2 = vsc8601_phy_read_epg_1                    (unit, phy_addr);            printk(MODULE_NAME":  crc_good        (18E)=%04x\n", cgc);      printk(MODULE_NAME":  resistor        (19E)=%04x\n", mcr);      vsc8601_phy_mii_print_ex_crtl_set_5(cs5);      vsc8601_phy_mii_print_skew_ctrl(skc);      printk(MODULE_NAME":  epg_1           (29E)=%04x\n", ep1);      printk(MODULE_NAME":  epg_2           (30E)=%04x\n", ep2);    }    break;  }  /* Speed specific */  switch(vsc8601_phy_get_speed(unit, phy_addr)) {  case AG7100_PHY_SPEED_10T:    printk(MODULE_NAME":  * current speed 10 base-t\n");    break;      case AG7100_PHY_SPEED_100TX:    {      uint16_t es = vsc8601_phy_read_100_status_ex (unit, phy_addr);      vsc8601_phy_mii_print_100_status_ex(es);      printk(MODULE_NAME":  * current speed 100 base-t\n");    }    break;      case AG7100_PHY_SPEED_1000T:    {      uint16_t gc  = vsc8601_phy_mii_read_gige_ctrl     (unit, phy_addr);      uint16_t gs  = vsc8601_phy_read_gige_status       (unit, phy_addr);      uint16_t gs2 = vsc8601_phy_read_gige_status_ex_2  (unit, phy_addr);            vsc8601_phy_mii_print_gige_ctrl(gc);      vsc8601_phy_mii_print_gige_status(gs);      vsc8601_phy_mii_print_gige_status_ex_2(gs2);      printk(MODULE_NAME":  * current speed gige\n");    }    break;      default:    printk(MODULE_NAME":  * current speed unknown\n");    break;  }  printk("\n");#else#if ( VERBOSE > 0 )  uint16_t ms  = vsc8601_phy_mii_read_mode_status     (unit, phy_addr);  uint16_t mc  = vsc8601_phy_mii_read_mode_ctrl       (unit, phy_addr);  uint16_t rec = vsc8601_phy_read_rx_error_count      (unit, phy_addr);  uint16_t fcc = vsc8601_phy_read_false_carrier_count (unit, phy_addr);  uint16_t dc  = vsc8601_phy_read_disconnect_count    (unit, phy_addr);    printk(MODULE_NAME": unit %d  phy_addr %d\n", unit, phy_addr);  vsc8601_phy_mii_print_mode_ctrl(mc);  vsc8601_phy_mii_print_mode_status(ms);  printk(MODULE_NAME":  rcv-error       (19 )=%04x\n", rec & 0xff);  printk(MODULE_NAME":  false-carrier   (20 )=%04x\n", fcc & 0xff);  printk(MODULE_NAME":  disconnect_cnt  (21 )=%04x\n", dc  & 0xff);#else  uint16_t ms  = vsc8601_phy_mii_read_mode_status     (unit, phy_addr);  printk(MODULE_NAME": unit %d  phy_addr %d\n", unit, phy_addr);//  vsc8601_phy_mii_print_mode_status(ms);#endif#endif  return 0;}/* *********************************************************** * * These are exported for use by ag7100_phy.h * * *********************************************************** */int vsc8601_phy_setup(int unit){  int ii;  vsc8601_phy_t *phy;  if (vsc8601_phy_discover_and_setup_phy(unit))    return -1;  for (ii = 0; ii < sizeof(phy_info)/sizeof(phy_info[0]); ii++) {    phy = &phy_info[ii];    if (phy->is_enet_port && (phy->mac_unit == unit))      vsc8601_phy_print_status_raw(phy->mac_unit, phy->phy_addr);  }  return 0;}unsigned int vsc8601_phy_get_link_status(int unit, int *link, int *fdx, ag7100_phy_speed_t *speed, unsigned int *cfg){  unsigned short ms;  unsigned short acs;  unsigned int   tc;  vsc8601_phy_t *phy = vsc8601_phy_find(unit);  if (!phy)    return 0;    ms = vsc8601_phy_mii_read_mode_status (unit, phy->phy_addr);    if (link) *link   = (ms & 1<<2) > 0;  if (speed) *speed = vsc8601_phy_get_speed(unit, phy->phy_addr);  if (fdx) {    acs = vsc8601_phy_read_aux_ctrl_status(unit, phy->phy_addr);    *fdx = (acs & 1<<5) > 0;  }  tc = phy->status != ms;  phy->status = ms;    if (tc)    vsc8601_phy_print_status_raw(unit, phy->phy_addr);  if (cfg)    *cfg=tc;   return tc;}intvsc8601_phy_print_link_status(int unit){  vsc8601_phy_t *phy = vsc8601_phy_find(unit);  if (!phy) {    printk(MODULE_NAME": could not find mac\n");    return -1;  }    vsc8601_phy_print_status_raw(unit, phy->phy_addr);  return 0;}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -