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 @@
#include <libsdbfs.h>
/* The following pointers are exported */
unsigned char *BASE_MINIC;
unsigned char *BASE_EP;
unsigned char *BASE_MINIC[wr_num_ports];
unsigned char *BASE_EP[wr_num_ports];
unsigned char *BASE_SOFTPLL;
unsigned char *BASE_PPS_GEN;
unsigned char *BASE_SYSCON;
......@@ -65,8 +65,10 @@ struct wrc_device {
};
struct wrc_device devs[] = {
{&BASE_MINIC, VID_CERN, 0xab28633a},
{&BASE_EP, VID_CERN, 0x650c2d4f},
{&BASE_MINIC[0], VID_CERN, 0xab28633a},
{&BASE_MINIC[1], VID_CERN, 0xa224633b},
{&BASE_EP[0], VID_CERN, 0x650c2d4f},
{&BASE_EP[1], VID_CERN, 0x621c2d4e},
{&BASE_SOFTPLL, VID_CERN, 0x65158dc0},
{&BASE_PPS_GEN, VID_CERN, 0xde0d8ced},
{&BASE_SYSCON, VID_CERN, 0xff07fc47},
......
......@@ -59,7 +59,7 @@
#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;
......
......@@ -27,115 +27,115 @@
#define DMTD_AVG_SAMPLES 256
static int autoneg_enabled;
volatile struct EP_WB *EP;
volatile struct EP_WB *EP[wr_num_ports];
/* 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);
while ((EP->MDIO_ASR & EP_MDIO_ASR_READY) == 0) ;
return EP_MDIO_ASR_RDATA_R(EP->MDIO_ASR) & 0xffff;
EP[port]->MDIO_CR = EP_MDIO_CR_ADDR_W(location >> 2);
while ((EP[port]->MDIO_ASR & EP_MDIO_ASR_READY) == 0) ;
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_RW;
while ((EP->MDIO_ASR & EP_MDIO_ASR_READY) == 0) ;
while ((EP[port]->MDIO_ASR & EP_MDIO_ASR_READY) == 0) ;
}
/* 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[4] << 8)
| ((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]);
}
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[4] = (EP->MACL & 0x0000ff00) >> 8;
dev_addr[3] = (EP->MACL & 0x00ff0000) >> 16;
dev_addr[2] = (EP->MACL & 0xff000000) >> 24;
dev_addr[1] = (EP->MACH & 0x000000ff);
dev_addr[0] = (EP->MACH & 0x0000ff00) >> 8;
dev_addr[5] = (EP[port]->MACL & 0x000000ff);
dev_addr[4] = (EP[port]->MACL & 0x0000ff00) >> 8;
dev_addr[3] = (EP[port]->MACL & 0x00ff0000) >> 16;
dev_addr[2] = (EP[port]->MACL & 0xff000000) >> 24;
dev_addr[1] = (EP[port]->MACH & 0x000000ff);
dev_addr[0] = (EP[port]->MACH & 0x0000ff00) >> 8;
}
/* 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;
set_mac_addr(mac_addr);
ep_sfp_enable(1);
EP[port] = (volatile struct EP_WB *)BASE_EP[port];
set_mac_addr(mac_addr,port);
ep_sfp_enable(1,port);
if (!IS_WR_NODE_SIM){
*(unsigned int *)(0x62000) = 0x2; // reset network stuff (cleanup required!)
*(unsigned int *)(0x62000) = 0;
}
EP->ECR = 0; /* disable Endpoint */
EP->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->TSCR = EP_TSCR_EN_TXTS | EP_TSCR_EN_RXTS; /* Enable timestamping */
EP[port]->ECR = 0; /* disable Endpoint */
EP[port]->VCR0 = EP_VCR0_QMODE_W(3); /* disable VLAN unit - not used by WRPC */
EP[port]->RFCR = EP_RFCR_MRU_W(1518); /* Set the max RX packet size */
EP[port]->TSCR = EP_TSCR_EN_TXTS | EP_TSCR_EN_RXTS; /* Enable timestamping */
/* 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,
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;
if (!enabled) {
EP->ECR = 0;
EP[port]->ECR = 0;
return 0;
}
/* Disable the endpoint */
EP->ECR = 0;
EP[port]->ECR = 0;
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 */
pfilter_init_default();
pfilter_init_default(port);
/* 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;
/* 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 */
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)
timer_delay_ms(200);
pcs_write(MDIO_REG_MCR, MDIO_MCR_RESET); /* reset the PHY */
pcs_write(MDIO_REG_MCR, 0); /* reset the PHY */
pcs_write(MDIO_REG_MCR, MDIO_MCR_RESET,port); /* reset the PHY */
pcs_write(MDIO_REG_MCR, 0,port); /* reset the PHY */
/* 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;
if (autoneg)
mcr |= MDIO_MCR_ANENABLE | MDIO_MCR_ANRESTART;
pcs_write(MDIO_REG_MCR, mcr);
pcs_write(MDIO_REG_MCR, mcr,port);
return 0;
}
/* Checks the link status. If the link is up, returns non-zero
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;
volatile uint16_t msr;
......@@ -143,70 +143,70 @@ int ep_link_up(uint16_t * lpa)
if (autoneg_enabled)
flags |= MDIO_MSR_ANEGCOMPLETE;
msr = pcs_read(MDIO_REG_MSR);
msr = pcs_read(MDIO_REG_MSR); /* Read this flag twice to make sure the status is updated */
msr = pcs_read(MDIO_REG_MSR,port);
msr = pcs_read(MDIO_REG_MSR,port); /* Read this flag twice to make sure the status is updated */
if (lpa)
*lpa = pcs_read(MDIO_REG_LPA);
*lpa = pcs_read(MDIO_REG_LPA,port);
return (msr & flags) == flags ? 1 : 0;
}
int ep_get_bitslide()
int ep_get_bitslide(int port)
{
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. */
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
should be added here */
*delta_tx = sfp_deltaTx;
*delta_tx = sfp_deltaTx[port];
*delta_rx =
sfp_deltaRx +
sfp_deltaRx[port] +
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;
}
int ep_cal_pattern_enable()
int ep_cal_pattern_enable(int port)
{
uint32_t val;
val = pcs_read(MDIO_REG_WR_SPEC);
val = pcs_read(MDIO_REG_WR_SPEC,port);
val |= MDIO_WR_SPEC_TX_CAL;
pcs_write(MDIO_REG_WR_SPEC, val);
pcs_write(MDIO_REG_WR_SPEC, val,port);
return 0;
}
int ep_cal_pattern_disable()
int ep_cal_pattern_disable(int port)
{
uint32_t val;
val = pcs_read(MDIO_REG_WR_SPEC);
val = pcs_read(MDIO_REG_WR_SPEC,port);
val &= (~MDIO_WR_SPEC_TX_CAL);
pcs_write(MDIO_REG_WR_SPEC, val);
pcs_write(MDIO_REG_WR_SPEC, val,port);
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);
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;
val = pcs_read(MDIO_REG_ECTRL);
val = pcs_read(MDIO_REG_ECTRL,port);
if(ena)
val &= (~MDIO_ECTRL_SFP_TX_DISABLE);
else
val |= MDIO_ECTRL_SFP_TX_DISABLE;
pcs_write(MDIO_REG_ECTRL, val);
pcs_write(MDIO_REG_ECTRL, val,port);
return 0;
}
......@@ -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)
{
......@@ -52,7 +52,7 @@ static uint32_t swap32(uint32_t v)
return res;
}
void pfilter_init_default(void)
void pfilter_init_default(int port)
{
struct rule_set *s;
uint8_t mac[6];
......@@ -60,7 +60,7 @@ void pfilter_init_default(void)
uint32_t m, *vini, *vend, *v, *v_vlan = NULL;
uint64_t cmd_word;
int i;
static int inited;
static int inited[2];
uint32_t latency_ethtype = CONFIG_LATENCY_ETHTYPE;
/* If vlan, use rule-set 1, else rule-set 0 */
......@@ -92,20 +92,20 @@ void pfilter_init_default(void)
* 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
*/
if (!inited) {
if (!inited[port]) {
if ( (((v[2] >> 13) & 0xffff) != 0x1234)
|| (((v[4] >> 13) & 0xffff) != 0x5678)
|| (((v[6] >> 13) & 0xffff) != 0x9abc)) {
pp_printf("pfilter: wrong rule-set, can't apply\n");
return;
}
inited++;
inited[port]++;
}
/*
* Patch the local MAC address in place,
* in the first three instructions after NOP
*/
get_mac_addr(mac);
get_mac_addr(mac,port);
v[2] &= ~(0xffff << 13);
v[4] &= ~(0xffff << 13);
v[6] &= ~(0xffff << 13);
......@@ -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++) {
uint32_t cr0, cr1;
......@@ -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) |
EP_PFCR0_MM_WRITE_MASK;
EP->PFCR1 = cr1;
EP->PFCR0 = cr0;
EP[port]->PFCR1 = cr1;
EP[port]->PFCR0 = cr0;
}
/* Restore the 0xaaa vlan number, so we can re-patch next time */
......@@ -177,5 +177,5 @@ void pfilter_init_default(void)
v[4] |= 0x5678 << 13;
v[6] |= 0x9abc << 13;
EP->PFCR0 = EP_PFCR0_ENABLE;
EP[port]->PFCR0 = EP_PFCR0_ENABLE;
}
......@@ -31,37 +31,39 @@
#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
#define EXPLODE_WR_TIMESTAMP(raw, rc, fc) \
rc = (raw) & 0xfffffff; \
fc = (raw >> 28) & 0xf;
struct wr_minic minic;
struct wr_minic minic[wr_num_ports];
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_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,
uint8_t *full)
uint8_t *full, int port)
{
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);
*data = (uint16_t) MINIC_RX_FIFO_DAT_R(rx);
if (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;
}
void minic_init()
void minic_init(int port)
{
uint32_t mcr;
/* 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) {
pp_printf("Error: Minic HDL version %d not supported by sw\n",
MINIC_MCR_VER_R(mcr));
......@@ -86,31 +88,31 @@ void minic_init()
/* disable interrupts, driver does polling */
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 */
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;
if (!ver_supported)
return 0;
mcr = minic_readl(MINIC_REG_MCR);
mcr = minic_readl(MINIC_REG_MCR, port);
return (mcr & MINIC_MCR_RX_EMPTY) ? 0 : 1;
}
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 raw_ts;
......@@ -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 */
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;
hdr_size = 0;
......@@ -135,7 +137,7 @@ int minic_rx_frame(struct wr_ethhdr *hdr, uint8_t * payload, uint32_t buf_size,
ptr16_payload = (uint16_t *)payload;
/* Read the whole frame till OOB or till the FIFO is empty */
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) {
/* reading header */
......@@ -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;
else if (oob_cnt == 2)
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++;
}
......@@ -211,9 +213,9 @@ int minic_rx_frame(struct wr_ethhdr *hdr, uint8_t * payload, uint32_t buf_size,
}
/* 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");
/* 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,
}
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;
uint8_t ts_valid;
......@@ -244,44 +246,44 @@ int minic_tx_frame(struct wr_ethhdr_vlan *hdr, uint8_t *payload, uint32_t size,
d_hdr = 0;
/* 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 */
ptr = (uint16_t *)hdr;
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) */
ptr = (uint16_t *)payload;
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) */
if (size % 2 == 0)
minic_txword(WRF_DATA, ptr[i]);
minic_txword(WRF_DATA, ptr[i], port);
else
minic_txword(WRF_BYTESEL, ptr[i]);
minic_txword(WRF_BYTESEL, ptr[i], port);
/* Write also OOB if needed */
if (hwts) {
minic_txword(WRF_OOB, TX_OOB);
minic_txword(WRF_OOB, WRPC_FID);
minic_txword(WRF_OOB, TX_OOB, port);
minic_txword(WRF_OOB, WRPC_FID, port);
}
/* 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");
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 */
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;
timer_delay_ms(1);
}
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) {
uint32_t raw_ts;
......@@ -292,7 +294,7 @@ int minic_tx_frame(struct wr_ethhdr_vlan *hdr, uint8_t *payload, uint32_t size,
/* wait for the timestamp */
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;
timer_delay_ms(1);
}
......@@ -301,21 +303,21 @@ int minic_tx_frame(struct wr_ethhdr_vlan *hdr, uint8_t *payload, uint32_t size,
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;
}
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);
raw_ts = minic_readl(MINIC_REG_TSR1);
fid = MINIC_TSR0_FID_R(minic_readl(MINIC_REG_TSR0));
raw_ts = minic_readl(MINIC_REG_TSR1, port);
fid = MINIC_TSR0_FID_R(minic_readl(MINIC_REG_TSR0, port));
if (fid != WRPC_FID) {
wrc_verbose("minic_tx_frame: unmatched fid %d vs %d\n",
fid, WRPC_FID);
wrc_verbose("minic_tx_frame: unmatched fid %d vs %d, port: %d\n",
fid, WRPC_FID, port);
}
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,
hwts->ahead = 0;
hwts->nsec = counter_r * (REF_CLOCK_PERIOD_PS / 1000);
minic.tx_count++;
minic[port].tx_count++;
}
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;
*rx_frames = minic.rx_count;
*tx_frames = minic[port].tx_count;
*rx_frames = minic[port].rx_count;
}
......@@ -122,7 +122,7 @@ static int cal_cur_phase;
ptpnetif's check lock function when the PLL has already locked, to avoid
complicating the API of ptp-noposix/ppsi. */
void rxts_calibration_start(void)
void rxts_calibration_start(uint8_t port)
{
cal_cur_phase = 0;
det_rising.prev_val = det_falling.prev_val = -1;
......@@ -136,7 +136,7 @@ void rxts_calibration_start(void)
/* Updates RX timestamper state machine. Non-zero return value means that
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;
......@@ -145,7 +145,7 @@ int rxts_calibration_update(uint32_t *t24p_value)
/* generate a fake RX timestamp and check if falling edge counter is
ahead of rising edge counter */
int flip = ep_timestamper_cal_pulse();
int flip = ep_timestamper_cal_pulse(port);
/* look for transitions (with deglitching) */
lookup_transition(&det_rising, flip, cal_cur_phase, 1);
......@@ -193,82 +193,82 @@ int rxts_calibration_update(uint32_t *t24p_value)
}
/* legacy function for 'calibration force' command */
int measure_t24p(uint32_t *value)
int measure_t24p(uint32_t *value, int port)
{
int rv;
pp_printf("Waiting for link...\n");
while (!ep_link_up(NULL))
while (!ep_link_up(NULL, port))
timer_delay_ms(100);
spll_init(SPLL_MODE_SLAVE, 0, 1);
spll_init(SPLL_MODE_SLAVE, port, 1);
pp_printf("Locking PLL...\n");
while (!spll_check_lock(0))
timer_delay_ms(100);
pp_printf("\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;
}
/* 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;
rv = storage_phtrans(value, 0);
rv = storage_phtrans(value, 0, port);
if(rv < 0) {
pp_printf("Error %d while reading t24p from storage\n", 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;
}
/*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;
uint32_t prev;
int retries = 0;
while (!(rv = rxts_calibration_update(value))) {
if (retries > CALIB_RETRIES || ep_link_up(NULL) == LINK_DOWN)
while (!(rv = rxts_calibration_update(value,port))) {
if (retries > CALIB_RETRIES || ep_link_up(NULL, port) == LINK_DOWN)
return -1;
retries++;
}
if (rv < 0) {
/* 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:
* 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)) {
rv = storage_phtrans(value, 1);
rv = storage_phtrans(value, 1, port);
pp_printf("Wrote new t24p value: %d ps (%s)\n", *value,
rv < 0 ? "Failed" : "Success");
}
return 0;
}
int calib_t24p(int mode, uint32_t *value)
int calib_t24p(int mode, uint32_t *value, int port)
{
int ret;
if (mode == WRC_MODE_SLAVE)
ret = calib_t24p_slave(value);
ret = calib_t24p_slave(value, port);
else
ret = calib_t24p_master(value);
ret = calib_t24p_master(value, port);
//update phtrans value in socket struct
if (ret >= 0)
ptpd_netif_set_phase_transition(*value);
ptpd_netif_set_phase_transition(*value, port);
return ret;
}
......@@ -31,7 +31,9 @@
#define SDB_DEV_INIT 0x77722d69 /* wr-i (nit) */
#define SDB_DEV_MAC 0x6d61632d /* mac- (address) */
#define SDB_DEV_SFP 0x7366702d /* sfp- (database) */
#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 */
#define EEPROM_START_ADR 0
......@@ -316,7 +318,7 @@ int get_persistent_mac(uint8_t portnum, uint8_t *mac)
if (IS_HOST_PROCESS) {
/* we don't have sdb working, so get the real eth address */
get_mac_addr(mac);
get_mac_addr(mac, 0);
return 0;
}
......@@ -392,11 +394,16 @@ int set_persistent_mac(uint8_t portnum, uint8_t *mac)
/* Erase SFB database in the memory */
int32_t storage_sfpdb_erase(void)
int32_t storage_sfpdb_erase(int port)
{
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;
ret = sdbfs_ferase(&wrc_sdb, 0, wrc_sdb.f_len);
if (ret == wrc_sdb.f_len)
......@@ -418,7 +425,7 @@ static int sfp_valid(struct s_sfpinfo *sfp)
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;
struct s_sfpinfo tempsfp;
......@@ -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 *ptr;
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)
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;
/* Read how many SFPs are in the database, but only in the first
......@@ -495,7 +507,7 @@ out:
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 temp;
......@@ -506,7 +518,7 @@ static int storage_update_sfp(struct s_sfpinfo *sfp)
/* copy entries from flash to the memory, update entry if matched */
for (i = 0; i < sfpcount; ++i) {
dbsfp = &sfp_db[i];
sfpcount = sfp_entry(dbsfp, SFP_GET, i);
sfpcount = sfp_entry(dbsfp, SFP_GET, i, port);
if (sfpcount <= 0)
return sfpcount;
if (!strncmp(dbsfp->pn, sfp->pn, 16)) {
......@@ -518,7 +530,7 @@ static int storage_update_sfp(struct s_sfpinfo *sfp)
}
/* 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");
return -1;
}
......@@ -526,7 +538,7 @@ static int storage_update_sfp(struct s_sfpinfo *sfp)
/* add all SFPs */
for (i = 0; i < sfpcount; ++i) {
dbsfp = &sfp_db[i];
temp = sfp_entry(dbsfp, SFP_ADD, 0);
temp = sfp_entry(dbsfp, SFP_ADD, 0, port);
if (temp < 0) {
/* if error, return it */
return temp;
......@@ -535,35 +547,35 @@ static int storage_update_sfp(struct s_sfpinfo *sfp)
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;
if (oper == SFP_GET) {
/* 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
* first */
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");
return sfp_entry(sfp, SFP_ADD, 0);
return sfp_entry(sfp, SFP_ADD, 0, port);
}
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;
int8_t i;
struct s_sfpinfo dbsfp;
for (i = 0; i < sfpcount; ++i) {
sfpcount = sfp_entry(&dbsfp, SFP_GET, i);
sfpcount = sfp_entry(&dbsfp, SFP_GET, i, port);
if (sfpcount <= 0)
return sfpcount;
if (!strncmp(dbsfp.pn, sfp->pn, 16)) {
......@@ -581,12 +593,17 @@ int storage_match_sfp(struct s_sfpinfo *sfp)
* Phase transition ("calibration" file)
*/
#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;
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;
if (write) {
sdbfs_ferase(&wrc_sdb, 0, wrc_sdb.f_len);
......
......@@ -19,44 +19,48 @@
#include "storage.h"
/* Calibration data (from EEPROM if available) */
int32_t sfp_alpha = 73622176; /* default values if could not read EEPROM */
int32_t sfp_deltaTx = 0;
int32_t sfp_deltaRx = 0;
int32_t sfp_in_db = 0;
int32_t sfp_alpha[2] = {64398396,-64398396}; /* default values if could not read EEPROM */
int32_t sfp_deltaTx[2] = {0,0};
int32_t sfp_deltaRx[2] = {0,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;
uint8_t data, sum;
mi2c_init(WRPC_SFP_I2C);
uint8_t sfp_num;
mi2c_start(WRPC_SFP_I2C);
mi2c_put_byte(WRPC_SFP_I2C, 0xA0);
mi2c_put_byte(WRPC_SFP_I2C, 0x00);
mi2c_repeat_start(WRPC_SFP_I2C);
mi2c_put_byte(WRPC_SFP_I2C, 0xA1);
mi2c_get_byte(WRPC_SFP_I2C, &data, 1);
mi2c_stop(WRPC_SFP_I2C);
if (port==0) sfp_num = WRPC_SFP_I2C;
else sfp_num = WRPC_DP_SFP_I2C;
mi2c_init(sfp_num);
mi2c_start(sfp_num);
mi2c_put_byte(sfp_num, 0xA0);
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;
mi2c_start(WRPC_SFP_I2C);
mi2c_put_byte(WRPC_SFP_I2C, 0xA1);
mi2c_start(sfp_num);
mi2c_put_byte(sfp_num, 0xA1);
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;
if (i >= 40 && i <= 55) //Part Number
part_id[i - 40] = data;
}
mi2c_get_byte(WRPC_SFP_I2C, &data, 1); //final word, checksum
mi2c_stop(WRPC_SFP_I2C);
mi2c_get_byte(sfp_num, &data, 1); //final word, checksum
mi2c_stop(sfp_num);
if (sum == data)
return 0;
......@@ -64,26 +68,31 @@ static int sfp_read_part_id(char *part_id)
return -1;
}
int sfp_match(void)
int sfp_match(int port)
{
struct s_sfpinfo sfp;
sfp_pn[0] = '\0';
if (!sfp_present()) {
sfp_pn[port][0] = '\0';
if (!sfp_present(port)) {
return -ENODEV;
}
if (sfp_read_part_id(sfp_pn)) {
if (sfp_read_part_id(sfp_pn[port], port)) {
return -EIO;
}
strncpy(sfp.pn, sfp_pn, SFP_PN_LEN);
if (storage_match_sfp(&sfp) == 0) {
sfp_in_db = SFP_NOT_MATCHED;
return -ENXIO;
}
sfp_deltaTx = sfp.dTx;
sfp_deltaRx = sfp.dRx;
sfp_alpha = sfp.alpha;
sfp_in_db = SFP_MATCHED;
strncpy(sfp.pn, sfp_pn[port], SFP_PN_LEN);
if (storage_match_sfp(&sfp,port) == 1) {
if (sfp.port==port)
{
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_in_db[port] = SFP_NOT_MATCHED;
pp_printf("port %d SFP not matched!\n",port);
return -ENXIO;
}
......@@ -10,9 +10,10 @@
#include <errno.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_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;
......
......@@ -30,7 +30,7 @@ void tcpip_init(void)
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_LOW32), (uint8_t *)tcpip_mac_addr+2, 4);
......@@ -38,7 +38,7 @@ void tcpip_init(void)
tcpip_tx_dst_port(60000);
tcpip_tx_src_port(60000);
getIP(tmp_ip_addr);
getIP(tmp_ip_addr, 0);
// tcpip module, default IP
tcpip_ip_addr(tmp_ip_addr);
// tcpip module, default gateway & tx ip addr
......@@ -133,7 +133,7 @@ uint8_t tcpip_poll()
return 0;
tcpip_get_hisIP(ip);
send_arp(ip);
send_arp(ip, 0);
arp_count=0;
}
......
......@@ -20,5 +20,5 @@
#define ARP_TPA (ARP_THA+6)
#define ARP_END (ARP_TPA+4)
void send_arp(uint8_t * hisIP);
int send_arp(uint8_t * hisIP, int port);
#endif
......@@ -48,9 +48,9 @@ int board_update(void);
#else
# define BOARD_DIVIDE_DMTD_CLOCKS 1
#endif
#define BOARD_MAX_CHAN_REF 1
#define BOARD_MAX_CHAN_REF 2
#define BOARD_MAX_CHAN_AUX 2
#define BOARD_MAX_PTRACKERS 1
#define BOARD_MAX_PTRACKERS 2
#ifdef CONFIG_IP
#define HAS_IP 1
......
......@@ -19,19 +19,19 @@ typedef enum {
NOT = 7
} pfilter_op_t;
void ep_init(uint8_t mac_addr[]);
void get_mac_addr(uint8_t dev_addr[]);
void set_mac_addr(uint8_t dev_addr[]);
int ep_enable(int enabled, int autoneg);
int ep_link_up(uint16_t * lpa);
int ep_get_bitslide(void);
int ep_get_deltas(uint32_t * delta_tx, uint32_t * delta_rx);
int ep_get_psval(int32_t * psval);
int ep_cal_pattern_enable(void);
int ep_cal_pattern_disable(void);
int ep_timestamper_cal_pulse(void);
int ep_sfp_enable(int ena);
void ep_init(uint8_t mac_addr[],int port);
void get_mac_addr(uint8_t dev_addr[],int port);
void set_mac_addr(uint8_t dev_addr[],int port);
int ep_enable(int enabled, int autoneg,int port);
int ep_link_up(uint16_t * lpa,int port);
int ep_get_bitslide(int port);
int ep_get_deltas(uint32_t * delta_tx, uint32_t * delta_rx,int port);
int ep_get_psval(int32_t * psval,int port);
int ep_cal_pattern_enable(int port);
int ep_cal_pattern_disable(int port);
int ep_timestamper_cal_pulse(int port);
int ep_sfp_enable(int ena,int port);
void pfilter_init_default(void);
void pfilter_init_default(int port);
#endif
......@@ -8,8 +8,8 @@
#define SDB_ADDRESS 0x30000
extern unsigned char *BASE_MINIC;
extern unsigned char *BASE_EP;
extern unsigned char *BASE_MINIC[2];
extern unsigned char *BASE_EP[2];
extern unsigned char *BASE_SOFTPLL;
extern unsigned char *BASE_PPS_GEN;
extern unsigned char *BASE_SYSCON;
......
......@@ -3,7 +3,7 @@
* File : wrc_syscon_regs.h
* 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
THIS FILE WAS GENERATED BY wbgen2 FROM SOURCE FILE wrc_syscon_wb.wb
......@@ -90,6 +90,21 @@
/* definitions for field: SPI bitbanged MISO in reg: GPIO Set/Readback Register */
#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 field: Status LED in reg: GPIO Clear Register */
......@@ -104,10 +119,16 @@
/* definitions for field: FMC I2C bitbanged SDA in reg: GPIO Clear Register */
#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 */
#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)
/* definitions for field: SPI bitbanged SCLK in reg: GPIO Clear Register */
......@@ -119,6 +140,12 @@
/* definitions for field: SPI bitbanged MOSI in reg: GPIO Clear Register */
#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 field: Memory size in reg: Hardware Feature Register */
......
......@@ -21,10 +21,10 @@
#define TX_OOB 0x1000
void minic_init(void);
void minic_disable(void);
int minic_poll_rx(void);
void minic_get_stats(int *tx_frames, int *rx_frames);
void minic_init(int port);
void minic_disable(int port);
int minic_poll_rx(int port);
void minic_get_stats(int *tx_frames, int *rx_frames, int port);
struct wr_ethhdr {
uint8_t dstmac[6];
......@@ -44,11 +44,11 @@ struct wr_minic {
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,
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,
struct hw_timestamp *hwts);
struct hw_timestamp *hwts, int port);
#endif
......@@ -18,7 +18,7 @@
#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 */
extern int link_status;
extern uint8_t link_status[2];
#define LINK_DOWN 0
#define LINK_WENT_UP 1
#define LINK_WENT_DOWN 2
......@@ -86,7 +86,7 @@ PACKED struct wr_timestamp {
// to bind_addr.
struct wrpc_socket *ptpd_netif_create_socket(struct wrpc_socket *s,
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.
// 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,
// This value is later used for recovering the precise transmit timestamp.
// 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,
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.
// 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
// All RXed packets are timestamped and the timestamp
// is stored in rx_timestamp (unless it's NULL).
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.
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,
int32_t dmtd_phase,
int cntr_ahead, int transition_point,
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;
int wrpc_get_port_state(struct hal_port_state *port,
const char *port_name /* unused */);
int wrpc_get_port_state(struct hal_port_state *state,
const char *port_name);
#endif /* __PTPD_NETIF_H */
......@@ -10,9 +10,9 @@
#ifndef __RXTS_CALIBRATOR_H
#define __RXTS_CALIBRATOR_H
void rxts_calibration_start(void);
int rxts_calibration_update(uint32_t *t24p_value);
int measure_t24p(uint32_t *value);
int calib_t24p(int mode, uint32_t *value);
void rxts_calibration_start(uint8_t port);
int rxts_calibration_update(uint32_t *t24p_value, int port);
int measure_t24p(uint32_t *value, int port);
int calib_t24p(int mode, uint32_t *value, int port);
#endif
......@@ -16,14 +16,14 @@
#define SFP_GET 0
#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_alpha;
extern int32_t sfp_deltaTx;
extern int32_t sfp_deltaRx;
extern int32_t sfp_in_db[2];
extern int32_t sfp_alpha[2];
extern int32_t sfp_deltaTx[2];
extern int32_t sfp_deltaRx[2];
/* Match plugged SFP with a DB entry */
int sfp_match(void);
int sfp_match(int port);
#endif
......@@ -52,11 +52,12 @@
#define HAS_GENSDBFS 0
#endif
extern uint32_t cal_phase_transition;
extern uint32_t cal_phase_transition[2];
extern uint8_t has_eeprom;
struct s_sfpinfo {
char pn[SFP_PN_LEN];
uint8_t port;
int32_t alpha;
int32_t dTx;
int32_t dRx;
......@@ -65,11 +66,11 @@ struct s_sfpinfo {
void storage_init(int i2cif, int i2c_addr);
int storage_sfpdb_erase(void);
int storage_match_sfp(struct s_sfpinfo *sfp);
int storage_get_sfp(struct s_sfpinfo *sfp, uint8_t add, uint8_t pos);
int storage_sfpdb_erase(int port);
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 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_add(const char *args[]);
......
......@@ -81,9 +81,12 @@ struct SYSCON_WB {
/*GPIO pins*/
#define GPIO_LED_LINK SYSC_GPSR_LED_LINK
#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_BTN2 SYSC_GPSR_BTN2
#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_NCS SYSC_GPSR_SPI_NCS
#define GPIO_SPI_MOSI SYSC_GPSR_SPI_MOSI
......@@ -91,6 +94,7 @@ struct SYSCON_WB {
#define WRPC_FMC_I2C 0
#define WRPC_SFP_I2C 1
#define WRPC_DP_SFP_I2C 2
#define FMC_I2C_DELAY 15
#define SFP_I2C_DELAY 300
......@@ -100,7 +104,7 @@ struct s_i2c_if {
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);
......
......@@ -79,4 +79,7 @@ void rtipc_action(void);
/* div64.c, lifted from the linux kernel through pp_printf or ppsi */
extern uint32_t __div64_32(uint64_t *n, uint32_t base);
// CUTE DP
#define wr_num_ports 2
#endif /* __WRC_H__ */
......@@ -6,13 +6,14 @@
#define WRC_MODE_MASTER 2
#define WRC_MODE_SLAVE 3
#define WRC_MODE_ABSCAL 4
extern int ptp_mode;
int wrc_ptp_init(void);
int wrc_ptp_set_mode(int mode);
int wrc_ptp_get_mode(void);
int wrc_ptp_start(void);
int wrc_ptp_stop(void);
int wrc_ptp_start(int port);
int wrc_ptp_stop(int port);
int wrc_ptp_update(void);
#endif
......@@ -16,27 +16,30 @@
#include "arp.h"
#include "tcpip_config.h"
static uint8_t __arp_queue[128];
static struct wrpc_socket __static_arp_socket = {
.queue.buff = __arp_queue,
.queue.size = sizeof(__arp_queue),
static uint8_t __arp_queue[2][128];
static struct wrpc_socket __static_arp_socket[2] = {
{.queue.buff = __arp_queue[0],
.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)
{
struct wr_sockaddr saddr;
int port=0;
/* Configure socket filter */
memset(&saddr, 0, sizeof(saddr));
// memset(&saddr.mac, 0xFF, 6); /* Broadcast */
saddr.ethertype = htons(0x0806); /* ARP */
arp_socket = ptpd_netif_create_socket(&__static_arp_socket, &saddr,
PTPD_SOCK_RAW_ETHERNET, 0);
for(port = 0; port<wr_num_ports; ++port)
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 hisIP[4];
......@@ -46,10 +49,10 @@ static int process_arp(uint8_t * buf, int len)
return 0;
/* Is it ARP request targetting our IP? */
getIP(myIP, port);
if (buf[ARP_OPER + 0] != 0)
return 0;
getIP(myIP);
if ( ((buf[ARP_OPER + 1] != 1)||memcmp(buf + ARP_TPA, myIP, 4)) == 0 )
{
memcpy(hisMAC, buf + ARP_SHA, 6);
......@@ -68,7 +71,7 @@ static int process_arp(uint8_t * buf, int len)
buf[ARP_OPER + 0] = 0;
buf[ARP_OPER + 1] = 2;
// my MAC+IP
get_mac_addr(buf + ARP_SHA);
get_mac_addr(buf + ARP_SHA, port);
memcpy(buf + ARP_SPA, myIP, 4);
// his MAC+IP
memcpy(buf + ARP_THA, hisMAC, 6);
......@@ -93,22 +96,29 @@ static int arp_poll(void)
uint8_t buf[ARP_END + 100];
struct wr_sockaddr addr;
int len;
int port;
int ret;
if (ip_status == IP_TRAINING)
return 0; /* can't do ARP w/o an address... */
if ((len = ptpd_netif_recvfrom(arp_socket,
&addr, buf, sizeof(buf), 0)) > 0) {
if ((len = process_arp(buf, len)) > 0)
ptpd_netif_sendto(arp_socket, &addr, buf, len, 0);
return 1;
ret = 0;
for (port=0; port<wr_num_ports; ++port) {
if ((len = ptpd_netif_recvfrom(arp_socket[port],
&addr, buf, sizeof(buf), 0, port)) > 0)
{
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];
struct wr_sockaddr addr;
/* Configure socket filter */
memset(&addr.mac, 0xFF, 6); /* Broadcast */
......@@ -126,16 +136,16 @@ void send_arp(uint8_t * hisIP)
buf[ARP_OPER + 0] = 0;
buf[ARP_OPER + 1] = 1;
get_mac_addr(buf + ARP_SHA);
getIP(buf + ARP_SPA);
get_mac_addr(buf + ARP_SHA, port);
getIP(buf + ARP_SPA, port);
memset(buf + ARP_THA, 0x00, 6); /* Broadcast */
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) = {
.name = "arp",
.enable = &link_status,
.enable = &link_status[0],
.init = arp_init,
.job = arp_poll,
};
......@@ -40,7 +40,7 @@ int prepare_bootp(struct wr_sockaddr *addr, uint8_t * buf, int retry)
buf[BOOTP_HOPS] = 0;
/* 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 + 1] ^= buf[BOOTP_XID + 5];
buf[BOOTP_XID + 2] ^= (retry >> 8) & 0xFF;
......@@ -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_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_FILE, 0, 128); /* desired BOOTP file */
......@@ -81,7 +81,7 @@ int process_bootp(uint8_t * buf, int len)
uint8_t mac[6];
uint8_t ip[4];
get_mac_addr(mac);
get_mac_addr(mac, 0);
if (len != BOOTP_END)
return 0;
......@@ -92,10 +92,10 @@ int process_bootp(uint8_t * buf, int len)
if (memcmp(buf + BOOTP_CHADDR, mac, 6))
return 0;
ip_status = IP_OK_BOOTP;
setIP(buf + BOOTP_YIADDR);
ip_status[0] = IP_OK_BOOTP;
setIP(buf + BOOTP_YIADDR, 0);
getIP(ip);
getIP(ip, 0);
pp_printf("Discovered IP address (%d.%d.%d.%d)!\n",
ip[0], ip[1], ip[2], ip[3]);
......
......@@ -28,7 +28,7 @@
#define ICMP_CHECKSUM (ICMP_CODE+1)
#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;
uint8_t hisIP[4];
......@@ -36,7 +36,7 @@ int process_icmp(uint8_t * buf, int len)
uint16_t sum;
/* Is it IP targetting us? */
getIP(myIP);
getIP(myIP,port);
if (buf[IP_VERSION] != 0x45 || memcmp(buf + IP_DEST, myIP, 4))
return 0;
......
......@@ -19,26 +19,30 @@
#include "flash.h"
#include "tcpip_config.h"
enum ip_status ip_status = IP_TRAINING;
static uint8_t myIP[4];
enum ip_status ip_status[2] = {IP_TRAINING,IP_TRAINING};
static uint8_t myIP[2][4];
/* magic UDP is deadbeef */
const uint8_t magicUDP[4] ={0x62,0x65,0x65,0x66};
/* bootp: bigger buffer, UDP based */
static uint8_t __bootp_queue[512];
static struct wrpc_socket __static_bootp_socket = {
.queue.buff = __bootp_queue,
.queue.size = sizeof(__bootp_queue),
static uint8_t __bootp_queue[2][512];
static struct wrpc_socket __static_bootp_socket[2] = {
{.queue.buff = __bootp_queue[0],
.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 */
static uint8_t __icmp_queue[128];
static struct wrpc_socket __static_icmp_socket = {
.queue.buff = __icmp_queue,
.queue.size = sizeof(__icmp_queue),
static uint8_t __icmp_queue[2][128];
static struct wrpc_socket __static_icmp_socket[2] = {
{.queue.buff = __icmp_queue[0],
.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". */
static uint8_t __rdate_queue[96];
......@@ -83,23 +87,26 @@ static void ipv4_init(void)
struct wr_sockaddr saddr;
/* Bootp: use UDP engine activated by function arguments */
bootp_socket = ptpd_netif_create_socket(&__static_bootp_socket, NULL,
PTPD_SOCK_UDP, 68 /* bootpc */);
bootp_socket[0] = ptpd_netif_create_socket(&__static_bootp_socket[0], NULL,
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 */
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 */
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 */
memset(&saddr, 0, sizeof(saddr));
saddr.ethertype = htons(0x0800);
icmp_socket = ptpd_netif_create_socket(&__static_icmp_socket, &saddr,
PTPD_SOCK_RAW_ETHERNET, 0);
icmp_socket[0] = ptpd_netif_create_socket(&__static_icmp_socket[0], &saddr,
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();
}
......@@ -113,10 +120,10 @@ static int bootp_poll(void)
uint8_t buf[400];
int len, ret = 0;
len = ptpd_netif_recvfrom(bootp_socket, &addr,
buf, sizeof(buf), NULL);
len = ptpd_netif_recvfrom(bootp_socket[0], &addr,
buf, sizeof(buf), NULL, 0);
if (ip_status != IP_TRAINING)
if (ip_status[0] != IP_TRAINING)
return 0;
if (len > 0)
......@@ -126,29 +133,29 @@ static int bootp_poll(void)
return ret;
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;
}
static int icmp_poll(void)
static int icmp_poll(int port)
{
struct wr_sockaddr addr;
uint8_t buf[128];
int len;
len = ptpd_netif_recvfrom(icmp_socket, &addr,
buf, sizeof(buf), NULL);
len = ptpd_netif_recvfrom(icmp_socket[port], &addr,
buf, sizeof(buf), NULL, port);
if (len <= 0)
return 0;
if (ip_status == IP_TRAINING)
if (ip_status[port] == IP_TRAINING)
return 0;
/* check the destination IP */
if (check_dest_ip(buf))
if (check_dest_ip(buf, port))
return 0;
if ((len = process_icmp(buf, len)) > 0)
ptpd_netif_sendto(icmp_socket, &addr, buf, len, 0);
if ((len = process_icmp(buf, len, port)) > 0)
ptpd_netif_sendto(icmp_socket[port], &addr, buf, len, 0, port);
return 1;
}
......@@ -161,12 +168,12 @@ static int rdate_poll(void)
int len;
len = ptpd_netif_recvfrom(rdate_socket, &addr,
buf, sizeof(buf), NULL);
buf, sizeof(buf), NULL, 0/* port */);
if (len <= 0)
return 0;
/* check the destination IP */
if (check_dest_ip(buf))
if (check_dest_ip(buf,0))
return 0;
shw_pps_gen_get_time(&secs, NULL);
......@@ -177,7 +184,7 @@ static int rdate_poll(void)
memcpy(buf + UDP_END, &result, sizeof(result));
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;
}
......@@ -192,13 +199,13 @@ static int rmupdate_poll(void)
int data_size;
len = ptpd_netif_recvfrom(rmupdate_socket, &addr,
buf, sizeof(buf), NULL);
buf, sizeof(buf), NULL, 0);
if (len <= 0)
return 0;
/* check the destination IP */
if (check_dest_ip(buf))
if (check_dest_ip(buf, 0))
return 0;
if (check_magic_udp(buf)<0)
......@@ -260,7 +267,7 @@ static int rmupdate_poll(void)
}
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;
}
......@@ -268,11 +275,12 @@ static int ipv4_poll(void)
{
int ret = 0;
if (link_status == LINK_WENT_UP && ip_status == IP_OK_BOOTP)
ip_status = IP_TRAINING;
if (link_status[0] == LINK_WENT_UP && ip_status[0] == IP_OK_BOOTP)
ip_status[0] = IP_TRAINING;
ret = bootp_poll();
ret += icmp_poll();
ret += icmp_poll(0);
ret += icmp_poll(1);
ret += rdate_poll();
......@@ -283,38 +291,38 @@ static int ipv4_poll(void)
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) = {
.name = "ipv4",
.enable = &link_status,
.enable = &link_status[0],
.init = ipv4_init,
.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 =
// (unsigned int *)(BASE_ETHERBONE_CFG + EB_IPV4);
// unsigned int ip;
// while (*eb_ip != ip)
// *eb_ip = ip;
memcpy(myIP, IP, 4);
memcpy(myIP[port], IP, 4);
bootp_retry = 0;
}
/* 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)
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 */
......
......@@ -44,11 +44,11 @@ enum ip_status {
IP_OK_BOOTP,
IP_OK_STATIC,
};
extern enum ip_status ip_status;
void setIP(unsigned char *IP);
void getIP(unsigned char *IP);
extern enum ip_status ip_status[2];
void setIP(unsigned char *IP, int port);
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 prepare_bootp(struct wr_sockaddr *addr, uint8_t * buf, int retry);
......@@ -61,7 +61,7 @@ struct wr_udp_addr {
};
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);
void syslog_init(void);
......
......@@ -45,7 +45,7 @@ static void latency_init(void)
latency_addr.ethertype = htons(CONFIG_LATENCY_ETHTYPE);
latency_socket = ptpd_netif_create_socket(&__static_latency_socket,
&latency_addr,
PTPD_SOCK_RAW_ETHERNET, 0);
PTPD_SOCK_RAW_ETHERNET, 0, 0, 0/*port*/);
}
static struct latency_frame {
......@@ -129,7 +129,7 @@ static int latency_poll_rx(void)
int i, j;
i = ptpd_netif_recvfrom(latency_socket, &addr,
&frame, sizeof(frame), &ts_tmp);
&frame, sizeof(frame), &ts_tmp, 0/*port*/);
if (i < sizeof(frame))
return 0;
......@@ -225,7 +225,7 @@ static int latency_poll_tx(void)
frame.type = 1;
latency_socket->prio = prios[0];
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;
if (frame.ts[0].nsec < 0) {
frame.ts[0].nsec += 1000 * 1000 * 1000;
......@@ -235,7 +235,7 @@ static int latency_poll_tx(void)
frame.type = 2;
latency_socket->prio = prios[1];
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;
if (frame.ts[1].nsec < 0) {
frame.ts[1].nsec += 1000 * 1000 * 1000;
......@@ -245,7 +245,7 @@ static int latency_poll_tx(void)
frame.type = 3;
latency_socket->prio = prios[2];
ptpd_netif_sendto(latency_socket, &latency_addr, &frame, sizeof(frame),
NULL);
NULL, 0/*port*/);
ltest_fake_delay_ns = 0;
/* Every 10s remind we are sending ltest */
......
......@@ -255,7 +255,7 @@ static int lldp_poll(void)
/* Update only when IP or MAC changed */
/* TODO: or VLAN changed */
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))
) {
/* update LLDP info */
......
......@@ -24,40 +24,41 @@
#include "softpll_ng.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
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;
}
void ptpd_netif_set_phase_transition(uint32_t phase)
void ptpd_netif_set_phase_transition(uint32_t phase, int port)
{
int i;
for (i=0; i< ARRAY_SIZE(socks); ++i) {
socks[i]->phase_transition = phase;
for (i=0; i< ARRAY_SIZE(socks[port]); ++i) {
socks[port][i]->phase_transition = phase;
}
}
struct wrpc_socket *ptpd_netif_create_socket(struct wrpc_socket *sock,
struct wr_sockaddr * bind_addr,
int udp_or_raw, int udpport)
int udp_or_raw, int udpport, int port)
{
int i;
struct hal_port_state pstate;
const char *port_name;
/* Look for the first available socket. */
for (i = 0; i < ARRAY_SIZE(socks); i++)
if (!socks[i]) {
socks[i] = sock;
for (i = 0; i < ARRAY_SIZE(socks[port]); i++)
if (!socks[port][i]) {
socks[port][i] = sock;
break;
}
if (i == ARRAY_SIZE(socks)) {
if (i == ARRAY_SIZE(socks[port])) {
pp_printf("%s: no socket slots left\n", __func__);
return NULL;
}
......@@ -65,7 +66,9 @@ struct wrpc_socket *ptpd_netif_create_socket(struct wrpc_socket *sock,
sock, ntohs(bind_addr->ethertype),
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;
/* 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,
}
/*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->dmtd_phase = pstate.phase_val;
......@@ -92,12 +94,12 @@ struct wrpc_socket *ptpd_netif_create_socket(struct wrpc_socket *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;
for (i = 0; i < ARRAY_SIZE(socks); i++)
if (socks[i] == s)
socks[i] = NULL;
for (i = 0; i < ARRAY_SIZE(socks[port]); i++)
if (socks[port][i] == sock)
socks[port][i] = NULL;
return 0;
}
......@@ -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,
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;
......@@ -246,8 +248,8 @@ int ptpd_netif_recvfrom(struct wrpc_socket *s, struct wr_sockaddr *from, void *d
if (rx_timestamp) {
rx_timestamp->raw_nsec = hwts.nsec;
rx_timestamp->raw_ahead = hwts.ahead;
spll_busy = (uint8_t) spll_shifter_busy(0);
spll_read_ptracker(0, &rx_timestamp->raw_phase, NULL);
spll_busy = (uint8_t) spll_shifter_busy(port);
spll_read_ptracker(port, &rx_timestamp->raw_phase, NULL);
rx_timestamp->sec = hwts.sec;
rx_timestamp->nsec = hwts.nsec;
......@@ -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,
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 hw_timestamp hwts;
......@@ -294,7 +296,7 @@ int ptpd_netif_sendto(struct wrpc_socket * sock, struct wr_sockaddr *to, void *d
rval =
minic_tx_frame(&hdr, (uint8_t *) data,
data_length, &hwts);
data_length, &hwts, port);
if (tx_timestamp) {
......@@ -306,7 +308,7 @@ int ptpd_netif_sendto(struct wrpc_socket * sock, struct wr_sockaddr *to, void *d
return rval;
}
static int update_rx_queues(void)
static int update_rx_queues()
{
struct wrpc_socket *s = NULL, *raws = NULL, *udps = NULL;
struct sockq *q;
......@@ -320,7 +322,7 @@ static int update_rx_queues(void)
recvd =
minic_rx_frame(&hdr, buffer, sizeof(buffer),
&hwts);
&hwts, 0/*port*/);
if (recvd <= 0) /* No data received? */
return 0;
......@@ -347,8 +349,97 @@ static int update_rx_queues(void)
else
port = 0;
for (i = 0; i < ARRAY_SIZE(socks); i++) {
s = socks[i];
for (i = 0; i < ARRAY_SIZE(socks[0]); 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)
continue;
if (hdr.ethtype != s->bind_addr.ethertype)
......@@ -359,6 +450,7 @@ static int update_rx_queues(void)
udps = s; /* match with udp socket */
}
s = udps;
if (!s)
s = raws;
if (!s) {
......@@ -397,8 +489,15 @@ static int update_rx_queues(void)
q->avail, q->n, q_required);
return 1;
}
DEFINE_WRC_TASK(net_bh) = {
.name = "net-bh",
.enable = &link_status,
.enable = &link_status[0],
.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;
/* 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;
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_valid = 1;
} else {
......@@ -35,34 +35,36 @@ static int read_phase_val(struct hal_port_state *port)
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)
port->mode = HEXP_PORT_MODE_WR_SLAVE;
int port = atoi(&port_name[2]);
int wrc_mode = wrc_ptp_get_mode();
if(port == 0)
if(wrc_mode == WRC_MODE_SLAVE)
state->mode = HEXP_PORT_MODE_WR_SLAVE;
else
port->mode = HEXP_PORT_MODE_WR_MASTER;
state->mode = HEXP_PORT_MODE_WR_MASTER;
/* all deltas are added anyway */
ep_get_deltas(&port->calib.delta_tx_board,
&port->calib.delta_rx_board);
port->calib.delta_tx_phy = 0;
port->calib.delta_rx_phy = 0;
port->calib.sfp.delta_tx_ps = 0;
port->calib.sfp.delta_rx_ps = 0;
read_phase_val(port);
port->state = ep_link_up(NULL);
port->calib.tx_calibrated = 1;
port->calib.rx_calibrated = 1;
port->locked = spll_check_lock(0);
/* port->lock_priority = 0;*/
/*spll_get_phase_shift(0, NULL, (int32_t *)&port->phase_setpoint);*/
port->clock_period = REF_CLOCK_PERIOD_PS;
port->t2_phase_transition = cal_phase_transition;
port->t4_phase_transition = cal_phase_transition;
get_mac_addr(port->hw_addr);
port->hw_index = 0;
ep_get_deltas(&state->calib.delta_tx_board, &state->calib.delta_rx_board, port);
state->calib.delta_tx_phy = 0;
state->calib.delta_rx_phy = 0;
state->calib.sfp.delta_tx_ps = 0;
state->calib.sfp.delta_rx_ps = 0;
read_phase_val(state,port);
state->state = ep_link_up(NULL,port);
state->calib.tx_calibrated = 1;
state->calib.rx_calibrated = 1;
state->locked = spll_check_lock(0);
state->clock_period = REF_CLOCK_PERIOD_PS;
state->t2_phase_transition = cal_phase_transition[port];
state->t4_phase_transition = cal_phase_transition[port];
get_mac_addr(state->hw_addr, port);
state->hw_index = 0;
return 0;
}
......
......@@ -218,7 +218,7 @@ static uint32_t aux_diag_reg_ro_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;
extern char wrc_hw_name[HW_NAME_LENGTH];
......@@ -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_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_wrpcPtpTX, get_p, NO_SET, ASN_COUNTER, &ppi_static.ptp_tx_count),
OID_FIELD_VAR( oid_wrpcPtpRX, get_p, NO_SET, ASN_COUNTER, &ppi_static.ptp_rx_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[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),
{ 0, }
};
......@@ -424,9 +424,9 @@ static struct snmp_oid oid_array_wrpcPtpConfigGroup[] = {
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_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_wrpcPortInternalTX, get_p, NO_SET, ASN_COUNTER, &minic.tx_count),
OID_FIELD_VAR( oid_wrpcPortInternalRX, get_p, NO_SET, ASN_COUNTER, &minic.rx_count),
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[0].tx_count),
OID_FIELD_VAR( oid_wrpcPortInternalRX, get_p, NO_SET, ASN_COUNTER, &minic[0].rx_count),
{ 0, }
};
......@@ -474,10 +474,10 @@ static void snmp_init(void)
uint32_t aux_diag_ver;
/* Use UDP engine activated by function arguments */
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 */
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) {
/* 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,
......@@ -880,7 +880,7 @@ static int get_port(uint8_t *buf, struct snmp_oid *obj)
switch ((int) obj->p) {
case (int)PORT_LINK_STATUS:
/* 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);
default:
break;
......@@ -1052,7 +1052,7 @@ static int get_sfp(uint8_t *buf, struct snmp_oid *obj)
col = obj->oid_match[TABLE_COL];
snmp_verbose("%s: row%d, col%d\n", __func__, row, col);
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) {
snmp_verbose("SFP database empty...\n");
return 0;
......@@ -1249,8 +1249,8 @@ static int set_ptp_restart(uint8_t *buf, struct snmp_oid *obj)
switch (*restart_val) {
case restartPtp:
snmp_verbose("%s: restart PTP\n", __func__);
wrc_ptp_stop();
wrc_ptp_start();
wrc_ptp_stop(0);
wrc_ptp_start(0);
*restart_val = restartPtpSuccessful;
break;
......@@ -1272,15 +1272,15 @@ static int set_ptp_config(uint8_t *buf, struct snmp_oid *obj)
return ret;
switch (*apply_mode) {
case writeToMemoryCurrentSfp:
sfp_deltaTx = snmp_ptp_config.dTx;
sfp_deltaRx = snmp_ptp_config.dRx;
sfp_alpha = snmp_ptp_config.alpha;
sfp_deltaTx[0] = snmp_ptp_config.dTx;
sfp_deltaRx[0] = snmp_ptp_config.dRx;
sfp_alpha[0] = snmp_ptp_config.alpha;
/* Since ppsi does not support update of deltas in runtime,
* we need to restart the ppsi */
pp_printf("SNMP: SFP updated in memory, restart PTP\n");
wrc_ptp_stop();
wrc_ptp_start();
wrc_ptp_stop(0);
wrc_ptp_start(0);
*apply_mode = applySuccessful;
break;
......@@ -1300,7 +1300,7 @@ static int set_ptp_config(uint8_t *buf, struct snmp_oid *obj)
snmp_ptp_config.pn[temp++] = ' ';
/* 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) {
snmp_verbose("%s: SFP DB is full\n", __func__);
*apply_mode = applyFailedDBFull;
......@@ -1311,7 +1311,7 @@ static int set_ptp_config(uint8_t *buf, struct snmp_oid *obj)
break;
}
/* perform a sfp match */
temp = sfp_match();
temp = sfp_match(0);
if (temp) {
snmp_verbose("%s: Match error (%d)\n", __func__, temp);
*apply_mode = applySuccessfulMatchFailed;
......@@ -1321,7 +1321,7 @@ static int set_ptp_config(uint8_t *buf, struct snmp_oid *obj)
*apply_mode = applySuccessful;
break;
case eraseFlash:
if (storage_sfpdb_erase() == EE_RET_I2CERR)
if (storage_sfpdb_erase(0) == EE_RET_I2CERR)
*apply_mode = applyFailed;
else
*apply_mode = applySuccessful;
......@@ -1655,14 +1655,14 @@ static int snmp_poll(void)
/* no need to wait for IP address: we won't get queries */
len = ptpd_netif_recvfrom(snmp_socket, &addr,
buf, sizeof(buf), NULL);
buf, sizeof(buf), NULL, 0/*port*/);
if (len <= UDP_END + sizeof(match_array))
return 0;
/* Check the destination IP of SNMP packets. IP version, protocol and
* port are checked in the function update_rx_queues, so no need to
* check it again */
if (check_dest_ip(buf)) {
if (check_dest_ip(buf,0)) {
snmp_verbose("wrong destination IP\n");
return 0;
}
......@@ -1673,13 +1673,13 @@ static int snmp_poll(void)
len += UDP_END;
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;
}
DEFINE_WRC_TASK(snmp) = {
.name = "snmp",
.enable = &link_status,
.enable = &link_status[0],
.init = snmp_init,
.job = snmp_poll,
};
......@@ -24,7 +24,7 @@ static uint32_t tics, tics_zero;
void syslog_init(void)
{
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);
tics_zero = timer_get_tics();
}
......@@ -76,7 +76,7 @@ static int syslog_header(char *buf, int level, unsigned char ip[4])
int len;
shw_pps_gen_get_time(&secs, NULL);
getIP(ip);
getIP(ip,0);
len = pp_sprintf(buf + UDP_END, "<%i> %s %s ", level,
format_time(secs, TIME_FORMAT_SYSLOG),
format_ip(b, ip));
......@@ -90,7 +90,7 @@ static void syslog_send(void *buf, unsigned char *ip, int len)
memcpy(&syslog_addr.saddr, ip, 4);
fill_udp((void *)buf, len, &syslog_addr);
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;
}
......@@ -120,7 +120,7 @@ int syslog_poll(void)
else
s = &((struct wr_data *)ppi->ext_data)->servo_state;
if (ip_status == IP_TRAINING)
if (ip_status[0] == IP_TRAINING)
return 0;
if (!syslog_addr.daddr)
return 0;
......@@ -138,9 +138,9 @@ int syslog_poll(void)
goto send;
}
if (link_status == LINK_WENT_DOWN)
if (link_status[0] == LINK_WENT_DOWN)
down_tics = now;
if (link_status == LINK_UP && down_tics) {
if (link_status[0] == LINK_UP && down_tics) {
down_tics = now - down_tics;
len = syslog_header(buf, SYSLOG_DEFAULT_LEVEL, ip);
len += pp_sprintf(buf + len, "Link up after %i.%03i s",
......@@ -260,7 +260,7 @@ void syslog_report(const char *msg)
unsigned char ip[4];
int len;
if (ip_status == IP_TRAINING)
if (ip_status[0] == IP_TRAINING)
return;
if (!syslog_addr.daddr)
return;
......
......@@ -28,8 +28,8 @@
#define WRC_DIAG_REFRESH_PERIOD (1 * TICS_PER_SECOND)
extern struct pp_servo servo;
extern struct pp_instance ppi_static;
struct pp_instance *ppi = &ppi_static;
extern struct pp_instance ppi_static[wr_num_ports];
struct pp_instance *ppi = &ppi_static[0];
const char *ptp_unknown_str= "unknown";
static void wrc_mon_std_servo(void);
......@@ -135,7 +135,7 @@ int wrc_mon_gui(void)
else
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);
if (!state.state) {
......@@ -146,9 +146,9 @@ int wrc_mon_gui(void)
uint8_t ip[4];
cprintf(C_WHITE, " IPv4: ");
getIP(ip);
getIP(ip, 0);
format_ip(buf, ip);
switch (ip_status) {
switch (ip_status[0]) {
case IP_TRAINING:
cprintf(C_RED, "BOOTP running");
break;
......@@ -334,7 +334,7 @@ static int wrc_log_stats(void)
shw_pps_gen_get_time(&sec, &nsec);
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("lock:%d ", state.locked ? 1 : 0);
pp_printf("ptp:%s ", wrc_ptp_state());
......@@ -423,7 +423,7 @@ int wrc_wr_diags(void)
wdiag_set_valid(0);
/* frame statistics */
minic_get_stats(&tx, &rx);
minic_get_stats(&tx, &rx, 0);
wdiags_write_cnts(tx,rx);
/* local time */
......
This diff is collapsed.
ppsi @ 61d931c0
Subproject commit cb5934e8dac07c21572d335a5691ea714eeebf57
Subproject commit 61d931c09fc567f374621bc624f29ba2cd78c543
......@@ -23,23 +23,24 @@
static int cmd_calibration(const char *args[])
{
uint32_t trans;
int port=0;
if (args[0] && !strcasecmp(args[0], "force")) {
if (measure_t24p(&trans) < 0)
if (measure_t24p(&trans, port) < 0)
return -1;
return storage_phtrans(&trans, 1);
return storage_phtrans(&trans, 1, port);
} else if (!args[0]) {
if (storage_phtrans(&trans, 0) > 0) {
pp_printf("Found phase transition in EEPROM: %dps\n",
trans);
cal_phase_transition = trans;
if (storage_phtrans(&trans, 0, port) > 0) {
pp_printf("Port %d Found phase transition in EEPROM: %dps\n",
port, trans);
cal_phase_transition[port] = trans;
return 0;
} else {
pp_printf("Measuring t2/t4 phase transition...\n");
if (measure_t24p(&trans) < 0)
pp_printf("Port %d Measuring t2/t4 phase transition...\n", port);
if (measure_t24p(&trans, port) < 0)
return -1;
cal_phase_transition = trans;
return storage_phtrans(&trans, 1);
cal_phase_transition[port] = trans;
return storage_phtrans(&trans, 1, port);
}
}
......
......@@ -41,17 +41,20 @@ static int cmd_ip(const char *args[])
char buf[20];
if (!args[0] || !strcasecmp(args[0], "get")) {
getIP(ip);
getIP(ip, 0);
getIP(ip, 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);
setIP(ip);
setIP(ip, 0);
ip[3]=ip[3]+1;
setIP(ip, 1);
} else {
return -EINVAL;
}
format_ip(buf, ip);
switch (ip_status) {
switch (ip_status[0]) {
case IP_TRAINING:
pp_printf("IP-address: in training\n");
break;
......
......@@ -36,12 +36,12 @@ DEFINE_WRC_COMMAND(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[])
{
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;
if (args[0] && !args[1]) {
......@@ -51,11 +51,11 @@ static int cmd_delays(const char *args[])
if (args[1]) {
fromdec(args[0], &tx);
fromdec(args[1], &rx);
sfp_deltaTx = tx;
sfp_deltaRx = rx;
sfp_deltaTx[0] = tx;
sfp_deltaRx[0] = rx;
/* Change the active value too (add bislide here) */
s->delta_tx_m = tx;
s->delta_rx_m = rx + ep_get_bitslide();
s->delta_rx_m = rx + ep_get_bitslide(0);
} else {
pp_printf("tx: %i rx: %i\n", sfp_deltaTx, sfp_deltaRx);
}
......
......@@ -45,15 +45,19 @@ static int cmd_mac(const char *args[])
if (!args[0] || !strcasecmp(args[0], "get")) {
/* get current MAC */
get_mac_addr(mac);
get_mac_addr(mac, 0);
get_mac_addr(mac, 1);
} else if (!strcasecmp(args[0], "getp")) {
/* get persistent MAC */
get_mac_addr(mac);
get_mac_addr(mac, 0);
get_persistent_mac(ONEWIRE_PORT, mac);
} else if (!strcasecmp(args[0], "set") && args[1]) {
decode_mac(args[1], mac);
set_mac_addr(mac);
pfilter_init_default();
set_mac_addr(mac, 0);
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]) {
decode_mac(args[1], mac);
set_persistent_mac(ONEWIRE_PORT, mac);
......
......@@ -34,7 +34,10 @@
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;
if (!args[0]) {
......@@ -42,7 +45,7 @@ static int cmd_sfp(const char *args[])
return -EINVAL;
}
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");
return -EIO;
}
......@@ -56,7 +59,12 @@ static int cmd_sfp(const char *args[])
sfp.dTx = atoi(args[2]);
sfp.dRx = atoi(args[3]);
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) {
pp_printf("SFP DB is full\n");
return -ENOSPC;
......@@ -64,55 +72,54 @@ static int cmd_sfp(const char *args[])
pp_printf("I2C error\n");
return -EIO;
} 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;
}
pp_printf("%d SFPs in DB\n", temp);
pp_printf("Port %d has %d SFPs in DB\n", sfp.port, temp);
return 0;
} else if (!strcasecmp(args[0], "show")) {
for (i = 0; i < sfpcount; ++i) {
sfpcount = storage_get_sfp(&sfp, SFP_GET, i);
if (sfpcount == 0) {
pp_printf("SFP database empty\n");
return 0;
} else if (sfpcount < 0) {
pp_printf("SFP database error (%d)\n",
sfpcount);
return -EFAULT;
}
pp_printf("%d: PN:", i + 1);
for (port = 0; port < 2; ++port) {
sfpcount[port] = storage_get_sfp(&sfp, SFP_GET, i, port);
if (sfpcount[port] == 0) {
pp_printf("Port %d SFP database empty\n", port);
} else if (sfpcount[port] < 0) {
pp_printf("Port %d SFP database error (%d)\n", port,
sfpcount[0]);
ret[port] = -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);
}
return 0;
}
}
return (ret[0] || ret[1]);
} else if (!strcasecmp(args[0], "match")) {
ret = sfp_match();
if (ret == -ENODEV) {
pp_printf("No SFP.\n");
return ret;
for (port = 0; port < 2; ++port) {
ret[port] = sfp_match(port);
if (ret[0] == -ENODEV)
pp_printf("Port %d No SFP.\n", port);
else if (ret[0] == -EIO)
pp_printf("Port %d SFP read error\n", port);
else if (ret == -ENXIO)
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]);
}
if (ret == -EIO) {
pp_printf("SFP read error\n");
return ret;
}
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")) {
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;
} else {
pp_printf("Wrong parameter\n");
......
......@@ -28,7 +28,8 @@ static int cmd_stat(const char *args[])
/* arguments: bts, on, off */
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")) {
wrc_stat_running = 1;
wrc_stats_last--; /* force a line to be printed */
......
......@@ -25,10 +25,12 @@ static int cmd_vlan(const char *args[])
return -EINVAL;
}
wrc_vlan_number = i;
pfilter_init_default();
pfilter_init_default(0);
pfilter_init_default(1);
} else if (!strcasecmp(args[0], "off")) {
wrc_vlan_number = 0;
pfilter_init_default();
pfilter_init_default(0);
pfilter_init_default(1);
} else {
return -EINVAL;
......
......@@ -43,7 +43,7 @@ int wrc_ui_refperiod = TICS_PER_SECOND; /* 1 sec */
int wrc_phase_tracking = 1;
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;
......@@ -53,8 +53,8 @@ uint32_t print_task_time_threshold = CONFIG_DEFAULT_PRINT_TASK_TIME_THRESHOLD;
static void wrc_initialize(void)
{
uint8_t mac_addr[6];
int port;
uint8_t mac_addr[wr_num_ports][6];
sdb_find_devices();
uart_init_hw();
......@@ -76,32 +76,54 @@ static void wrc_initialize(void)
/*init storage (Flash / W1 EEPROM / I2C EEPROM*/
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");
mac_addr[0] = 0x22; /*
mac_addr[1] = 0x33; *
mac_addr[2] = 0x44; * fallback MAC if get_persistent_mac fails
mac_addr[3] = 0x55; *
mac_addr[4] = 0x66; *
mac_addr[5] = 0x77; */
mac_addr[0][0] = 0x22; /*
mac_addr[0][1] = 0x33; *
mac_addr[0][2] = 0x44; * fallback MAC if get_persistent_mac fails
mac_addr[0][3] = 0x55; *
mac_addr[0][4] = 0x66; *
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",
mac_addr[0], mac_addr[1], mac_addr[2], mac_addr[3],
mac_addr[4], mac_addr[5]);
pp_printf("PORT 0 Local MAC address: %02x:%02x:%02x:%02x:%02x:%02x\n",
mac_addr[0][0], mac_addr[0][1], mac_addr[0][2], mac_addr[0][3],
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();
ep_init(mac_addr);
//Duplicate the configuration for both ports.
for (port=0; port<wr_num_ports;port++)
{
ep_init(mac_addr[port], port);
/* Sleep for 1s to make sure WRS v4.2 always realizes that
* the link is down */
timer_delay_ms(200);
ep_enable(1, 1);
ep_enable(1, 1, port);
minic_init(port);
}
minic_init();
shw_pps_gen_init();
wrc_ptp_init();
/* 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();
usleep_init();
shell_init();
......@@ -110,7 +132,8 @@ static void wrc_initialize(void)
_endram = ENDRAM_MAGIC;
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);
/* get tics */
prev_ticks_for_profile = timer_get_tics();
......@@ -121,34 +144,54 @@ DEFINE_WRC_TASK0(idle) = {
.init = wrc_initialize,
};
int link_status;
uint8_t link_status[wr_num_ports];
static int wrc_check_link(void)
{
static int prev_state = 0;
int state = ep_link_up(NULL);
static int prev_state[wr_num_ports] = {-1,-1};
int state[wr_num_ports];
int rv = 0;
int port;
for(port=0; port<wr_num_ports; port++)
state[port] = ep_link_up(NULL, port);
if (!prev_state && state) {
wrc_verbose("Link up.\n");
if (!prev_state[0] && state[0]) {
wrc_verbose("Port 0 Link up.\n");
gpio_out(GPIO_LED_LINK, 1);
sfp_match();
wrc_ptp_start();
link_status = LINK_WENT_UP;
sfp_match(0);
wrc_ptp_start(0);
link_status[0] = LINK_WENT_UP;
rv = 1;
} else if (prev_state && !state) {
wrc_verbose("Link down.\n");
} else if (prev_state[0] && !state[0]) {
wrc_verbose("Port 0 Link down.\n");
gpio_out(GPIO_LED_LINK, 0);
link_status = LINK_WENT_DOWN;
wrc_ptp_stop();
link_status[0] = LINK_WENT_DOWN;
wrc_ptp_stop(0);
rv = 1;
/* special case */
spll_init(SPLL_MODE_FREE_RUNNING_MASTER, 0, 1);
shw_pps_gen_enable_output(0);
} else
link_status[0] = (state[0] ? LINK_UP : LINK_DOWN);
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 = (state ? LINK_UP : LINK_DOWN);
prev_state = state;
link_status[1] = (state[1] ? LINK_UP : LINK_DOWN);
prev_state[1] = state[1];
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