/[dynamips]/trunk/dev_nm_16esw.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 /trunk/dev_nm_16esw.c

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

upstream/dynamips-0.2.6-RC3/dev_nm_16esw.c revision 4 by dpavlin, Sat Oct 6 16:06:49 2007 UTC upstream/dynamips-0.2.7/dev_nm_16esw.c revision 10 by dpavlin, Sat Oct 6 16:29:14 2007 UTC
# Line 1  Line 1 
1  /*  /*
2   * Cisco C3600 simulation platform.   * Cisco router simulation platform.
3   * Copyright (c) 2006 Christophe Fillot (cf@utc.fr)   * Copyright (c) 2006 Christophe Fillot (cf@utc.fr)
4   *   *
5   * NM-16ESW ethernet switch module (experimental!)   * NM-16ESW ethernet switch module (experimental!)
# Line 30  Line 30 
30  #define DEBUG_ACCESS     0  #define DEBUG_ACCESS     0
31  #define DEBUG_UNKNOWN    0  #define DEBUG_UNKNOWN    0
32  #define DEBUG_MII        0  #define DEBUG_MII        0
33  #define DEBUG_MEM        0  #define DEBUG_MEM        1
34  #define DEBUG_REG        1  #define DEBUG_REG        1
35  #define DEBUG_TRANSMIT   0  #define DEBUG_TRANSMIT   0
36  #define DEBUG_RECEIVE    0  #define DEBUG_RECEIVE    0
37  #define DEBUG_FORWARD    0  #define DEBUG_FORWARD    1
38  #define DEBUG_MIRROR     0  #define DEBUG_MIRROR     0
39  #define DEBUG_ARL        0  #define DEBUG_ARL        0
40    
# Line 1395  static void bcm5600_handle_schan_cmd(str Line 1395  static void bcm5600_handle_schan_cmd(str
1395     switch(cmd) {     switch(cmd) {
1396        case BCM5600_SCHAN_CMD_EXEC:        case BCM5600_SCHAN_CMD_EXEC:
1397           bcm5600_handle_gen_cmd(d);           bcm5600_handle_gen_cmd(d);
1398           d->schan_cmd_res = 0xFFFFFFFF;           d->schan_cmd_res = 0x00008002;
1399           break;           break;
1400    
1401        case BCM5600_SCHAN_CMD_READ_MII:        case BCM5600_SCHAN_CMD_READ_MII:
1402           bcm5600_mii_read(d);           bcm5600_mii_read(d);
1403           d->schan_cmd_res = 0xFFFFFFFF;           d->schan_cmd_res = 0x00048000;
1404           break;           break;
1405    
1406        case BCM5600_SCHAN_CMD_WRITE_MII:        case BCM5600_SCHAN_CMD_WRITE_MII:
1407           bcm5600_mii_write(d);           bcm5600_mii_write(d);
1408           d->schan_cmd_res = 0xFFFFFFFF;           d->schan_cmd_res = 0x00048000;
1409           break;           break;
1410    
1411        case BCM5600_SCHAN_CMD_LINKSCAN:        case BCM5600_SCHAN_CMD_LINKSCAN:
# Line 1423  static void bcm5600_handle_schan_cmd(str Line 1423  static void bcm5600_handle_schan_cmd(str
1423  /*  /*
1424   * dev_bcm5605_access()   * dev_bcm5605_access()
1425   */   */
1426  void *dev_bcm5605_access(cpu_mips_t *cpu,struct vdevice *dev,m_uint32_t offset,  void *dev_bcm5605_access(cpu_gen_t *cpu,struct vdevice *dev,m_uint32_t offset,
1427                           u_int op_size,u_int op_type,m_uint64_t *data)                           u_int op_size,u_int op_type,m_uint64_t *data)
1428  {  {
1429     struct nm_16esw_data *d = dev->priv_data;     struct nm_16esw_data *d = dev->priv_data;
# Line 1434  void *dev_bcm5605_access(cpu_mips_t *cpu Line 1434  void *dev_bcm5605_access(cpu_mips_t *cpu
1434    
1435  #if DEBUG_ACCESS  #if DEBUG_ACCESS
1436     if (op_type == MTS_READ) {     if (op_type == MTS_READ) {
1437        BCM_LOG(d,"read  access to offset=0x%x, pc=0x%llx\n",offset,cpu->pc);        BCM_LOG(d,"read  access to offset=0x%x, pc=0x%llx\n",
1438                  offset,cpu_get_pc(cpu));
1439     } else {     } else {
1440        BCM_LOG(d,"write access to offset=0x%x, pc=0x%llx, val=0x%llx\n",        BCM_LOG(d,"write access to offset=0x%x, pc=0x%llx, val=0x%llx\n",
1441                offset,cpu->pc,*data);                offset,cpu_get_pc(cpu),*data);
1442     }     }
1443  #endif  #endif
1444    
# Line 1519  void *dev_bcm5605_access(cpu_mips_t *cpu Line 1520  void *dev_bcm5605_access(cpu_mips_t *cpu
1520                 *data |= BCM5600_INTR_LINKSTAT_MOD;                 *data |= BCM5600_INTR_LINKSTAT_MOD;
1521                 d->mii_intr = FALSE;                 d->mii_intr = FALSE;
1522              }              }
1523    
1524                pci_dev_clear_irq(d->vm,d->pci_dev);
1525           }           }
1526           break;           break;
1527    
# Line 1545  void *dev_bcm5605_access(cpu_mips_t *cpu Line 1548  void *dev_bcm5605_access(cpu_mips_t *cpu
1548        default:        default:
1549           if (op_type == MTS_READ) {           if (op_type == MTS_READ) {
1550              BCM_LOG(d,"read from unknown addr 0x%x, pc=0x%llx (size=%u)\n",              BCM_LOG(d,"read from unknown addr 0x%x, pc=0x%llx (size=%u)\n",
1551                      offset,cpu->pc,op_size);                      offset,cpu_get_pc(cpu),op_size);
1552           } else {           } else {
1553              BCM_LOG(d,"write to unknown addr 0x%x, value=0x%llx, "              BCM_LOG(d,"write to unknown addr 0x%x, value=0x%llx, "
1554                      "pc=0x%llx (size=%u)\n",offset,*data,cpu->pc,op_size);                      "pc=0x%llx (size=%u)\n",
1555                        offset,*data,cpu_get_pc(cpu),op_size);
1556           }           }
1557  #endif  #endif
1558     }     }
# Line 1850  static int bcm5600_dst_mac_lookup(struct Line 1854  static int bcm5600_dst_mac_lookup(struct
1854      */      */
1855     if (dst_mac_index == -1) {     if (dst_mac_index == -1) {
1856  #if DEBUG_FORWARD  #if DEBUG_FORWARD
1857        BCM_LOG(d,"Destination MAC address unknown, flooding.\n");        BCM_LOG(d,"Destination MAC address "
1858                  "%2.2x%2.2x.%2.2x%2.2x.%2.2x%2.2x unknown, flooding.\n",
1859                  dst_mac->eth_addr_byte[0],dst_mac->eth_addr_byte[1],
1860                  dst_mac->eth_addr_byte[2],dst_mac->eth_addr_byte[3],  
1861                  dst_mac->eth_addr_byte[4],dst_mac->eth_addr_byte[5]);
1862  #endif  #endif
1863        p->egress_bitmap = p->vlan_entry[1] & BCM5600_VTABLE_PORT_BMAP_MASK;        p->egress_bitmap = p->vlan_entry[1] & BCM5600_VTABLE_PORT_BMAP_MASK;
1864    
# Line 2058  static int bcm5600_forward_pkt(struct nm Line 2066  static int bcm5600_forward_pkt(struct nm
2066     return(TRUE);     return(TRUE);
2067  }  }
2068    
2069    /* Determine if the specified MAC address matches a BPDU */
2070    static inline int bcm5600_is_bpdu(n_eth_addr_t *m)
2071    {
2072       /* PVST+ */
2073       if (!memcmp(m,"\x01\x00\x0c\xcc\xcc\xcd",6))
2074          return(TRUE);
2075    
2076       /* Classical 802.1D */
2077       if (!memcmp(m,"\x01\x80\xc2\x00\x00",5) && !(m->eth_addr_byte[5] & 0xF0))
2078          return(TRUE);
2079    
2080       /*
2081        * CDP: this is cleary a hack, but IOS seems to program this address
2082        * in BPDU registers.
2083        */
2084       if (!memcmp(m,"\x01\x00\x0c\xcc\xcc\xcc",6))
2085          return(TRUE);
2086      
2087       return(FALSE);
2088    }
2089    
2090  /* Handle a received packet */  /* Handle a received packet */
2091  static int bcm5600_handle_rx_pkt(struct nm_16esw_data *d,struct bcm5600_pkt *p)  static int bcm5600_handle_rx_pkt(struct nm_16esw_data *d,struct bcm5600_pkt *p)
2092  {  {
# Line 2077  static int bcm5600_handle_rx_pkt(struct Line 2106  static int bcm5600_handle_rx_pkt(struct
2106     /* Analyze the Ethernet header */     /* Analyze the Ethernet header */
2107     eth_hdr = (n_eth_dot1q_hdr_t *)p->pkt;     eth_hdr = (n_eth_dot1q_hdr_t *)p->pkt;
2108    
2109       /* Determine VLAN */
2110       if (ntohs(eth_hdr->type) != N_ETH_PROTO_DOT1Q) {
2111          p->orig_vlan = -1;
2112          p->real_vlan = port_entry[0] & BCM5600_PTABLE_VLAN_TAG_MASK;
2113    
2114         /* TODO: 802.1p/CoS remarking */
2115         if (port_entry[4] & BCM5600_PTABLE_RPE_FLAG) {
2116         }
2117       } else {
2118          p->orig_vlan = p->real_vlan = ntohs(eth_hdr->vlan_id) & 0xFFF;
2119       }
2120    
2121       /* Check that this VLAN exists */
2122       if (!(p->vlan_entry = bcm5600_vtable_get_entry_by_vlan(d,p->real_vlan)))
2123          return(FALSE);
2124    
2125     /* Check for the reserved addresses (BPDU for spanning-tree) */     /* Check for the reserved addresses (BPDU for spanning-tree) */
2126     if (!memcmp(&eth_hdr->daddr,"\x01\x80\xc2\x00\x00",5) ||     if (bcm5600_is_bpdu(&eth_hdr->daddr)) {
        !memcmp(&eth_hdr->daddr,"\x01\x00\x0c\xcc\xcc\xcd",6))  
    {  
2127  #if DEBUG_RECEIVE  #if DEBUG_RECEIVE
2128        BCM_LOG(d,"Received a BPDU packet:\n");        BCM_LOG(d,"Received a BPDU packet:\n");
2129        mem_dump(d->vm->log_fd,p->pkt,p->pkt_len);        mem_dump(d->vm->log_fd,p->pkt,p->pkt_len);
2130  #endif  #endif
       p->orig_vlan = 0;  
2131        p->egress_bitmap |= 1 << d->cpu_port;        p->egress_bitmap |= 1 << d->cpu_port;
2132        return(bcm5600_forward_pkt(d,p));        return(bcm5600_forward_pkt(d,p));
2133     }     }
2134    
2135       /* Check that this port is a member of this VLAN */
2136       if (!(p->vlan_entry[1] & (1 << p->ingress_port)))
2137          return(FALSE);
2138    
2139     /* Discard packet ? */     /* Discard packet ? */
2140     discard = port_entry[0] & BCM5600_PTABLE_PRT_DIS_MASK;     discard = port_entry[0] & BCM5600_PTABLE_PRT_DIS_MASK;
2141     discard >>= BCM5600_PTABLE_PRT_DIS_SHIFT;     discard >>= BCM5600_PTABLE_PRT_DIS_SHIFT;
2142    
2143     if (discard) {     if ((p->orig_vlan == -1) && discard) {
2144        if (discard != 0x20) {        if (discard != 0x20) {
2145           printf("\n\n\n"           printf("\n\n\n"
2146                  "-----------------------------------------------------------"                  "-----------------------------------------------------------"
# Line 2113  static int bcm5600_handle_rx_pkt(struct Line 2159  static int bcm5600_handle_rx_pkt(struct
2159     if (port_entry[1] & BCM5600_PTABLE_MI_FLAG)     if (port_entry[1] & BCM5600_PTABLE_MI_FLAG)
2160        bcm5600_mirror_pkt(d,p,0);        bcm5600_mirror_pkt(d,p,0);
2161    
    /* Determine VLAN */  
    if (ntohs(eth_hdr->type) != N_ETH_PROTO_DOT1Q) {  
       p->orig_vlan = -1;  
       p->real_vlan = port_entry[0] & BCM5600_PTABLE_VLAN_TAG_MASK;  
   
      if (!(p->vlan_entry = bcm5600_vtable_get_entry_by_vlan(d,p->real_vlan)))  
         return(FALSE);  
   
      /* TODO: 802.1p/CoS remarking */  
      if (port_entry[4] & BCM5600_PTABLE_RPE_FLAG) {  
      }  
    } else {  
       p->orig_vlan = p->real_vlan = ntohs(eth_hdr->vlan_id) & 0xFFF;  
   
       /* Check that this VLAN exists */  
       if (!(p->vlan_entry = bcm5600_vtable_get_entry_by_vlan(d,p->real_vlan)))  
          return(FALSE);  
   
       /* Check that this port is a member of this VLAN */  
       if (!(p->vlan_entry[1] & (1 << p->ingress_port)))  
          return(FALSE);  
    }  
   
2162  #if DEBUG_RECEIVE  #if DEBUG_RECEIVE
2163     BCM_LOG(d,"%s: received a packet on VLAN %u\n",     BCM_LOG(d,"%s: received a packet on VLAN %u\n",
2164             d->ports[p->ingress_port].name,p->real_vlan);             d->ports[p->ingress_port].name,p->real_vlan);
# Line 2353  static int dev_bcm5600_handle_rxring(net Line 2376  static int dev_bcm5600_handle_rxring(net
2376  }  }
2377    
2378  /* pci_bcm5605_read() */  /* pci_bcm5605_read() */
2379  static m_uint32_t pci_bcm5605_read(cpu_mips_t *cpu,struct pci_device *dev,  static m_uint32_t pci_bcm5605_read(cpu_gen_t *cpu,struct pci_device *dev,
2380                                     int reg)                                     int reg)
2381  {  {
2382     struct nm_16esw_data *d = dev->priv_data;     struct nm_16esw_data *d = dev->priv_data;
# Line 2367  static m_uint32_t pci_bcm5605_read(cpu_m Line 2390  static m_uint32_t pci_bcm5605_read(cpu_m
2390  }  }
2391    
2392  /* pci_bcm5605_write() */  /* pci_bcm5605_write() */
2393  static void pci_bcm5605_write(cpu_mips_t *cpu,struct pci_device *dev,  static void pci_bcm5605_write(cpu_gen_t *cpu,struct pci_device *dev,
2394                                int reg,m_uint32_t value)                                int reg,m_uint32_t value)
2395  {  {
2396     struct nm_16esw_data *d = dev->priv_data;     struct nm_16esw_data *d = dev->priv_data;

Legend:
Removed from v.4  
changed lines
  Added in v.10

  ViewVC Help
Powered by ViewVC 1.1.26