📄 dev_nm_16esw.c
字号:
/* * Cisco C3600 simulation platform. * Copyright (c) 2006 Christophe Fillot (cf@utc.fr) * * NM-16ESW ethernet switch module (experimental!) * * It's an attempt of proof of concept, so not optimized at all at this time. * Only L2 switching will be managed (no L3 at all). * * To do next: QoS features (CoS/DSCP handling). */#include <stdio.h>#include <stdlib.h>#include <string.h>#include <stdarg.h>#include <unistd.h>#include <time.h>#include <errno.h>#include <assert.h>#include "utils.h"#include "timer.h"#include "net.h"#include "net_io.h"#include "ptask.h"#include "dev_nm_16esw.h"/* Debugging flags */#define DEBUG_ACCESS 0#define DEBUG_UNKNOWN 0#define DEBUG_MII 0#define DEBUG_MEM 0#define DEBUG_REG 1#define DEBUG_TRANSMIT 0#define DEBUG_RECEIVE 0#define DEBUG_FORWARD 0#define DEBUG_MIRROR 0#define DEBUG_ARL 0/* Invalid VLAN value */#define VLAN_INVALID 0xFFF/* Maximum packet size */#define BCM5600_MAX_PKT_SIZE 2048/* PCI vendor/product codes */#define BCM5605_PCI_VENDOR_ID 0x14e4#define BCM5605_PCI_PRODUCT_ID 0x5605/* "S-channel" commands */#define BCM5600_SCHAN_CMD_LINKSCAN 0x13#define BCM5600_SCHAN_CMD_EXEC 0x80#define BCM5600_SCHAN_CMD_READ_MII 0x90#define BCM5600_SCHAN_CMD_WRITE_MII 0x91/* Opcodes */#define BCM5600_OP_BP_WARN_STATUS 0x01#define BCM5600_OP_BP_DISCARD_STATUS 0x02#define BCM5600_OP_COS_QSTAT_NOTIFY 0x03#define BCM5600_OP_HOL_STAT_NOTIFY 0x04#define BCM5600_OP_GBP_FULL_NOTIFY 0x05#define BCM5600_OP_GBP_AVAIL_NOTIFY 0x06#define BCM5600_OP_READ_MEM_CMD 0x07#define BCM5600_OP_READ_MEM_ACK 0x08#define BCM5600_OP_WRITE_MEM_CMD 0x09#define BCM5600_OP_WRITE_MEM_ACK 0x0A#define BCM5600_OP_READ_REG_CMD 0x0B#define BCM5600_OP_READ_REG_ACK 0x0C#define BCM5600_OP_WRITE_REG_CMD 0x0D#define BCM5600_OP_WRITE_REG_ACK 0x0E#define BCM5600_OP_ARL_INSERT_CMD 0x0F#define BCM5600_OP_ARL_INSERT_DONE 0x10#define BCM5600_OP_ARL_DELETE_CMD 0x11#define BCM5600_OP_ARL_DELETE_DONE 0x12#define BCM5600_OP_LINKSTAT_NOTIFY 0x13#define BCM5600_OP_MEM_FAIL_NOTIFY 0x14#define BCM5600_OP_INIT_CFAP 0x15#define BCM5600_OP_INIT_SFAP 0x16#define BCM5600_OP_ENTER_DEBUG_MODE 0x17#define BCM5600_OP_EXIT_DEBUG_MODE 0x18#define BCM5600_OP_ARL_LOOKUP_CMD 0x19/* Command details */#define BCM5600_CMD_OP_MASK 0xFC000000#define BCM5600_CMD_OP_SHIFT 26#define BCM5600_CMD_DST_MASK 0x03F00000#define BCM5600_CMD_DST_SHIFT 20#define BCM5600_CMD_SRC_MASK 0x000FC000#define BCM5600_CMD_SRC_SHIFT 14#define BCM5600_CMD_LEN_MASK 0x00003F80#define BCM5600_CMD_LEN_SHIFT 7#define BCM5600_CMD_EBIT_MASK 0x00000040#define BCM5600_CMD_EBIT_SHIFT 6#define BCM5600_CMD_ECODE_MASK 0x00000030#define BCM5600_CMD_ECODE_SHIFT 4#define BCM5600_CMD_COS_MASK 0x0000000E#define BCM5600_CMD_COS_SHIFT 1#define BCM5600_CMD_CPU_MASK 0x00000001#define BCM5600_CMD_CPU_SHIFT 0/* Memory zones */#define BCM5600_ADDR_ARLCNT0 0x01000000#define BCM5600_ADDR_ARLCNT1 0x01100000#define BCM5600_ADDR_ARLCNT2 0x01200000#define BCM5600_ADDR_ARL0 0x02000000#define BCM5600_ADDR_ARL1 0x02100000#define BCM5600_ADDR_ARL2 0x02200000#define BCM5600_ADDR_PTABLE0 0x03000000#define BCM5600_ADDR_PTABLE1 0x03100000#define BCM5600_ADDR_PTABLE2 0x03200000#define BCM5600_ADDR_VTABLE0 0x05000000#define BCM5600_ADDR_VTABLE1 0x05100000#define BCM5600_ADDR_VTABLE2 0x05200000#define BCM5600_ADDR_TTR0 0x06000000#define BCM5600_ADDR_TBMAP0 0x06010000#define BCM5600_ADDR_TTR1 0x06100000#define BCM5600_ADDR_TBMAP1 0x06110000#define BCM5600_ADDR_TTR2 0x06200000#define BCM5600_ADDR_TBMAP2 0x06210000#define BCM5600_ADDR_IMASK0 0x07000000#define BCM5600_ADDR_IRULE0 0x07020000#define BCM5600_ADDR_IMASK1 0x07100000#define BCM5600_ADDR_IRULE1 0x07120000#define BCM5600_ADDR_IMASK2 0x07200000#define BCM5600_ADDR_IRULE2 0x07220000#define BCM5600_ADDR_GIMASK 0x07300000#define BCM5600_ADDR_GIRULE 0x07320000#define BCM5600_ADDR_MARL0 0x08000000#define BCM5600_ADDR_MARL1 0x08100000#define BCM5600_ADDR_MARL2 0x08200000#define BCM5600_ADDR_L3 0x09000000#define BCM5600_ADDR_DEFIP 0x09010000#define BCM5600_ADDR_L3INTF 0x09020000#define BCM5600_ADDR_IPMC 0x09030000#define BCM5600_ADDR_CBPHDR 0x0A600000#define BCM5600_ADDR_CAB0 0x0A610000#define BCM5600_ADDR_CAB1 0x0A620000#define BCM5600_ADDR_CAB2 0x0A630000#define BCM5600_ADDR_CAB3 0x0A640000#define BCM5600_ADDR_CCP 0x0A650000#define BCM5600_ADDR_PPP 0x0A660000#define BCM5600_ADDR_CFAP 0x0A670000#define BCM5600_ADDR_SFAP 0x0A680000#define BCM5600_ADDR_CBPDATA0 0x0A6A0000#define BCM5600_ADDR_CBPDATA1 0x0A6B0000#define BCM5600_ADDR_CBPDATA2 0x0A6C0000#define BCM5600_ADDR_CBPDATA3 0x0A6D0000#define BCM5600_ADDR_PID 0x0A900000#define BCM5600_ADDR_XQ_BASE 0x0B600000#define BCM5600_ADDR_GBP 0x12000000/* Number of "Data Words" */#define BCM5600_DW_MAX 32/* === VTABLE definitions === *//* Word 0 */#define BCM5600_VTABLE_VLAN_TAG_MASK 0x00000FFF/* Word 1: Port bitmap */#define BCM5600_VTABLE_PORT_BMAP_MASK 0x1FFFFFFF/* Word 2: Untagged port bitmap */#define BCM5600_VTABLE_UT_PORT_BMAP_MASK 0x1FFFFFFF/* Word 3: Module bitmap */#define BCM5600_VTABLE_MOD_BMAP_MASK 0xFFFFFFFF/* === PTABLE definitions === *//* Word 0 */#define BCM5600_PTABLE_VLAN_TAG_MASK 0x00000FFF#define BCM5600_PTABLE_SP_ST_MASK 0x00003000#define BCM5600_PTABLE_SP_ST_SHIFT 12#define BCM5600_PTABLE_PRT_DIS_MASK 0x000FC000#define BCM5600_PTABLE_PRT_DIS_SHIFT 14#define BCM5600_PTABLE_JUMBO_FLAG 0x00100000#define BCM5600_PTABLE_RTAG_MASK 0x00E00000#define BCM5600_PTABLE_RTAG_SHIFT 21#define BCM5600_PTABLE_TGID_MASK 0x07000000#define BCM5600_PTABLE_TGID_SHIFT 24#define BCM5600_PTABLE_TRUNK_FLAG 0x08000000#define BCM5600_PTABLE_CPU_FLAG 0x10000000#define BCM5600_PTABLE_PTYPE_MASK 0x60000000#define BCM5600_PTABLE_PTYPE_SHIFT 29#define BCM5600_PTABLE_BPDU_FLAG 0x80000000/* Word 1 */#define BCM5600_PTABLE_PORT_BMAP_MASK 0x1FFFFFFF#define BCM5600_PTABLE_MI_FLAG 0x20000000#define BCM5600_PTABLE_CML_MASK 0xC0000000#define BCM5600_PTABLE_CML_SHIFT 30/* Word 2 */#define BCM5600_PTABLE_UT_PORT_BMAP_MASK 0x1FFFFFFF/* Word 4 */#define BCM5600_PTABLE_DSCP_MASK 0x0000003F#define BCM5600_PTABLE_DSCP_SHIFT 0#define BCM5600_PTABLE_DSE_MODE_MASK 0x000000C0#define BCM5600_PTABLE_DSE_MODE_SHIFT 6#define BCM5600_PTABLE_RPE_FLAG 0x00000100#define BCM5600_PTABLE_PRI_MASK 0x00000E00#define BCM5600_PTABLE_PRI_SHIFT 9#define BCM5600_PTABLE_L3_DIS_FLAG 0x00001000/* === ARL (Addess Resolution Logic) definitions === *//* Word 0: MAC address LSB *//* Word 1 */#define BCM5600_ARL_MAC_MSB_MASK 0x0000FFFF#define BCM5600_ARL_VLAN_TAG_MASK 0x0FFF0000#define BCM5600_ARL_VLAN_TAG_SHIFT 16#define BCM5600_ARL_COS_DST_MASK 0x70000000#define BCM5600_ARL_COS_DST_SHIFT 28#define BCM5600_ARL_CPU_FLAG 0x80000000/* Word 2 */#define BCM5600_ARL_L3_FLAG 0x00000001#define BCM5600_ARL_SD_DIS_MASK 0x00000006#define BCM5600_ARL_SD_DIS_SHIFT 1#define BCM5600_ARL_ST_FLAG 0x00000008#define BCM5600_ARL_HIT_FLAG 0x00000010#define BCM5600_ARL_COS_SRC_MASK 0x000000E0#define BCM5600_ARL_COS_SRC_SHIFT 5#define BCM5600_ARL_TRUNK_FLAG 0x00000100#define BCM5600_ARL_TGID_MASK 0x00000E00#define BCM5600_ARL_TGID_SHIFT 9#define BCM5600_ARL_RTAG_MASK 0x00007000#define BCM5600_ARL_RTAG_SHIFT 12#define BCM5600_ARL_PORT_MASK 0x001F8000#define BCM5600_ARL_PORT_SHIFT 15#define BCM5600_ARL_SCP_FLAG 0x00200000#define BCM5600_ARL_MOD_ID_MASK 0x07C00000#define BCM5600_ARL_MOD_ID_SHIFT 22/* === Multicast ARL definitions === *//* Word 0: MAC address LSB *//* Word 1 */#define BCM5600_MARL_MAC_MSB_MASK 0x0000FFFF#define BCM5600_MARL_VLAN_TAG_MASK 0x0FFF0000#define BCM5600_MARL_VLAN_TAG_SHIFT 16#define BCM5600_MARL_COS_DST_MASK 0x70000000#define BCM5600_MARL_COS_DST_SHIFT 28/* Word 2 */#define BCM5600_MARL_PORT_BMAP_MASK 0x1FFFFFFF/* Word 3 */#define BCM5600_MARL_UT_PORT_BMAP_MASK 0x1FFFFFFF/* Word 4 */#define BCM5600_MARL_MOD_BMAP_MASK 0xFFFFFFFF/* === Trunk bitmap === */#define BCM5600_TBMAP_MASK 0x0FFFFFFF/* === Trunk table === *//* Word 0 */#define BCM5600_TTR_TP0_MASK 0x0000003F#define BCM5600_TTR_TP0_SHIFT 0#define BCM5600_TTR_TP1_MASK 0x00000FC0#define BCM5600_TTR_TP1_SHIFT 6#define BCM5600_TTR_TP2_MASK 0x0003F000#define BCM5600_TTR_TP2_SHIFT 12#define BCM5600_TTR_TP3_MASK 0x00FC0000#define BCM5600_TTR_TP3_SHIFT 18#define BCM5600_TTR_TP4_MASK 0x3F000000#define BCM5600_TTR_TP4_SHIFT 24/* Word 1 */#define BCM5600_TTR_TP5_MASK 0x0000003F#define BCM5600_TTR_TP5_SHIFT 0#define BCM5600_TTR_TP6_MASK 0x00000FC0#define BCM5600_TTR_TP6_SHIFT 6#define BCM5600_TTR_TP7_MASK 0x0003F000#define BCM5600_TTR_TP7_SHIFT 12#define BCM5600_TTR_TG_SIZE_MASK 0x003C0000#define BCM5600_TTR_TG_SIZE_SHIFT 18/* Trunks (port aggregation) */#define BCM5600_MAX_TRUNKS 6#define BCM5600_MAX_PORTS_PER_TRUNK 8/* ======================================================================= *//* Transmit descriptor size */#define BCM5600_TXD_SIZE 32#define BCM5600_TXD_RING_CONT 0x80000000 /* ring is continuing */#define BCM5600_TXD_UNKNOWN 0x04000000 /* valid packet (?) */#define BCM5600_TXD_NEOP 0x00040000 /* end of packet if not set *//* Receive descriptor size */#define BCM5600_RXD_SIZE 32#define BCM5600_RXD_RING_CONT 0x80000000 /* ring is continuing */#define BCM5600_RXD_UNKNOWN 0x00040000 /* unknown *//* Interrupt sources */#define BCM5600_INTR_STAT_ITER_DONE 0x00100000 /* Unknown */#define BCM5600_INTR_RX_UNDERRUN 0x00000400 /* RX ring underrun */#define BCM5600_INTR_RX_AVAIL 0x00000200 /* packet available */#define BCM5600_INTR_TX_UNDERRUN 0x00000100 /* TX ring underrun */#define BCM5600_INTR_LINKSTAT_MOD 0x00000010 /* Link status modified *//* ======================================================================= *//* Port Mirroring */#define BCM5600_MIRROR_ENABLE 0x40#define BCM5600_MIRROR_PORT_MASK 0x3F/* ======================================================================= */#define BCM5600_REG_HASH_SIZE 8192/* BCM5600 register */struct bcm5600_reg { m_uint32_t addr; m_uint32_t value; struct bcm5600_reg *next;};/* BCM5600 table */struct bcm5600_table { char *name; long offset; m_uint32_t addr; u_int min_index,max_index; u_int nr_words;};/* BCM5600 in-transit packet */struct bcm5600_pkt { /* Received packet data */ u_char *pkt; ssize_t pkt_len; /* Rewritten packet (802.1Q tag pushed or poped) */ u_char *rewr_pkt; int rewrite_done; /* Original VLAN (-1 for untagged packet) and Real VLAN */ int orig_vlan,real_vlan; /* VLAN entry */ m_uint32_t *vlan_entry; /* Ingress Port and Egress Port bitmap */ u_int ingress_port,egress_bitmap,egress_ut_bitmap; u_int egress_filter_bitmap; /* RX descriptor */ m_uint32_t rdes[4]; /* Packet sent to CPU */ u_int sent_to_cpu;};/* BCM5600 physical port */struct bcm5600_port { netio_desc_t *nio; u_int id; char name[32];};/* NM-16ESW private data */struct nm_16esw_data { char *name; u_int nr_port; vm_instance_t *vm; struct vdevice *dev; struct pci_device *pci_dev; pthread_mutex_t lock; /* Ager task */ timer_id ager_tid; /* S-channel command and command result */ m_uint32_t schan_cmd,schan_cmd_res; /* Data Words */ m_uint32_t dw[BCM5600_DW_MAX]; /* Interrupt mask */ m_uint32_t intr_mask; /* MII registers */ m_uint16_t mii_regs[64][32]; m_uint32_t mii_input,mii_output; u_int mii_intr; /* RX/TX rings addresses */ m_uint32_t rx_ring_addr,tx_ring_addr; m_uint32_t tx_current,tx_end_scan; m_uint32_t rx_current,rx_end_scan; /* TX ring scanner task id */ ptask_id_t tx_tid; /* TX buffer */ u_char tx_buffer[BCM5600_MAX_PKT_SIZE]; u_int tx_bufsize; /* Port Mirroring */ u_int mirror_dst_port; u_int mirror_egress_ports; /* Registers hash table */ struct bcm5600_reg *reg_hash_table[BCM5600_REG_HASH_SIZE]; /* Most used tables... */ struct bcm5600_table *t_ptable,*t_vtable; struct bcm5600_table *t_arl,*t_marl; struct bcm5600_table *t_tbmap,*t_ttr; /* Ports (only 16 are "real" and usable) */ struct bcm5600_port ports[32]; /* CPU port */ u_int cpu_port; /* Current egress port of all trunks */ u_int trunk_last_egress_port[BCM5600_MAX_TRUNKS]; /* ARL count table */ m_uint32_t *arl_cnt; /* ARL (Address Resolution Logic) Table */ m_uint32_t *arl_table; /* Multicast ARL Table */ m_uint32_t *marl_table; /* VTABLE (VLAN Table) */ m_uint32_t *vtable; /* Trunks */ m_uint32_t *ttr,*tbmap; /* PTABLE (Port Table) */ m_uint32_t *ptable;};/* NM-16ESW Port physical port mapping table (Cisco => BCM) */static int nm16esw_port_mapping[] = { 2, 0, 6, 4, 10, 8, 14, 12, 3, 1, 7, 5, 11, 9, 15, 13,};/* Log a BCM message */#define BCM_LOG(d,msg...) vm_log((d)->vm,(d)->name,msg)/* Lock/Unlock primitives */#define BCM_LOCK(d) pthread_mutex_lock(&(d)->lock)#define BCM_UNLOCK(d) pthread_mutex_unlock(&(d)->lock)/* Trunk group info */struct bcm5600_tg_info { u_int index,mask,shift;};static struct bcm5600_tg_info tg_info[8] = { { 0, BCM5600_TTR_TP0_MASK, BCM5600_TTR_TP0_SHIFT }, { 0, BCM5600_TTR_TP1_MASK, BCM5600_TTR_TP1_SHIFT }, { 0, BCM5600_TTR_TP2_MASK, BCM5600_TTR_TP2_SHIFT }, { 0, BCM5600_TTR_TP3_MASK, BCM5600_TTR_TP3_SHIFT }, { 0, BCM5600_TTR_TP4_MASK, BCM5600_TTR_TP4_SHIFT }, { 1, BCM5600_TTR_TP5_MASK, BCM5600_TTR_TP5_SHIFT }, { 1, BCM5600_TTR_TP6_MASK, BCM5600_TTR_TP6_SHIFT }, { 1, BCM5600_TTR_TP7_MASK, BCM5600_TTR_TP7_SHIFT },
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -