Commit 0a497ec0 authored by li hongming's avatar li hongming

Add another WR port. Change many variables to lists.

parent 9fb9a6bd
...@@ -11,8 +11,8 @@ ...@@ -11,8 +11,8 @@
#include <libsdbfs.h> #include <libsdbfs.h>
/* The following pointers are exported */ /* The following pointers are exported */
unsigned char *BASE_MINIC; unsigned char *BASE_MINIC[wr_num_ports];
unsigned char *BASE_EP; unsigned char *BASE_EP[wr_num_ports];
unsigned char *BASE_SOFTPLL; unsigned char *BASE_SOFTPLL;
unsigned char *BASE_PPS_GEN; unsigned char *BASE_PPS_GEN;
unsigned char *BASE_SYSCON; unsigned char *BASE_SYSCON;
...@@ -65,8 +65,10 @@ struct wrc_device { ...@@ -65,8 +65,10 @@ struct wrc_device {
}; };
struct wrc_device devs[] = { struct wrc_device devs[] = {
{&BASE_MINIC, VID_CERN, 0xab28633a}, {&BASE_MINIC[0], VID_CERN, 0xab28633a},
{&BASE_EP, VID_CERN, 0x650c2d4f}, {&BASE_MINIC[1], VID_CERN, 0xa224633b},
{&BASE_EP[0], VID_CERN, 0x650c2d4f},
{&BASE_EP[1], VID_CERN, 0x621c2d4e},
{&BASE_SOFTPLL, VID_CERN, 0x65158dc0}, {&BASE_SOFTPLL, VID_CERN, 0x65158dc0},
{&BASE_PPS_GEN, VID_CERN, 0xde0d8ced}, {&BASE_PPS_GEN, VID_CERN, 0xde0d8ced},
{&BASE_SYSCON, VID_CERN, 0xff07fc47}, {&BASE_SYSCON, VID_CERN, 0xff07fc47},
......
...@@ -59,7 +59,7 @@ ...@@ -59,7 +59,7 @@
#define SFP_DB_EMPTY 0xff #define SFP_DB_EMPTY 0xff
static uint8_t sfpcount = SFP_DB_EMPTY; static uint8_t sfpcount[2] = {SFP_DB_EMPTY,SFP_DB_EMPTY};
uint8_t has_eeprom = 0; uint8_t has_eeprom = 0;
......
...@@ -27,115 +27,115 @@ ...@@ -27,115 +27,115 @@
#define DMTD_AVG_SAMPLES 256 #define DMTD_AVG_SAMPLES 256
static int autoneg_enabled; static int autoneg_enabled;
volatile struct EP_WB *EP; volatile struct EP_WB *EP[wr_num_ports];
/* functions for accessing PCS (MDIO) registers */ /* functions for accessing PCS (MDIO) registers */
static uint16_t pcs_read(int location) static uint16_t pcs_read(int location, int port)
{ {
EP->MDIO_CR = EP_MDIO_CR_ADDR_W(location >> 2); EP[port]->MDIO_CR = EP_MDIO_CR_ADDR_W(location >> 2);
while ((EP->MDIO_ASR & EP_MDIO_ASR_READY) == 0) ; while ((EP[port]->MDIO_ASR & EP_MDIO_ASR_READY) == 0) ;
return EP_MDIO_ASR_RDATA_R(EP->MDIO_ASR) & 0xffff; return EP_MDIO_ASR_RDATA_R(EP[port]->MDIO_ASR) & 0xffff;
} }
static void pcs_write(int location, int value) static void pcs_write(int location, int value, int port)
{ {
EP->MDIO_CR = EP_MDIO_CR_ADDR_W(location >> 2) EP[port]->MDIO_CR = EP_MDIO_CR_ADDR_W(location >> 2)
| EP_MDIO_CR_DATA_W(value) | EP_MDIO_CR_DATA_W(value)
| EP_MDIO_CR_RW; | EP_MDIO_CR_RW;
while ((EP->MDIO_ASR & EP_MDIO_ASR_READY) == 0) ; while ((EP[port]->MDIO_ASR & EP_MDIO_ASR_READY) == 0) ;
} }
/* MAC address setting */ /* MAC address setting */
void set_mac_addr(uint8_t dev_addr[]) void set_mac_addr(uint8_t dev_addr[], int port)
{ {
EP->MACL = ((uint32_t) dev_addr[2] << 24) EP[port]->MACL = ((uint32_t) dev_addr[2] << 24)
| ((uint32_t) dev_addr[3] << 16) | ((uint32_t) dev_addr[3] << 16)
| ((uint32_t) dev_addr[4] << 8) | ((uint32_t) dev_addr[4] << 8)
| ((uint32_t) dev_addr[5]); | ((uint32_t) dev_addr[5]);
EP->MACH = ((uint32_t) dev_addr[0] << 8) EP[port]->MACH = ((uint32_t) dev_addr[0] << 8)
| ((uint32_t) dev_addr[1]); | ((uint32_t) dev_addr[1]);
} }
void get_mac_addr(uint8_t dev_addr[]) void get_mac_addr(uint8_t dev_addr[], int port)
{ {
dev_addr[5] = (EP->MACL & 0x000000ff); dev_addr[5] = (EP[port]->MACL & 0x000000ff);
dev_addr[4] = (EP->MACL & 0x0000ff00) >> 8; dev_addr[4] = (EP[port]->MACL & 0x0000ff00) >> 8;
dev_addr[3] = (EP->MACL & 0x00ff0000) >> 16; dev_addr[3] = (EP[port]->MACL & 0x00ff0000) >> 16;
dev_addr[2] = (EP->MACL & 0xff000000) >> 24; dev_addr[2] = (EP[port]->MACL & 0xff000000) >> 24;
dev_addr[1] = (EP->MACH & 0x000000ff); dev_addr[1] = (EP[port]->MACH & 0x000000ff);
dev_addr[0] = (EP->MACH & 0x0000ff00) >> 8; dev_addr[0] = (EP[port]->MACH & 0x0000ff00) >> 8;
} }
/* Initializes the endpoint and sets its local MAC address */ /* Initializes the endpoint and sets its local MAC address */
void ep_init(uint8_t mac_addr[]) void ep_init(uint8_t mac_addr[], int port)
{ {
EP = (volatile struct EP_WB *)BASE_EP; EP[port] = (volatile struct EP_WB *)BASE_EP[port];
set_mac_addr(mac_addr); set_mac_addr(mac_addr,port);
ep_sfp_enable(1); ep_sfp_enable(1,port);
if (!IS_WR_NODE_SIM){ if (!IS_WR_NODE_SIM){
*(unsigned int *)(0x62000) = 0x2; // reset network stuff (cleanup required!) *(unsigned int *)(0x62000) = 0x2; // reset network stuff (cleanup required!)
*(unsigned int *)(0x62000) = 0; *(unsigned int *)(0x62000) = 0;
} }
EP->ECR = 0; /* disable Endpoint */ EP[port]->ECR = 0; /* disable Endpoint */
EP->VCR0 = EP_VCR0_QMODE_W(3); /* disable VLAN unit - not used by WRPC */ EP[port]->VCR0 = EP_VCR0_QMODE_W(3); /* disable VLAN unit - not used by WRPC */
EP->RFCR = EP_RFCR_MRU_W(1518); /* Set the max RX packet size */ EP[port]->RFCR = EP_RFCR_MRU_W(1518); /* Set the max RX packet size */
EP->TSCR = EP_TSCR_EN_TXTS | EP_TSCR_EN_RXTS; /* Enable timestamping */ EP[port]->TSCR = EP_TSCR_EN_TXTS | EP_TSCR_EN_RXTS; /* Enable timestamping */
/* Configure DMTD phase tracking */ /* Configure DMTD phase tracking */
EP->DMCR = EP_DMCR_EN | EP_DMCR_N_AVG_W(DMTD_AVG_SAMPLES); EP[port]->DMCR = EP_DMCR_EN | EP_DMCR_N_AVG_W(DMTD_AVG_SAMPLES);
} }
/* Enables/disables transmission and reception. When autoneg is set to 1, /* Enables/disables transmission and reception. When autoneg is set to 1,
starts up 802.3 autonegotiation process */ starts up 802.3 autonegotiation process */
int ep_enable(int enabled, int autoneg) int ep_enable(int enabled, int autoneg, int port)
{ {
uint16_t mcr; uint16_t mcr;
if (!enabled) { if (!enabled) {
EP->ECR = 0; EP[port]->ECR = 0;
return 0; return 0;
} }
/* Disable the endpoint */ /* Disable the endpoint */
EP->ECR = 0; EP[port]->ECR = 0;
if (!IS_WR_NODE_SIM) if (!IS_WR_NODE_SIM)
pp_printf("ID: %x\n", EP->IDCODE); pp_printf("ID: %x\n", EP[port]->IDCODE);
/* Load default packet classifier rules - see ep_pfilter.c for details */ /* Load default packet classifier rules - see ep_pfilter.c for details */
pfilter_init_default(); pfilter_init_default(port);
/* Enable TX/RX paths, reset RMON counters */ /* Enable TX/RX paths, reset RMON counters */
EP->ECR = EP_ECR_TX_EN | EP_ECR_RX_EN | EP_ECR_RST_CNT; EP[port]->ECR = EP_ECR_TX_EN | EP_ECR_RX_EN | EP_ECR_RST_CNT;
autoneg_enabled = autoneg; autoneg_enabled = autoneg;
/* Reset the GTP Transceiver - it's important to do the GTP phase alignment every time /* Reset the GTP Transceiver - it's important to do the GTP phase alignment every time
we start up the software, otherwise the calibration RX/TX deltas may not be correct */ we start up the software, otherwise the calibration RX/TX deltas may not be correct */
pcs_write(MDIO_REG_MCR, MDIO_MCR_PDOWN); /* reset the PHY */ pcs_write(MDIO_REG_MCR, MDIO_MCR_PDOWN,port); /* reset the PHY */
if (!IS_WR_NODE_SIM) if (!IS_WR_NODE_SIM)
timer_delay_ms(200); timer_delay_ms(200);
pcs_write(MDIO_REG_MCR, MDIO_MCR_RESET); /* reset the PHY */ pcs_write(MDIO_REG_MCR, MDIO_MCR_RESET,port); /* reset the PHY */
pcs_write(MDIO_REG_MCR, 0); /* reset the PHY */ pcs_write(MDIO_REG_MCR, 0,port); /* reset the PHY */
/* Don't advertise anything - we don't want flow control */ /* Don't advertise anything - we don't want flow control */
pcs_write(MDIO_REG_ADVERTISE, 0); pcs_write(MDIO_REG_ADVERTISE, 0,port);
mcr = MDIO_MCR_SPEED1000_MASK | MDIO_MCR_FULLDPLX_MASK; mcr = MDIO_MCR_SPEED1000_MASK | MDIO_MCR_FULLDPLX_MASK;
if (autoneg) if (autoneg)
mcr |= MDIO_MCR_ANENABLE | MDIO_MCR_ANRESTART; mcr |= MDIO_MCR_ANENABLE | MDIO_MCR_ANRESTART;
pcs_write(MDIO_REG_MCR, mcr); pcs_write(MDIO_REG_MCR, mcr,port);
return 0; return 0;
} }
/* Checks the link status. If the link is up, returns non-zero /* Checks the link status. If the link is up, returns non-zero
and stores the Link Partner Ability (LPA) autonegotiation register at *lpa */ and stores the Link Partner Ability (LPA) autonegotiation register at *lpa */
int ep_link_up(uint16_t * lpa) int ep_link_up(uint16_t * lpa,int port)
{ {
uint16_t flags = MDIO_MSR_LSTATUS; uint16_t flags = MDIO_MSR_LSTATUS;
volatile uint16_t msr; volatile uint16_t msr;
...@@ -143,70 +143,70 @@ int ep_link_up(uint16_t * lpa) ...@@ -143,70 +143,70 @@ int ep_link_up(uint16_t * lpa)
if (autoneg_enabled) if (autoneg_enabled)
flags |= MDIO_MSR_ANEGCOMPLETE; flags |= MDIO_MSR_ANEGCOMPLETE;
msr = pcs_read(MDIO_REG_MSR); msr = pcs_read(MDIO_REG_MSR,port);
msr = pcs_read(MDIO_REG_MSR); /* Read this flag twice to make sure the status is updated */ msr = pcs_read(MDIO_REG_MSR,port); /* Read this flag twice to make sure the status is updated */
if (lpa) if (lpa)
*lpa = pcs_read(MDIO_REG_LPA); *lpa = pcs_read(MDIO_REG_LPA,port);
return (msr & flags) == flags ? 1 : 0; return (msr & flags) == flags ? 1 : 0;
} }
int ep_get_bitslide() int ep_get_bitslide(int port)
{ {
return PICOS_PER_SERIAL_BIT * return PICOS_PER_SERIAL_BIT *
MDIO_WR_SPEC_BSLIDE_R(pcs_read(MDIO_REG_WR_SPEC)); MDIO_WR_SPEC_BSLIDE_R(pcs_read(MDIO_REG_WR_SPEC,port));
} }
/* Returns the TX/RX latencies. They are valid only when the link is up. */ /* Returns the TX/RX latencies. They are valid only when the link is up. */
int ep_get_deltas(uint32_t * delta_tx, uint32_t * delta_rx) int ep_get_deltas(uint32_t * delta_tx, uint32_t * delta_rx, int port)
{ {
/* fixme: these values should be stored in calibration block in the EEPROM on the FMC. Also, the TX/RX delays of a particular SFP /* fixme: these values should be stored in calibration block in the EEPROM on the FMC. Also, the TX/RX delays of a particular SFP
should be added here */ should be added here */
*delta_tx = sfp_deltaTx; *delta_tx = sfp_deltaTx[port];
*delta_rx = *delta_rx =
sfp_deltaRx + sfp_deltaRx[port] +
PICOS_PER_SERIAL_BIT * PICOS_PER_SERIAL_BIT *
MDIO_WR_SPEC_BSLIDE_R(pcs_read(MDIO_REG_WR_SPEC)); MDIO_WR_SPEC_BSLIDE_R(pcs_read(MDIO_REG_WR_SPEC,port));
return 0; return 0;
} }
int ep_cal_pattern_enable() int ep_cal_pattern_enable(int port)
{ {
uint32_t val; uint32_t val;
val = pcs_read(MDIO_REG_WR_SPEC); val = pcs_read(MDIO_REG_WR_SPEC,port);
val |= MDIO_WR_SPEC_TX_CAL; val |= MDIO_WR_SPEC_TX_CAL;
pcs_write(MDIO_REG_WR_SPEC, val); pcs_write(MDIO_REG_WR_SPEC, val,port);
return 0; return 0;
} }
int ep_cal_pattern_disable() int ep_cal_pattern_disable(int port)
{ {
uint32_t val; uint32_t val;
val = pcs_read(MDIO_REG_WR_SPEC); val = pcs_read(MDIO_REG_WR_SPEC,port);
val &= (~MDIO_WR_SPEC_TX_CAL); val &= (~MDIO_WR_SPEC_TX_CAL);
pcs_write(MDIO_REG_WR_SPEC, val); pcs_write(MDIO_REG_WR_SPEC, val,port);
return 0; return 0;
} }
int ep_timestamper_cal_pulse() int ep_timestamper_cal_pulse(int port)
{ {
EP->TSCR |= EP_TSCR_RX_CAL_START; EP[port]->TSCR |= EP_TSCR_RX_CAL_START;
timer_delay_ms(1); timer_delay_ms(1);
return EP->TSCR & EP_TSCR_RX_CAL_RESULT ? 1 : 0; return EP[port]->TSCR & EP_TSCR_RX_CAL_RESULT ? 1 : 0;
} }
int ep_sfp_enable(int ena) int ep_sfp_enable(int ena, int port)
{ {
uint32_t val; uint32_t val;
val = pcs_read(MDIO_REG_ECTRL); val = pcs_read(MDIO_REG_ECTRL,port);
if(ena) if(ena)
val &= (~MDIO_ECTRL_SFP_TX_DISABLE); val &= (~MDIO_ECTRL_SFP_TX_DISABLE);
else else
val |= MDIO_ECTRL_SFP_TX_DISABLE; val |= MDIO_ECTRL_SFP_TX_DISABLE;
pcs_write(MDIO_REG_ECTRL, val); pcs_write(MDIO_REG_ECTRL, val,port);
return 0; return 0;
} }
...@@ -39,7 +39,7 @@ struct rule_set { ...@@ -39,7 +39,7 @@ struct rule_set {
}; };
extern volatile struct EP_WB *EP; extern volatile struct EP_WB *EP[wr_num_ports];
static uint32_t swap32(uint32_t v) static uint32_t swap32(uint32_t v)
{ {
...@@ -52,7 +52,7 @@ static uint32_t swap32(uint32_t v) ...@@ -52,7 +52,7 @@ static uint32_t swap32(uint32_t v)
return res; return res;
} }
void pfilter_init_default(void) void pfilter_init_default(int port)
{ {
struct rule_set *s; struct rule_set *s;
uint8_t mac[6]; uint8_t mac[6];
...@@ -60,7 +60,7 @@ void pfilter_init_default(void) ...@@ -60,7 +60,7 @@ void pfilter_init_default(void)
uint32_t m, *vini, *vend, *v, *v_vlan = NULL; uint32_t m, *vini, *vend, *v, *v_vlan = NULL;
uint64_t cmd_word; uint64_t cmd_word;
int i; int i;
static int inited; static int inited[2];
uint32_t latency_ethtype = CONFIG_LATENCY_ETHTYPE; uint32_t latency_ethtype = CONFIG_LATENCY_ETHTYPE;
/* If vlan, use rule-set 1, else rule-set 0 */ /* If vlan, use rule-set 1, else rule-set 0 */
...@@ -92,20 +92,20 @@ void pfilter_init_default(void) ...@@ -92,20 +92,20 @@ void pfilter_init_default(void)
* First time: be extra-careful that the rule-set is ok. But if * First time: be extra-careful that the rule-set is ok. But if
* we change MAC address, this is re-called, and v[] is already changed * we change MAC address, this is re-called, and v[] is already changed
*/ */
if (!inited) { if (!inited[port]) {
if ( (((v[2] >> 13) & 0xffff) != 0x1234) if ( (((v[2] >> 13) & 0xffff) != 0x1234)
|| (((v[4] >> 13) & 0xffff) != 0x5678) || (((v[4] >> 13) & 0xffff) != 0x5678)
|| (((v[6] >> 13) & 0xffff) != 0x9abc)) { || (((v[6] >> 13) & 0xffff) != 0x9abc)) {
pp_printf("pfilter: wrong rule-set, can't apply\n"); pp_printf("pfilter: wrong rule-set, can't apply\n");
return; return;
} }
inited++; inited[port]++;
} }
/* /*
* Patch the local MAC address in place, * Patch the local MAC address in place,
* in the first three instructions after NOP * in the first three instructions after NOP
*/ */
get_mac_addr(mac); get_mac_addr(mac,port);
v[2] &= ~(0xffff << 13); v[2] &= ~(0xffff << 13);
v[4] &= ~(0xffff << 13); v[4] &= ~(0xffff << 13);
v[6] &= ~(0xffff << 13); v[6] &= ~(0xffff << 13);
...@@ -143,7 +143,7 @@ void pfilter_init_default(void) ...@@ -143,7 +143,7 @@ void pfilter_init_default(void)
} }
} }
EP->PFCR0 = 0; // disable pfilter EP[port]->PFCR0 = 0; // disable pfilter
for (i = 0, v = vini + 1; v < vend; v += 2, i++) { for (i = 0, v = vini + 1; v < vend; v += 2, i++) {
uint32_t cr0, cr1; uint32_t cr0, cr1;
...@@ -157,8 +157,8 @@ void pfilter_init_default(void) ...@@ -157,8 +157,8 @@ void pfilter_init_default(void)
cr0 = EP_PFCR0_MM_ADDR_W(i) | EP_PFCR0_MM_DATA_MSB_W(cmd_word >> 12) | cr0 = EP_PFCR0_MM_ADDR_W(i) | EP_PFCR0_MM_DATA_MSB_W(cmd_word >> 12) |
EP_PFCR0_MM_WRITE_MASK; EP_PFCR0_MM_WRITE_MASK;
EP->PFCR1 = cr1; EP[port]->PFCR1 = cr1;
EP->PFCR0 = cr0; EP[port]->PFCR0 = cr0;
} }
/* Restore the 0xaaa vlan number, so we can re-patch next time */ /* Restore the 0xaaa vlan number, so we can re-patch next time */
...@@ -177,5 +177,5 @@ void pfilter_init_default(void) ...@@ -177,5 +177,5 @@ void pfilter_init_default(void)
v[4] |= 0x5678 << 13; v[4] |= 0x5678 << 13;
v[6] |= 0x9abc << 13; v[6] |= 0x9abc << 13;
EP->PFCR0 = EP_PFCR0_ENABLE; EP[port]->PFCR0 = EP_PFCR0_ENABLE;
} }
...@@ -31,37 +31,39 @@ ...@@ -31,37 +31,39 @@
#define RX_OOB_SIZE 3 /* as the number of FIFO data words */ #define RX_OOB_SIZE 3 /* as the number of FIFO data words */
#define ETH_HEADER_SIZE 14
// extracts the values of TS rising and falling edge counters from the descriptor header // extracts the values of TS rising and falling edge counters from the descriptor header
#define EXPLODE_WR_TIMESTAMP(raw, rc, fc) \ #define EXPLODE_WR_TIMESTAMP(raw, rc, fc) \
rc = (raw) & 0xfffffff; \ rc = (raw) & 0xfffffff; \
fc = (raw >> 28) & 0xf; fc = (raw >> 28) & 0xf;
struct wr_minic minic; struct wr_minic minic[wr_num_ports];
int ver_supported; int ver_supported;
static inline void minic_writel(uint32_t reg, uint32_t data) static inline void minic_writel(uint32_t reg, uint32_t data, int port)
{ {
*(volatile uint32_t *)(BASE_MINIC + reg) = data; *(volatile uint32_t *)(BASE_MINIC[port] + reg) = data;
} }
static inline uint32_t minic_readl(uint32_t reg) static inline uint32_t minic_readl(uint32_t reg, int port)
{ {
return *(volatile uint32_t *)(BASE_MINIC + reg); return *(volatile uint32_t *)(BASE_MINIC[port] + reg);
} }
static inline void minic_txword(uint8_t type, uint16_t word) static inline void minic_txword(uint8_t type, uint16_t word, int port)
{ {
minic_writel(MINIC_REG_TX_FIFO, minic_writel(MINIC_REG_TX_FIFO,
MINIC_TX_FIFO_TYPE_W(type) | MINIC_TX_FIFO_DAT_W(word)); MINIC_TX_FIFO_TYPE_W(type) | MINIC_TX_FIFO_DAT_W(word),port);
} }
static inline void minic_rxword(uint8_t *type, uint16_t *data, uint8_t *empty, static inline void minic_rxword(uint8_t *type, uint16_t *data, uint8_t *empty,
uint8_t *full) uint8_t *full, int port)
{ {
uint32_t rx; uint32_t rx;
rx = minic_readl(MINIC_REG_RX_FIFO); rx = minic_readl(MINIC_REG_RX_FIFO, port);
*type = (uint8_t) MINIC_RX_FIFO_TYPE_R(rx); *type = (uint8_t) MINIC_RX_FIFO_TYPE_R(rx);
*data = (uint16_t) MINIC_RX_FIFO_DAT_R(rx); *data = (uint16_t) MINIC_RX_FIFO_DAT_R(rx);
if (empty) if (empty)
...@@ -70,12 +72,12 @@ static inline void minic_rxword(uint8_t *type, uint16_t *data, uint8_t *empty, ...@@ -70,12 +72,12 @@ static inline void minic_rxword(uint8_t *type, uint16_t *data, uint8_t *empty,
*full = (rx & MINIC_RX_FIFO_FULL) ? 1 : 0; *full = (rx & MINIC_RX_FIFO_FULL) ? 1 : 0;
} }
void minic_init() void minic_init(int port)
{ {
uint32_t mcr; uint32_t mcr;
/* before doing anything, check the HDL interface version */ /* before doing anything, check the HDL interface version */
mcr = minic_readl(MINIC_REG_MCR); mcr = minic_readl(MINIC_REG_MCR, port);
if (MINIC_MCR_VER_R(mcr) != MINIC_HDL_VERSION) { if (MINIC_MCR_VER_R(mcr) != MINIC_HDL_VERSION) {
pp_printf("Error: Minic HDL version %d not supported by sw\n", pp_printf("Error: Minic HDL version %d not supported by sw\n",
MINIC_MCR_VER_R(mcr)); MINIC_MCR_VER_R(mcr));
...@@ -86,31 +88,31 @@ void minic_init() ...@@ -86,31 +88,31 @@ void minic_init()
/* disable interrupts, driver does polling */ /* disable interrupts, driver does polling */
minic_writel(MINIC_REG_EIC_IDR, MINIC_EIC_IDR_TX | minic_writel(MINIC_REG_EIC_IDR, MINIC_EIC_IDR_TX |
MINIC_EIC_IDR_RX | MINIC_EIC_IDR_TXTS); MINIC_EIC_IDR_RX | MINIC_EIC_IDR_TXTS, port);
/* enable RX path */ /* enable RX path */
minic_writel(MINIC_REG_MCR, mcr | MINIC_MCR_RX_EN); minic_writel(MINIC_REG_MCR, mcr | MINIC_MCR_RX_EN, port);
} }
void minic_disable() void minic_disable(int port)
{ {
minic_writel(MINIC_REG_MCR, 0); minic_writel(MINIC_REG_MCR, 0, port);
} }
int minic_poll_rx() int minic_poll_rx(port)
{ {
uint32_t mcr; uint32_t mcr;
if (!ver_supported) if (!ver_supported)
return 0; return 0;
mcr = minic_readl(MINIC_REG_MCR); mcr = minic_readl(MINIC_REG_MCR, port);
return (mcr & MINIC_MCR_RX_EMPTY) ? 0 : 1; return (mcr & MINIC_MCR_RX_EMPTY) ? 0 : 1;
} }
int minic_rx_frame(struct wr_ethhdr *hdr, uint8_t * payload, uint32_t buf_size, int minic_rx_frame(struct wr_ethhdr *hdr, uint8_t * payload, uint32_t buf_size,
struct hw_timestamp *hwts) struct hw_timestamp *hwts, int port)
{ {
uint32_t hdr_size, payload_size; uint32_t hdr_size, payload_size;
uint32_t raw_ts; uint32_t raw_ts;
...@@ -125,7 +127,7 @@ int minic_rx_frame(struct wr_ethhdr *hdr, uint8_t * payload, uint32_t buf_size, ...@@ -125,7 +127,7 @@ int minic_rx_frame(struct wr_ethhdr *hdr, uint8_t * payload, uint32_t buf_size,
/* check if there is something in the Rx FIFO to be retrieved */ /* check if there is something in the Rx FIFO to be retrieved */
if ((minic_readl(MINIC_REG_MCR) & MINIC_MCR_RX_EMPTY) || !ver_supported) if ((minic_readl(MINIC_REG_MCR, port) & MINIC_MCR_RX_EMPTY) || !ver_supported)
return 0; return 0;
hdr_size = 0; hdr_size = 0;
...@@ -135,7 +137,7 @@ int minic_rx_frame(struct wr_ethhdr *hdr, uint8_t * payload, uint32_t buf_size, ...@@ -135,7 +137,7 @@ int minic_rx_frame(struct wr_ethhdr *hdr, uint8_t * payload, uint32_t buf_size,
ptr16_payload = (uint16_t *)payload; ptr16_payload = (uint16_t *)payload;
/* Read the whole frame till OOB or till the FIFO is empty */ /* Read the whole frame till OOB or till the FIFO is empty */
do { do {
minic_rxword(&rx_type, &rx_data, &rx_empty, &rx_full); minic_rxword(&rx_type, &rx_data, &rx_empty, &rx_full, port);
if (rx_type == WRF_DATA && hdr_size < ETH_HEADER_SIZE) { if (rx_type == WRF_DATA && hdr_size < ETH_HEADER_SIZE) {
/* reading header */ /* reading header */
...@@ -177,7 +179,7 @@ int minic_rx_frame(struct wr_ethhdr *hdr, uint8_t * payload, uint32_t buf_size, ...@@ -177,7 +179,7 @@ int minic_rx_frame(struct wr_ethhdr *hdr, uint8_t * payload, uint32_t buf_size,
raw_ts = (rx_data << 16) & 0xffff0000; raw_ts = (rx_data << 16) & 0xffff0000;
else if (oob_cnt == 2) else if (oob_cnt == 2)
raw_ts |= (rx_data & 0x0000ffff); raw_ts |= (rx_data & 0x0000ffff);
minic_rxword(&rx_type, &rx_data, &rx_empty, &rx_full); minic_rxword(&rx_type, &rx_data, &rx_empty, &rx_full, port);
oob_cnt++; oob_cnt++;
} }
...@@ -211,9 +213,9 @@ int minic_rx_frame(struct wr_ethhdr *hdr, uint8_t * payload, uint32_t buf_size, ...@@ -211,9 +213,9 @@ int minic_rx_frame(struct wr_ethhdr *hdr, uint8_t * payload, uint32_t buf_size,
} }
/* Increment Rx counter for statistics */ /* Increment Rx counter for statistics */
minic.rx_count++; minic[port].rx_count++;
if (minic_readl(MINIC_REG_MCR) & MINIC_MCR_RX_FULL) if (minic_readl(MINIC_REG_MCR, port) & MINIC_MCR_RX_FULL)
pp_printf("Warning: Minic Rx fifo full, expect wrong frames\n"); pp_printf("Warning: Minic Rx fifo full, expect wrong frames\n");
/* return number of bytes written to the *payload buffer */ /* return number of bytes written to the *payload buffer */
...@@ -221,7 +223,7 @@ int minic_rx_frame(struct wr_ethhdr *hdr, uint8_t * payload, uint32_t buf_size, ...@@ -221,7 +223,7 @@ int minic_rx_frame(struct wr_ethhdr *hdr, uint8_t * payload, uint32_t buf_size,
} }
int minic_tx_frame(struct wr_ethhdr_vlan *hdr, uint8_t *payload, uint32_t size, int minic_tx_frame(struct wr_ethhdr_vlan *hdr, uint8_t *payload, uint32_t size,
struct hw_timestamp *hwts) struct hw_timestamp *hwts, int port)
{ {
uint32_t d_hdr, mcr, pwords, hwords; uint32_t d_hdr, mcr, pwords, hwords;
uint8_t ts_valid; uint8_t ts_valid;
...@@ -244,44 +246,44 @@ int minic_tx_frame(struct wr_ethhdr_vlan *hdr, uint8_t *payload, uint32_t size, ...@@ -244,44 +246,44 @@ int minic_tx_frame(struct wr_ethhdr_vlan *hdr, uint8_t *payload, uint32_t size,
d_hdr = 0; d_hdr = 0;
/* First we write status word (empty status for Tx) */ /* First we write status word (empty status for Tx) */
minic_txword(WRF_STATUS, 0); minic_txword(WRF_STATUS, 0, port);
/* Write the header of the frame */ /* Write the header of the frame */
ptr = (uint16_t *)hdr; ptr = (uint16_t *)hdr;
for (i = 0; i < hwords; ++i) for (i = 0; i < hwords; ++i)
minic_txword(WRF_DATA, ptr[i]); minic_txword(WRF_DATA, ptr[i], port);
/* Write the payload without the last word (which can be one byte) */ /* Write the payload without the last word (which can be one byte) */
ptr = (uint16_t *)payload; ptr = (uint16_t *)payload;
for (i = 0; i < pwords-1; ++i) for (i = 0; i < pwords-1; ++i)
minic_txword(WRF_DATA, ptr[i]); minic_txword(WRF_DATA, ptr[i], port);
/* Write last word of the payload (which can be one byte) */ /* Write last word of the payload (which can be one byte) */
if (size % 2 == 0) if (size % 2 == 0)
minic_txword(WRF_DATA, ptr[i]); minic_txword(WRF_DATA, ptr[i], port);
else else
minic_txword(WRF_BYTESEL, ptr[i]); minic_txword(WRF_BYTESEL, ptr[i], port);
/* Write also OOB if needed */ /* Write also OOB if needed */
if (hwts) { if (hwts) {
minic_txword(WRF_OOB, TX_OOB); minic_txword(WRF_OOB, TX_OOB, port);
minic_txword(WRF_OOB, WRPC_FID); minic_txword(WRF_OOB, WRPC_FID, port);
} }
/* Start sending the frame, and while we read mcr check for fifo full */ /* Start sending the frame, and while we read mcr check for fifo full */
mcr = minic_readl(MINIC_REG_MCR); mcr = minic_readl(MINIC_REG_MCR, port);
assert_warn((mcr & MINIC_MCR_TX_FULL) == 0, "Minic tx fifo full"); assert_warn((mcr & MINIC_MCR_TX_FULL) == 0, "Minic tx fifo full");
minic_writel(MINIC_REG_MCR, mcr | MINIC_MCR_TX_START); minic_writel(MINIC_REG_MCR, mcr | MINIC_MCR_TX_START, port);
/* wait for the DMA to finish */ /* wait for the DMA to finish */
for (i = 0; i < 1000; ++i) { for (i = 0; i < 1000; ++i) {
mcr = minic_readl(MINIC_REG_MCR); mcr = minic_readl(MINIC_REG_MCR, port);
if ((mcr & MINIC_MCR_TX_IDLE) != 0) break; if ((mcr & MINIC_MCR_TX_IDLE) != 0) break;
timer_delay_ms(1); timer_delay_ms(1);
} }
if (i == 1000) if (i == 1000)
pp_printf("Warning: tx not terminated infinite mcr=0x%x\n",mcr); pp_printf("Warning: tx not terminated infinite mcr=0x%x, port = %d\n",mcr, port);
if (hwts) { if (hwts) {
uint32_t raw_ts; uint32_t raw_ts;
...@@ -292,7 +294,7 @@ int minic_tx_frame(struct wr_ethhdr_vlan *hdr, uint8_t *payload, uint32_t size, ...@@ -292,7 +294,7 @@ int minic_tx_frame(struct wr_ethhdr_vlan *hdr, uint8_t *payload, uint32_t size,
/* wait for the timestamp */ /* wait for the timestamp */
for (i = 0; i < 100; ++i) { for (i = 0; i < 100; ++i) {
mcr = minic_readl(MINIC_REG_MCR); mcr = minic_readl(MINIC_REG_MCR,port);
if ((mcr & MINIC_MCR_TX_TS_READY) != 0) break; if ((mcr & MINIC_MCR_TX_TS_READY) != 0) break;
timer_delay_ms(1); timer_delay_ms(1);
} }
...@@ -301,21 +303,21 @@ int minic_tx_frame(struct wr_ethhdr_vlan *hdr, uint8_t *payload, uint32_t size, ...@@ -301,21 +303,21 @@ int minic_tx_frame(struct wr_ethhdr_vlan *hdr, uint8_t *payload, uint32_t size,
if (i == 100) if (i == 100)
{ {
pp_printf("Warning: tx timestamp never became available\n"); pp_printf("Warning: tx timestamp never became available, port = %d\n", port);
ts_valid = 0; ts_valid = 0;
} }
if(ts_valid) if(ts_valid)
ts_valid = (uint8_t)(minic_readl(MINIC_REG_TSR0) ts_valid = (uint8_t)(minic_readl(MINIC_REG_TSR0, port)
& MINIC_TSR0_VALID); & MINIC_TSR0_VALID);
raw_ts = minic_readl(MINIC_REG_TSR1); raw_ts = minic_readl(MINIC_REG_TSR1, port);
fid = MINIC_TSR0_FID_R(minic_readl(MINIC_REG_TSR0)); fid = MINIC_TSR0_FID_R(minic_readl(MINIC_REG_TSR0, port));
if (fid != WRPC_FID) { if (fid != WRPC_FID) {
wrc_verbose("minic_tx_frame: unmatched fid %d vs %d\n", wrc_verbose("minic_tx_frame: unmatched fid %d vs %d, port: %d\n",
fid, WRPC_FID); fid, WRPC_FID, port);
} }
EXPLODE_WR_TIMESTAMP(raw_ts, counter_r, counter_f); EXPLODE_WR_TIMESTAMP(raw_ts, counter_r, counter_f);
...@@ -329,14 +331,14 @@ int minic_tx_frame(struct wr_ethhdr_vlan *hdr, uint8_t *payload, uint32_t size, ...@@ -329,14 +331,14 @@ int minic_tx_frame(struct wr_ethhdr_vlan *hdr, uint8_t *payload, uint32_t size,
hwts->ahead = 0; hwts->ahead = 0;
hwts->nsec = counter_r * (REF_CLOCK_PERIOD_PS / 1000); hwts->nsec = counter_r * (REF_CLOCK_PERIOD_PS / 1000);
minic.tx_count++; minic[port].tx_count++;
} }
return size; return size;
} }
void minic_get_stats(int *tx_frames, int *rx_frames) void minic_get_stats(int *tx_frames, int *rx_frames, int port)
{ {
*tx_frames = minic.tx_count; *tx_frames = minic[port].tx_count;
*rx_frames = minic.rx_count; *rx_frames = minic[port].rx_count;
} }
...@@ -122,7 +122,7 @@ static int cal_cur_phase; ...@@ -122,7 +122,7 @@ static int cal_cur_phase;
ptpnetif's check lock function when the PLL has already locked, to avoid ptpnetif's check lock function when the PLL has already locked, to avoid
complicating the API of ptp-noposix/ppsi. */ complicating the API of ptp-noposix/ppsi. */
void rxts_calibration_start(void) void rxts_calibration_start(uint8_t port)
{ {
cal_cur_phase = 0; cal_cur_phase = 0;
det_rising.prev_val = det_falling.prev_val = -1; det_rising.prev_val = det_falling.prev_val = -1;
...@@ -136,7 +136,7 @@ void rxts_calibration_start(void) ...@@ -136,7 +136,7 @@ void rxts_calibration_start(void)
/* Updates RX timestamper state machine. Non-zero return value means that /* Updates RX timestamper state machine. Non-zero return value means that
calibration is done. */ calibration is done. */
int rxts_calibration_update(uint32_t *t24p_value) int rxts_calibration_update(uint32_t *t24p_value, int port)
{ {
int32_t ttrans = 0; int32_t ttrans = 0;
...@@ -145,7 +145,7 @@ int rxts_calibration_update(uint32_t *t24p_value) ...@@ -145,7 +145,7 @@ int rxts_calibration_update(uint32_t *t24p_value)
/* generate a fake RX timestamp and check if falling edge counter is /* generate a fake RX timestamp and check if falling edge counter is
ahead of rising edge counter */ ahead of rising edge counter */
int flip = ep_timestamper_cal_pulse(); int flip = ep_timestamper_cal_pulse(port);
/* look for transitions (with deglitching) */ /* look for transitions (with deglitching) */
lookup_transition(&det_rising, flip, cal_cur_phase, 1); lookup_transition(&det_rising, flip, cal_cur_phase, 1);
...@@ -193,82 +193,82 @@ int rxts_calibration_update(uint32_t *t24p_value) ...@@ -193,82 +193,82 @@ int rxts_calibration_update(uint32_t *t24p_value)
} }
/* legacy function for 'calibration force' command */ /* legacy function for 'calibration force' command */
int measure_t24p(uint32_t *value) int measure_t24p(uint32_t *value, int port)
{ {
int rv; int rv;
pp_printf("Waiting for link...\n"); pp_printf("Waiting for link...\n");
while (!ep_link_up(NULL)) while (!ep_link_up(NULL, port))
timer_delay_ms(100); timer_delay_ms(100);
spll_init(SPLL_MODE_SLAVE, 0, 1); spll_init(SPLL_MODE_SLAVE, port, 1);
pp_printf("Locking PLL...\n"); pp_printf("Locking PLL...\n");
while (!spll_check_lock(0)) while (!spll_check_lock(0))
timer_delay_ms(100); timer_delay_ms(100);
pp_printf("\n"); pp_printf("\n");
pp_printf("Calibrating RX timestamper...\n"); pp_printf("Calibrating RX timestamper...\n");
rxts_calibration_start(); rxts_calibration_start(port);
while (!(rv = rxts_calibration_update(value))) ; while (!(rv = rxts_calibration_update(value,port))) ;
return rv; return rv;
} }
/* Delays for master must have been calibrated while running as slave */ /* Delays for master must have been calibrated while running as slave */
static int calib_t24p_master(uint32_t *value) static int calib_t24p_master(uint32_t *value, int port)
{ {
int rv; int rv;
rv = storage_phtrans(value, 0); rv = storage_phtrans(value, 0, port);
if(rv < 0) { if(rv < 0) {
pp_printf("Error %d while reading t24p from storage\n", rv); pp_printf("Error %d while reading t24p from storage\n", rv);
return rv; return rv;
} }
pp_printf("t24p read from storage: %d ps\n", *value); pp_printf("port %d t24p read from storage: %d ps\n", port,*value);
return rv; return rv;
} }
/*SoftPLL must be locked prior calling this function*/ /*SoftPLL must be locked prior calling this function*/
static int calib_t24p_slave(uint32_t *value) static int calib_t24p_slave(uint32_t *value, int port)
{ {
int rv; int rv;
uint32_t prev; uint32_t prev;
int retries = 0; int retries = 0;
while (!(rv = rxts_calibration_update(value))) { while (!(rv = rxts_calibration_update(value,port))) {
if (retries > CALIB_RETRIES || ep_link_up(NULL) == LINK_DOWN) if (retries > CALIB_RETRIES || ep_link_up(NULL, port) == LINK_DOWN)
return -1; return -1;
retries++; retries++;
} }
if (rv < 0) { if (rv < 0) {
/* Fall back on master == eeprom-or-error */ /* Fall back on master == eeprom-or-error */
return calib_t24p_master(value); return calib_t24p_master(value,port);
} }
/* /*
* Let's see if we have a matching value in EEPROM: * Let's see if we have a matching value in EEPROM:
* accept a 200ps difference, otherwise rewrite eeprom * accept a 200ps difference, otherwise rewrite eeprom
*/ */
rv = storage_phtrans(&prev, 0 /* rd */); rv = storage_phtrans(&prev, 0 /* rd */, port);
if (rv < 0 || (prev < *value - 200) || (prev > *value + 200)) { if (rv < 0 || (prev < *value - 200) || (prev > *value + 200)) {
rv = storage_phtrans(value, 1); rv = storage_phtrans(value, 1, port);
pp_printf("Wrote new t24p value: %d ps (%s)\n", *value, pp_printf("Wrote new t24p value: %d ps (%s)\n", *value,
rv < 0 ? "Failed" : "Success"); rv < 0 ? "Failed" : "Success");
} }
return 0; return 0;
} }
int calib_t24p(int mode, uint32_t *value) int calib_t24p(int mode, uint32_t *value, int port)
{ {
int ret; int ret;
if (mode == WRC_MODE_SLAVE) if (mode == WRC_MODE_SLAVE)
ret = calib_t24p_slave(value); ret = calib_t24p_slave(value, port);
else else
ret = calib_t24p_master(value); ret = calib_t24p_master(value, port);
//update phtrans value in socket struct //update phtrans value in socket struct
if (ret >= 0) if (ret >= 0)
ptpd_netif_set_phase_transition(*value); ptpd_netif_set_phase_transition(*value, port);
return ret; return ret;
} }
...@@ -30,8 +30,10 @@ ...@@ -30,8 +30,10 @@
#define SDB_VENDOR 0x46696c6544617461LL /* "FileData" */ #define SDB_VENDOR 0x46696c6544617461LL /* "FileData" */
#define SDB_DEV_INIT 0x77722d69 /* wr-i (nit) */ #define SDB_DEV_INIT 0x77722d69 /* wr-i (nit) */
#define SDB_DEV_MAC 0x6d61632d /* mac- (address) */ #define SDB_DEV_MAC 0x6d61632d /* mac- (address) */
#define SDB_DEV_SFP 0x7366702d /* sfp- (database) */ #define SDB_DEV_SFP 0x7366702d /* sfp- (database) */
#define SDB_DEV_CALIB 0x63616c69 /* cali (bration) */ #define SDB_DEV_DP_SFP 0x8366702d /* sfp1- (database) */
#define SDB_DEV_CALIB 0x63616c69 /* cali (bration) */
#define SDB_DEV_DP_CALIB 0x73616c69 /* cali (bration) */
/* constants for scanning I2C EEPROMs */ /* constants for scanning I2C EEPROMs */
#define EEPROM_START_ADR 0 #define EEPROM_START_ADR 0
...@@ -316,7 +318,7 @@ int get_persistent_mac(uint8_t portnum, uint8_t *mac) ...@@ -316,7 +318,7 @@ int get_persistent_mac(uint8_t portnum, uint8_t *mac)
if (IS_HOST_PROCESS) { if (IS_HOST_PROCESS) {
/* we don't have sdb working, so get the real eth address */ /* we don't have sdb working, so get the real eth address */
get_mac_addr(mac); get_mac_addr(mac, 0);
return 0; return 0;
} }
...@@ -392,11 +394,16 @@ int set_persistent_mac(uint8_t portnum, uint8_t *mac) ...@@ -392,11 +394,16 @@ int set_persistent_mac(uint8_t portnum, uint8_t *mac)
/* Erase SFB database in the memory */ /* Erase SFB database in the memory */
int32_t storage_sfpdb_erase(void) int32_t storage_sfpdb_erase(int port)
{ {
int ret; int ret;
uint32_t sdb_dev_addr;
if (port==0)
sdb_dev_addr = SDB_DEV_SFP;
else
sdb_dev_addr = SDB_DEV_DP_SFP;
if (sdbfs_open_id(&wrc_sdb, SDB_VENDOR, SDB_DEV_SFP) < 0) if (sdbfs_open_id(&wrc_sdb, SDB_VENDOR, sdb_dev_addr) < 0)
return -1; return -1;
ret = sdbfs_ferase(&wrc_sdb, 0, wrc_sdb.f_len); ret = sdbfs_ferase(&wrc_sdb, 0, wrc_sdb.f_len);
if (ret == wrc_sdb.f_len) if (ret == wrc_sdb.f_len)
...@@ -418,7 +425,7 @@ static int sfp_valid(struct s_sfpinfo *sfp) ...@@ -418,7 +425,7 @@ static int sfp_valid(struct s_sfpinfo *sfp)
return 1; return 1;
} }
static int sfp_entry(struct s_sfpinfo *sfp, uint8_t oper, uint8_t pos) static int sfp_entry(struct s_sfpinfo *sfp, uint8_t oper, uint8_t pos, int port)
{ {
static uint8_t sfpcount = 0; static uint8_t sfpcount = 0;
struct s_sfpinfo tempsfp; struct s_sfpinfo tempsfp;
...@@ -426,11 +433,16 @@ static int sfp_entry(struct s_sfpinfo *sfp, uint8_t oper, uint8_t pos) ...@@ -426,11 +433,16 @@ static int sfp_entry(struct s_sfpinfo *sfp, uint8_t oper, uint8_t pos)
uint8_t i, chksum = 0; uint8_t i, chksum = 0;
uint8_t *ptr; uint8_t *ptr;
int sdb_offset; int sdb_offset;
uint32_t sdb_dev_addr;
if (port==0)
sdb_dev_addr = SDB_DEV_SFP;
else
sdb_dev_addr = SDB_DEV_DP_SFP;
if (pos >= SFPS_MAX) if (pos >= SFPS_MAX)
return EE_RET_POSERR; /* position outside the range */ return EE_RET_POSERR; /* position outside the range */
if (sdbfs_open_id(&wrc_sdb, SDB_VENDOR, SDB_DEV_SFP) < 0) if (sdbfs_open_id(&wrc_sdb, SDB_VENDOR, sdb_dev_addr) < 0)
return -1; return -1;
/* Read how many SFPs are in the database, but only in the first /* Read how many SFPs are in the database, but only in the first
...@@ -495,7 +507,7 @@ out: ...@@ -495,7 +507,7 @@ out:
return ret; return ret;
} }
static int storage_update_sfp(struct s_sfpinfo *sfp) static int storage_update_sfp(struct s_sfpinfo *sfp, int port)
{ {
int sfpcount = 1; int sfpcount = 1;
int temp; int temp;
...@@ -506,7 +518,7 @@ static int storage_update_sfp(struct s_sfpinfo *sfp) ...@@ -506,7 +518,7 @@ static int storage_update_sfp(struct s_sfpinfo *sfp)
/* copy entries from flash to the memory, update entry if matched */ /* copy entries from flash to the memory, update entry if matched */
for (i = 0; i < sfpcount; ++i) { for (i = 0; i < sfpcount; ++i) {
dbsfp = &sfp_db[i]; dbsfp = &sfp_db[i];
sfpcount = sfp_entry(dbsfp, SFP_GET, i); sfpcount = sfp_entry(dbsfp, SFP_GET, i, port);
if (sfpcount <= 0) if (sfpcount <= 0)
return sfpcount; return sfpcount;
if (!strncmp(dbsfp->pn, sfp->pn, 16)) { if (!strncmp(dbsfp->pn, sfp->pn, 16)) {
...@@ -518,7 +530,7 @@ static int storage_update_sfp(struct s_sfpinfo *sfp) ...@@ -518,7 +530,7 @@ static int storage_update_sfp(struct s_sfpinfo *sfp)
} }
/* erase entire database */ /* erase entire database */
if (storage_sfpdb_erase() == EE_RET_I2CERR) { if (storage_sfpdb_erase(port) == EE_RET_I2CERR) {
pp_printf("Could not erase DB\n"); pp_printf("Could not erase DB\n");
return -1; return -1;
} }
...@@ -526,7 +538,7 @@ static int storage_update_sfp(struct s_sfpinfo *sfp) ...@@ -526,7 +538,7 @@ static int storage_update_sfp(struct s_sfpinfo *sfp)
/* add all SFPs */ /* add all SFPs */
for (i = 0; i < sfpcount; ++i) { for (i = 0; i < sfpcount; ++i) {
dbsfp = &sfp_db[i]; dbsfp = &sfp_db[i];
temp = sfp_entry(dbsfp, SFP_ADD, 0); temp = sfp_entry(dbsfp, SFP_ADD, 0, port);
if (temp < 0) { if (temp < 0) {
/* if error, return it */ /* if error, return it */
return temp; return temp;
...@@ -535,35 +547,35 @@ static int storage_update_sfp(struct s_sfpinfo *sfp) ...@@ -535,35 +547,35 @@ static int storage_update_sfp(struct s_sfpinfo *sfp)
return i; return i;
} }
int storage_get_sfp(struct s_sfpinfo *sfp, uint8_t oper, uint8_t pos) int storage_get_sfp(struct s_sfpinfo *sfp, uint8_t oper, uint8_t pos, int port)
{ {
struct s_sfpinfo tmp_sfp; struct s_sfpinfo tmp_sfp;
if (oper == SFP_GET) { if (oper == SFP_GET) {
/* Get SFP entry */ /* Get SFP entry */
return sfp_entry(sfp, SFP_GET, pos); return sfp_entry(sfp, SFP_GET, pos, port);
} }
/* storage_match_sfp replaces content of parameter, so do the copy /* storage_match_sfp replaces content of parameter, so do the copy
* first */ * first */
tmp_sfp = *sfp; tmp_sfp = *sfp;
if (!storage_match_sfp(&tmp_sfp)) { /* add a new sfp entry */ if (!storage_match_sfp(&tmp_sfp, port)) { /* add a new sfp entry */
pp_printf("Adding new SFP entry\n"); pp_printf("Adding new SFP entry\n");
return sfp_entry(sfp, SFP_ADD, 0); return sfp_entry(sfp, SFP_ADD, 0, port);
} }
pp_printf("Update existing SFP entry\n"); pp_printf("Update existing SFP entry\n");
return storage_update_sfp(sfp); return storage_update_sfp(sfp, port);
} }
int storage_match_sfp(struct s_sfpinfo *sfp) int storage_match_sfp(struct s_sfpinfo *sfp, int port)
{ {
uint8_t sfpcount = 1; uint8_t sfpcount = 1;
int8_t i; int8_t i;
struct s_sfpinfo dbsfp; struct s_sfpinfo dbsfp;
for (i = 0; i < sfpcount; ++i) { for (i = 0; i < sfpcount; ++i) {
sfpcount = sfp_entry(&dbsfp, SFP_GET, i); sfpcount = sfp_entry(&dbsfp, SFP_GET, i, port);
if (sfpcount <= 0) if (sfpcount <= 0)
return sfpcount; return sfpcount;
if (!strncmp(dbsfp.pn, sfp->pn, 16)) { if (!strncmp(dbsfp.pn, sfp->pn, 16)) {
...@@ -581,12 +593,17 @@ int storage_match_sfp(struct s_sfpinfo *sfp) ...@@ -581,12 +593,17 @@ int storage_match_sfp(struct s_sfpinfo *sfp)
* Phase transition ("calibration" file) * Phase transition ("calibration" file)
*/ */
#define VALIDITY_BIT 0x80000000 #define VALIDITY_BIT 0x80000000
int storage_phtrans(uint32_t *valp, uint8_t write) int storage_phtrans(uint32_t *valp, uint8_t write, int port)
{ {
int ret = -1; int ret = -1;
uint32_t value; uint32_t value;
uint32_t sdb_dev_addr;
if (port==0)
sdb_dev_addr = SDB_DEV_CALIB;
else
sdb_dev_addr = SDB_DEV_DP_CALIB;
if (sdbfs_open_id(&wrc_sdb, SDB_VENDOR, SDB_DEV_CALIB) < 0) if (sdbfs_open_id(&wrc_sdb, SDB_VENDOR, sdb_dev_addr) < 0)
return -1; return -1;
if (write) { if (write) {
sdbfs_ferase(&wrc_sdb, 0, wrc_sdb.f_len); sdbfs_ferase(&wrc_sdb, 0, wrc_sdb.f_len);
......
...@@ -19,44 +19,48 @@ ...@@ -19,44 +19,48 @@
#include "storage.h" #include "storage.h"
/* Calibration data (from EEPROM if available) */ /* Calibration data (from EEPROM if available) */
int32_t sfp_alpha = 73622176; /* default values if could not read EEPROM */ int32_t sfp_alpha[2] = {64398396,-64398396}; /* default values if could not read EEPROM */
int32_t sfp_deltaTx = 0; int32_t sfp_deltaTx[2] = {0,0};
int32_t sfp_deltaRx = 0; int32_t sfp_deltaRx[2] = {0,0};
int32_t sfp_in_db = 0; int32_t sfp_in_db[2] = {0,0};
char sfp_pn[SFP_PN_LEN]; char sfp_pn[2][SFP_PN_LEN];
static int sfp_present(void) int sfp_present(int port)
{ {
return !gpio_in(GPIO_SFP_DET); return (port) ? (!gpio_in(GPIO_DP_SFP_DET)) : (!gpio_in(GPIO_SFP_DET));
} }
static int sfp_read_part_id(char *part_id) static int sfp_read_part_id(char *part_id, int port)
{ {
int i; int i;
uint8_t data, sum; uint8_t data, sum;
mi2c_init(WRPC_SFP_I2C); uint8_t sfp_num;
mi2c_start(WRPC_SFP_I2C); if (port==0) sfp_num = WRPC_SFP_I2C;
mi2c_put_byte(WRPC_SFP_I2C, 0xA0); else sfp_num = WRPC_DP_SFP_I2C;
mi2c_put_byte(WRPC_SFP_I2C, 0x00);
mi2c_repeat_start(WRPC_SFP_I2C); mi2c_init(sfp_num);
mi2c_put_byte(WRPC_SFP_I2C, 0xA1); mi2c_start(sfp_num);
mi2c_get_byte(WRPC_SFP_I2C, &data, 1); mi2c_put_byte(sfp_num, 0xA0);
mi2c_stop(WRPC_SFP_I2C); mi2c_put_byte(sfp_num, 0x00);
mi2c_repeat_start(sfp_num);
mi2c_put_byte(sfp_num, 0xA1);
mi2c_get_byte(sfp_num, &data, 1);
mi2c_stop(sfp_num);
sum = data; sum = data;
mi2c_start(WRPC_SFP_I2C); mi2c_start(sfp_num);
mi2c_put_byte(WRPC_SFP_I2C, 0xA1); mi2c_put_byte(sfp_num, 0xA1);
for (i = 1; i < 63; ++i) { for (i = 1; i < 63; ++i) {
mi2c_get_byte(WRPC_SFP_I2C, &data, 0); mi2c_get_byte(sfp_num, &data, 0);
sum = (uint8_t) ((uint16_t) sum + data) & 0xff; sum = (uint8_t) ((uint16_t) sum + data) & 0xff;
if (i >= 40 && i <= 55) //Part Number if (i >= 40 && i <= 55) //Part Number
part_id[i - 40] = data; part_id[i - 40] = data;
} }
mi2c_get_byte(WRPC_SFP_I2C, &data, 1); //final word, checksum mi2c_get_byte(sfp_num, &data, 1); //final word, checksum
mi2c_stop(WRPC_SFP_I2C); mi2c_stop(sfp_num);
if (sum == data) if (sum == data)
return 0; return 0;
...@@ -64,26 +68,31 @@ static int sfp_read_part_id(char *part_id) ...@@ -64,26 +68,31 @@ static int sfp_read_part_id(char *part_id)
return -1; return -1;
} }
int sfp_match(void) int sfp_match(int port)
{ {
struct s_sfpinfo sfp; struct s_sfpinfo sfp;
sfp_pn[0] = '\0'; sfp_pn[port][0] = '\0';
if (!sfp_present()) { if (!sfp_present(port)) {
return -ENODEV; return -ENODEV;
} }
if (sfp_read_part_id(sfp_pn)) { if (sfp_read_part_id(sfp_pn[port], port)) {
return -EIO; return -EIO;
} }
strncpy(sfp.pn, sfp_pn, SFP_PN_LEN); strncpy(sfp.pn, sfp_pn[port], SFP_PN_LEN);
if (storage_match_sfp(&sfp) == 0) { if (storage_match_sfp(&sfp,port) == 1) {
sfp_in_db = SFP_NOT_MATCHED; if (sfp.port==port)
return -ENXIO; {
sfp_deltaTx[port] = sfp.dTx;
sfp_deltaRx[port] = sfp.dRx;
sfp_alpha[port] = sfp.alpha;
sfp_in_db[port] = SFP_MATCHED;
pp_printf("port %d SFP matched!\n",port);
return 0;
}
} }
sfp_deltaTx = sfp.dTx; sfp_in_db[port] = SFP_NOT_MATCHED;
sfp_deltaRx = sfp.dRx; pp_printf("port %d SFP not matched!\n",port);
sfp_alpha = sfp.alpha; return -ENXIO;
sfp_in_db = SFP_MATCHED;
return 0;
} }
...@@ -10,9 +10,10 @@ ...@@ -10,9 +10,10 @@
#include <errno.h> #include <errno.h>
#include <string.h> #include <string.h>
struct s_i2c_if i2c_if[2] = { struct s_i2c_if i2c_if[3] = {
{SYSC_GPSR_FMC_SCL, SYSC_GPSR_FMC_SDA, FMC_I2C_DELAY}, {SYSC_GPSR_FMC_SCL, SYSC_GPSR_FMC_SDA, FMC_I2C_DELAY},
{SYSC_GPSR_SFP_SCL, SYSC_GPSR_SFP_SDA, SFP_I2C_DELAY} {SYSC_GPSR_SFP_SCL, SYSC_GPSR_SFP_SDA, SFP_I2C_DELAY},
{SYSC_GPSR_DP_SFP_SCL, SYSC_GPSR_DP_SFP_SDA, SFP_I2C_DELAY},
}; };
volatile struct SYSCON_WB *syscon; volatile struct SYSCON_WB *syscon;
......
...@@ -30,7 +30,7 @@ void tcpip_init(void) ...@@ -30,7 +30,7 @@ void tcpip_init(void)
return; return;
} }
get_mac_addr(tcpip_mac_addr); get_mac_addr(tcpip_mac_addr, 0);
memcpy((uint8_t *)(BASE_TCPIP_CFG + TCPIP_MAC_HIGH16 + 2), (uint8_t *)tcpip_mac_addr, 2); memcpy((uint8_t *)(BASE_TCPIP_CFG + TCPIP_MAC_HIGH16 + 2), (uint8_t *)tcpip_mac_addr, 2);
memcpy((uint8_t *)(BASE_TCPIP_CFG + TCPIP_MAC_LOW32), (uint8_t *)tcpip_mac_addr+2, 4); memcpy((uint8_t *)(BASE_TCPIP_CFG + TCPIP_MAC_LOW32), (uint8_t *)tcpip_mac_addr+2, 4);
...@@ -38,7 +38,7 @@ void tcpip_init(void) ...@@ -38,7 +38,7 @@ void tcpip_init(void)
tcpip_tx_dst_port(60000); tcpip_tx_dst_port(60000);
tcpip_tx_src_port(60000); tcpip_tx_src_port(60000);
getIP(tmp_ip_addr); getIP(tmp_ip_addr, 0);
// tcpip module, default IP // tcpip module, default IP
tcpip_ip_addr(tmp_ip_addr); tcpip_ip_addr(tmp_ip_addr);
// tcpip module, default gateway & tx ip addr // tcpip module, default gateway & tx ip addr
...@@ -133,7 +133,7 @@ uint8_t tcpip_poll() ...@@ -133,7 +133,7 @@ uint8_t tcpip_poll()
return 0; return 0;
tcpip_get_hisIP(ip); tcpip_get_hisIP(ip);
send_arp(ip); send_arp(ip, 0);
arp_count=0; arp_count=0;
} }
......
...@@ -20,5 +20,5 @@ ...@@ -20,5 +20,5 @@
#define ARP_TPA (ARP_THA+6) #define ARP_TPA (ARP_THA+6)
#define ARP_END (ARP_TPA+4) #define ARP_END (ARP_TPA+4)
void send_arp(uint8_t * hisIP); int send_arp(uint8_t * hisIP, int port);
#endif #endif
...@@ -48,9 +48,9 @@ int board_update(void); ...@@ -48,9 +48,9 @@ int board_update(void);
#else #else
# define BOARD_DIVIDE_DMTD_CLOCKS 1 # define BOARD_DIVIDE_DMTD_CLOCKS 1
#endif #endif
#define BOARD_MAX_CHAN_REF 1 #define BOARD_MAX_CHAN_REF 2
#define BOARD_MAX_CHAN_AUX 2 #define BOARD_MAX_CHAN_AUX 2
#define BOARD_MAX_PTRACKERS 1 #define BOARD_MAX_PTRACKERS 2
#ifdef CONFIG_IP #ifdef CONFIG_IP
#define HAS_IP 1 #define HAS_IP 1
......
...@@ -19,19 +19,19 @@ typedef enum { ...@@ -19,19 +19,19 @@ typedef enum {
NOT = 7 NOT = 7
} pfilter_op_t; } pfilter_op_t;
void ep_init(uint8_t mac_addr[]); void ep_init(uint8_t mac_addr[],int port);
void get_mac_addr(uint8_t dev_addr[]); void get_mac_addr(uint8_t dev_addr[],int port);
void set_mac_addr(uint8_t dev_addr[]); void set_mac_addr(uint8_t dev_addr[],int port);
int ep_enable(int enabled, int autoneg); int ep_enable(int enabled, int autoneg,int port);
int ep_link_up(uint16_t * lpa); int ep_link_up(uint16_t * lpa,int port);
int ep_get_bitslide(void); int ep_get_bitslide(int port);
int ep_get_deltas(uint32_t * delta_tx, uint32_t * delta_rx); int ep_get_deltas(uint32_t * delta_tx, uint32_t * delta_rx,int port);
int ep_get_psval(int32_t * psval); int ep_get_psval(int32_t * psval,int port);
int ep_cal_pattern_enable(void); int ep_cal_pattern_enable(int port);
int ep_cal_pattern_disable(void); int ep_cal_pattern_disable(int port);
int ep_timestamper_cal_pulse(void); int ep_timestamper_cal_pulse(int port);
int ep_sfp_enable(int ena); int ep_sfp_enable(int ena,int port);
void pfilter_init_default(void); void pfilter_init_default(int port);
#endif #endif
...@@ -8,8 +8,8 @@ ...@@ -8,8 +8,8 @@
#define SDB_ADDRESS 0x30000 #define SDB_ADDRESS 0x30000
extern unsigned char *BASE_MINIC; extern unsigned char *BASE_MINIC[2];
extern unsigned char *BASE_EP; extern unsigned char *BASE_EP[2];
extern unsigned char *BASE_SOFTPLL; extern unsigned char *BASE_SOFTPLL;
extern unsigned char *BASE_PPS_GEN; extern unsigned char *BASE_PPS_GEN;
extern unsigned char *BASE_SYSCON; extern unsigned char *BASE_SYSCON;
......
...@@ -3,7 +3,7 @@ ...@@ -3,7 +3,7 @@
* File : wrc_syscon_regs.h * File : wrc_syscon_regs.h
* Author : auto-generated by wbgen2 from wrc_syscon_wb.wb * Author : auto-generated by wbgen2 from wrc_syscon_wb.wb
* Created : Mon Nov 27 13:37:56 2017 * Created : Wed Sep 26 16:28:55 2018
* Standard : ANSI C * Standard : ANSI C
THIS FILE WAS GENERATED BY wbgen2 FROM SOURCE FILE wrc_syscon_wb.wb THIS FILE WAS GENERATED BY wbgen2 FROM SOURCE FILE wrc_syscon_wb.wb
...@@ -90,6 +90,21 @@ ...@@ -90,6 +90,21 @@
/* definitions for field: SPI bitbanged MISO in reg: GPIO Set/Readback Register */ /* definitions for field: SPI bitbanged MISO in reg: GPIO Set/Readback Register */
#define SYSC_GPSR_SPI_MISO WBGEN2_GEN_MASK(13, 1) #define SYSC_GPSR_SPI_MISO WBGEN2_GEN_MASK(13, 1)
/* definitions for field: DP Status LED in reg: GPIO Set/Readback Register */
#define SYSC_GPSR_DP_LED_STAT WBGEN2_GEN_MASK(14, 1)
/* definitions for field: DP Link LED in reg: GPIO Set/Readback Register */
#define SYSC_GPSR_DP_LED_LINK WBGEN2_GEN_MASK(15, 1)
/* definitions for field: DP SFP detect (MOD_DEF0 signal) in reg: GPIO Set/Readback Register */
#define SYSC_GPSR_DP_SFP_DET WBGEN2_GEN_MASK(16, 1)
/* definitions for field: DP SFP I2C bitbanged SCL in reg: GPIO Set/Readback Register */
#define SYSC_GPSR_DP_SFP_SCL WBGEN2_GEN_MASK(17, 1)
/* definitions for field: DP SFP I2C bitbanged SDA in reg: GPIO Set/Readback Register */
#define SYSC_GPSR_DP_SFP_SDA WBGEN2_GEN_MASK(18, 1)
/* definitions for register: GPIO Clear Register */ /* definitions for register: GPIO Clear Register */
/* definitions for field: Status LED in reg: GPIO Clear Register */ /* definitions for field: Status LED in reg: GPIO Clear Register */
...@@ -104,10 +119,16 @@ ...@@ -104,10 +119,16 @@
/* definitions for field: FMC I2C bitbanged SDA in reg: GPIO Clear Register */ /* definitions for field: FMC I2C bitbanged SDA in reg: GPIO Clear Register */
#define SYSC_GPCR_FMC_SDA WBGEN2_GEN_MASK(3, 1) #define SYSC_GPCR_FMC_SDA WBGEN2_GEN_MASK(3, 1)
/* definitions for field: DP Status LED in reg: GPIO Clear Register */
#define SYSC_GPCR_DP_LED_STAT WBGEN2_GEN_MASK(4, 1)
/* definitions for field: DP Link LED in reg: GPIO Clear Register */
#define SYSC_GPCR_DP_LED_LINK WBGEN2_GEN_MASK(5, 1)
/* definitions for field: SFP I2C bitbanged SCL in reg: GPIO Clear Register */ /* definitions for field: SFP I2C bitbanged SCL in reg: GPIO Clear Register */
#define SYSC_GPCR_SFP_SCL WBGEN2_GEN_MASK(8, 1) #define SYSC_GPCR_SFP_SCL WBGEN2_GEN_MASK(8, 1)
/* definitions for field: FMC I2C bitbanged SDA in reg: GPIO Clear Register */ /* definitions for field: SFP I2C bitbanged SDA in reg: GPIO Clear Register */
#define SYSC_GPCR_SFP_SDA WBGEN2_GEN_MASK(9, 1) #define SYSC_GPCR_SFP_SDA WBGEN2_GEN_MASK(9, 1)
/* definitions for field: SPI bitbanged SCLK in reg: GPIO Clear Register */ /* definitions for field: SPI bitbanged SCLK in reg: GPIO Clear Register */
...@@ -119,6 +140,12 @@ ...@@ -119,6 +140,12 @@
/* definitions for field: SPI bitbanged MOSI in reg: GPIO Clear Register */ /* definitions for field: SPI bitbanged MOSI in reg: GPIO Clear Register */
#define SYSC_GPCR_SPI_MOSI WBGEN2_GEN_MASK(12, 1) #define SYSC_GPCR_SPI_MOSI WBGEN2_GEN_MASK(12, 1)
/* definitions for field: DP SFP I2C bitbanged SCL in reg: GPIO Clear Register */
#define SYSC_GPCR_DP_SFP_SCL WBGEN2_GEN_MASK(13, 1)
/* definitions for field: DP SFP I2C bitbanged SDA in reg: GPIO Clear Register */
#define SYSC_GPCR_DP_SFP_SDA WBGEN2_GEN_MASK(14, 1)
/* definitions for register: Hardware Feature Register */ /* definitions for register: Hardware Feature Register */
/* definitions for field: Memory size in reg: Hardware Feature Register */ /* definitions for field: Memory size in reg: Hardware Feature Register */
......
...@@ -21,10 +21,10 @@ ...@@ -21,10 +21,10 @@
#define TX_OOB 0x1000 #define TX_OOB 0x1000
void minic_init(void); void minic_init(int port);
void minic_disable(void); void minic_disable(int port);
int minic_poll_rx(void); int minic_poll_rx(int port);
void minic_get_stats(int *tx_frames, int *rx_frames); void minic_get_stats(int *tx_frames, int *rx_frames, int port);
struct wr_ethhdr { struct wr_ethhdr {
uint8_t dstmac[6]; uint8_t dstmac[6];
...@@ -44,11 +44,11 @@ struct wr_minic { ...@@ -44,11 +44,11 @@ struct wr_minic {
int tx_count, rx_count; int tx_count, rx_count;
}; };
extern struct wr_minic minic; extern struct wr_minic minic[2];
int minic_rx_frame(struct wr_ethhdr *hdr, uint8_t * payload, uint32_t buf_size, int minic_rx_frame(struct wr_ethhdr *hdr, uint8_t * payload, uint32_t buf_size,
struct hw_timestamp *hwts); struct hw_timestamp *hwts, int port);
int minic_tx_frame(struct wr_ethhdr_vlan *hdr, uint8_t * payload, uint32_t size, int minic_tx_frame(struct wr_ethhdr_vlan *hdr, uint8_t * payload, uint32_t size,
struct hw_timestamp *hwts); struct hw_timestamp *hwts, int port);
#endif #endif
...@@ -18,7 +18,7 @@ ...@@ -18,7 +18,7 @@
#define PTPD_SOCK_UDP 0 /* wrong name, it should be "WRPC" */ #define PTPD_SOCK_UDP 0 /* wrong name, it should be "WRPC" */
#define PTPD_SOCK_RAW_ETHERNET 1 /* but used in ppsi, which I won't change */ #define PTPD_SOCK_RAW_ETHERNET 1 /* but used in ppsi, which I won't change */
extern int link_status; extern uint8_t link_status[2];
#define LINK_DOWN 0 #define LINK_DOWN 0
#define LINK_WENT_UP 1 #define LINK_WENT_UP 1
#define LINK_WENT_DOWN 2 #define LINK_WENT_DOWN 2
...@@ -86,7 +86,7 @@ PACKED struct wr_timestamp { ...@@ -86,7 +86,7 @@ PACKED struct wr_timestamp {
// to bind_addr. // to bind_addr.
struct wrpc_socket *ptpd_netif_create_socket(struct wrpc_socket *s, struct wrpc_socket *ptpd_netif_create_socket(struct wrpc_socket *s,
struct wr_sockaddr * bind_addr, struct wr_sockaddr * bind_addr,
int udp_or_raw, int udpport); int udp_or_raw, int udpport, int port);
// Sends a UDP/RAW packet (data, data_length) to addr in wr_sockaddr. // Sends a UDP/RAW packet (data, data_length) to addr in wr_sockaddr.
// For raw frames, mac/ethertype needs to be provided, for UDP - ip/port. // For raw frames, mac/ethertype needs to be provided, for UDP - ip/port.
...@@ -94,7 +94,7 @@ struct wrpc_socket *ptpd_netif_create_socket(struct wrpc_socket *s, ...@@ -94,7 +94,7 @@ struct wrpc_socket *ptpd_netif_create_socket(struct wrpc_socket *s,
// This value is later used for recovering the precise transmit timestamp. // This value is later used for recovering the precise transmit timestamp.
// If user doesn't need it, tag parameter can be left NULL. // If user doesn't need it, tag parameter can be left NULL.
int ptpd_netif_sendto(struct wrpc_socket *sock, struct wr_sockaddr *to, void *data, int ptpd_netif_sendto(struct wrpc_socket *sock, struct wr_sockaddr *to, void *data,
size_t data_length, struct wr_timestamp *tx_ts); size_t data_length, struct wr_timestamp *tx_ts, int port);
// Receives an UDP/RAW packet. Data is written to (data) and len is returned. // Receives an UDP/RAW packet. Data is written to (data) and len is returned.
// Maximum buffer length can be specified by data_length parameter. // Maximum buffer length can be specified by data_length parameter.
...@@ -102,21 +102,21 @@ int ptpd_netif_sendto(struct wrpc_socket *sock, struct wr_sockaddr *to, void *da ...@@ -102,21 +102,21 @@ int ptpd_netif_sendto(struct wrpc_socket *sock, struct wr_sockaddr *to, void *da
// All RXed packets are timestamped and the timestamp // All RXed packets are timestamped and the timestamp
// is stored in rx_timestamp (unless it's NULL). // is stored in rx_timestamp (unless it's NULL).
int ptpd_netif_recvfrom(struct wrpc_socket *sock, struct wr_sockaddr *from, void *data, int ptpd_netif_recvfrom(struct wrpc_socket *sock, struct wr_sockaddr *from, void *data,
size_t data_length, struct wr_timestamp *rx_timestamp); size_t data_length, struct wr_timestamp *rx_timestamp, int port);
// Closes the socket. // Closes the socket.
int ptpd_netif_close_socket(struct wrpc_socket * sock); int ptpd_netif_close_socket(struct wrpc_socket * sock, int port);
int ptpd_netif_get_hw_addr(struct wrpc_socket * sock, mac_addr_t * mac); int ptpd_netif_get_hw_addr(struct wrpc_socket * sock, mac_addr_t * mac, int port);
void ptpd_netif_linearize_rx_timestamp(struct wr_timestamp *ts, void ptpd_netif_linearize_rx_timestamp(struct wr_timestamp *ts,
int32_t dmtd_phase, int32_t dmtd_phase,
int cntr_ahead, int transition_point, int cntr_ahead, int transition_point,
int clock_period); int clock_period);
void ptpd_netif_set_phase_transition(uint32_t phase); void ptpd_netif_set_phase_transition(uint32_t phase, int port);
struct hal_port_state; struct hal_port_state;
int wrpc_get_port_state(struct hal_port_state *port, int wrpc_get_port_state(struct hal_port_state *state,
const char *port_name /* unused */); const char *port_name);
#endif /* __PTPD_NETIF_H */ #endif /* __PTPD_NETIF_H */
...@@ -10,9 +10,9 @@ ...@@ -10,9 +10,9 @@
#ifndef __RXTS_CALIBRATOR_H #ifndef __RXTS_CALIBRATOR_H
#define __RXTS_CALIBRATOR_H #define __RXTS_CALIBRATOR_H
void rxts_calibration_start(void); void rxts_calibration_start(uint8_t port);
int rxts_calibration_update(uint32_t *t24p_value); int rxts_calibration_update(uint32_t *t24p_value, int port);
int measure_t24p(uint32_t *value); int measure_t24p(uint32_t *value, int port);
int calib_t24p(int mode, uint32_t *value); int calib_t24p(int mode, uint32_t *value, int port);
#endif #endif
...@@ -16,14 +16,14 @@ ...@@ -16,14 +16,14 @@
#define SFP_GET 0 #define SFP_GET 0
#define SFP_ADD 1 #define SFP_ADD 1
extern char sfp_pn[SFP_PN_LEN]; extern char sfp_pn[2][SFP_PN_LEN];
extern int32_t sfp_in_db; extern int32_t sfp_in_db[2];
extern int32_t sfp_alpha; extern int32_t sfp_alpha[2];
extern int32_t sfp_deltaTx; extern int32_t sfp_deltaTx[2];
extern int32_t sfp_deltaRx; extern int32_t sfp_deltaRx[2];
/* Match plugged SFP with a DB entry */ /* Match plugged SFP with a DB entry */
int sfp_match(void); int sfp_match(int port);
#endif #endif
...@@ -52,11 +52,12 @@ ...@@ -52,11 +52,12 @@
#define HAS_GENSDBFS 0 #define HAS_GENSDBFS 0
#endif #endif
extern uint32_t cal_phase_transition; extern uint32_t cal_phase_transition[2];
extern uint8_t has_eeprom; extern uint8_t has_eeprom;
struct s_sfpinfo { struct s_sfpinfo {
char pn[SFP_PN_LEN]; char pn[SFP_PN_LEN];
uint8_t port;
int32_t alpha; int32_t alpha;
int32_t dTx; int32_t dTx;
int32_t dRx; int32_t dRx;
...@@ -65,11 +66,11 @@ struct s_sfpinfo { ...@@ -65,11 +66,11 @@ struct s_sfpinfo {
void storage_init(int i2cif, int i2c_addr); void storage_init(int i2cif, int i2c_addr);
int storage_sfpdb_erase(void); int storage_sfpdb_erase(int port);
int storage_match_sfp(struct s_sfpinfo *sfp); int storage_match_sfp(struct s_sfpinfo *sfp, int port);
int storage_get_sfp(struct s_sfpinfo *sfp, uint8_t add, uint8_t pos); int storage_get_sfp(struct s_sfpinfo *sfp, uint8_t add, uint8_t pos, int port);
int storage_phtrans(uint32_t *val, uint8_t write); int storage_phtrans(uint32_t *val, uint8_t write, int port);
int storage_init_erase(void); int storage_init_erase(void);
int storage_init_add(const char *args[]); int storage_init_add(const char *args[]);
......
...@@ -81,9 +81,12 @@ struct SYSCON_WB { ...@@ -81,9 +81,12 @@ struct SYSCON_WB {
/*GPIO pins*/ /*GPIO pins*/
#define GPIO_LED_LINK SYSC_GPSR_LED_LINK #define GPIO_LED_LINK SYSC_GPSR_LED_LINK
#define GPIO_LED_STAT SYSC_GPSR_LED_STAT #define GPIO_LED_STAT SYSC_GPSR_LED_STAT
#define GPIO_DP_LED_LINK SYSC_GPSR_DP_LED_LINK
#define GPIO_DP_LED_STAT SYSC_GPSR_DP_LED_STAT
#define GPIO_BTN1 SYSC_GPSR_BTN1 #define GPIO_BTN1 SYSC_GPSR_BTN1
#define GPIO_BTN2 SYSC_GPSR_BTN2 #define GPIO_BTN2 SYSC_GPSR_BTN2
#define GPIO_SFP_DET SYSC_GPSR_SFP_DET #define GPIO_SFP_DET SYSC_GPSR_SFP_DET
#define GPIO_DP_SFP_DET SYSC_GPSR_DP_SFP_DET
#define GPIO_SPI_SCLK SYSC_GPSR_SPI_SCLK #define GPIO_SPI_SCLK SYSC_GPSR_SPI_SCLK
#define GPIO_SPI_NCS SYSC_GPSR_SPI_NCS #define GPIO_SPI_NCS SYSC_GPSR_SPI_NCS
#define GPIO_SPI_MOSI SYSC_GPSR_SPI_MOSI #define GPIO_SPI_MOSI SYSC_GPSR_SPI_MOSI
...@@ -91,6 +94,7 @@ struct SYSCON_WB { ...@@ -91,6 +94,7 @@ struct SYSCON_WB {
#define WRPC_FMC_I2C 0 #define WRPC_FMC_I2C 0
#define WRPC_SFP_I2C 1 #define WRPC_SFP_I2C 1
#define WRPC_DP_SFP_I2C 2
#define FMC_I2C_DELAY 15 #define FMC_I2C_DELAY 15
#define SFP_I2C_DELAY 300 #define SFP_I2C_DELAY 300
...@@ -100,7 +104,7 @@ struct s_i2c_if { ...@@ -100,7 +104,7 @@ struct s_i2c_if {
uint32_t loop_delay; uint32_t loop_delay;
}; };
extern struct s_i2c_if i2c_if[2]; extern struct s_i2c_if i2c_if[3];
void timer_init(uint32_t enable); void timer_init(uint32_t enable);
......
...@@ -79,4 +79,7 @@ void rtipc_action(void); ...@@ -79,4 +79,7 @@ void rtipc_action(void);
/* div64.c, lifted from the linux kernel through pp_printf or ppsi */ /* div64.c, lifted from the linux kernel through pp_printf or ppsi */
extern uint32_t __div64_32(uint64_t *n, uint32_t base); extern uint32_t __div64_32(uint64_t *n, uint32_t base);
// CUTE DP
#define wr_num_ports 2
#endif /* __WRC_H__ */ #endif /* __WRC_H__ */
...@@ -6,13 +6,14 @@ ...@@ -6,13 +6,14 @@
#define WRC_MODE_MASTER 2 #define WRC_MODE_MASTER 2
#define WRC_MODE_SLAVE 3 #define WRC_MODE_SLAVE 3
#define WRC_MODE_ABSCAL 4 #define WRC_MODE_ABSCAL 4
extern int ptp_mode; extern int ptp_mode;
int wrc_ptp_init(void); int wrc_ptp_init(void);
int wrc_ptp_set_mode(int mode); int wrc_ptp_set_mode(int mode);
int wrc_ptp_get_mode(void); int wrc_ptp_get_mode(void);
int wrc_ptp_start(void); int wrc_ptp_start(int port);
int wrc_ptp_stop(void); int wrc_ptp_stop(int port);
int wrc_ptp_update(void); int wrc_ptp_update(void);
#endif #endif
...@@ -16,27 +16,30 @@ ...@@ -16,27 +16,30 @@
#include "arp.h" #include "arp.h"
#include "tcpip_config.h" #include "tcpip_config.h"
static uint8_t __arp_queue[128]; static uint8_t __arp_queue[2][128];
static struct wrpc_socket __static_arp_socket = { static struct wrpc_socket __static_arp_socket[2] = {
.queue.buff = __arp_queue, {.queue.buff = __arp_queue[0],
.queue.size = sizeof(__arp_queue), .queue.size = sizeof(__arp_queue),},
{.queue.buff = __arp_queue[1],
.queue.size = sizeof(__arp_queue),},
}; };
static struct wrpc_socket *arp_socket; static struct wrpc_socket *arp_socket[2];
static void arp_init(void) static void arp_init(void)
{ {
struct wr_sockaddr saddr; struct wr_sockaddr saddr;
int port=0;
/* Configure socket filter */ /* Configure socket filter */
memset(&saddr, 0, sizeof(saddr)); memset(&saddr, 0, sizeof(saddr));
// memset(&saddr.mac, 0xFF, 6); /* Broadcast */ // memset(&saddr.mac, 0xFF, 6); /* Broadcast */
saddr.ethertype = htons(0x0806); /* ARP */ saddr.ethertype = htons(0x0806); /* ARP */
arp_socket = ptpd_netif_create_socket(&__static_arp_socket, &saddr, for(port = 0; port<wr_num_ports; ++port)
PTPD_SOCK_RAW_ETHERNET, 0); arp_socket[port] = ptpd_netif_create_socket(&__static_arp_socket, &saddr,
PTPD_SOCK_RAW_ETHERNET, 0, port);
} }
static int process_arp(uint8_t * buf, int len) static int process_arp(uint8_t * buf, int len, int port)
{ {
uint8_t hisMAC[6]; uint8_t hisMAC[6];
uint8_t hisIP[4]; uint8_t hisIP[4];
...@@ -46,10 +49,10 @@ static int process_arp(uint8_t * buf, int len) ...@@ -46,10 +49,10 @@ static int process_arp(uint8_t * buf, int len)
return 0; return 0;
/* Is it ARP request targetting our IP? */ /* Is it ARP request targetting our IP? */
getIP(myIP, port);
if (buf[ARP_OPER + 0] != 0) if (buf[ARP_OPER + 0] != 0)
return 0; return 0;
getIP(myIP);
if ( ((buf[ARP_OPER + 1] != 1)||memcmp(buf + ARP_TPA, myIP, 4)) == 0 ) if ( ((buf[ARP_OPER + 1] != 1)||memcmp(buf + ARP_TPA, myIP, 4)) == 0 )
{ {
memcpy(hisMAC, buf + ARP_SHA, 6); memcpy(hisMAC, buf + ARP_SHA, 6);
...@@ -68,7 +71,7 @@ static int process_arp(uint8_t * buf, int len) ...@@ -68,7 +71,7 @@ static int process_arp(uint8_t * buf, int len)
buf[ARP_OPER + 0] = 0; buf[ARP_OPER + 0] = 0;
buf[ARP_OPER + 1] = 2; buf[ARP_OPER + 1] = 2;
// my MAC+IP // my MAC+IP
get_mac_addr(buf + ARP_SHA); get_mac_addr(buf + ARP_SHA, port);
memcpy(buf + ARP_SPA, myIP, 4); memcpy(buf + ARP_SPA, myIP, 4);
// his MAC+IP // his MAC+IP
memcpy(buf + ARP_THA, hisMAC, 6); memcpy(buf + ARP_THA, hisMAC, 6);
...@@ -93,22 +96,29 @@ static int arp_poll(void) ...@@ -93,22 +96,29 @@ static int arp_poll(void)
uint8_t buf[ARP_END + 100]; uint8_t buf[ARP_END + 100];
struct wr_sockaddr addr; struct wr_sockaddr addr;
int len; int len;
int port;
int ret;
if (ip_status == IP_TRAINING) if (ip_status == IP_TRAINING)
return 0; /* can't do ARP w/o an address... */ return 0; /* can't do ARP w/o an address... */
if ((len = ptpd_netif_recvfrom(arp_socket, ret = 0;
&addr, buf, sizeof(buf), 0)) > 0) { for (port=0; port<wr_num_ports; ++port) {
if ((len = process_arp(buf, len)) > 0) if ((len = ptpd_netif_recvfrom(arp_socket[port],
ptpd_netif_sendto(arp_socket, &addr, buf, len, 0); &addr, buf, sizeof(buf), 0, port)) > 0)
return 1; {
if ((len = process_arp(buf, len, 0)) > 0)
ptpd_netif_sendto(arp_socket, &addr, buf, len, 0, port);
ret = 1;
}
} }
return 0; return ret;
} }
void send_arp(uint8_t * hisIP) int send_arp(uint8_t * hisIP, int port)
{ {
uint8_t buf[ARP_END + 100]; uint8_t buf[ARP_END + 100];
struct wr_sockaddr addr; struct wr_sockaddr addr;
/* Configure socket filter */ /* Configure socket filter */
memset(&addr.mac, 0xFF, 6); /* Broadcast */ memset(&addr.mac, 0xFF, 6); /* Broadcast */
...@@ -126,16 +136,16 @@ void send_arp(uint8_t * hisIP) ...@@ -126,16 +136,16 @@ void send_arp(uint8_t * hisIP)
buf[ARP_OPER + 0] = 0; buf[ARP_OPER + 0] = 0;
buf[ARP_OPER + 1] = 1; buf[ARP_OPER + 1] = 1;
get_mac_addr(buf + ARP_SHA); get_mac_addr(buf + ARP_SHA, port);
getIP(buf + ARP_SPA); getIP(buf + ARP_SPA, port);
memset(buf + ARP_THA, 0x00, 6); /* Broadcast */ memset(buf + ARP_THA, 0x00, 6); /* Broadcast */
memcpy(buf + ARP_TPA, hisIP, 4); memcpy(buf + ARP_TPA, hisIP, 4);
return (ptpd_netif_sendto(arp_socket, &addr, buf, ARP_END+10, 0)); return (ptpd_netif_sendto(arp_socket, &addr, buf, ARP_END+10, 0, port));
} }
DEFINE_WRC_TASK(arp) = { DEFINE_WRC_TASK(arp) = {
.name = "arp", .name = "arp",
.enable = &link_status, .enable = &link_status[0],
.init = arp_init, .init = arp_init,
.job = arp_poll, .job = arp_poll,
}; };
...@@ -40,7 +40,7 @@ int prepare_bootp(struct wr_sockaddr *addr, uint8_t * buf, int retry) ...@@ -40,7 +40,7 @@ int prepare_bootp(struct wr_sockaddr *addr, uint8_t * buf, int retry)
buf[BOOTP_HOPS] = 0; buf[BOOTP_HOPS] = 0;
/* A unique identifier for the request !!! FIXME */ /* A unique identifier for the request !!! FIXME */
get_mac_addr(buf + BOOTP_XID); get_mac_addr(buf + BOOTP_XID, 0);
buf[BOOTP_XID + 0] ^= buf[BOOTP_XID + 4]; buf[BOOTP_XID + 0] ^= buf[BOOTP_XID + 4];
buf[BOOTP_XID + 1] ^= buf[BOOTP_XID + 5]; buf[BOOTP_XID + 1] ^= buf[BOOTP_XID + 5];
buf[BOOTP_XID + 2] ^= (retry >> 8) & 0xFF; buf[BOOTP_XID + 2] ^= (retry >> 8) & 0xFF;
...@@ -56,7 +56,7 @@ int prepare_bootp(struct wr_sockaddr *addr, uint8_t * buf, int retry) ...@@ -56,7 +56,7 @@ int prepare_bootp(struct wr_sockaddr *addr, uint8_t * buf, int retry)
memset(buf + BOOTP_GIADDR, 0, 4); memset(buf + BOOTP_GIADDR, 0, 4);
memset(buf + BOOTP_CHADDR, 0, 16); memset(buf + BOOTP_CHADDR, 0, 16);
get_mac_addr(buf + BOOTP_CHADDR); /* own MAC address */ get_mac_addr(buf + BOOTP_CHADDR, 0); /* own MAC address */
memset(buf + BOOTP_SNAME, 0, 64); /* desired BOOTP server */ memset(buf + BOOTP_SNAME, 0, 64); /* desired BOOTP server */
memset(buf + BOOTP_FILE, 0, 128); /* desired BOOTP file */ memset(buf + BOOTP_FILE, 0, 128); /* desired BOOTP file */
...@@ -81,7 +81,7 @@ int process_bootp(uint8_t * buf, int len) ...@@ -81,7 +81,7 @@ int process_bootp(uint8_t * buf, int len)
uint8_t mac[6]; uint8_t mac[6];
uint8_t ip[4]; uint8_t ip[4];
get_mac_addr(mac); get_mac_addr(mac, 0);
if (len != BOOTP_END) if (len != BOOTP_END)
return 0; return 0;
...@@ -92,10 +92,10 @@ int process_bootp(uint8_t * buf, int len) ...@@ -92,10 +92,10 @@ int process_bootp(uint8_t * buf, int len)
if (memcmp(buf + BOOTP_CHADDR, mac, 6)) if (memcmp(buf + BOOTP_CHADDR, mac, 6))
return 0; return 0;
ip_status = IP_OK_BOOTP; ip_status[0] = IP_OK_BOOTP;
setIP(buf + BOOTP_YIADDR); setIP(buf + BOOTP_YIADDR, 0);
getIP(ip); getIP(ip, 0);
pp_printf("Discovered IP address (%d.%d.%d.%d)!\n", pp_printf("Discovered IP address (%d.%d.%d.%d)!\n",
ip[0], ip[1], ip[2], ip[3]); ip[0], ip[1], ip[2], ip[3]);
......
...@@ -28,7 +28,7 @@ ...@@ -28,7 +28,7 @@
#define ICMP_CHECKSUM (ICMP_CODE+1) #define ICMP_CHECKSUM (ICMP_CODE+1)
#define ICMP_END (ICMP_CHECKSUM+2) #define ICMP_END (ICMP_CHECKSUM+2)
int process_icmp(uint8_t * buf, int len) int process_icmp(uint8_t * buf, int len, int port)
{ {
int iplen, hisBodyLen; int iplen, hisBodyLen;
uint8_t hisIP[4]; uint8_t hisIP[4];
...@@ -36,7 +36,7 @@ int process_icmp(uint8_t * buf, int len) ...@@ -36,7 +36,7 @@ int process_icmp(uint8_t * buf, int len)
uint16_t sum; uint16_t sum;
/* Is it IP targetting us? */ /* Is it IP targetting us? */
getIP(myIP); getIP(myIP,port);
if (buf[IP_VERSION] != 0x45 || memcmp(buf + IP_DEST, myIP, 4)) if (buf[IP_VERSION] != 0x45 || memcmp(buf + IP_DEST, myIP, 4))
return 0; return 0;
......
...@@ -19,26 +19,30 @@ ...@@ -19,26 +19,30 @@
#include "flash.h" #include "flash.h"
#include "tcpip_config.h" #include "tcpip_config.h"
enum ip_status ip_status = IP_TRAINING; enum ip_status ip_status[2] = {IP_TRAINING,IP_TRAINING};
static uint8_t myIP[4]; static uint8_t myIP[2][4];
/* magic UDP is deadbeef */ /* magic UDP is deadbeef */
const uint8_t magicUDP[4] ={0x62,0x65,0x65,0x66}; const uint8_t magicUDP[4] ={0x62,0x65,0x65,0x66};
/* bootp: bigger buffer, UDP based */ /* bootp: bigger buffer, UDP based */
static uint8_t __bootp_queue[512]; static uint8_t __bootp_queue[2][512];
static struct wrpc_socket __static_bootp_socket = { static struct wrpc_socket __static_bootp_socket[2] = {
.queue.buff = __bootp_queue, {.queue.buff = __bootp_queue[0],
.queue.size = sizeof(__bootp_queue), .queue.size = sizeof(__bootp_queue[0]),},
{.queue.buff = __bootp_queue[1],
.queue.size = sizeof(__bootp_queue[1]),}
}; };
static struct wrpc_socket *bootp_socket; static struct wrpc_socket *bootp_socket[2];
/* ICMP: smaller buffer */ /* ICMP: smaller buffer */
static uint8_t __icmp_queue[128]; static uint8_t __icmp_queue[2][128];
static struct wrpc_socket __static_icmp_socket = { static struct wrpc_socket __static_icmp_socket[2] = {
.queue.buff = __icmp_queue, {.queue.buff = __icmp_queue[0],
.queue.size = sizeof(__icmp_queue), .queue.size = sizeof(__icmp_queue[0]),},
{.queue.buff = __icmp_queue[1],
.queue.size = sizeof(__icmp_queue[1]),}
}; };
static struct wrpc_socket *icmp_socket; static struct wrpc_socket *icmp_socket[2];
/* RDATE: even smaller buffer -- but we require 86. 96 is "even". */ /* RDATE: even smaller buffer -- but we require 86. 96 is "even". */
static uint8_t __rdate_queue[96]; static uint8_t __rdate_queue[96];
...@@ -83,23 +87,26 @@ static void ipv4_init(void) ...@@ -83,23 +87,26 @@ static void ipv4_init(void)
struct wr_sockaddr saddr; struct wr_sockaddr saddr;
/* Bootp: use UDP engine activated by function arguments */ /* Bootp: use UDP engine activated by function arguments */
bootp_socket = ptpd_netif_create_socket(&__static_bootp_socket, NULL, bootp_socket[0] = ptpd_netif_create_socket(&__static_bootp_socket[0], NULL,
PTPD_SOCK_UDP, 68 /* bootpc */); PTPD_SOCK_UDP, 68 /* bootpc */, 0);
bootp_socket[1] = ptpd_netif_create_socket(&__static_bootp_socket[1], NULL,
PTPD_SOCK_UDP, 68 /* bootpc */, 1);
/* time (rdate): UDP */ /* time (rdate): UDP */
rdate_socket = ptpd_netif_create_socket(&__static_rdate_socket, NULL, rdate_socket = ptpd_netif_create_socket(&__static_rdate_socket, NULL,
PTPD_SOCK_UDP, 37 /* time */); PTPD_SOCK_UDP, 37 /* time */, 0);
/* remote update (rmupdate): UDP */ /* remote update (rmupdate): UDP */
rmupdate_socket = ptpd_netif_create_socket(&__static_rmupdate_socket, NULL, rmupdate_socket = ptpd_netif_create_socket(&__static_rmupdate_socket, NULL,
PTPD_SOCK_UDP, 71 /* remote update */); PTPD_SOCK_UDP, 71 /* remote update */, 0);
/* ICMP: specify raw (not UDP), with IPV4 ethtype */ /* ICMP: specify raw (not UDP), with IPV4 ethtype */
memset(&saddr, 0, sizeof(saddr)); memset(&saddr, 0, sizeof(saddr));
saddr.ethertype = htons(0x0800); saddr.ethertype = htons(0x0800);
icmp_socket = ptpd_netif_create_socket(&__static_icmp_socket, &saddr, icmp_socket[0] = ptpd_netif_create_socket(&__static_icmp_socket[0], &saddr,
PTPD_SOCK_RAW_ETHERNET, 0); PTPD_SOCK_RAW_ETHERNET, 0, 0);
icmp_socket[1] = ptpd_netif_create_socket(&__static_icmp_socket[1], &saddr,
PTPD_SOCK_RAW_ETHERNET, 0, 1);
syslog_init(); syslog_init();
} }
...@@ -113,10 +120,10 @@ static int bootp_poll(void) ...@@ -113,10 +120,10 @@ static int bootp_poll(void)
uint8_t buf[400]; uint8_t buf[400];
int len, ret = 0; int len, ret = 0;
len = ptpd_netif_recvfrom(bootp_socket, &addr, len = ptpd_netif_recvfrom(bootp_socket[0], &addr,
buf, sizeof(buf), NULL); buf, sizeof(buf), NULL, 0);
if (ip_status != IP_TRAINING) if (ip_status[0] != IP_TRAINING)
return 0; return 0;
if (len > 0) if (len > 0)
...@@ -126,29 +133,29 @@ static int bootp_poll(void) ...@@ -126,29 +133,29 @@ static int bootp_poll(void)
return ret; return ret;
len = prepare_bootp(&addr, buf, ++bootp_retry); len = prepare_bootp(&addr, buf, ++bootp_retry);
ptpd_netif_sendto(bootp_socket, &addr, buf, len, 0); ptpd_netif_sendto(bootp_socket[0], &addr, buf, len, 0, 0);
return 1; return 1;
} }
static int icmp_poll(void) static int icmp_poll(int port)
{ {
struct wr_sockaddr addr; struct wr_sockaddr addr;
uint8_t buf[128]; uint8_t buf[128];
int len; int len;
len = ptpd_netif_recvfrom(icmp_socket, &addr, len = ptpd_netif_recvfrom(icmp_socket[port], &addr,
buf, sizeof(buf), NULL); buf, sizeof(buf), NULL, port);
if (len <= 0) if (len <= 0)
return 0; return 0;
if (ip_status == IP_TRAINING) if (ip_status[port] == IP_TRAINING)
return 0; return 0;
/* check the destination IP */ /* check the destination IP */
if (check_dest_ip(buf)) if (check_dest_ip(buf, port))
return 0; return 0;
if ((len = process_icmp(buf, len)) > 0) if ((len = process_icmp(buf, len, port)) > 0)
ptpd_netif_sendto(icmp_socket, &addr, buf, len, 0); ptpd_netif_sendto(icmp_socket[port], &addr, buf, len, 0, port);
return 1; return 1;
} }
...@@ -161,12 +168,12 @@ static int rdate_poll(void) ...@@ -161,12 +168,12 @@ static int rdate_poll(void)
int len; int len;
len = ptpd_netif_recvfrom(rdate_socket, &addr, len = ptpd_netif_recvfrom(rdate_socket, &addr,
buf, sizeof(buf), NULL); buf, sizeof(buf), NULL, 0/* port */);
if (len <= 0) if (len <= 0)
return 0; return 0;
/* check the destination IP */ /* check the destination IP */
if (check_dest_ip(buf)) if (check_dest_ip(buf,0))
return 0; return 0;
shw_pps_gen_get_time(&secs, NULL); shw_pps_gen_get_time(&secs, NULL);
...@@ -177,7 +184,7 @@ static int rdate_poll(void) ...@@ -177,7 +184,7 @@ static int rdate_poll(void)
memcpy(buf + UDP_END, &result, sizeof(result)); memcpy(buf + UDP_END, &result, sizeof(result));
fill_udp(buf, len, NULL); fill_udp(buf, len, NULL);
ptpd_netif_sendto(rdate_socket, &addr, buf, len, 0); ptpd_netif_sendto(rdate_socket, &addr, buf, len, 0, 0);
return 1; return 1;
} }
...@@ -192,13 +199,13 @@ static int rmupdate_poll(void) ...@@ -192,13 +199,13 @@ static int rmupdate_poll(void)
int data_size; int data_size;
len = ptpd_netif_recvfrom(rmupdate_socket, &addr, len = ptpd_netif_recvfrom(rmupdate_socket, &addr,
buf, sizeof(buf), NULL); buf, sizeof(buf), NULL, 0);
if (len <= 0) if (len <= 0)
return 0; return 0;
/* check the destination IP */ /* check the destination IP */
if (check_dest_ip(buf)) if (check_dest_ip(buf, 0))
return 0; return 0;
if (check_magic_udp(buf)<0) if (check_magic_udp(buf)<0)
...@@ -260,7 +267,7 @@ static int rmupdate_poll(void) ...@@ -260,7 +267,7 @@ static int rmupdate_poll(void)
} }
fill_udp(buf, len, NULL); fill_udp(buf, len, NULL);
ptpd_netif_sendto(rdate_socket, &addr, buf, len, 0); ptpd_netif_sendto(rdate_socket, &addr, buf, len, 0, 0);
return 1; return 1;
} }
...@@ -268,11 +275,12 @@ static int ipv4_poll(void) ...@@ -268,11 +275,12 @@ static int ipv4_poll(void)
{ {
int ret = 0; int ret = 0;
if (link_status == LINK_WENT_UP && ip_status == IP_OK_BOOTP) if (link_status[0] == LINK_WENT_UP && ip_status[0] == IP_OK_BOOTP)
ip_status = IP_TRAINING; ip_status[0] = IP_TRAINING;
ret = bootp_poll(); ret = bootp_poll();
ret += icmp_poll(); ret += icmp_poll(0);
ret += icmp_poll(1);
ret += rdate_poll(); ret += rdate_poll();
...@@ -283,38 +291,38 @@ static int ipv4_poll(void) ...@@ -283,38 +291,38 @@ static int ipv4_poll(void)
return ret != 0; return ret != 0;
} }
void getIP(unsigned char *IP) void getIP(unsigned char *IP, int port)
{ {
memcpy(IP, myIP, 4); memcpy(IP, myIP[port], 4);
} }
DEFINE_WRC_TASK(ipv4) = { DEFINE_WRC_TASK(ipv4) = {
.name = "ipv4", .name = "ipv4",
.enable = &link_status, .enable = &link_status[0],
.init = ipv4_init, .init = ipv4_init,
.job = ipv4_poll, .job = ipv4_poll,
}; };
void setIP(unsigned char *IP) void setIP(unsigned char *IP, int port)
{ {
uint8_t tmp[4]; // uint8_t tmp[4];
// volatile unsigned int *eb_ip = // volatile unsigned int *eb_ip =
// (unsigned int *)(BASE_ETHERBONE_CFG + EB_IPV4); // (unsigned int *)(BASE_ETHERBONE_CFG + EB_IPV4);
// unsigned int ip; // unsigned int ip;
// while (*eb_ip != ip) // while (*eb_ip != ip)
// *eb_ip = ip; // *eb_ip = ip;
memcpy(myIP, IP, 4); memcpy(myIP[port], IP, 4);
bootp_retry = 0; bootp_retry = 0;
} }
/* Check the destination IP of the incoming packet */ /* Check the destination IP of the incoming packet */
int check_dest_ip(unsigned char *buf) int check_dest_ip(unsigned char *buf, int port)
{ {
if (!buf) if (!buf)
return -1; return -1;
return memcmp(buf + IP_DEST, myIP, 4); return memcmp(buf + IP_DEST, myIP[port], 4);
} }
/* Check the magic number of the incoming remote update packet */ /* Check the magic number of the incoming remote update packet */
......
...@@ -44,11 +44,11 @@ enum ip_status { ...@@ -44,11 +44,11 @@ enum ip_status {
IP_OK_BOOTP, IP_OK_BOOTP,
IP_OK_STATIC, IP_OK_STATIC,
}; };
extern enum ip_status ip_status; extern enum ip_status ip_status[2];
void setIP(unsigned char *IP); void setIP(unsigned char *IP, int port);
void getIP(unsigned char *IP); void getIP(unsigned char *IP, int port);
int process_icmp(uint8_t * buf, int len); int process_icmp(uint8_t * buf, int len, int port);
int process_bootp(uint8_t * buf, int len); /* non-zero if IP was set */ int process_bootp(uint8_t * buf, int len); /* non-zero if IP was set */
int prepare_bootp(struct wr_sockaddr *addr, uint8_t * buf, int retry); int prepare_bootp(struct wr_sockaddr *addr, uint8_t * buf, int retry);
...@@ -61,7 +61,7 @@ struct wr_udp_addr { ...@@ -61,7 +61,7 @@ struct wr_udp_addr {
}; };
void fill_udp(uint8_t * buf, int len, struct wr_udp_addr *uaddr); void fill_udp(uint8_t * buf, int len, struct wr_udp_addr *uaddr);
int check_dest_ip(unsigned char *buf); int check_dest_ip(unsigned char *buf, int port);
int check_magic_udp(unsigned char *buf); int check_magic_udp(unsigned char *buf);
void syslog_init(void); void syslog_init(void);
......
...@@ -45,7 +45,7 @@ static void latency_init(void) ...@@ -45,7 +45,7 @@ static void latency_init(void)
latency_addr.ethertype = htons(CONFIG_LATENCY_ETHTYPE); latency_addr.ethertype = htons(CONFIG_LATENCY_ETHTYPE);
latency_socket = ptpd_netif_create_socket(&__static_latency_socket, latency_socket = ptpd_netif_create_socket(&__static_latency_socket,
&latency_addr, &latency_addr,
PTPD_SOCK_RAW_ETHERNET, 0); PTPD_SOCK_RAW_ETHERNET, 0, 0, 0/*port*/);
} }
static struct latency_frame { static struct latency_frame {
...@@ -129,7 +129,7 @@ static int latency_poll_rx(void) ...@@ -129,7 +129,7 @@ static int latency_poll_rx(void)
int i, j; int i, j;
i = ptpd_netif_recvfrom(latency_socket, &addr, i = ptpd_netif_recvfrom(latency_socket, &addr,
&frame, sizeof(frame), &ts_tmp); &frame, sizeof(frame), &ts_tmp, 0/*port*/);
if (i < sizeof(frame)) if (i < sizeof(frame))
return 0; return 0;
...@@ -225,7 +225,7 @@ static int latency_poll_tx(void) ...@@ -225,7 +225,7 @@ static int latency_poll_tx(void)
frame.type = 1; frame.type = 1;
latency_socket->prio = prios[0]; latency_socket->prio = prios[0];
ptpd_netif_sendto(latency_socket, &latency_addr, &frame, sizeof(frame), ptpd_netif_sendto(latency_socket, &latency_addr, &frame, sizeof(frame),
frame.ts + 0); frame.ts + 0, 0/*port*/);
frame.ts[0].nsec -= ltest_fake_delay_ns; frame.ts[0].nsec -= ltest_fake_delay_ns;
if (frame.ts[0].nsec < 0) { if (frame.ts[0].nsec < 0) {
frame.ts[0].nsec += 1000 * 1000 * 1000; frame.ts[0].nsec += 1000 * 1000 * 1000;
...@@ -235,7 +235,7 @@ static int latency_poll_tx(void) ...@@ -235,7 +235,7 @@ static int latency_poll_tx(void)
frame.type = 2; frame.type = 2;
latency_socket->prio = prios[1]; latency_socket->prio = prios[1];
ptpd_netif_sendto(latency_socket, &latency_addr, &frame, sizeof(frame), ptpd_netif_sendto(latency_socket, &latency_addr, &frame, sizeof(frame),
frame.ts + 1); frame.ts + 1, 0/*port*/);
frame.ts[1].nsec -= ltest_fake_delay_ns; frame.ts[1].nsec -= ltest_fake_delay_ns;
if (frame.ts[1].nsec < 0) { if (frame.ts[1].nsec < 0) {
frame.ts[1].nsec += 1000 * 1000 * 1000; frame.ts[1].nsec += 1000 * 1000 * 1000;
...@@ -245,7 +245,7 @@ static int latency_poll_tx(void) ...@@ -245,7 +245,7 @@ static int latency_poll_tx(void)
frame.type = 3; frame.type = 3;
latency_socket->prio = prios[2]; latency_socket->prio = prios[2];
ptpd_netif_sendto(latency_socket, &latency_addr, &frame, sizeof(frame), ptpd_netif_sendto(latency_socket, &latency_addr, &frame, sizeof(frame),
NULL); NULL, 0/*port*/);
ltest_fake_delay_ns = 0; ltest_fake_delay_ns = 0;
/* Every 10s remind we are sending ltest */ /* Every 10s remind we are sending ltest */
......
...@@ -255,7 +255,7 @@ static int lldp_poll(void) ...@@ -255,7 +255,7 @@ static int lldp_poll(void)
/* Update only when IP or MAC changed */ /* Update only when IP or MAC changed */
/* TODO: or VLAN changed */ /* TODO: or VLAN changed */
if (memcmp(&new_mac, &old_mac, ETH_ALEN) if (memcmp(&new_mac, &old_mac, ETH_ALEN)
|| (HAS_IP && (ip_status != IP_TRAINING) || (HAS_IP && (ip_status[0] != IP_TRAINING)
&& memcmp(&new_ipWR, &old_ipWR, IPLEN)) && memcmp(&new_ipWR, &old_ipWR, IPLEN))
) { ) {
/* update LLDP info */ /* update LLDP info */
......
...@@ -24,40 +24,41 @@ ...@@ -24,40 +24,41 @@
#include "softpll_ng.h" #include "softpll_ng.h"
#include "ipv4.h" #include "ipv4.h"
static struct wrpc_socket *socks[NET_MAX_SOCKETS]; static struct wrpc_socket *socks[2][NET_MAX_SOCKETS];
//#define net_verbose pp_printf //#define net_verbose pp_printf
int ptpd_netif_get_hw_addr(struct wrpc_socket *sock, mac_addr_t *mac) int ptpd_netif_get_hw_addr(struct wrpc_socket *sock, mac_addr_t *mac, int port)
{ {
get_mac_addr((uint8_t *) mac); get_mac_addr((uint8_t *) mac, port);
return 0; return 0;
} }
void ptpd_netif_set_phase_transition(uint32_t phase) void ptpd_netif_set_phase_transition(uint32_t phase, int port)
{ {
int i; int i;
for (i=0; i< ARRAY_SIZE(socks); ++i) { for (i=0; i< ARRAY_SIZE(socks[port]); ++i) {
socks[i]->phase_transition = phase; socks[port][i]->phase_transition = phase;
} }
} }
struct wrpc_socket *ptpd_netif_create_socket(struct wrpc_socket *sock, struct wrpc_socket *ptpd_netif_create_socket(struct wrpc_socket *sock,
struct wr_sockaddr * bind_addr, struct wr_sockaddr * bind_addr,
int udp_or_raw, int udpport) int udp_or_raw, int udpport, int port)
{ {
int i; int i;
struct hal_port_state pstate; struct hal_port_state pstate;
const char *port_name;
/* Look for the first available socket. */ /* Look for the first available socket. */
for (i = 0; i < ARRAY_SIZE(socks); i++) for (i = 0; i < ARRAY_SIZE(socks[port]); i++)
if (!socks[i]) { if (!socks[port][i]) {
socks[i] = sock; socks[port][i] = sock;
break; break;
} }
if (i == ARRAY_SIZE(socks)) {
if (i == ARRAY_SIZE(socks[port])) {
pp_printf("%s: no socket slots left\n", __func__); pp_printf("%s: no socket slots left\n", __func__);
return NULL; return NULL;
} }
...@@ -65,7 +66,9 @@ struct wrpc_socket *ptpd_netif_create_socket(struct wrpc_socket *sock, ...@@ -65,7 +66,9 @@ struct wrpc_socket *ptpd_netif_create_socket(struct wrpc_socket *sock,
sock, ntohs(bind_addr->ethertype), sock, ntohs(bind_addr->ethertype),
udpport, i); udpport, i);
if (wrpc_get_port_state(&pstate, "wr0" /* unused */) < 0) port_name = (port) ? "wr0" : "wr1";
if (wrpc_get_port_state(&pstate, port_name) < 0)
return NULL; return NULL;
/* copy and complete the bind information. If MAC is 0 use unicast */ /* copy and complete the bind information. If MAC is 0 use unicast */
...@@ -79,8 +82,7 @@ struct wrpc_socket *ptpd_netif_create_socket(struct wrpc_socket *sock, ...@@ -79,8 +82,7 @@ struct wrpc_socket *ptpd_netif_create_socket(struct wrpc_socket *sock,
} }
/*get mac from endpoint */ /*get mac from endpoint */
get_mac_addr(sock->local_mac); get_mac_addr(sock->local_mac, port);
sock->phase_transition = pstate.t2_phase_transition; sock->phase_transition = pstate.t2_phase_transition;
sock->dmtd_phase = pstate.phase_val; sock->dmtd_phase = pstate.phase_val;
...@@ -92,12 +94,12 @@ struct wrpc_socket *ptpd_netif_create_socket(struct wrpc_socket *sock, ...@@ -92,12 +94,12 @@ struct wrpc_socket *ptpd_netif_create_socket(struct wrpc_socket *sock,
return sock; return sock;
} }
int ptpd_netif_close_socket(struct wrpc_socket *s) int ptpd_netif_close_socket(struct wrpc_socket *sock, int port)
{ {
int i; int i;
for (i = 0; i < ARRAY_SIZE(socks); i++) for (i = 0; i < ARRAY_SIZE(socks[port]); i++)
if (socks[i] == s) if (socks[port][i] == sock)
socks[i] = NULL; socks[port][i] = NULL;
return 0; return 0;
} }
...@@ -218,7 +220,7 @@ static int wrap_copy_out(struct sockq *q, void *src, size_t len) ...@@ -218,7 +220,7 @@ static int wrap_copy_out(struct sockq *q, void *src, size_t len)
} }
int ptpd_netif_recvfrom(struct wrpc_socket *s, struct wr_sockaddr *from, void *data, int ptpd_netif_recvfrom(struct wrpc_socket *s, struct wr_sockaddr *from, void *data,
size_t data_length, struct wr_timestamp *rx_timestamp) size_t data_length, struct wr_timestamp *rx_timestamp, int port)
{ {
struct sockq *q = &s->queue; struct sockq *q = &s->queue;
...@@ -246,8 +248,8 @@ int ptpd_netif_recvfrom(struct wrpc_socket *s, struct wr_sockaddr *from, void *d ...@@ -246,8 +248,8 @@ int ptpd_netif_recvfrom(struct wrpc_socket *s, struct wr_sockaddr *from, void *d
if (rx_timestamp) { if (rx_timestamp) {
rx_timestamp->raw_nsec = hwts.nsec; rx_timestamp->raw_nsec = hwts.nsec;
rx_timestamp->raw_ahead = hwts.ahead; rx_timestamp->raw_ahead = hwts.ahead;
spll_busy = (uint8_t) spll_shifter_busy(0); spll_busy = (uint8_t) spll_shifter_busy(port);
spll_read_ptracker(0, &rx_timestamp->raw_phase, NULL); spll_read_ptracker(port, &rx_timestamp->raw_phase, NULL);
rx_timestamp->sec = hwts.sec; rx_timestamp->sec = hwts.sec;
rx_timestamp->nsec = hwts.nsec; rx_timestamp->nsec = hwts.nsec;
...@@ -271,7 +273,7 @@ int ptpd_netif_recvfrom(struct wrpc_socket *s, struct wr_sockaddr *from, void *d ...@@ -271,7 +273,7 @@ int ptpd_netif_recvfrom(struct wrpc_socket *s, struct wr_sockaddr *from, void *d
} }
int ptpd_netif_sendto(struct wrpc_socket * sock, struct wr_sockaddr *to, void *data, int ptpd_netif_sendto(struct wrpc_socket * sock, struct wr_sockaddr *to, void *data,
size_t data_length, struct wr_timestamp *tx_timestamp) size_t data_length, struct wr_timestamp *tx_timestamp, int port)
{ {
struct wrpc_socket *s = (struct wrpc_socket *)sock; struct wrpc_socket *s = (struct wrpc_socket *)sock;
struct hw_timestamp hwts; struct hw_timestamp hwts;
...@@ -294,7 +296,7 @@ int ptpd_netif_sendto(struct wrpc_socket * sock, struct wr_sockaddr *to, void *d ...@@ -294,7 +296,7 @@ int ptpd_netif_sendto(struct wrpc_socket * sock, struct wr_sockaddr *to, void *d
rval = rval =
minic_tx_frame(&hdr, (uint8_t *) data, minic_tx_frame(&hdr, (uint8_t *) data,
data_length, &hwts); data_length, &hwts, port);
if (tx_timestamp) { if (tx_timestamp) {
...@@ -306,7 +308,7 @@ int ptpd_netif_sendto(struct wrpc_socket * sock, struct wr_sockaddr *to, void *d ...@@ -306,7 +308,7 @@ int ptpd_netif_sendto(struct wrpc_socket * sock, struct wr_sockaddr *to, void *d
return rval; return rval;
} }
static int update_rx_queues(void) static int update_rx_queues()
{ {
struct wrpc_socket *s = NULL, *raws = NULL, *udps = NULL; struct wrpc_socket *s = NULL, *raws = NULL, *udps = NULL;
struct sockq *q; struct sockq *q;
...@@ -320,7 +322,7 @@ static int update_rx_queues(void) ...@@ -320,7 +322,7 @@ static int update_rx_queues(void)
recvd = recvd =
minic_rx_frame(&hdr, buffer, sizeof(buffer), minic_rx_frame(&hdr, buffer, sizeof(buffer),
&hwts); &hwts, 0/*port*/);
if (recvd <= 0) /* No data received? */ if (recvd <= 0) /* No data received? */
return 0; return 0;
...@@ -347,8 +349,97 @@ static int update_rx_queues(void) ...@@ -347,8 +349,97 @@ static int update_rx_queues(void)
else else
port = 0; port = 0;
for (i = 0; i < ARRAY_SIZE(socks); i++) { for (i = 0; i < ARRAY_SIZE(socks[0]); i++) {
s = socks[i]; s = socks[0][i];
if (!s)
continue;
if (hdr.ethtype != s->bind_addr.ethertype)
continue;
if (!port && !s->bind_addr.udpport)
raws = s; /* match with raw socket */
if (port && s->bind_addr.udpport == port)
udps = s; /* match with udp socket */
}
s = udps;
if (!s)
s = raws;
if (!s) {
net_verbose("%s: could not find socket for packet\n",
__FUNCTION__);
return 1;
}
q = &s->queue;
q_required =
sizeof(struct wr_ethhdr) + recvd + sizeof(struct hw_timestamp) + 2;
if (q->avail < q_required) {
net_verbose
("%s: queue for socket full; [avail %d required %d]\n",
__FUNCTION__, q->avail, q_required);
return 1;
}
size = recvd;
q->avail -= wrap_copy_out(q, &size, 2);
q->avail -= wrap_copy_out(q, &hwts, sizeof(struct hw_timestamp));
q->avail -= wrap_copy_out(q, &hdr, sizeof(struct wr_ethhdr));
q->avail -= wrap_copy_out(q, payload, size);
q->n++;
net_verbose("Q: Size %d head %d Smac %x:%x:%x:%x:%x:%x\n", recvd,
q->head, hdr.srcmac[0], hdr.srcmac[1], hdr.srcmac[2],
hdr.srcmac[3], hdr.srcmac[4], hdr.srcmac[5]);
net_verbose("%s: saved packet to socket %04x:%04x "
"[avail %d n %d size %d]\n", __FUNCTION__,
ntohs(s->bind_addr.ethertype),
s->bind_addr.udpport,
q->avail, q->n, q_required);
return 1;
}
static int update_dp_rx_queues(void)
{
struct wrpc_socket *s = NULL, *raws = NULL, *udps = NULL;
struct sockq *q;
struct hw_timestamp hwts;
static struct wr_ethhdr hdr;
int recvd, i, q_required;
static uint8_t buffer[NET_MAX_SKBUF_SIZE - 32];
uint8_t *payload = buffer;
uint16_t size, port;
uint16_t ethtype, tag;
recvd = minic_rx_frame(&hdr, buffer, sizeof(buffer), &hwts, 1);
if (recvd <= 0)return 0;
/* Remove the vlan tag, but make sure it's the right one */
ethtype = hdr.ethtype;
tag = 0;
if (ntohs(ethtype) == 0x8100) {
memcpy(&tag, buffer, 2);
memcpy(&hdr.ethtype, buffer + 2, 2);
payload += 4;
recvd -= 4;
}
if ((ntohs(tag) & 0xfff) != wrc_vlan_number) {
net_verbose("%s: want vlan %i, got %i: discard\n",
__func__, wrc_vlan_number,
ntohs(tag) & 0xfff);
return 0;
}
/* Prepare for IP/UDP checks */
if (payload[IP_VERSION] == 0x45 && payload[IP_PROTOCOL] == 17)
port = payload[UDP_DPORT] << 8 | payload[UDP_DPORT + 1];
else
port = 0;
for (i = 0; i < ARRAY_SIZE(socks[1]); i++) {
s = socks[1][i];
if (!s) if (!s)
continue; continue;
if (hdr.ethtype != s->bind_addr.ethertype) if (hdr.ethtype != s->bind_addr.ethertype)
...@@ -359,6 +450,7 @@ static int update_rx_queues(void) ...@@ -359,6 +450,7 @@ static int update_rx_queues(void)
udps = s; /* match with udp socket */ udps = s; /* match with udp socket */
} }
s = udps; s = udps;
if (!s) if (!s)
s = raws; s = raws;
if (!s) { if (!s) {
...@@ -397,8 +489,15 @@ static int update_rx_queues(void) ...@@ -397,8 +489,15 @@ static int update_rx_queues(void)
q->avail, q->n, q_required); q->avail, q->n, q_required);
return 1; return 1;
} }
DEFINE_WRC_TASK(net_bh) = { DEFINE_WRC_TASK(net_bh) = {
.name = "net-bh", .name = "net-bh",
.enable = &link_status, .enable = &link_status[0],
.job = update_rx_queues, .job = update_rx_queues,
}; };
DEFINE_WRC_TASK(dp_net_bh) = {
.name = "dp-net-bh",
.enable = &link_status[1],
.job = update_dp_rx_queues,
};
\ No newline at end of file
...@@ -20,11 +20,11 @@ struct wrs_shm_head *ppsi_head; ...@@ -20,11 +20,11 @@ struct wrs_shm_head *ppsi_head;
/* Following code from ptp-noposix/libposix/freestanding-wrapper.c */ /* Following code from ptp-noposix/libposix/freestanding-wrapper.c */
static int read_phase_val(struct hal_port_state *port) static int read_phase_val(struct hal_port_state *port, int ep_port)
{ {
int32_t dmtd_phase; int32_t dmtd_phase;
if (spll_read_ptracker(0, &dmtd_phase, NULL)) { if (spll_read_ptracker(ep_port, &dmtd_phase, NULL)) {
port->phase_val = dmtd_phase; port->phase_val = dmtd_phase;
port->phase_val_valid = 1; port->phase_val_valid = 1;
} else { } else {
...@@ -35,34 +35,36 @@ static int read_phase_val(struct hal_port_state *port) ...@@ -35,34 +35,36 @@ static int read_phase_val(struct hal_port_state *port)
return 0; return 0;
} }
extern uint32_t cal_phase_transition; extern uint32_t cal_phase_transition[2];
extern int32_t sfp_alpha[2];
int wrpc_get_port_state(struct hal_port_state *port, const char *port_name) int wrpc_get_port_state(struct hal_port_state *state, const char *port_name)
{ {
if (wrc_ptp_get_mode() == WRC_MODE_SLAVE) int port = atoi(&port_name[2]);
port->mode = HEXP_PORT_MODE_WR_SLAVE; int wrc_mode = wrc_ptp_get_mode();
else
port->mode = HEXP_PORT_MODE_WR_MASTER; if(port == 0)
if(wrc_mode == WRC_MODE_SLAVE)
state->mode = HEXP_PORT_MODE_WR_SLAVE;
else
state->mode = HEXP_PORT_MODE_WR_MASTER;
/* all deltas are added anyway */ /* all deltas are added anyway */
ep_get_deltas(&port->calib.delta_tx_board, ep_get_deltas(&state->calib.delta_tx_board, &state->calib.delta_rx_board, port);
&port->calib.delta_rx_board); state->calib.delta_tx_phy = 0;
port->calib.delta_tx_phy = 0; state->calib.delta_rx_phy = 0;
port->calib.delta_rx_phy = 0; state->calib.sfp.delta_tx_ps = 0;
port->calib.sfp.delta_tx_ps = 0; state->calib.sfp.delta_rx_ps = 0;
port->calib.sfp.delta_rx_ps = 0; read_phase_val(state,port);
read_phase_val(port); state->state = ep_link_up(NULL,port);
port->state = ep_link_up(NULL); state->calib.tx_calibrated = 1;
port->calib.tx_calibrated = 1; state->calib.rx_calibrated = 1;
port->calib.rx_calibrated = 1; state->locked = spll_check_lock(0);
port->locked = spll_check_lock(0); state->clock_period = REF_CLOCK_PERIOD_PS;
/* port->lock_priority = 0;*/ state->t2_phase_transition = cal_phase_transition[port];
/*spll_get_phase_shift(0, NULL, (int32_t *)&port->phase_setpoint);*/ state->t4_phase_transition = cal_phase_transition[port];
port->clock_period = REF_CLOCK_PERIOD_PS; get_mac_addr(state->hw_addr, port);
port->t2_phase_transition = cal_phase_transition; state->hw_index = 0;
port->t4_phase_transition = cal_phase_transition;
get_mac_addr(port->hw_addr);
port->hw_index = 0;
return 0; return 0;
} }
......
...@@ -218,7 +218,7 @@ static uint32_t aux_diag_reg_ro_num; ...@@ -218,7 +218,7 @@ static uint32_t aux_diag_reg_ro_num;
static uint32_t aux_diag_reg_rw_num; static uint32_t aux_diag_reg_rw_num;
extern struct pp_instance ppi_static; extern struct pp_instance ppi_static[wr_num_ports];
static struct wr_servo_state *wr_s_state; static struct wr_servo_state *wr_s_state;
extern char wrc_hw_name[HW_NAME_LENGTH]; extern char wrc_hw_name[HW_NAME_LENGTH];
...@@ -403,8 +403,8 @@ static struct snmp_oid oid_array_wrpcPtpGroup[] = { ...@@ -403,8 +403,8 @@ static struct snmp_oid oid_array_wrpcPtpGroup[] = {
OID_FIELD_STRUCT(oid_wrpcPtpClockOffsetErrCnt,get_pp, NO_SET, ASN_COUNTER, struct wr_servo_state, &wr_s_state, n_err_offset), OID_FIELD_STRUCT(oid_wrpcPtpClockOffsetErrCnt,get_pp, NO_SET, ASN_COUNTER, struct wr_servo_state, &wr_s_state, n_err_offset),
OID_FIELD_STRUCT(oid_wrpcPtpRTTErrCnt, get_pp, NO_SET, ASN_COUNTER, struct wr_servo_state, &wr_s_state, n_err_delta_rtt), OID_FIELD_STRUCT(oid_wrpcPtpRTTErrCnt, get_pp, NO_SET, ASN_COUNTER, struct wr_servo_state, &wr_s_state, n_err_delta_rtt),
OID_FIELD_VAR( oid_wrpcPtpAsymmetry, get_servo, NO_SET, ASN_COUNTER64, SERVO_ASYMMETRY), OID_FIELD_VAR( oid_wrpcPtpAsymmetry, get_servo, NO_SET, ASN_COUNTER64, SERVO_ASYMMETRY),
OID_FIELD_VAR( oid_wrpcPtpTX, get_p, NO_SET, ASN_COUNTER, &ppi_static.ptp_tx_count), OID_FIELD_VAR( oid_wrpcPtpTX, get_p, NO_SET, ASN_COUNTER, &ppi_static[0].ptp_tx_count),
OID_FIELD_VAR( oid_wrpcPtpRX, get_p, NO_SET, ASN_COUNTER, &ppi_static.ptp_rx_count), OID_FIELD_VAR( oid_wrpcPtpRX, get_p, NO_SET, ASN_COUNTER, &ppi_static[0].ptp_rx_count),
OID_FIELD_STRUCT(oid_wrpcPtpAlpha, get_pp, NO_SET, ASN_INTEGER, struct wr_servo_state, &wr_s_state, fiber_fix_alpha), OID_FIELD_STRUCT(oid_wrpcPtpAlpha, get_pp, NO_SET, ASN_INTEGER, struct wr_servo_state, &wr_s_state, fiber_fix_alpha),
{ 0, } { 0, }
}; };
...@@ -424,9 +424,9 @@ static struct snmp_oid oid_array_wrpcPtpConfigGroup[] = { ...@@ -424,9 +424,9 @@ static struct snmp_oid oid_array_wrpcPtpConfigGroup[] = {
static struct snmp_oid oid_array_wrpcPortGroup[] = { static struct snmp_oid oid_array_wrpcPortGroup[] = {
OID_FIELD_VAR( oid_wrpcPortLinkStatus, get_port, NO_SET, ASN_INTEGER, PORT_LINK_STATUS), OID_FIELD_VAR( oid_wrpcPortLinkStatus, get_port, NO_SET, ASN_INTEGER, PORT_LINK_STATUS),
OID_FIELD_VAR( oid_wrpcPortSfpPn, get_p, NO_SET, ASN_OCTET_STR, &sfp_pn), OID_FIELD_VAR( oid_wrpcPortSfpPn, get_p, NO_SET, ASN_OCTET_STR, &sfp_pn),
OID_FIELD_VAR( oid_wrpcPortSfpInDB, get_p, NO_SET, ASN_INTEGER, &sfp_in_db), OID_FIELD_VAR( oid_wrpcPortSfpInDB, get_p, NO_SET, ASN_INTEGER, &sfp_in_db[0]),
OID_FIELD_VAR( oid_wrpcPortInternalTX, get_p, NO_SET, ASN_COUNTER, &minic.tx_count), OID_FIELD_VAR( oid_wrpcPortInternalTX, get_p, NO_SET, ASN_COUNTER, &minic[0].tx_count),
OID_FIELD_VAR( oid_wrpcPortInternalRX, get_p, NO_SET, ASN_COUNTER, &minic.rx_count), OID_FIELD_VAR( oid_wrpcPortInternalRX, get_p, NO_SET, ASN_COUNTER, &minic[0].rx_count),
{ 0, } { 0, }
}; };
...@@ -474,10 +474,10 @@ static void snmp_init(void) ...@@ -474,10 +474,10 @@ static void snmp_init(void)
uint32_t aux_diag_ver; uint32_t aux_diag_ver;
/* Use UDP engine activated by function arguments */ /* Use UDP engine activated by function arguments */
snmp_socket = ptpd_netif_create_socket(&__static_snmp_socket, NULL, snmp_socket = ptpd_netif_create_socket(&__static_snmp_socket, NULL,
PTPD_SOCK_UDP, 161 /* snmp */); PTPD_SOCK_UDP, 161 /* snmp */, 0/*port*/);
/* TODO: check if pointer(s) is initialized already */ /* TODO: check if pointer(s) is initialized already */
wr_s_state = wr_s_state =
&((struct wr_data *)ppi_static.ext_data)->servo_state; &((struct wr_data *)ppi_static[0].ext_data)->servo_state;
if (SNMP_AUX_DIAG_ENABLED) { if (SNMP_AUX_DIAG_ENABLED) {
/* Fix ID and version of aux diag registers by values read from FPGA */ /* Fix ID and version of aux diag registers by values read from FPGA */
diag_read_info(&aux_diag_id, &aux_diag_ver, &aux_diag_reg_rw_num, diag_read_info(&aux_diag_id, &aux_diag_ver, &aux_diag_reg_rw_num,
...@@ -880,7 +880,7 @@ static int get_port(uint8_t *buf, struct snmp_oid *obj) ...@@ -880,7 +880,7 @@ static int get_port(uint8_t *buf, struct snmp_oid *obj)
switch ((int) obj->p) { switch ((int) obj->p) {
case (int)PORT_LINK_STATUS: case (int)PORT_LINK_STATUS:
/* overkill, since we need the link to be up to use SNMP */ /* overkill, since we need the link to be up to use SNMP */
tmp_int32 = 1 + ep_link_up(NULL); tmp_int32 = 1 + ep_link_up(NULL,0);
return get_value(buf, obj->asn, &tmp_int32); return get_value(buf, obj->asn, &tmp_int32);
default: default:
break; break;
...@@ -1052,7 +1052,7 @@ static int get_sfp(uint8_t *buf, struct snmp_oid *obj) ...@@ -1052,7 +1052,7 @@ static int get_sfp(uint8_t *buf, struct snmp_oid *obj)
col = obj->oid_match[TABLE_COL]; col = obj->oid_match[TABLE_COL];
snmp_verbose("%s: row%d, col%d\n", __func__, row, col); snmp_verbose("%s: row%d, col%d\n", __func__, row, col);
for (i = 1; i < sfpcount+1; ++i) { for (i = 1; i < sfpcount+1; ++i) {
sfpcount = storage_get_sfp(&sfp, SFP_GET, i - 1); sfpcount = storage_get_sfp(&sfp, SFP_GET, i - 1, 0);
if (sfpcount == 0) { if (sfpcount == 0) {
snmp_verbose("SFP database empty...\n"); snmp_verbose("SFP database empty...\n");
return 0; return 0;
...@@ -1249,8 +1249,8 @@ static int set_ptp_restart(uint8_t *buf, struct snmp_oid *obj) ...@@ -1249,8 +1249,8 @@ static int set_ptp_restart(uint8_t *buf, struct snmp_oid *obj)
switch (*restart_val) { switch (*restart_val) {
case restartPtp: case restartPtp:
snmp_verbose("%s: restart PTP\n", __func__); snmp_verbose("%s: restart PTP\n", __func__);
wrc_ptp_stop(); wrc_ptp_stop(0);
wrc_ptp_start(); wrc_ptp_start(0);
*restart_val = restartPtpSuccessful; *restart_val = restartPtpSuccessful;
break; break;
...@@ -1272,15 +1272,15 @@ static int set_ptp_config(uint8_t *buf, struct snmp_oid *obj) ...@@ -1272,15 +1272,15 @@ static int set_ptp_config(uint8_t *buf, struct snmp_oid *obj)
return ret; return ret;
switch (*apply_mode) { switch (*apply_mode) {
case writeToMemoryCurrentSfp: case writeToMemoryCurrentSfp:
sfp_deltaTx = snmp_ptp_config.dTx; sfp_deltaTx[0] = snmp_ptp_config.dTx;
sfp_deltaRx = snmp_ptp_config.dRx; sfp_deltaRx[0] = snmp_ptp_config.dRx;
sfp_alpha = snmp_ptp_config.alpha; sfp_alpha[0] = snmp_ptp_config.alpha;
/* Since ppsi does not support update of deltas in runtime, /* Since ppsi does not support update of deltas in runtime,
* we need to restart the ppsi */ * we need to restart the ppsi */
pp_printf("SNMP: SFP updated in memory, restart PTP\n"); pp_printf("SNMP: SFP updated in memory, restart PTP\n");
wrc_ptp_stop(); wrc_ptp_stop(0);
wrc_ptp_start(); wrc_ptp_start(0);
*apply_mode = applySuccessful; *apply_mode = applySuccessful;
break; break;
...@@ -1300,7 +1300,7 @@ static int set_ptp_config(uint8_t *buf, struct snmp_oid *obj) ...@@ -1300,7 +1300,7 @@ static int set_ptp_config(uint8_t *buf, struct snmp_oid *obj)
snmp_ptp_config.pn[temp++] = ' '; snmp_ptp_config.pn[temp++] = ' ';
/* add a sfp to the DB */ /* add a sfp to the DB */
temp = storage_get_sfp(&snmp_ptp_config, SFP_ADD, 0); temp = storage_get_sfp(&snmp_ptp_config, SFP_ADD, 0, 0);
if (temp == EE_RET_DBFULL) { if (temp == EE_RET_DBFULL) {
snmp_verbose("%s: SFP DB is full\n", __func__); snmp_verbose("%s: SFP DB is full\n", __func__);
*apply_mode = applyFailedDBFull; *apply_mode = applyFailedDBFull;
...@@ -1311,7 +1311,7 @@ static int set_ptp_config(uint8_t *buf, struct snmp_oid *obj) ...@@ -1311,7 +1311,7 @@ static int set_ptp_config(uint8_t *buf, struct snmp_oid *obj)
break; break;
} }
/* perform a sfp match */ /* perform a sfp match */
temp = sfp_match(); temp = sfp_match(0);
if (temp) { if (temp) {
snmp_verbose("%s: Match error (%d)\n", __func__, temp); snmp_verbose("%s: Match error (%d)\n", __func__, temp);
*apply_mode = applySuccessfulMatchFailed; *apply_mode = applySuccessfulMatchFailed;
...@@ -1321,7 +1321,7 @@ static int set_ptp_config(uint8_t *buf, struct snmp_oid *obj) ...@@ -1321,7 +1321,7 @@ static int set_ptp_config(uint8_t *buf, struct snmp_oid *obj)
*apply_mode = applySuccessful; *apply_mode = applySuccessful;
break; break;
case eraseFlash: case eraseFlash:
if (storage_sfpdb_erase() == EE_RET_I2CERR) if (storage_sfpdb_erase(0) == EE_RET_I2CERR)
*apply_mode = applyFailed; *apply_mode = applyFailed;
else else
*apply_mode = applySuccessful; *apply_mode = applySuccessful;
...@@ -1655,14 +1655,14 @@ static int snmp_poll(void) ...@@ -1655,14 +1655,14 @@ static int snmp_poll(void)
/* no need to wait for IP address: we won't get queries */ /* no need to wait for IP address: we won't get queries */
len = ptpd_netif_recvfrom(snmp_socket, &addr, len = ptpd_netif_recvfrom(snmp_socket, &addr,
buf, sizeof(buf), NULL); buf, sizeof(buf), NULL, 0/*port*/);
if (len <= UDP_END + sizeof(match_array)) if (len <= UDP_END + sizeof(match_array))
return 0; return 0;
/* Check the destination IP of SNMP packets. IP version, protocol and /* Check the destination IP of SNMP packets. IP version, protocol and
* port are checked in the function update_rx_queues, so no need to * port are checked in the function update_rx_queues, so no need to
* check it again */ * check it again */
if (check_dest_ip(buf)) { if (check_dest_ip(buf,0)) {
snmp_verbose("wrong destination IP\n"); snmp_verbose("wrong destination IP\n");
return 0; return 0;
} }
...@@ -1673,13 +1673,13 @@ static int snmp_poll(void) ...@@ -1673,13 +1673,13 @@ static int snmp_poll(void)
len += UDP_END; len += UDP_END;
fill_udp(buf, len, NULL); fill_udp(buf, len, NULL);
ptpd_netif_sendto(snmp_socket, &addr, buf, len, 0); ptpd_netif_sendto(snmp_socket, &addr, buf, len, 0 ,0/*port*/);
return 1; return 1;
} }
DEFINE_WRC_TASK(snmp) = { DEFINE_WRC_TASK(snmp) = {
.name = "snmp", .name = "snmp",
.enable = &link_status, .enable = &link_status[0],
.init = snmp_init, .init = snmp_init,
.job = snmp_poll, .job = snmp_poll,
}; };
...@@ -24,7 +24,7 @@ static uint32_t tics, tics_zero; ...@@ -24,7 +24,7 @@ static uint32_t tics, tics_zero;
void syslog_init(void) void syslog_init(void)
{ {
syslog_socket = ptpd_netif_create_socket(&__static_syslog_socket, NULL, syslog_socket = ptpd_netif_create_socket(&__static_syslog_socket, NULL,
PTPD_SOCK_UDP, 514 /* time */); PTPD_SOCK_UDP, 514 /* time */, 0/*port*/);
syslog_addr.sport = syslog_addr.dport = htons(514); syslog_addr.sport = syslog_addr.dport = htons(514);
tics_zero = timer_get_tics(); tics_zero = timer_get_tics();
} }
...@@ -76,7 +76,7 @@ static int syslog_header(char *buf, int level, unsigned char ip[4]) ...@@ -76,7 +76,7 @@ static int syslog_header(char *buf, int level, unsigned char ip[4])
int len; int len;
shw_pps_gen_get_time(&secs, NULL); shw_pps_gen_get_time(&secs, NULL);
getIP(ip); getIP(ip,0);
len = pp_sprintf(buf + UDP_END, "<%i> %s %s ", level, len = pp_sprintf(buf + UDP_END, "<%i> %s %s ", level,
format_time(secs, TIME_FORMAT_SYSLOG), format_time(secs, TIME_FORMAT_SYSLOG),
format_ip(b, ip)); format_ip(b, ip));
...@@ -90,7 +90,7 @@ static void syslog_send(void *buf, unsigned char *ip, int len) ...@@ -90,7 +90,7 @@ static void syslog_send(void *buf, unsigned char *ip, int len)
memcpy(&syslog_addr.saddr, ip, 4); memcpy(&syslog_addr.saddr, ip, 4);
fill_udp((void *)buf, len, &syslog_addr); fill_udp((void *)buf, len, &syslog_addr);
memcpy(&addr.mac, syslog_mac, 6); memcpy(&addr.mac, syslog_mac, 6);
ptpd_netif_sendto(syslog_socket, &addr, buf, len, 0); ptpd_netif_sendto(syslog_socket, &addr, buf, len, 0, 0/*port*/);
return; return;
} }
...@@ -120,7 +120,7 @@ int syslog_poll(void) ...@@ -120,7 +120,7 @@ int syslog_poll(void)
else else
s = &((struct wr_data *)ppi->ext_data)->servo_state; s = &((struct wr_data *)ppi->ext_data)->servo_state;
if (ip_status == IP_TRAINING) if (ip_status[0] == IP_TRAINING)
return 0; return 0;
if (!syslog_addr.daddr) if (!syslog_addr.daddr)
return 0; return 0;
...@@ -138,9 +138,9 @@ int syslog_poll(void) ...@@ -138,9 +138,9 @@ int syslog_poll(void)
goto send; goto send;
} }
if (link_status == LINK_WENT_DOWN) if (link_status[0] == LINK_WENT_DOWN)
down_tics = now; down_tics = now;
if (link_status == LINK_UP && down_tics) { if (link_status[0] == LINK_UP && down_tics) {
down_tics = now - down_tics; down_tics = now - down_tics;
len = syslog_header(buf, SYSLOG_DEFAULT_LEVEL, ip); len = syslog_header(buf, SYSLOG_DEFAULT_LEVEL, ip);
len += pp_sprintf(buf + len, "Link up after %i.%03i s", len += pp_sprintf(buf + len, "Link up after %i.%03i s",
...@@ -260,7 +260,7 @@ void syslog_report(const char *msg) ...@@ -260,7 +260,7 @@ void syslog_report(const char *msg)
unsigned char ip[4]; unsigned char ip[4];
int len; int len;
if (ip_status == IP_TRAINING) if (ip_status[0] == IP_TRAINING)
return; return;
if (!syslog_addr.daddr) if (!syslog_addr.daddr)
return; return;
......
...@@ -28,8 +28,8 @@ ...@@ -28,8 +28,8 @@
#define WRC_DIAG_REFRESH_PERIOD (1 * TICS_PER_SECOND) #define WRC_DIAG_REFRESH_PERIOD (1 * TICS_PER_SECOND)
extern struct pp_servo servo; extern struct pp_servo servo;
extern struct pp_instance ppi_static; extern struct pp_instance ppi_static[wr_num_ports];
struct pp_instance *ppi = &ppi_static; struct pp_instance *ppi = &ppi_static[0];
const char *ptp_unknown_str= "unknown"; const char *ptp_unknown_str= "unknown";
static void wrc_mon_std_servo(void); static void wrc_mon_std_servo(void);
...@@ -135,7 +135,7 @@ int wrc_mon_gui(void) ...@@ -135,7 +135,7 @@ int wrc_mon_gui(void)
else else
cprintf(C_RED, "Link down "); cprintf(C_RED, "Link down ");
minic_get_stats(&tx, &rx); minic_get_stats(&tx, &rx, 0);
cprintf(C_GREY, "(RX: %d, TX: %d)", rx, tx); cprintf(C_GREY, "(RX: %d, TX: %d)", rx, tx);
if (!state.state) { if (!state.state) {
...@@ -146,9 +146,9 @@ int wrc_mon_gui(void) ...@@ -146,9 +146,9 @@ int wrc_mon_gui(void)
uint8_t ip[4]; uint8_t ip[4];
cprintf(C_WHITE, " IPv4: "); cprintf(C_WHITE, " IPv4: ");
getIP(ip); getIP(ip, 0);
format_ip(buf, ip); format_ip(buf, ip);
switch (ip_status) { switch (ip_status[0]) {
case IP_TRAINING: case IP_TRAINING:
cprintf(C_RED, "BOOTP running"); cprintf(C_RED, "BOOTP running");
break; break;
...@@ -334,7 +334,7 @@ static int wrc_log_stats(void) ...@@ -334,7 +334,7 @@ static int wrc_log_stats(void)
shw_pps_gen_get_time(&sec, &nsec); shw_pps_gen_get_time(&sec, &nsec);
wrpc_get_port_state(&state, NULL); wrpc_get_port_state(&state, NULL);
minic_get_stats(&tx, &rx); minic_get_stats(&tx, &rx, 0);
pp_printf("lnk:%d rx:%d tx:%d ", state.state, rx, tx); pp_printf("lnk:%d rx:%d tx:%d ", state.state, rx, tx);
pp_printf("lock:%d ", state.locked ? 1 : 0); pp_printf("lock:%d ", state.locked ? 1 : 0);
pp_printf("ptp:%s ", wrc_ptp_state()); pp_printf("ptp:%s ", wrc_ptp_state());
...@@ -423,7 +423,7 @@ int wrc_wr_diags(void) ...@@ -423,7 +423,7 @@ int wrc_wr_diags(void)
wdiag_set_valid(0); wdiag_set_valid(0);
/* frame statistics */ /* frame statistics */
minic_get_stats(&tx, &rx); minic_get_stats(&tx, &rx, 0);
wdiags_write_cnts(tx,rx); wdiags_write_cnts(tx,rx);
/* local time */ /* local time */
......
This diff is collapsed.
ppsi @ 61d931c0
Subproject commit cb5934e8dac07c21572d335a5691ea714eeebf57 Subproject commit 61d931c09fc567f374621bc624f29ba2cd78c543
...@@ -23,23 +23,24 @@ ...@@ -23,23 +23,24 @@
static int cmd_calibration(const char *args[]) static int cmd_calibration(const char *args[])
{ {
uint32_t trans; uint32_t trans;
int port=0;
if (args[0] && !strcasecmp(args[0], "force")) { if (args[0] && !strcasecmp(args[0], "force")) {
if (measure_t24p(&trans) < 0) if (measure_t24p(&trans, port) < 0)
return -1; return -1;
return storage_phtrans(&trans, 1); return storage_phtrans(&trans, 1, port);
} else if (!args[0]) { } else if (!args[0]) {
if (storage_phtrans(&trans, 0) > 0) { if (storage_phtrans(&trans, 0, port) > 0) {
pp_printf("Found phase transition in EEPROM: %dps\n", pp_printf("Port %d Found phase transition in EEPROM: %dps\n",
trans); port, trans);
cal_phase_transition = trans; cal_phase_transition[port] = trans;
return 0; return 0;
} else { } else {
pp_printf("Measuring t2/t4 phase transition...\n"); pp_printf("Port %d Measuring t2/t4 phase transition...\n", port);
if (measure_t24p(&trans) < 0) if (measure_t24p(&trans, port) < 0)
return -1; return -1;
cal_phase_transition = trans; cal_phase_transition[port] = trans;
return storage_phtrans(&trans, 1); return storage_phtrans(&trans, 1, port);
} }
} }
......
...@@ -41,17 +41,20 @@ static int cmd_ip(const char *args[]) ...@@ -41,17 +41,20 @@ static int cmd_ip(const char *args[])
char buf[20]; char buf[20];
if (!args[0] || !strcasecmp(args[0], "get")) { if (!args[0] || !strcasecmp(args[0], "get")) {
getIP(ip); getIP(ip, 0);
getIP(ip, 1);
} else if (!strcasecmp(args[0], "set") && args[1]) { } else if (!strcasecmp(args[0], "set") && args[1]) {
ip_status = IP_OK_STATIC; ip_status[0] = IP_OK_STATIC;
decode_ip(args[1], ip); decode_ip(args[1], ip);
setIP(ip); setIP(ip, 0);
ip[3]=ip[3]+1;
setIP(ip, 1);
} else { } else {
return -EINVAL; return -EINVAL;
} }
format_ip(buf, ip); format_ip(buf, ip);
switch (ip_status) { switch (ip_status[0]) {
case IP_TRAINING: case IP_TRAINING:
pp_printf("IP-address: in training\n"); pp_printf("IP-address: in training\n");
break; break;
......
...@@ -36,12 +36,12 @@ DEFINE_WRC_COMMAND(devmem) = { ...@@ -36,12 +36,12 @@ DEFINE_WRC_COMMAND(devmem) = {
.exec = cmd_devmem, .exec = cmd_devmem,
}; };
extern struct pp_instance ppi_static; extern struct pp_instance ppi_static[wr_num_ports];
static int cmd_delays(const char *args[]) static int cmd_delays(const char *args[])
{ {
int tx, rx; int tx, rx;
struct wr_data *wrp = (void *)(ppi_static.ext_data); struct wr_data *wrp = (void *)(ppi_static[0].ext_data);
struct wr_servo_state *s = &wrp->servo_state; struct wr_servo_state *s = &wrp->servo_state;
if (args[0] && !args[1]) { if (args[0] && !args[1]) {
...@@ -51,11 +51,11 @@ static int cmd_delays(const char *args[]) ...@@ -51,11 +51,11 @@ static int cmd_delays(const char *args[])
if (args[1]) { if (args[1]) {
fromdec(args[0], &tx); fromdec(args[0], &tx);
fromdec(args[1], &rx); fromdec(args[1], &rx);
sfp_deltaTx = tx; sfp_deltaTx[0] = tx;
sfp_deltaRx = rx; sfp_deltaRx[0] = rx;
/* Change the active value too (add bislide here) */ /* Change the active value too (add bislide here) */
s->delta_tx_m = tx; s->delta_tx_m = tx;
s->delta_rx_m = rx + ep_get_bitslide(); s->delta_rx_m = rx + ep_get_bitslide(0);
} else { } else {
pp_printf("tx: %i rx: %i\n", sfp_deltaTx, sfp_deltaRx); pp_printf("tx: %i rx: %i\n", sfp_deltaTx, sfp_deltaRx);
} }
......
...@@ -45,15 +45,19 @@ static int cmd_mac(const char *args[]) ...@@ -45,15 +45,19 @@ static int cmd_mac(const char *args[])
if (!args[0] || !strcasecmp(args[0], "get")) { if (!args[0] || !strcasecmp(args[0], "get")) {
/* get current MAC */ /* get current MAC */
get_mac_addr(mac); get_mac_addr(mac, 0);
get_mac_addr(mac, 1);
} else if (!strcasecmp(args[0], "getp")) { } else if (!strcasecmp(args[0], "getp")) {
/* get persistent MAC */ /* get persistent MAC */
get_mac_addr(mac); get_mac_addr(mac, 0);
get_persistent_mac(ONEWIRE_PORT, mac); get_persistent_mac(ONEWIRE_PORT, mac);
} else if (!strcasecmp(args[0], "set") && args[1]) { } else if (!strcasecmp(args[0], "set") && args[1]) {
decode_mac(args[1], mac); decode_mac(args[1], mac);
set_mac_addr(mac); set_mac_addr(mac, 0);
pfilter_init_default(); pfilter_init_default(0);
mac[0]=mac[0]+1;
set_mac_addr(mac, 1);
pfilter_init_default(1);
} else if (!strcasecmp(args[0], "setp") && args[1]) { } else if (!strcasecmp(args[0], "setp") && args[1]) {
decode_mac(args[1], mac); decode_mac(args[1], mac);
set_persistent_mac(ONEWIRE_PORT, mac); set_persistent_mac(ONEWIRE_PORT, mac);
......
...@@ -34,7 +34,10 @@ ...@@ -34,7 +34,10 @@
static int cmd_sfp(const char *args[]) static int cmd_sfp(const char *args[])
{ {
int8_t sfpcount = 1, i, temp, ret; int8_t sfpcount[2] = {1,1};
int8_t i, temp, ret[2];
int port;
struct s_sfpinfo sfp; struct s_sfpinfo sfp;
if (!args[0]) { if (!args[0]) {
...@@ -42,7 +45,7 @@ static int cmd_sfp(const char *args[]) ...@@ -42,7 +45,7 @@ static int cmd_sfp(const char *args[])
return -EINVAL; return -EINVAL;
} }
if (!strcasecmp(args[0], "erase")) { if (!strcasecmp(args[0], "erase")) {
if (storage_sfpdb_erase() == EE_RET_I2CERR) { if (storage_sfpdb_erase(0) == EE_RET_I2CERR) {
pp_printf("Could not erase DB\n"); pp_printf("Could not erase DB\n");
return -EIO; return -EIO;
} }
...@@ -56,7 +59,12 @@ static int cmd_sfp(const char *args[]) ...@@ -56,7 +59,12 @@ static int cmd_sfp(const char *args[])
sfp.dTx = atoi(args[2]); sfp.dTx = atoi(args[2]);
sfp.dRx = atoi(args[3]); sfp.dRx = atoi(args[3]);
sfp.alpha = atoi(args[4]); sfp.alpha = atoi(args[4]);
temp = storage_get_sfp(&sfp, SFP_ADD, 0);
if (args[5])
sfp.port = atoi(args[5]);
else
sfp.port = 0;
temp = storage_get_sfp(&sfp, SFP_ADD, 0, sfp.port);
if (temp == EE_RET_DBFULL) { if (temp == EE_RET_DBFULL) {
pp_printf("SFP DB is full\n"); pp_printf("SFP DB is full\n");
return -ENOSPC; return -ENOSPC;
...@@ -64,55 +72,54 @@ static int cmd_sfp(const char *args[]) ...@@ -64,55 +72,54 @@ static int cmd_sfp(const char *args[])
pp_printf("I2C error\n"); pp_printf("I2C error\n");
return -EIO; return -EIO;
} else if (temp < 0) { } else if (temp < 0) {
pp_printf("SFP database error (%d)\n", temp); pp_printf("Port %d SFP database error (%d)\n", sfp.port, temp);
return -EFAULT; return -EFAULT;
} }
pp_printf("%d SFPs in DB\n", temp); pp_printf("Port %d has %d SFPs in DB\n", sfp.port, temp);
return 0; return 0;
} else if (!strcasecmp(args[0], "show")) { } else if (!strcasecmp(args[0], "show")) {
for (i = 0; i < sfpcount; ++i) { for (port = 0; port < 2; ++port) {
sfpcount = storage_get_sfp(&sfp, SFP_GET, i); sfpcount[port] = storage_get_sfp(&sfp, SFP_GET, i, port);
if (sfpcount == 0) { if (sfpcount[port] == 0) {
pp_printf("SFP database empty\n"); pp_printf("Port %d SFP database empty\n", port);
return 0; } else if (sfpcount[port] < 0) {
} else if (sfpcount < 0) { pp_printf("Port %d SFP database error (%d)\n", port,
pp_printf("SFP database error (%d)\n", sfpcount[0]);
sfpcount); ret[port] = -EFAULT;
return -EFAULT; } else {
for (i = 0; i< sfpcount[0]; ++i) {
pp_printf("Port %d, SFP %d: PN:", port, i + 1);
for (temp = 0; temp < SFP_PN_LEN; ++temp)
pp_printf("%c", sfp.pn[temp]);
pp_printf(" dTx: %8d dRx: %8d alpha: %8d\n", sfp.dTx,
sfp.dRx, sfp.alpha);
}
} }
pp_printf("%d: PN:", i + 1);
for (temp = 0; temp < SFP_PN_LEN; ++temp)
pp_printf("%c", sfp.pn[temp]);
pp_printf(" dTx: %8d dRx: %8d alpha: %8d\n", sfp.dTx,
sfp.dRx, sfp.alpha);
} }
return 0; return (ret[0] || ret[1]);
} else if (!strcasecmp(args[0], "match")) { } else if (!strcasecmp(args[0], "match")) {
ret = sfp_match(); for (port = 0; port < 2; ++port) {
if (ret == -ENODEV) { ret[port] = sfp_match(port);
pp_printf("No SFP.\n"); if (ret[0] == -ENODEV)
return ret; pp_printf("Port %d No SFP.\n", port);
} else if (ret[0] == -EIO)
if (ret == -EIO) { pp_printf("Port %d SFP read error\n", port);
pp_printf("SFP read error\n"); else if (ret == -ENXIO)
return ret; pp_printf("Port %d Could not match to DB\n", port);
else {
/* match successful */
pp_printf("\nPort %d SFP matched, dTx=%d dRx=%d alpha=%d\n",
port, sfp_deltaTx[0], sfp_deltaRx[0], sfp_alpha[0]);
}
} }
return (ret[0] || ret[1]);
/* SFP read correctly */
for (temp = 0; temp < SFP_PN_LEN; ++temp)
pp_printf("%c", sfp_pn[temp]);
pp_printf("\n");
if (ret == -ENXIO) {
pp_printf("Could not match to DB\n");
return ret;
}
/* match successful */
pp_printf("SFP matched, dTx=%d dRx=%d alpha=%d\n",
sfp_deltaTx, sfp_deltaRx, sfp_alpha);
return ret;
} else if (args[1] && !strcasecmp(args[0], "ena")) { } else if (args[1] && !strcasecmp(args[0], "ena")) {
ep_sfp_enable(atoi(args[1])); if (args[2])
sfp.port = atoi(args[2]);
else
sfp.port = 0;
ep_sfp_enable(atoi(args[1]), sfp.port);
return 0; return 0;
} else { } else {
pp_printf("Wrong parameter\n"); pp_printf("Wrong parameter\n");
......
...@@ -28,7 +28,8 @@ static int cmd_stat(const char *args[]) ...@@ -28,7 +28,8 @@ static int cmd_stat(const char *args[])
/* arguments: bts, on, off */ /* arguments: bts, on, off */
if (!strcasecmp(args[0], "bts")) { if (!strcasecmp(args[0], "bts")) {
pp_printf("%d ps\n", ep_get_bitslide()); pp_printf("port 0 %d ps\n", ep_get_bitslide(0));
pp_printf("port 1 %d ps\n", ep_get_bitslide(1));
} else if (!strcasecmp(args[0], "on")) { } else if (!strcasecmp(args[0], "on")) {
wrc_stat_running = 1; wrc_stat_running = 1;
wrc_stats_last--; /* force a line to be printed */ wrc_stats_last--; /* force a line to be printed */
......
...@@ -25,10 +25,12 @@ static int cmd_vlan(const char *args[]) ...@@ -25,10 +25,12 @@ static int cmd_vlan(const char *args[])
return -EINVAL; return -EINVAL;
} }
wrc_vlan_number = i; wrc_vlan_number = i;
pfilter_init_default(); pfilter_init_default(0);
pfilter_init_default(1);
} else if (!strcasecmp(args[0], "off")) { } else if (!strcasecmp(args[0], "off")) {
wrc_vlan_number = 0; wrc_vlan_number = 0;
pfilter_init_default(); pfilter_init_default(0);
pfilter_init_default(1);
} else { } else {
return -EINVAL; return -EINVAL;
......
...@@ -43,7 +43,7 @@ int wrc_ui_refperiod = TICS_PER_SECOND; /* 1 sec */ ...@@ -43,7 +43,7 @@ int wrc_ui_refperiod = TICS_PER_SECOND; /* 1 sec */
int wrc_phase_tracking = 1; int wrc_phase_tracking = 1;
char wrc_hw_name[HW_NAME_LENGTH]; char wrc_hw_name[HW_NAME_LENGTH];
uint32_t cal_phase_transition = 2389; uint32_t cal_phase_transition[wr_num_ports] = {2389,2389};
int wrc_vlan_number = CONFIG_VLAN_NR; int wrc_vlan_number = CONFIG_VLAN_NR;
...@@ -53,8 +53,8 @@ uint32_t print_task_time_threshold = CONFIG_DEFAULT_PRINT_TASK_TIME_THRESHOLD; ...@@ -53,8 +53,8 @@ uint32_t print_task_time_threshold = CONFIG_DEFAULT_PRINT_TASK_TIME_THRESHOLD;
static void wrc_initialize(void) static void wrc_initialize(void)
{ {
uint8_t mac_addr[6]; int port;
uint8_t mac_addr[wr_num_ports][6];
sdb_find_devices(); sdb_find_devices();
uart_init_hw(); uart_init_hw();
...@@ -76,32 +76,54 @@ static void wrc_initialize(void) ...@@ -76,32 +76,54 @@ static void wrc_initialize(void)
/*init storage (Flash / W1 EEPROM / I2C EEPROM*/ /*init storage (Flash / W1 EEPROM / I2C EEPROM*/
storage_init(WRPC_FMC_I2C, FMC_EEPROM_ADR); storage_init(WRPC_FMC_I2C, FMC_EEPROM_ADR);
if (get_persistent_mac(ONEWIRE_PORT, mac_addr) == -1) { if (get_persistent_mac(ONEWIRE_PORT, mac_addr[0]) == -1) {
pp_printf("Unable to determine MAC address\n"); pp_printf("Unable to determine MAC address\n");
mac_addr[0] = 0x22; /* mac_addr[0][0] = 0x22; /*
mac_addr[1] = 0x33; * mac_addr[0][1] = 0x33; *
mac_addr[2] = 0x44; * fallback MAC if get_persistent_mac fails mac_addr[0][2] = 0x44; * fallback MAC if get_persistent_mac fails
mac_addr[3] = 0x55; * mac_addr[0][3] = 0x55; *
mac_addr[4] = 0x66; * mac_addr[0][4] = 0x66; *
mac_addr[5] = 0x77; */ mac_addr[0][5] = 0x77; */
mac_addr[1][0] = 0x23; /*
mac_addr[1][1] = 0x33; *
mac_addr[1][2] = 0x44; * fallback MAC if get_persistent_mac fails
mac_addr[1][3] = 0x55; *
mac_addr[1][4] = 0x66; *
mac_addr[1][5] = 0x77; */
} else {
mac_addr[1][0]=mac_addr[0][0]+1;
mac_addr[1][1]=mac_addr[0][1];
mac_addr[1][2]=mac_addr[0][2];
mac_addr[1][3]=mac_addr[0][3];
mac_addr[1][4]=mac_addr[0][4];
mac_addr[1][5]=mac_addr[0][5];
} }
pp_printf("Local MAC address: %02x:%02x:%02x:%02x:%02x:%02x\n", pp_printf("PORT 0 Local MAC address: %02x:%02x:%02x:%02x:%02x:%02x\n",
mac_addr[0], mac_addr[1], mac_addr[2], mac_addr[3], mac_addr[0][0], mac_addr[0][1], mac_addr[0][2], mac_addr[0][3],
mac_addr[4], mac_addr[5]); mac_addr[0][4], mac_addr[0][5]);
pp_printf("PORT 1 Local MAC address: %02x:%02x:%02x:%02x:%02x:%02x\n",
mac_addr[1][0], mac_addr[1][1], mac_addr[1][2], mac_addr[1][3],
mac_addr[1][4], mac_addr[1][5]);
net_rst(); net_rst();
ep_init(mac_addr); //Duplicate the configuration for both ports.
/* Sleep for 1s to make sure WRS v4.2 always realizes that for (port=0; port<wr_num_ports;port++)
* the link is down */ {
timer_delay_ms(200); ep_init(mac_addr[port], port);
ep_enable(1, 1); /* Sleep for 1s to make sure WRS v4.2 always realizes that
* the link is down */
timer_delay_ms(200);
ep_enable(1, 1, port);
minic_init(port);
}
minic_init();
shw_pps_gen_init(); shw_pps_gen_init();
wrc_ptp_init(); wrc_ptp_init();
/* try reading t24 phase transition from EEPROM */ /* try reading t24 phase transition from EEPROM */
calib_t24p(WRC_MODE_MASTER, &cal_phase_transition); for (port=0; port<wr_num_ports;port++)
calib_t24p(WRC_MODE_MASTER, &cal_phase_transition[port],port);
spll_very_init(); spll_very_init();
usleep_init(); usleep_init();
shell_init(); shell_init();
...@@ -110,7 +132,8 @@ static void wrc_initialize(void) ...@@ -110,7 +132,8 @@ static void wrc_initialize(void)
_endram = ENDRAM_MAGIC; _endram = ENDRAM_MAGIC;
wrc_ptp_set_mode(WRC_MODE_SLAVE); wrc_ptp_set_mode(WRC_MODE_SLAVE);
wrc_ptp_start(); wrc_ptp_start(0);
wrc_ptp_start(1);
shw_pps_gen_get_time(NULL, &prev_nanos_for_profile); shw_pps_gen_get_time(NULL, &prev_nanos_for_profile);
/* get tics */ /* get tics */
prev_ticks_for_profile = timer_get_tics(); prev_ticks_for_profile = timer_get_tics();
...@@ -121,34 +144,54 @@ DEFINE_WRC_TASK0(idle) = { ...@@ -121,34 +144,54 @@ DEFINE_WRC_TASK0(idle) = {
.init = wrc_initialize, .init = wrc_initialize,
}; };
int link_status; uint8_t link_status[wr_num_ports];
static int wrc_check_link(void) static int wrc_check_link(void)
{ {
static int prev_state = 0; static int prev_state[wr_num_ports] = {-1,-1};
int state = ep_link_up(NULL); int state[wr_num_ports];
int rv = 0; int rv = 0;
int port;
for(port=0; port<wr_num_ports; port++)
state[port] = ep_link_up(NULL, port);
if (!prev_state && state) { if (!prev_state[0] && state[0]) {
wrc_verbose("Link up.\n"); wrc_verbose("Port 0 Link up.\n");
gpio_out(GPIO_LED_LINK, 1); gpio_out(GPIO_LED_LINK, 1);
sfp_match(); sfp_match(0);
wrc_ptp_start(); wrc_ptp_start(0);
link_status = LINK_WENT_UP; link_status[0] = LINK_WENT_UP;
rv = 1; rv = 1;
} else if (prev_state && !state) { } else if (prev_state[0] && !state[0]) {
wrc_verbose("Link down.\n"); wrc_verbose("Port 0 Link down.\n");
gpio_out(GPIO_LED_LINK, 0); gpio_out(GPIO_LED_LINK, 0);
link_status = LINK_WENT_DOWN; link_status[0] = LINK_WENT_DOWN;
wrc_ptp_stop(); wrc_ptp_stop(0);
rv = 1; rv = 1;
/* special case */ /* special case */
spll_init(SPLL_MODE_FREE_RUNNING_MASTER, 0, 1); spll_init(SPLL_MODE_FREE_RUNNING_MASTER, 0, 1);
shw_pps_gen_enable_output(0); shw_pps_gen_enable_output(0);
} else } else
link_status = (state ? LINK_UP : LINK_DOWN); link_status[0] = (state[0] ? LINK_UP : LINK_DOWN);
prev_state = state; prev_state[0] = state[0];
if (!prev_state[1] && state[1]) {
wrc_verbose("Port 1 Link up.\n");
gpio_out(GPIO_DP_LED_LINK, 1);
sfp_match(1);
wrc_ptp_start(1);
link_status[1] = LINK_WENT_UP;
rv = 1;
} else if (prev_state[1] && !state[1]) {
wrc_verbose("Port 1 Link down.\n");
gpio_out(GPIO_DP_LED_LINK, 1);
link_status[1] = LINK_WENT_DOWN;
wrc_ptp_stop(1);
rv = 1;
} else
link_status[1] = (state[1] ? LINK_UP : LINK_DOWN);
prev_state[1] = state[1];
return rv; return rv;
} }
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment