/[dynamips]/upstream/dynamips-0.2.6-RC2/dev_c3600_esw.c
This is repository of my old source code which isn't updated any more. Go to git.rot13.org for current projects!
ViewVC logotype

Diff of /upstream/dynamips-0.2.6-RC2/dev_c3600_esw.c

Parent Directory Parent Directory | Revision Log Revision Log | View Patch Patch

upstream/dynamips-0.2.6-RC1/dev_c3600_esw.c revision 2 by dpavlin, Sat Oct 6 16:03:58 2007 UTC upstream/dynamips-0.2.6-RC2/dev_c3600_esw.c revision 3 by dpavlin, Sat Oct 6 16:05:34 2007 UTC
# Line 20  Line 20 
20  #include <assert.h>  #include <assert.h>
21    
22  #include "utils.h"  #include "utils.h"
23    #include "timer.h"
24  #include "net.h"  #include "net.h"
25  #include "net_io.h"  #include "net_io.h"
26  #include "ptask.h"  #include "ptask.h"
# Line 101  Line 102 
102  #define BCM5600_CMD_CPU_SHIFT    0  #define BCM5600_CMD_CPU_SHIFT    0
103    
104  /* Memory zones */  /* Memory zones */
105  #define BCM5600_ADDR_ARLCNT      0x01000000  #define BCM5600_ADDR_ARLCNT0     0x01000000
106    #define BCM5600_ADDR_ARLCNT1     0x01100000
107    #define BCM5600_ADDR_ARLCNT2     0x01200000
108  #define BCM5600_ADDR_ARL0        0x02000000  #define BCM5600_ADDR_ARL0        0x02000000
109  #define BCM5600_ADDR_ARL1        0x02100000  #define BCM5600_ADDR_ARL1        0x02100000
110  #define BCM5600_ADDR_ARL2        0x02200000  #define BCM5600_ADDR_ARL2        0x02200000
# Line 361  struct bcm5600_port { Line 364  struct bcm5600_port {
364     netio_desc_t *nio;     netio_desc_t *nio;
365     u_int id;     u_int id;
366     char name[32];     char name[32];
   
    /* Other info ? */  
367  };  };
368    
369  /* NM-16ESW private data */  /* NM-16ESW private data */
# Line 376  struct nm_16esw_data { Line 377  struct nm_16esw_data {
377    
378     pthread_mutex_t lock;     pthread_mutex_t lock;
379    
380       /* Ager task */
381       timer_id ager_tid;
382    
383     /* S-channel command and command result */     /* S-channel command and command result */
384     m_uint32_t schan_cmd,schan_cmd_res;     m_uint32_t schan_cmd,schan_cmd_res;
385        
# Line 423  struct nm_16esw_data { Line 427  struct nm_16esw_data {
427     /* Current egress port of all trunks */     /* Current egress port of all trunks */
428     u_int trunk_last_egress_port[BCM5600_MAX_TRUNKS];     u_int trunk_last_egress_port[BCM5600_MAX_TRUNKS];
429    
430       /* ARL count table */
431       m_uint32_t *arl_cnt;
432    
433     /* ARL (Address Resolution Logic) Table */     /* ARL (Address Resolution Logic) Table */
434     m_uint32_t *arl_table;     m_uint32_t *arl_table;
435    
# Line 444  static int nm16esw_port_mapping[] = { Line 451  static int nm16esw_port_mapping[] = {
451     2, 0, 6, 4, 10, 8, 14, 12, 3, 1, 7, 5, 11, 9, 15, 13,     2, 0, 6, 4, 10, 8, 14, 12, 3, 1, 7, 5, 11, 9, 15, 13,
452  };  };
453    
 /* NM-16ESW: 16 Ethernet port switch module */  
 static m_uint16_t eeprom_c3600_nm_16esw_data[] = {  
    0x04FF, 0x4002, 0xA941, 0x0100, 0xC046, 0x0320, 0x003B, 0x3401,  
    0x4245, 0x3080, 0x0000, 0x0000, 0x0203, 0xC18B, 0x464F, 0x4330,  
    0x3931, 0x3132, 0x454E, 0x3803, 0x0081, 0x0000, 0x0000, 0x0400,  
    0xCF06, 0x0013, 0x1A1D, 0x0BD1, 0x4300, 0x11FF, 0xFFFF, 0xFFFF,  
    0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF,  
    0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF,  
    0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF,  
    0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF,  
 };  
   
 static const struct c3600_eeprom eeprom_c3600_nm_16esw = {  
    "NM-16ESW", (m_uint16_t *)eeprom_c3600_nm_16esw_data,  
    sizeof(eeprom_c3600_nm_16esw_data)/2,  
 };  
   
