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

📄 dev_nm_16esw.c

📁 思科路由器仿真器,用来仿7200系列得,可以在电脑上模拟路由器-Cisco router simulator, used to fake a 7200 series can be simulated
💻 C
📖 第 1 页 / 共 5 页
字号:
      }      printf("\n");   }   printf("\n");   return(0);}/* Dump the "trunk" ports */static int bcm5600_dump_trunks(struct nm_16esw_data *d){      struct bcm5600_table *table;   struct bcm5600_port *port;   m_uint32_t *entry;   int i,j;   if (!(table = bcm5600_table_find(d,BCM5600_ADDR_TBMAP0)))      return(-1);   printf("%s: trunk ports:\n",d->name);   for(i=table->min_index;i<=table->max_index;i++) {      if (!(entry = bcm5600_table_get_entry(d,table,i)))         break;      if (!entry[0])         continue;      printf("  Trunk %d: ",i);      for(j=0;j<d->nr_port;j++) {         if (entry[0] & (1 << j)) {            port = &d->ports[j];            printf("%s ",port->name);         }      }      printf("\n");   }   printf("\n");   return(0);}/* Dump the physical port info */static int bcm5600_dump_ports(struct nm_16esw_data *d){      struct bcm5600_table *table;   struct bcm5600_port *port;   m_uint32_t *entry;   u_int vlan,tgid;   int i;   if (!(table = bcm5600_table_find(d,BCM5600_ADDR_PTABLE0)))      return(-1);   printf("%s: physical ports:\n",d->name);   for(i=0;i<d->nr_port;i++) {      if (!(entry = bcm5600_table_get_entry(d,table,i)))         break;      port = &d->ports[i];      vlan = entry[0] & BCM5600_PTABLE_VLAN_TAG_MASK;            printf("  %-10s: VLAN %u",port->name,vlan);      if (entry[0] & BCM5600_PTABLE_TRUNK_FLAG) {         tgid = entry[0] & BCM5600_PTABLE_TGID_MASK;         tgid >>= BCM5600_PTABLE_TGID_SHIFT;         printf(", Trunk Group %u ",tgid);      }      printf("\n");   }   printf("\n");   return(0);}/* Dump the physical port bitmaps */static int bcm5600_dump_port_bitmaps(struct nm_16esw_data *d){      struct bcm5600_table *table;   struct bcm5600_port *port;   m_uint32_t *entry,tbmp,ubmp;   int i,j;   if (!(table = bcm5600_table_find(d,BCM5600_ADDR_PTABLE0)))      return(-1);   printf("%s: dumping bitmaps of the port table:\n",d->name);   for(i=0;i<d->nr_port;i++) {      if (!(entry = bcm5600_table_get_entry(d,table,i)))         break;      port = &d->ports[i];      printf("  %-10s: ",port->name);      for(j=0;j<d->nr_port;j++) {         tbmp = entry[1] & (1 << j);         ubmp = entry[2] & (1 << j);         if (tbmp || ubmp) {            printf("%s (",d->ports[j].name);            if (tbmp)                printf("T%s",ubmp ? "/" : ") ");            if (ubmp)               printf("UT) ");         }      }      printf("\n");   }   printf("\n");   return(0);}/* Dump main tables */static void bcm5600_dump_main_tables(struct nm_16esw_data *d){   bcm5600_dump_ports(d);   bcm5600_dump_port_bitmaps(d);   bcm5600_dump_vtable(d);   bcm5600_dump_trunks(d);}/* Find a free ARL entry */static int bcm5600_find_free_arl_entry(struct nm_16esw_data *d){      struct bcm5600_table *table = d->t_arl;   if (d->arl_cnt[0] == table->max_index)      return(-1);   return(d->arl_cnt[0] - 1);}/* ARL Lookup. TODO: this must be optimized in the future. */static inline int bcm5600_gen_arl_lookup(struct nm_16esw_data *d,                                         struct bcm5600_table *table,                                         u_int index_start,u_int index_end,                                         n_eth_addr_t *mac_addr,                                         u_int vlan){   m_uint32_t *entry,tmp[2],mask;   int i;   tmp[0]  = mac_addr->eth_addr_byte[2] << 24;   tmp[0] |= mac_addr->eth_addr_byte[3] << 16;   tmp[0] |= mac_addr->eth_addr_byte[4] << 8;   tmp[0] |= mac_addr->eth_addr_byte[5];   tmp[1] = (mac_addr->eth_addr_byte[0] << 8) | mac_addr->eth_addr_byte[1];   tmp[1] |= vlan << BCM5600_ARL_VLAN_TAG_SHIFT;   mask = BCM5600_ARL_VLAN_TAG_MASK | BCM5600_ARL_MAC_MSB_MASK;   for(i=index_start;i<index_end;i++) {      entry = bcm5600_table_get_entry(d,table,i);      if ((entry[0] == tmp[0]) && ((entry[1] & mask) == tmp[1]))         return(i);   }   return(-1);}/* ARL Lookup */static inline int bcm5600_arl_lookup(struct nm_16esw_data *d,                                     n_eth_addr_t *mac_addr,                                     u_int vlan){   struct bcm5600_table *table = d->t_arl;   return(bcm5600_gen_arl_lookup(d,table,1,d->arl_cnt[0]-1,mac_addr,vlan));}/* MARL Lookup */static inline int bcm5600_marl_lookup(struct nm_16esw_data *d,                                      n_eth_addr_t *mac_addr,                                      u_int vlan){   struct bcm5600_table *table = d->t_marl;   return(bcm5600_gen_arl_lookup(d,table,table->min_index,table->max_index+1,                                 mac_addr,vlan));}/* Invalidate an ARL entry */static void bcm5600_invalidate_arl_entry(m_uint32_t *entry){   entry[0] = entry[1] = entry[2] = 0;}/* Insert an entry into the ARL table */static int bcm5600_insert_arl_entry(struct nm_16esw_data *d){      struct bcm5600_table *table = d->t_arl;   m_uint32_t *entry,mask;   int i,index;   mask = BCM5600_ARL_VLAN_TAG_MASK | BCM5600_ARL_MAC_MSB_MASK;   for(i=0;i<d->arl_cnt[0]-1;i++) {      entry = bcm5600_table_get_entry(d,table,i);      /* If entry already exists, just modify it */      if ((entry[0] == d->dw[1]) && ((entry[1] & mask) == (d->dw[2] & mask))) {         entry[0] = d->dw[1];         entry[1] = d->dw[2];         entry[2] = d->dw[3];         d->dw[1] = i;         return(0);      }   }   index = d->arl_cnt[0] - 1;   entry = bcm5600_table_get_entry(d,table,index);   entry[0] = d->dw[1];   entry[1] = d->dw[2];   entry[2] = d->dw[3];   d->dw[1] = index;      d->arl_cnt[0]++;   return(0);}/* Delete an entry from the ARL table */static int bcm5600_delete_arl_entry(struct nm_16esw_data *d){     struct bcm5600_table *table;   m_uint32_t *entry,*last_entry,mac_msb;   u_int cvlan,vlan;   int i;   if (!(table = bcm5600_table_find(d,BCM5600_ADDR_ARL0)))      return(-1);   vlan = d->dw[2] & BCM5600_ARL_VLAN_TAG_MASK;   vlan >>= BCM5600_ARL_VLAN_TAG_SHIFT;   mac_msb = d->dw[2] & BCM5600_ARL_MAC_MSB_MASK;   for(i=table->min_index;i<=table->max_index;i++) {      entry = bcm5600_table_get_entry(d,table,i);      /* compare VLANs and MAC addresses */      cvlan = (entry[1] & BCM5600_ARL_VLAN_TAG_MASK);      cvlan >>= BCM5600_ARL_VLAN_TAG_SHIFT;      if ((cvlan == vlan) && (entry[0] == d->dw[1]) &&          ((entry[1] & BCM5600_ARL_MAC_MSB_MASK) == mac_msb))      {                     d->dw[1] = i;         last_entry = bcm5600_table_get_entry(d,d->t_arl,d->arl_cnt[0]-2);                     entry[0] = last_entry[0];         entry[1] = last_entry[1];         entry[2] = last_entry[2];         d->arl_cnt[0]--;         return(i);      }   }   return(0);}/* Reset the ARL tables */static int bcm5600_reset_arl(struct nm_16esw_data *d){   struct bcm5600_table *table;   m_uint32_t *entry;   int i;      if (!(table = bcm5600_table_find(d,BCM5600_ADDR_ARL0)))      return(-1);   for(i=table->min_index;i<=table->max_index;i++) {      entry = bcm5600_table_get_entry(d,table,i);      bcm5600_invalidate_arl_entry(entry);   }   return(0);}/* MAC Address Ager */static int bcm5600_arl_ager(struct nm_16esw_data *d){   m_uint32_t *entry,*last_entry;   int i;   BCM_LOCK(d);   for(i=1;i<d->arl_cnt[0]-1;i++) {      entry = bcm5600_table_get_entry(d,d->t_arl,i);      assert(entry);      if (entry[2] & BCM5600_ARL_ST_FLAG)         continue;      /* The entry has expired, purge it */      if (!(entry[2] & BCM5600_ARL_HIT_FLAG)) {         last_entry = bcm5600_table_get_entry(d,d->t_arl,d->arl_cnt[0]-2);                 entry[0] = last_entry[0];         entry[1] = last_entry[1];         entry[2] = last_entry[2];         d->arl_cnt[0]--;         i--;      } else {         entry[2] &= ~BCM5600_ARL_HIT_FLAG;      }   }   BCM_UNLOCK(d);   return(TRUE);}/* Get the VTABLE entry matching the specified VLAN */static m_uint32_t *bcm5600_vtable_get_entry_by_vlan(struct nm_16esw_data *d,                                                    u_int vlan){   struct bcm5600_table *table = d->t_vtable;   m_uint32_t *entry;   int i;   for(i=table->min_index;i<=table->max_index;i++) {      if (!(entry = bcm5600_table_get_entry(d,table,i)))         break;      if ((entry[0] & BCM5600_VTABLE_VLAN_TAG_MASK) == vlan)         return entry;   }   return NULL;}/* Read memory command */static void bcm5600_handle_read_mem_cmd(struct nm_16esw_data *d){   int i;   if (bcm5600_table_read_entry(d) != 0) {      for(i=1;i<BCM5600_DW_MAX;i++)         d->dw[i] = 0;   }   d->dw[0] = BCM5600_OP_READ_MEM_ACK << BCM5600_CMD_OP_SHIFT;}/* Write memory command */static void bcm5600_handle_write_mem_cmd(struct nm_16esw_data *d){   bcm5600_table_write_entry(d);   d->dw[0] = BCM5600_OP_WRITE_MEM_ACK << BCM5600_CMD_OP_SHIFT;}/* Handle a "general" command */static void bcm5600_handle_gen_cmd(struct nm_16esw_data *d){   m_uint32_t op,src,dst,len;   /* Extract the opcode */   op  = (d->dw[0] & BCM5600_CMD_OP_MASK) >> BCM5600_CMD_OP_SHIFT;   src = (d->dw[0] & BCM5600_CMD_SRC_MASK) >> BCM5600_CMD_SRC_SHIFT;   dst = (d->dw[0] & BCM5600_CMD_DST_MASK) >> BCM5600_CMD_DST_SHIFT;   len = (d->dw[0] & BCM5600_CMD_LEN_MASK) >> BCM5600_CMD_LEN_SHIFT;#if DEBUG_ACCESS   BCM_LOG(d,"gen_cmd: opcode 0x%2.2x [src=0x%2.2x,dst=0x%2.2x,len=0x%2.2x] "           "(dw[0]=0x%8.8x, dw[1]=0x%8.8x, dw[2]=0x%8.8x, dw[3]=0x%8.8x)\n",           op,src,dst,len,d->dw[0],d->dw[1],d->dw[2],d->dw[3]);#endif   switch(op) {      case BCM5600_OP_READ_MEM_CMD:         bcm5600_handle_read_mem_cmd(d);         break;      case BCM5600_OP_WRITE_MEM_CMD:         bcm5600_handle_write_mem_cmd(d);         break;      case BCM5600_OP_READ_REG_CMD:         d->dw[0] = BCM5600_OP_READ_REG_ACK << BCM5600_CMD_OP_SHIFT;#if DEBUG_REG         BCM_LOG(d,"READ_REG: reg_addr=0x%8.8x\n",d->dw[1]);#endif         d->dw[1] = bcm5600_reg_read(d,d->dw[1]);         break;      case BCM5600_OP_WRITE_REG_CMD:         d->dw[0] = BCM5600_OP_WRITE_REG_ACK << BCM5600_CMD_OP_SHIFT;#if DEBUG_REG         BCM_LOG(d,"WRITE_REG: reg_addr=0x%8.8x val=0x%8.8x\n",                 d->dw[1],d->dw[2]);#endif         bcm5600_reg_write(d,d->dw[1],d->dw[2]);         bcm5600_reg_write_special(d,d->dw[1],d->dw[2]);         break;      case BCM5600_OP_ARL_INSERT_CMD:         d->dw[0] = BCM5600_OP_ARL_INSERT_DONE << BCM5600_CMD_OP_SHIFT;#if DEBUG_ARL         BCM_LOG(d,"ARL_INSERT_CMD "                 "(dw[1]=0x%8.8x,dw[2]=0x%8.8x,dw[3]=0x%8.8x)\n",                 d->dw[1],d->dw[2],d->dw[3]);#endif         bcm5600_insert_arl_entry(d);         break;      case BCM5600_OP_ARL_DELETE_CMD:         d->dw[0] = BCM5600_OP_ARL_DELETE_DONE << BCM5600_CMD_OP_SHIFT;#if DEBUG_ARL         BCM_LOG(d,"ARL_DELETE_CMD (dw[1]=0x%8.8x,dw[2]=0x%8.8x)\n",                 d->dw[1],d->dw[2]);#endif         bcm5600_delete_arl_entry(d);         break;      case BCM5600_OP_ARL_LOOKUP_CMD:         d->dw[0] = BCM5600_OP_READ_MEM_ACK << BCM5600_CMD_OP_SHIFT;         break;      default:         BCM_LOG(d,"unknown opcode 0x%8.8x (cmd=0x%8.8x)\n",op,d->dw[0]);   }}/* Handle a s-channel command */static void bcm5600_handle_schan_cmd(struct nm_16esw_data *d,m_uint32_t cmd){   d->schan_cmd = cmd;#if DEBUG_ACCESS   BCM_LOG(d,"s-chan command 0x%8.8x\n",cmd);#endif   switch(cmd) {      case BCM5600_SCHAN_CMD_EXEC:         bcm5600_handle_gen_cmd(d);         d->schan_cmd_res = 0xFFFFFFFF;         break;      case BCM5600_SCHAN_CMD_READ_MII:         bcm5600_mii_read(d);         d->schan_cmd_res = 0xFFFFFFFF;         break;      case BCM5600_SCHAN_CMD_WRITE_MII:         bcm5600_mii_write(d);         d->schan_cmd_res = 0xFFFFFFFF;         break;      case BCM5600_SCHAN_CMD_LINKSCAN:         d->schan_cmd_res = 0x0;         break;      default:#if DEBUG_UNKNOWN

⌨️ 快捷键说明

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