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

📄 vsc73xx.c

📁 linux下atheros的ag7100驱动
💻 C
📖 第 1 页 / 共 2 页
字号:
    udelay(10000);  } while (1);}#endifstatic voidvsc73xx_print_val_bit_desc (unsigned int val, char *fieldName, char *bit_descriptions[]) {  int ii;  char *p2;    printk(MODULE_NAME":   %s=%04x\n", fieldName, val);  for (ii=0;ii<32; ii++) {    p2 = val & 1<<(31-ii) ? bit_descriptions[ii*2] : bit_descriptions[ii*2+1];    if (p2 && p2[0])            printk(MODULE_NAME":     %s\n", p2);  }}/* Port 0..4, 6 */static inline int vsc73xx_get_mac_cfg(int port, unsigned int *d){  return vsc73xx_rd(VSC73XX_MAC, port, VSC73XX_MAC_CFG, d);}static char *mac_cfg_desc[32*2] = {  "wexc_dis","", /* 31 */  "","", /* 30 */  "port_rst","", /* 29 */  "tx_en","", /* 28 */  "seed_load","", /* 27 */  "","", /* 26 */  "","", /* 25 */  "","", /* 24 */  "","", /* 23 */  "","", /* 22 */  "","", /* 21 */  "","", /* 20 */  "","", /* 19 */  "en-fdx","", /* 18 */  "gige","", /* 17 */  "rx_en","", /* 16 */  "vlan_dblawr","", /* 15 */  "vlan_awr","", /* 14 */  "100-base-T","", /* 13 */  "","", /* 12 */  "","", /* 11 */  "","", /* 10 */  "","", /*  9 */  "","", /*  8 */  "","", /*  7 */  "","", /*  6 */  "mac_rx_rst","", /*  5 */  "mac_tx_rst","", /*  4 */  "","", /*  3 */  "","", /*  2 */  "","", /*  1 */  "","", /*  0 */};static inline voidvsc73xx_print_mac_cfg_val(unsigned int val){  vsc73xx_print_val_bit_desc (val, "mac_cfg        (01P00)", mac_cfg_desc);  printk(MODULE_NAME":   clk_sel: %02x\n", (val>>0)&0x3);  printk(MODULE_NAME":   tx_ipg:  %02x\n", (val>>6)&0x1f);}static inline int vsc73xx_set_mac_cfg(int port, unsigned int value){  return vsc73xx_wr(VSC73XX_MAC, port, VSC73XX_MAC_CFG, value);}static inline int vsc73xx_get_clock_delay_reg(unsigned int *val){  return vsc73xx_rd(VSC73XX_SYSTEM, 0, VSC73XX_ICPU_CLOCK_DELAY, val);}static inline intvsc73xx_set_clock_delay_reg(unsigned int val){  return vsc73xx_wr(VSC73XX_SYSTEM, 0, VSC73XX_ICPU_CLOCK_DELAY, val);}static inline int vsc73xx_get_advportm(int port, unsigned int *val){  return vsc73xx_rd(VSC73XX_MAC, port, VSC73XX_ADVPORTM, val);}static char *advportm_desc[32*2] = {  "","", /* 31 */  "","", /* 30 */  "","", /* 29 */  "","", /* 28 */  "","", /* 27 */  "","", /* 26 */  "","", /* 25 */  "","", /* 24 */  "","", /* 23 */  "","", /* 22 */  "","", /* 21 */  "","", /* 20 */  "","", /* 19 */  "","", /* 18 */  "","", /* 17 */  "","", /* 16 */  "","", /* 15 */  "","", /* 14 */  "","", /* 13 */  "","", /* 12 */  "","", /* 11 */  "","", /* 10 */  "","", /*  9 */  "","", /*  8 */  "ifg_ppm","",       /*  7 */  "exc_col","",       /*  6 */  "ext_port","",      /*  5 */  "inv_gtx","",       /*  4 */  "ena_gtx","",       /*  3 */  "ddr_mode","",      /*  2 */  "io_loopback","",   /*  1 */  "host_loopback","", /*  0 */};static inline voidvsc73xx_print_advportm_val(unsigned int val){  vsc73xx_print_val_bit_desc (val, "advportm      (01P19)", advportm_desc);}static inline intvsc73xx_set_advportm(int port, unsigned int val){  return vsc73xx_wr(VSC73XX_MAC, port, VSC73XX_ADVPORTM, val);}/* HERE */static inline unsigned int vsc73xx_get_c_rx0(int port){  unsigned int d;  vsc73xx_rd(VSC73XX_MAC, port, VSC73XX_C_RX0, &d);  return d;}static inline unsigned int vsc73xx_get_c_rx1(int port){  unsigned int d;  vsc73xx_rd(VSC73XX_MAC, port, VSC73XX_C_RX1, &d);  return d;}static inline unsigned int vsc73xx_get_c_rx2(int port){  unsigned int d;  vsc73xx_rd(VSC73XX_MAC, port, VSC73XX_C_RX2, &d);  return d;}static inline unsigned int vsc73xx_get_c_tx0(int port){  unsigned int d;  vsc73xx_rd(VSC73XX_MAC, port, VSC73XX_C_TX0, &d);  return d;}static inline unsigned int vsc73xx_get_c_tx1(int port){  unsigned int d;  vsc73xx_rd(VSC73XX_MAC, port, VSC73XX_C_TX1, &d);  return d;}static inline unsigned int vsc73xx_get_c_tx2(int port){  unsigned int d;  vsc73xx_rd(VSC73XX_MAC, port, VSC73XX_C_TX2, &d);  return d;}static inline unsigned int vsc73xx_get_c_cfg(int port){  unsigned int d;  vsc73xx_rd(VSC73XX_MAC, port, VSC73XX_C_CFG, &d);  return d;}static inline voidvsc73xx_set_c_cfg(int port, unsigned int value){  vsc73xx_wr(VSC73XX_MAC, port, VSC73XX_C_CFG, value);}voidvsc73xx_print_counts(int port){  printk(MODULE_NAME":counters port %d\n", port);  printk(MODULE_NAME":   cfg: %8x\n", vsc73xx_get_c_cfg(port));  printk(MODULE_NAME":   rx0: %9d\n", vsc73xx_get_c_rx0(port));  printk(MODULE_NAME":   rx0: %9d\n", vsc73xx_get_c_rx1(port));  printk(MODULE_NAME":   rx0: %9d\n", vsc73xx_get_c_tx2(port));  printk(MODULE_NAME":   tx0: %9d\n", vsc73xx_get_c_tx0(port));  printk(MODULE_NAME":   tx0: %9d\n", vsc73xx_get_c_tx1(port));  printk(MODULE_NAME":   tx0: %9d\n", vsc73xx_get_c_tx2(port));}static inline voidvsc73xx_print_link_status_from_value(int port, int up, int fdx, int speed, unsigned int cfg){  printk(MODULE_NAME": STATUS Port: %d  up: %d  fdx: %d  speed: %d  mac cfg: %08x\n", port, up, fdx, speed, cfg);  vsc73xx_print_mac_cfg_val(cfg);}#if 0/* WARNING: Do not use this if the switch application is running on the 8051. This *          function may be used if the switch application is on the host and the  *          8051 is in reset. */unsigned shortvsc73xx_rw_phy(int writeFlg, int unit, int phy_addr, int reg, uint16_t value){  /* unit 0   = mac0 and should not happen here   * unit 1   = mac1, PHY we connect to using MAC 1   * unit 2-6 = ports on switch */    unsigned int  request;  unsigned int  resp;  int sublockA;  int sublockB;  /* This needs to be checked since we are at a new level of 8051 code */  sublockA = unit==1 ? 6:0; /* unit==1 is PHY tied to MAC using RGMII */  sublockB = unit==1 ? 1:0; /* unit>=1 is PHY on switch                */                            /* With the new 8051 code this has to be figured			     * out again ( that is sublock values )			     */  request = (writeFlg ? 0 : 1)<<26 | (phy_addr<<21) | (reg<<16) | value;    vsc73xx_wr(VSC73XX_MII, sublockA, VSC73XX_MII_CMD, request, 0);  udelay(10);  do {    vsc73xx_rd(VSC73XX_MII, sublockB, VSC73XX_MII_STAT, &resp, 0);    udelay(10);  } while ( resp & 0xf );    if (writeFlg)    return 0;    udelay(1);    vsc73xx_rd(VSC73XX_MII, sublockB, VSC73XX_MII_DATA, &resp, 0);    if (resp & 1<<16) {    return 0xffff;  }  return resp & 0xffff;}#endifstatic intvsc73xx_setup_raw(void){  int          rc;  int          sVersion=0;  int          resetNeeded=0;  unsigned int t_cfg;  unsigned int t_clock_delay;  unsigned int t_advportm;#ifdef CONFIG_AR9100  vsc73xx_wr(7,0,0x5,0x33);#endif  rc = generic_spi_init(GENERIC_SPI_VSC73XX_CS);  if (rc < 0) {    printk(MODULE_NAME": could not initialize spi interface, err %d\n", rc);    return rc;  }  vsc73xx_get_sVersion_resetNeeded(&sVersion, &resetNeeded); if ( (resetNeeded) || (sVersion < VSC73XX_SFTW_VERSION) ) {    rc = vsc73xx_load_firmware();    if (rc < 0)      return rc;  }  /* The VSC73XX does not work very well unless we setup 2 nsec delay */  vsc73xx_set_clock_delay_reg(VSC73XX_CLOCK_DELAY);  vsc73xx_get_clock_delay_reg(&t_clock_delay);      if ((t_clock_delay & VSC73XX_CLOCK_DELAY_MASK) != VSC73XX_CLOCK_DELAY) {    printk(MODULE_NAME":   unable to set clock_delay %08x %08x\n",  		   VSC73XX_CLOCK_DELAY, 		   VSC73XX_CLOCK_DELAY_MASK &  t_clock_delay);    return -1;  }  else    printk(MODULE_NAME":  clock_delay_reg %08x\n", t_clock_delay);    /* We must tell the VSC73XX that it has an external interface */  vsc73xx_set_advportm(VSC73XX_PORT_MAC, 		       VSC73XX_ADVPORTM_HYDRA);  vsc73xx_get_advportm(VSC73XX_PORT_MAC, &t_advportm);   if ((VSC73XX_ADVPORTM_HYDRA_MASK & t_advportm) != VSC73XX_ADVPORTM_HYDRA) {    printk(MODULE_NAME":   unable to set advanportm for MAC port (6) %08x %08x\n", 		   VSC73XX_ADVPORTM_HYDRA,		   VSC73XX_ADVPORTM_HYDRA_MASK & t_advportm);  }  else    vsc73xx_print_advportm_val(t_advportm);    /* We must tell the VSC73XX that it can send/recieve data */#ifdef CONFIG_AR9100  vsc73xx_set_mac_cfg(VSC73XX_PORT_MAC, VSC73XX_MAC_CFG_PORT_RST |		VSC73XX_MAC_CFG_MAC_RX_RST | VSC73XX_MAC_CFG_MAC_TX_RST);  vsc73xx_set_mac_cfg(VSC73XX_PORT_MAC, VSC73XX_MAC_CFG_AR9100);#else  vsc73xx_set_mac_cfg(VSC73XX_PORT_MAC, 		      VSC73XX_MAC_CFG_HYDRA );#endif  vsc73xx_get_mac_cfg(VSC73XX_PORT_MAC, &t_cfg);#ifndef CONFIG_AR9100  if ((VSC73XX_MAC_CFG_HYDRA_MASK & t_cfg) != VSC73XX_MAC_CFG_HYDRA) {    printk(MODULE_NAME":   unable to set mac_cfg for port 6 %08x %08x\n", 		   VSC73XX_MAC_CFG_HYDRA, 		   VSC73XX_MAC_CFG_HYDRA_MASK & t_cfg);  }  else#endif    vsc73xx_print_mac_cfg_val(t_cfg);    return rc;}static unsigned int mac_cfg_port[7] = { 0, 0, 0, 0, 0, 0, 0 };static unsigned intvsc73xx_get_link_status_raw(int port, int *up, int *fdx, ag7100_phy_speed_t *speed, unsigned int *cfg){  int rc;  int t_up;  int t_fdx;  ag7100_phy_speed_t t_speed;  unsigned int t_cfg;  unsigned int t_chg;  rc = vsc73xx_get_mac_cfg(port, &t_cfg);  if (rc<0)    return ~0;  /* FIXME WCL   * Occasionally the VSC73XX will return 0xffffffff for cfg status with no apparent error.   */  if (t_cfg == 0xffffffff)     return ~0;  t_chg = mac_cfg_port[port] ^ t_cfg;  mac_cfg_port[port] = t_cfg;  t_up  = (t_cfg & ( VSC73XX_MAC_CFG_TX_EN | VSC73XX_MAC_CFG_RX_EN )) == ( VSC73XX_MAC_CFG_TX_EN | VSC73XX_MAC_CFG_RX_EN );  t_fdx = (t_cfg & VSC73XX_MAC_CFG_FDX ) != 0;    if ( t_cfg & VSC73XX_MAC_CFG_GIGA_MODE )    t_speed = AG7100_PHY_SPEED_1000T;  else    if ( t_cfg & VSC73XX_MAC_CFG_100_BASE_T )      t_speed = AG7100_PHY_SPEED_100TX;    else      t_speed = AG7100_PHY_SPEED_10T;      if (up)    *up    = t_up;  if (fdx)   *fdx   = t_fdx;  if (speed) *speed = t_speed;  if (cfg)   *cfg   = t_cfg;    return t_chg;}#ifdef USE_TEST_CODEvoidvsc73xx_test_link_status(void){  int          port;  int          ii;  unsigned int t_up;  unsigned int t_fdx;  ag7100_phy_speed_t t_speed;  unsigned int t_cfg;  unsigned int t_chg;  int          rc;  printk(MODULE_NAME": looping on load firmware / reset firmware\n" );  vsc73xx_setup_raw();  do {    t_chg = vsc73xx_get_link_status_raw(port, &t_up, &t_fdx, &t_speed, &t_cfg);    if (t_chg == ~0) {      printk(MODULE_NAME": bad read from switch\n");    }    else {      if (t_chg)	vsc73xx_print_link_status_from_value(port, t_up, t_fdx, t_speed, t_cfg);    }  } while (1);}#endifint vsc73xx_setup(int unit){  return vsc73xx_setup_raw();}intvsc73xx_get_link_status(int unit, int *up, int *fdx, ag7100_phy_speed_t *speed, unsigned int *cfg){  int          port;  unsigned int t_up;  unsigned int t_fdx;  ag7100_phy_speed_t t_speed;  unsigned int t_cfg;  unsigned int t_chg;  /* The VSC73XX uses a fixed numbering scheme to get to ports - rather than using PHY Address.   *     * unit 0   == mac 0   * unit 1   == mac 1    * unit 2-6 == ports 0-4    */  switch (unit) {    case 1: port=VSC73XX_PORT_MAC; break;    case 2: port=VSC73XX_PORT_0; break;    case 3: port=VSC73XX_PORT_1; break;    case 4: port=VSC73XX_PORT_2; break;    case 5: port=VSC73XX_PORT_3; break;    case 6: port=VSC73XX_PORT_4; break;    default:      printk(MODULE_NAME": bad unit number %d\n", unit);      return -1;  } #ifdef CONFIG_AR9100  vsc73xx_wr(7,0,0x5,0x33);#endif  t_chg = vsc73xx_get_link_status_raw(port, &t_up, &t_fdx, &t_speed, &t_cfg);  if (t_chg == ~0)    return -2;    if (up)    *up    = t_up;  if (fdx)   *fdx   = t_fdx;  if (speed) *speed = t_speed;  if (cfg)   *cfg   = t_cfg;#ifdef VSC73XX_DEBUG  printk("\t==== vsc(%d) up:%d fdx:%d speed:%d cfg=0x%08x\n", unit, t_up, t_fdx, t_speed, t_cfg);#endif  return 0;}#ifdef VSC73XX_DEBUGvoidvsc73xx_get_link_status_dbg(void){	printk("\n");	vsc73xx_get_link_status(1, 0, 0, 0, 0);	vsc73xx_get_link_status(2, 0, 0, 0, 0);	vsc73xx_get_link_status(3, 0, 0, 0, 0);	vsc73xx_get_link_status(4, 0, 0, 0, 0);	vsc73xx_get_link_status(5, 0, 0, 0, 0);	vsc73xx_get_link_status(6, 0, 0, 0, 0);}#endif /* VSC73XX_DEBUG */intvsc73xx_phy_print_link_status(int unit){  int          port;  unsigned int t_up;  unsigned int t_fdx;  ag7100_phy_speed_t t_speed;  unsigned int t_cfg;  unsigned int t_chg;  /* The VSC73XX uses a fixed numbering scheme to get to ports - rather than using PHY Address.   *     * unit 0   == mac 0   * unit 1   == mac 1    * unit 2-6 == ports 0-4    */  switch (unit) {    case 1: port=VSC73XX_PORT_MAC; break;    case 2: port=VSC73XX_PORT_0; break;    case 3: port=VSC73XX_PORT_1; break;    case 4: port=VSC73XX_PORT_2; break;    case 5: port=VSC73XX_PORT_3; break;    case 6: port=VSC73XX_PORT_4; break;    default:      printk(MODULE_NAME": bad unit number %d\n", unit);      return -1;  }   t_chg = vsc73xx_get_link_status_raw(port, &t_up, &t_fdx, &t_speed, &t_cfg);  if (t_chg == ~0)    return -2;    vsc73xx_print_link_status_from_value(port, t_up, t_fdx, t_speed, t_cfg);   return 0;}

⌨️ 快捷键说明

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