454  /* Log a BCM message */  /* Log a BCM message */
455  #define BCM_LOG(d,msg...) vm_log((d)->vm,(d)->name,msg)  #define BCM_LOG(d,msg...) vm_log((d)->vm,(d)->name,msg)
456    
# Line 524  static void bcm5600_mii_read(struct nm_1 Line 514  static void bcm5600_mii_read(struct nm_1
514              d->mii_output |= 0x1000;  /* autoneg */              d->mii_output |= 0x1000;  /* autoneg */
515              break;              break;
516           case 0x01:           case 0x01:
517              if (bcm5600_mii_port_status(d,port))              if (d->ports[port].nio && bcm5600_mii_port_status(d,port))
518                 d->mii_output = 0x782C;                 d->mii_output = 0x782C;
519              else              else
520                 d->mii_output = 0;                 d->mii_output = 0;
# Line 651  static void bcm5600_reg_write_special(st Line 641  static void bcm5600_reg_write_special(st
641        case 0x8000d:        case 0x8000d:
642           d->mirror_egress_ports = value;           d->mirror_egress_ports = value;
643           break;           break;
644    
645          case 0x80009:
646             /* age timer */
647             break;
648     }     }
649  }  }
650    
# Line 704  static char *bcm5600_port_bitmap_str(str Line 698  static char *bcm5600_port_bitmap_str(str
698    
699  static struct bcm5600_table bcm5600_tables[] = {  static struct bcm5600_table bcm5600_tables[] = {
700     /* ARL tables */     /* ARL tables */
701     { "arl0", BCM_OFFSET(arl_table), BCM5600_ADDR_ARL0, 1, 8191, 3 },     { "arlcnt0", BCM_OFFSET(arl_cnt), BCM5600_ADDR_ARLCNT0, 0, 0, 1 },
702     { "arl1", BCM_OFFSET(arl_table), BCM5600_ADDR_ARL1, 1, 8191, 3 },     { "arlcnt1", BCM_OFFSET(arl_cnt), BCM5600_ADDR_ARLCNT1, 0, 0, 1 },
703     { "arl2", BCM_OFFSET(arl_table), BCM5600_ADDR_ARL2, 1, 8191, 3 },     { "arlcnt2", BCM_OFFSET(arl_cnt), BCM5600_ADDR_ARLCNT2, 0, 0, 1 },
704    
705       /* ARL tables */
706       { "arl0", BCM_OFFSET(arl_table), BCM5600_ADDR_ARL0, 0, 8191, 3 },
707       { "arl1", BCM_OFFSET(arl_table), BCM5600_ADDR_ARL1, 0, 8191, 3 },
708       { "arl2", BCM_OFFSET(arl_table), BCM5600_ADDR_ARL2, 0, 8191, 3 },
709    
710     /* Multicast ARL tables */     /* Multicast ARL tables */
711     { "marl0", BCM_OFFSET(marl_table), BCM5600_ADDR_MARL0, 1, 255, 5 },     { "marl0", BCM_OFFSET(marl_table), BCM5600_ADDR_MARL0, 1, 255, 5 },
# Line 1083  static void bcm5600_dump_main_tables(str Line 1082  static void bcm5600_dump_main_tables(str
1082  static int bcm5600_find_free_arl_entry(struct nm_16esw_data *d)  static int bcm5600_find_free_arl_entry(struct nm_16esw_data *d)
1083  {    {  
1084     struct bcm5600_table *table = d->t_arl;     struct bcm5600_table *table = d->t_arl;
    m_uint32_t *entry;  
    u_int vlan;  
    int i;  
1085    
1086     for(i=table->min_index;i<=table->max_index;i++) {     if (d->arl_cnt[0] == table->max_index)
1087        entry = bcm5600_table_get_entry(d,table,i);        return(-1);
   
       vlan = (entry[1] & BCM5600_ARL_VLAN_TAG_MASK);  
       vlan >>= BCM5600_ARL_VLAN_TAG_SHIFT;  
   
       if (vlan == 0xFFF)  
          return(i);  
    }  
1088    
1089     return(-1);     return(d->arl_cnt[0] - 1);
1090  }  }
1091    
1092  /* ARL Lookup. TODO: this must be optimized in the future. */  /* ARL Lookup. TODO: this must be optimized in the future. */
1093  static inline int bcm5600_gen_arl_lookup(struct nm_16esw_data *d,  static inline int bcm5600_gen_arl_lookup(struct nm_16esw_data *d,
1094                                           struct bcm5600_table *table,                                           struct bcm5600_table *table,
1095                                             u_int index_start,u_int index_end,
1096                                           n_eth_addr_t *mac_addr,                                           n_eth_addr_t *mac_addr,
1097                                           u_int vlan)                                           u_int vlan)
1098  {  {
# Line 1119  static inline int bcm5600_gen_arl_lookup Line 1109  static inline int bcm5600_gen_arl_lookup
1109    
1110     mask = BCM5600_ARL_VLAN_TAG_MASK | BCM5600_ARL_MAC_MSB_MASK;     mask = BCM5600_ARL_VLAN_TAG_MASK | BCM5600_ARL_MAC_MSB_MASK;
1111    
1112     for(i=table->min_index;i<=table->max_index;i++) {     for(i=index_start;i<index_end;i++) {
1113        entry = bcm5600_table_get_entry(d,table,i);        entry = bcm5600_table_get_entry(d,table,i);
1114    
1115        if ((entry[0] == tmp[0]) && ((entry[1] & mask) == tmp[1]))        if ((entry[0] == tmp[0]) && ((entry[1] & mask) == tmp[1]))
# Line 1134  static inline int bcm5600_arl_lookup(str Line 1124  static inline int bcm5600_arl_lookup(str
1124                                       n_eth_addr_t *mac_addr,                                       n_eth_addr_t *mac_addr,
1125                                       u_int vlan)                                       u_int vlan)
1126  {  {
1127     return(bcm5600_gen_arl_lookup(d,d->t_arl,mac_addr,vlan));     struct bcm5600_table *table = d->t_arl;
1128       return(bcm5600_gen_arl_lookup(d,table,1,d->arl_cnt[0]-1,mac_addr,vlan));
1129  }  }
1130    
1131  /* MARL Lookup */  /* MARL Lookup */
# Line 1142  static inline int bcm5600_marl_lookup(st Line 1133  static inline int bcm5600_marl_lookup(st
1133                                        n_eth_addr_t *mac_addr,                                        n_eth_addr_t *mac_addr,
1134                                        u_int vlan)                                        u_int vlan)
1135  {  {
1136     return(bcm5600_gen_arl_lookup(d,d->t_marl,mac_addr,vlan));     struct bcm5600_table *table = d->t_marl;
1137       return(bcm5600_gen_arl_lookup(d,table,table->min_index,table->max_index+1,
1138                                     mac_addr,vlan));
1139    }
1140    
1141    /* Invalidate an ARL entry */
1142    static void bcm5600_invalidate_arl_entry(m_uint32_t *entry)
1143    {
1144       entry[0] = entry[1] = entry[2] = 0;
1145  }  }
1146    
1147  /* Insert an entry into the ARL table */  /* Insert an entry into the ARL table */
1148  static int bcm5600_insert_arl_entry(struct nm_16esw_data *d)  static int bcm5600_insert_arl_entry(struct nm_16esw_data *d)
1149  {    {  
1150     struct bcm5600_table *table = d->t_arl;     struct bcm5600_table *table = d->t_arl;
1151     m_uint32_t *entry;     m_uint32_t *entry,mask;
1152     int index;     int i,index;
1153    
1154     if ((index = bcm5600_find_free_arl_entry(d)) == -1)     mask = BCM5600_ARL_VLAN_TAG_MASK | BCM5600_ARL_MAC_MSB_MASK;
1155        return(-1);  
1156       for(i=0;i<d->arl_cnt[0]-1;i++) {
1157          entry = bcm5600_table_get_entry(d,table,i);
1158    
1159          /* If entry already exists, just modify it */
1160          if ((entry[0] == d->dw[1]) && ((entry[1] & mask) == (d->dw[2] & mask))) {
1161             entry[0] = d->dw[1];
1162             entry[1] = d->dw[2];
1163             entry[2] = d->dw[3];
1164             d->dw[1] = i;
1165             return(0);
1166          }
1167       }
1168    
1169       index = d->arl_cnt[0] - 1;
1170    
1171     entry = bcm5600_table_get_entry(d,table,index);     entry = bcm5600_table_get_entry(d,table,index);
1172     entry[0] = d->dw[1];     entry[0] = d->dw[1];
1173     entry[1] = d->dw[2];     entry[1] = d->dw[2];
1174     entry[2] = d->dw[3];     entry[2] = d->dw[3];
1175     d->dw[1] = index;     d->dw[1] = index;
1176      
1177       d->arl_cnt[0]++;
1178     return(0);     return(0);
1179  }  }
1180    
# Line 1167  static int bcm5600_insert_arl_entry(stru Line 1182  static int bcm5600_insert_arl_entry(stru
1182  static int bcm5600_delete_arl_entry(struct nm_16esw_data *d)  static int bcm5600_delete_arl_entry(struct nm_16esw_data *d)
1183  {    {  
1184     struct bcm5600_table *table;     struct bcm5600_table *table;
1185     m_uint32_t *entry,mac_msb;     m_uint32_t *entry,*last_entry,mac_msb;
1186     u_int cvlan,vlan;     u_int cvlan,vlan;
1187     int i;     int i;
1188    
# Line 1189  static int bcm5600_delete_arl_entry(stru Line 1204  static int bcm5600_delete_arl_entry(stru
1204        if ((cvlan == vlan) && (entry[0] == d->dw[1]) &&        if ((cvlan == vlan) && (entry[0] == d->dw[1]) &&
1205            ((entry[1] & BCM5600_ARL_MAC_MSB_MASK) == mac_msb))            ((entry[1] & BCM5600_ARL_MAC_MSB_MASK) == mac_msb))
1206        {                    {            
          entry[0] = 0xFFFFFFFF;  
          entry[1] = (VLAN_INVALID << BCM5600_ARL_VLAN_TAG_SHIFT) | 0xFFFF;  
          entry[2] = 0;  
   
1207           d->dw[1] = i;           d->dw[1] = i;
1208    
1209             last_entry = bcm5600_table_get_entry(d,d->t_arl,d->arl_cnt[0]-2);
1210                
1211             entry[0] = last_entry[0];
1212             entry[1] = last_entry[1];
1213             entry[2] = last_entry[2];
1214    
1215             d->arl_cnt[0]--;
1216           return(i);           return(i);
1217        }        }
1218     }     }
# Line 1203  static int bcm5600_delete_arl_entry(stru Line 1222  static int bcm5600_delete_arl_entry(stru
1222    
1223  /* Reset the ARL tables */  /* Reset the ARL tables */
1224  static int bcm5600_reset_arl(struct nm_16esw_data *d)  static int bcm5600_reset_arl(struct nm_16esw_data *d)
1225  {    {
1226     struct bcm5600_table *table;     struct bcm5600_table *table;
1227     m_uint32_t *entry;     m_uint32_t *entry;
1228     int i;     int i;
# Line 1213  static int bcm5600_reset_arl(struct nm_1 Line 1232  static int bcm5600_reset_arl(struct nm_1
1232    
1233     for(i=table->min_index;i<=table->max_index;i++) {     for(i=table->min_index;i<=table->max_index;i++) {
1234        entry = bcm5600_table_get_entry(d,table,i);        entry = bcm5600_table_get_entry(d,table,i);
1235          bcm5600_invalidate_arl_entry(entry);
       entry[0] = 0xFFFFFFFF;  
       entry[1] = (VLAN_INVALID << BCM5600_ARL_VLAN_TAG_SHIFT) | 0xFFFF;  
       entry[2] = 0;  
1236     }     }
1237    
1238     return(0);     return(0);
1239  }  }
1240    
1241    /* MAC Address Ager */
1242    static int bcm5600_arl_ager(struct nm_16esw_data *d)
1243    {
1244       m_uint32_t *entry,*last_entry;
1245       int i;
1246    
1247       BCM_LOCK(d);
1248    
1249       for(i=1;i<d->arl_cnt[0]-1;i++) {
1250          entry = bcm5600_table_get_entry(d,d->t_arl,i);
1251          assert(entry);
1252    
1253          if (entry[2] & BCM5600_ARL_ST_FLAG)
1254             continue;
1255    
1256          /* The entry has expired, purge it */
1257          if (!(entry[2] & BCM5600_ARL_HIT_FLAG)) {
1258             last_entry = bcm5600_table_get_entry(d,d->t_arl,d->arl_cnt[0]-2);
1259            
1260             entry[0] = last_entry[0];
1261             entry[1] = last_entry[1];
1262             entry[2] = last_entry[2];
1263    
1264             d->arl_cnt[0]--;
1265             i--;
1266          } else {
1267             entry[2] &= ~BCM5600_ARL_HIT_FLAG;
1268          }
1269       }
1270    
1271       BCM_UNLOCK(d);
1272       return(TRUE);
1273    }
1274    
1275  /* Get the VTABLE entry matching the specified VLAN */  /* Get the VTABLE entry matching the specified VLAN */
1276  static m_uint32_t *bcm5600_vtable_get_entry_by_vlan(struct nm_16esw_data *d,  static m_uint32_t *bcm5600_vtable_get_entry_by_vlan(struct nm_16esw_data *d,
1277                                                      u_int vlan)                                                      u_int vlan)
# Line 1247  static void bcm5600_handle_read_mem_cmd( Line 1297  static void bcm5600_handle_read_mem_cmd(
1297     int i;     int i;
1298    
1299     if (bcm5600_table_read_entry(d) != 0) {     if (bcm5600_table_read_entry(d) != 0) {
1300        for(i=0;i<BCM5600_DW_MAX;i++)        for(i=1;i<BCM5600_DW_MAX;i++)
1301           d->dw[i] = 0;           d->dw[i] = 0;
1302     }     }
1303    
# Line 1699  static int bcm5600_src_mac_learning(stru Line 1749  static int bcm5600_src_mac_learning(stru
1749     src_mac_index = bcm5600_find_free_arl_entry(d);     src_mac_index = bcm5600_find_free_arl_entry(d);
1750    
1751     if (src_mac_index == -1) {     if (src_mac_index == -1) {
1752  #if DEBUG_FORWARD        BCM_LOG(d,"no free entries in ARL table!\n");
       BCM_LOG(d,"no free entries in ARL table.\n");  
 #endif  
1753        return(FALSE);        return(FALSE);
1754     }     }
1755    
# Line 1726  static int bcm5600_src_mac_learning(stru Line 1774  static int bcm5600_src_mac_learning(stru
1774        arl_entry[2] |= (trunk_id << BCM5600_ARL_TGID_SHIFT);        arl_entry[2] |= (trunk_id << BCM5600_ARL_TGID_SHIFT);
1775     }     }
1776    
1777       d->arl_cnt[0]++;
1778     return(TRUE);     return(TRUE);
1779  }  }
1780    
# Line 1784  static int bcm5600_dst_mac_lookup(struct Line 1833  static int bcm5600_dst_mac_lookup(struct
1833     int dst_mac_index;     int dst_mac_index;
1834     int is_mcast;     int is_mcast;
1835    
1836     /* Check for the reserved addresses (BPDU for spanning-tree) */     /* Select the appropriate ARL table and do the lookup on dst MAC + VLAN */
    if (!memcmp(&eth_hdr->daddr,"\x01\x80\xc2\x00\x00",5)) {  
       p->egress_bitmap |= 1 << d->cpu_port;  
       return(TRUE);  
    }  
   
    /* Select the appropriate ARL table */  
1837     if (eth_addr_is_mcast(dst_mac)) {     if (eth_addr_is_mcast(dst_mac)) {
1838        is_mcast = TRUE;        is_mcast = TRUE;
1839        arl_table = d->t_marl;        arl_table = d->t_marl;
1840          dst_mac_index = bcm5600_marl_lookup(d,dst_mac,p->real_vlan);
1841     } else {     } else {
1842        is_mcast = FALSE;        is_mcast = FALSE;
1843        arl_table = d->t_arl;        arl_table = d->t_arl;
1844          dst_mac_index = bcm5600_arl_lookup(d,dst_mac,p->real_vlan);
1845     }     }
1846    
    /* ARL Lookup for this MAC address + VLAN */  
    dst_mac_index = bcm5600_gen_arl_lookup(d,arl_table,dst_mac,p->real_vlan);  
   
1847     /*     /*
1848      * Destination Lookup Failure (DLF).      * Destination Lookup Failure (DLF).
1849      *      *
# Line 2023  static int bcm5600_handle_rx_pkt(struct Line 2065  static int bcm5600_handle_rx_pkt(struct
2065  {  {
2066     m_uint32_t *port_entry;     m_uint32_t *port_entry;
2067     n_eth_dot1q_hdr_t *eth_hdr;     n_eth_dot1q_hdr_t *eth_hdr;
2068         u_int discard;
2069    
2070       /* No egress port at this time */
2071       p->egress_bitmap = 0;
2072    
2073       /* Never send back frames to the source port */
2074       p->egress_filter_bitmap = 1 << p->ingress_port;
2075    
2076     if (!(port_entry = bcm5600_table_get_entry(d,d->t_ptable,p->ingress_port)))     if (!(port_entry = bcm5600_table_get_entry(d,d->t_ptable,p->ingress_port)))
2077        return(FALSE);        return(FALSE);
2078    
2079       /* Analyze the Ethernet header */
2080     eth_hdr = (n_eth_dot1q_hdr_t *)p->pkt;     eth_hdr = (n_eth_dot1q_hdr_t *)p->pkt;
2081    
2082       /* Check for the reserved addresses (BPDU for spanning-tree) */
2083       if (!memcmp(&eth_hdr->daddr,"\x01\x80\xc2\x00\x00",5)) {
2084          p->egress_bitmap |= 1 << d->cpu_port;
2085          return(bcm5600_forward_pkt(d,p));
2086       }
2087    
2088       /* Discard packet ? */
2089       discard = port_entry[0] & BCM5600_PTABLE_PRT_DIS_MASK;
2090       discard >>= BCM5600_PTABLE_PRT_DIS_SHIFT;
2091    
2092       if (discard) {
2093          if (discard != 0x20) {
2094             printf("\n\n\n"
2095                    "-----------------------------------------------------------"
2096                    "---------------------------------\n"
2097                    "Unspported feature: please post your current configuration "
2098                    "on http://www.ipflow.utc.fr/blog/\n"
2099                    "-----------------------------------------------------------"
2100                    "---------------------------------\n");
2101          }
2102    
2103          /* Drop the packet */
2104          return(FALSE);
2105       }
2106    
2107     /* Mirroring on Ingress ? */     /* Mirroring on Ingress ? */
2108     if (port_entry[1] & BCM5600_PTABLE_MI_FLAG)     if (port_entry[1] & BCM5600_PTABLE_MI_FLAG)
2109        bcm5600_mirror_pkt(d,p,0);        bcm5600_mirror_pkt(d,p,0);
# Line 2061  static int bcm5600_handle_rx_pkt(struct Line 2136  static int bcm5600_handle_rx_pkt(struct
2136             d->ports[p->ingress_port].name,p->real_vlan);             d->ports[p->ingress_port].name,p->real_vlan);
2137  #endif  #endif
2138    
    /* No egress port at this time */  
    p->egress_bitmap = 0;  
   
    /* Never send back frames to the source port */  
    p->egress_filter_bitmap = 1 << p->ingress_port;  
   
2139     /* Source MAC address learning */     /* Source MAC address learning */
2140     if (!bcm5600_src_mac_learning(d,p))     if (!bcm5600_src_mac_learning(d,p))
2141        return(FALSE);        return(FALSE);
# Line 2085  static int bcm5600_handle_tx_pkt(struct Line 2154  static int bcm5600_handle_tx_pkt(struct
2154                                   u_int egress_bitmap)                                   u_int egress_bitmap)
2155  {    {  
2156     n_eth_dot1q_hdr_t *eth_hdr;     n_eth_dot1q_hdr_t *eth_hdr;
   
    {      
       eth_hdr = (n_eth_dot1q_hdr_t *)p->pkt;  
   
       if (ntohs(eth_hdr->type) == 0x9000) {  
          printf("bcm5600_handle_tx_pkt: KEEPALIVE ????\n");  
          return(FALSE);  
       }  
    }  
2157        
2158     /* Never send back frames to the source port */     /* Never send back frames to the source port */
2159     p->egress_filter_bitmap = 1 << p->ingress_port;     p->egress_filter_bitmap = 1 << p->ingress_port;
# Line 2312  static void pci_bcm5605_write(cpu_mips_t Line 2372  static void pci_bcm5605_write(cpu_mips_t
2372     }     }
2373  }  }
2374    
2375    /* Rewrite the base MAC address */
2376    static int dev_c3600_nm_16esw_burn_mac_addr(c3600_t *router,u_int nm_bay)
2377    {
2378       struct cisco_eeprom *eeprom;
2379       m_uint8_t eeprom_ver;
2380       size_t offset;
2381       n_eth_addr_t addr;
2382       m_uint16_t pid;
2383    
2384       pid = (m_uint16_t)getpid();
2385    
2386       /* Generate automatically the MAC address */
2387       addr.eth_addr_byte[0] = 0xCE;
2388       addr.eth_addr_byte[1] = router->vm->instance_id & 0xFF;
2389       addr.eth_addr_byte[2] = pid >> 8;
2390       addr.eth_addr_byte[3] = pid & 0xFF;
2391       addr.eth_addr_byte[4] = nm_bay;
2392       addr.eth_addr_byte[5] = 0x00;
2393    
2394       /* Modify the EEPROM data which have been duplicated */
2395       eeprom = &router->nm_bay[nm_bay].eeprom;
2396      
2397       /* Read EEPROM format version */
2398       cisco_eeprom_get_byte(eeprom,0,&eeprom_ver);
2399    
2400       if (eeprom_ver != 4)
2401          return(-1);
2402    
2403       if (cisco_eeprom_v4_find_field(eeprom,0xCF,&offset) == -1)
2404          return(-1);
2405    
2406       cisco_eeprom_set_region(eeprom,offset,addr.eth_addr_byte,6);
2407       return(0);
2408    }
2409    
2410  /* Initialize a NM-16ESW module */  /* Initialize a NM-16ESW module */
2411  static int dev_c3600_nm_16esw_init(c3600_t *router,char *name,u_int nm_bay)  static int dev_c3600_nm_16esw_init(c3600_t *router,char *name,u_int nm_bay)
2412  {  {
# Line 2339  static int dev_c3600_nm_16esw_init(c3600 Line 2434  static int dev_c3600_nm_16esw_init(c3600
2434    
2435     /* Clear the various tables */     /* Clear the various tables */
2436     bcm5600_reset_arl(data);     bcm5600_reset_arl(data);
2437       data->arl_cnt[0] = 1;
2438     data->t_ptable = bcm5600_table_find(data,BCM5600_ADDR_PTABLE0);     data->t_ptable = bcm5600_table_find(data,BCM5600_ADDR_PTABLE0);
2439     data->t_vtable = bcm5600_table_find(data,BCM5600_ADDR_VTABLE0);     data->t_vtable = bcm5600_table_find(data,BCM5600_ADDR_VTABLE0);
2440     data->t_arl    = bcm5600_table_find(data,BCM5600_ADDR_ARL0);     data->t_arl    = bcm5600_table_find(data,BCM5600_ADDR_ARL0);
# Line 2359  static int dev_c3600_nm_16esw_init(c3600 Line 2454  static int dev_c3600_nm_16esw_init(c3600
2454     }     }
2455    
2456     /* Set the EEPROM */     /* Set the EEPROM */
2457     c3600_nm_set_eeprom(router,nm_bay,&eeprom_c3600_nm_16esw);     c3600_nm_set_eeprom(router,nm_bay,cisco_eeprom_find_nm("NM-16ESW"));
2458       dev_c3600_nm_16esw_burn_mac_addr(router,nm_bay);
2459    
2460     /* Get PCI bus info about this bay */     /* Get PCI bus info about this bay */
2461     bay_info = c3600_nm_get_bay_info(c3600_chassis_get_id(router),nm_bay);     bay_info = c3600_nm_get_bay_info(c3600_chassis_get_id(router),nm_bay);
# Line 2398  static int dev_c3600_nm_16esw_init(c3600 Line 2494  static int dev_c3600_nm_16esw_init(c3600
2494     data->tx_tid = ptask_add((ptask_callback)dev_bcm5606_handle_txring,     data->tx_tid = ptask_add((ptask_callback)dev_bcm5606_handle_txring,
2495                              data,NULL);                              data,NULL);
2496    
2497       /* Start the MAC address ager */
2498       data->ager_tid = timer_create_entry(15000,FALSE,10,
2499                                           (timer_proc)bcm5600_arl_ager,data);
2500    
2501     /* Store device info into the router structure */     /* Store device info into the router structure */
2502     return(c3600_nm_set_drvinfo(router,nm_bay,data));     return(c3600_nm_set_drvinfo(router,nm_bay,data));
2503  }  }
# Line 2416  static int dev_c3600_nm_16esw_shutdown(c Line 2516  static int dev_c3600_nm_16esw_shutdown(c
2516     /* Remove the NM EEPROM */     /* Remove the NM EEPROM */
2517     c3600_nm_unset_eeprom(router,nm_bay);     c3600_nm_unset_eeprom(router,nm_bay);
2518    
2519       /* Stop the Ager */
2520       timer_remove(data->ager_tid);
2521    
2522     /* Stop the TX ring task */     /* Stop the TX ring task */
2523     ptask_remove(data->tx_tid);     ptask_remove(data->tx_tid);
2524    
# Line 2476  static int dev_c3600_nm_16esw_show_info( Line 2579  static int dev_c3600_nm_16esw_show_info(
2579        return(-1);        return(-1);
2580        
2581     BCM_LOCK(d);     BCM_LOCK(d);
2582       printf("ARL count = %u\n\n",d->arl_cnt[0]);
2583     bcm5600_dump_main_tables(d);     bcm5600_dump_main_tables(d);
2584     bcm5600_mirror_show_status(d);     bcm5600_mirror_show_status(d);
2585     bcm5600_reg_dump(d,FALSE);     bcm5600_reg_dump(d,FALSE);

Legend:
Removed from v.2  
changed lines
  Added in v.3

  ViewVC Help
Powered by ViewVC 1.1.26