arch/risc-v/src/mpfs: Generate an unique locally administrated MAC address
Add a function to read PolarFire's serial number from system controller, and use the first five digits as device's mac address Signed-off-by: Jukka Laitinen <jukkax@ssrc.tii.ae>
This commit is contained in:
parent
ef18d2b599
commit
b750f94896
@ -32,7 +32,7 @@ CHIP_CSRCS += mpfs_irq.c mpfs_irq_dispatch.c
|
|||||||
CHIP_CSRCS += mpfs_lowputc.c mpfs_serial.c
|
CHIP_CSRCS += mpfs_lowputc.c mpfs_serial.c
|
||||||
CHIP_CSRCS += mpfs_start.c mpfs_timerisr.c
|
CHIP_CSRCS += mpfs_start.c mpfs_timerisr.c
|
||||||
CHIP_CSRCS += mpfs_gpio.c mpfs_systemreset.c
|
CHIP_CSRCS += mpfs_gpio.c mpfs_systemreset.c
|
||||||
CHIP_CSRCS += mpfs_plic.c
|
CHIP_CSRCS += mpfs_plic.c mpfs_dsn.c
|
||||||
|
|
||||||
ifeq ($(CONFIG_MPFS_DMA),y)
|
ifeq ($(CONFIG_MPFS_DMA),y)
|
||||||
CHIP_CSRCS += mpfs_dma.c
|
CHIP_CSRCS += mpfs_dma.c
|
||||||
|
154
arch/risc-v/src/mpfs/mpfs_dsn.c
Normal file
154
arch/risc-v/src/mpfs/mpfs_dsn.c
Normal file
@ -0,0 +1,154 @@
|
|||||||
|
/****************************************************************************
|
||||||
|
* arch/risc-v/src/mpfs/mpfs_dsn.c
|
||||||
|
*
|
||||||
|
* Licensed to the Apache Software Foundation (ASF) under one or more
|
||||||
|
* contributor license agreements. See the NOTICE file distributed with
|
||||||
|
* this work for additional information regarding copyright ownership. The
|
||||||
|
* ASF licenses this file to you under the Apache License, Version 2.0 (the
|
||||||
|
* "License"); you may not use this file except in compliance with the
|
||||||
|
* License. You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
|
||||||
|
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
|
||||||
|
* License for the specific language governing permissions and limitations
|
||||||
|
* under the License.
|
||||||
|
*
|
||||||
|
****************************************************************************/
|
||||||
|
|
||||||
|
/****************************************************************************
|
||||||
|
* Included Files
|
||||||
|
****************************************************************************/
|
||||||
|
|
||||||
|
#include <nuttx/config.h>
|
||||||
|
#include <errno.h>
|
||||||
|
#include <unistd.h>
|
||||||
|
#include "mpfs_dsn.h"
|
||||||
|
#include "riscv_internal.h"
|
||||||
|
|
||||||
|
/****************************************************************************
|
||||||
|
* Pre-processor Definitions
|
||||||
|
****************************************************************************/
|
||||||
|
|
||||||
|
#define MPFS_SCBCTRL_BASE 0x37020000ul
|
||||||
|
#define SERVICES_CR_OFFSET 0x50
|
||||||
|
#define SERVICES_SR_OFFSET 0x54
|
||||||
|
|
||||||
|
#define SERVICES_CR (MPFS_SCBCTRL_BASE + SERVICES_CR_OFFSET)
|
||||||
|
#define SERVICES_SR (MPFS_SCBCTRL_BASE + SERVICES_SR_OFFSET)
|
||||||
|
|
||||||
|
/* Command bits */
|
||||||
|
|
||||||
|
#define SCBCTRL_SERVICESCR_REQ (1 << 0)
|
||||||
|
|
||||||
|
/* Status bits */
|
||||||
|
|
||||||
|
#define SCBCTRL_SERVICESSR_BUSY (1 << 1)
|
||||||
|
|
||||||
|
/* 2kB long mailbox. */
|
||||||
|
|
||||||
|
#define MSS_SCBMAILBOX 0x37020800ul
|
||||||
|
|
||||||
|
/* Retry count */
|
||||||
|
|
||||||
|
#define RETRIES 500
|
||||||
|
|
||||||
|
/****************************************************************************
|
||||||
|
* Public Functions
|
||||||
|
****************************************************************************/
|
||||||
|
|
||||||
|
/****************************************************************************
|
||||||
|
* Name: mpfs_read_dsn
|
||||||
|
*
|
||||||
|
* Description:
|
||||||
|
* Read n bytes of the device serial number. Full serial number is 16 bytes
|
||||||
|
*
|
||||||
|
* Parameters:
|
||||||
|
* dsn - A pointer to the destination buffer
|
||||||
|
* len - Number of bytes to read
|
||||||
|
*
|
||||||
|
* Returned Value:
|
||||||
|
* Number of bytes read, -ETIMEDOUT on error
|
||||||
|
*
|
||||||
|
****************************************************************************/
|
||||||
|
|
||||||
|
int mpfs_read_dsn(uint8_t *dsn, size_t len)
|
||||||
|
{
|
||||||
|
uint32_t reg;
|
||||||
|
uint8_t *p = (uint8_t *)MSS_SCBMAILBOX;
|
||||||
|
irqstate_t flags = enter_critical_section();
|
||||||
|
unsigned retries = RETRIES;
|
||||||
|
|
||||||
|
/* Wait until the system controller is not busy.
|
||||||
|
* Read the SN inside critical section, just in case someone else is
|
||||||
|
* using the system controller services
|
||||||
|
*/
|
||||||
|
|
||||||
|
while ((getreg32(SERVICES_SR) & SCBCTRL_SERVICESSR_BUSY) && --retries > 0)
|
||||||
|
{
|
||||||
|
leave_critical_section(flags);
|
||||||
|
usleep(1000);
|
||||||
|
flags = enter_critical_section();
|
||||||
|
}
|
||||||
|
|
||||||
|
if (retries == 0)
|
||||||
|
{
|
||||||
|
goto out;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Read at max MPFS_DSN_LENGTH bytes, set the rest to 0 */
|
||||||
|
|
||||||
|
if (len > MPFS_DSN_LENGTH)
|
||||||
|
{
|
||||||
|
len = MPFS_DSN_LENGTH;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Command: bits 0 to 6 is the opcode, bits 7 to 15 is the Mailbox
|
||||||
|
* offset. In this case, opcode == 0 and offset == 0.
|
||||||
|
*/
|
||||||
|
|
||||||
|
putreg32(SCBCTRL_SERVICESCR_REQ, SERVICES_CR);
|
||||||
|
|
||||||
|
/* Wait until the system controller has started processing the command */
|
||||||
|
|
||||||
|
retries = RETRIES;
|
||||||
|
do
|
||||||
|
{
|
||||||
|
reg = getreg32(SERVICES_CR);
|
||||||
|
}
|
||||||
|
while ((reg & SCBCTRL_SERVICESCR_REQ) && --retries);
|
||||||
|
|
||||||
|
if (retries == 0)
|
||||||
|
{
|
||||||
|
goto out;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Wait for the completion of the command */
|
||||||
|
|
||||||
|
retries = RETRIES;
|
||||||
|
do
|
||||||
|
{
|
||||||
|
reg = getreg32(SERVICES_SR);
|
||||||
|
}
|
||||||
|
while ((reg & SCBCTRL_SERVICESSR_BUSY) && --retries);
|
||||||
|
|
||||||
|
if (retries == 0)
|
||||||
|
{
|
||||||
|
goto out;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Read the bytes of serial from service mailbox */
|
||||||
|
|
||||||
|
for (uint8_t i = 0; i < len; i++)
|
||||||
|
{
|
||||||
|
dsn[i] = getreg8(p++);
|
||||||
|
}
|
||||||
|
|
||||||
|
out:
|
||||||
|
|
||||||
|
leave_critical_section(flags);
|
||||||
|
|
||||||
|
return retries > 0 ? len : -ETIMEDOUT;
|
||||||
|
}
|
81
arch/risc-v/src/mpfs/mpfs_dsn.h
Normal file
81
arch/risc-v/src/mpfs/mpfs_dsn.h
Normal file
@ -0,0 +1,81 @@
|
|||||||
|
/****************************************************************************
|
||||||
|
* arch/risc-v/src/mpfs/mpfs_dsn.h
|
||||||
|
*
|
||||||
|
* Licensed to the Apache Software Foundation (ASF) under one or more
|
||||||
|
* contributor license agreements. See the NOTICE file distributed with
|
||||||
|
* this work for additional information regarding copyright ownership. The
|
||||||
|
* ASF licenses this file to you under the Apache License, Version 2.0 (the
|
||||||
|
* "License"); you may not use this file except in compliance with the
|
||||||
|
* License. You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
|
||||||
|
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
|
||||||
|
* License for the specific language governing permissions and limitations
|
||||||
|
* under the License.
|
||||||
|
*
|
||||||
|
****************************************************************************/
|
||||||
|
|
||||||
|
/****************************************************************************
|
||||||
|
* Included Files
|
||||||
|
****************************************************************************/
|
||||||
|
|
||||||
|
#ifndef __ARCH_RISCV_SRC_MPFS_MPFS_DSN_H
|
||||||
|
#define __ARCH_RISCV_SRC_MPFS_MPFS_DSN_H
|
||||||
|
|
||||||
|
/****************************************************************************
|
||||||
|
* Included Files
|
||||||
|
****************************************************************************/
|
||||||
|
|
||||||
|
#include <stdint.h>
|
||||||
|
#include <stddef.h>
|
||||||
|
|
||||||
|
#ifndef __ASSEMBLY__
|
||||||
|
|
||||||
|
#undef EXTERN
|
||||||
|
#if defined(__cplusplus)
|
||||||
|
#define EXTERN extern "C"
|
||||||
|
extern "C"
|
||||||
|
{
|
||||||
|
#else
|
||||||
|
#define EXTERN extern
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/****************************************************************************
|
||||||
|
* Pre-Processor Declarations
|
||||||
|
****************************************************************************/
|
||||||
|
|
||||||
|
/* This is the length of the serial number */
|
||||||
|
|
||||||
|
#define MPFS_DSN_LENGTH 16
|
||||||
|
|
||||||
|
/****************************************************************************
|
||||||
|
* Public Function Prototypes
|
||||||
|
****************************************************************************/
|
||||||
|
|
||||||
|
/****************************************************************************
|
||||||
|
* Name: mpfs_read_dsn
|
||||||
|
*
|
||||||
|
* Description:
|
||||||
|
* Read n bytes of the device serial number. Full serial number is 16 bytes
|
||||||
|
*
|
||||||
|
* Parameters:
|
||||||
|
* dsn - A pointer to the destination buffer
|
||||||
|
* len - Number of bytes to read
|
||||||
|
*
|
||||||
|
* Returned Value:
|
||||||
|
* Number of bytes read or negated errno
|
||||||
|
*
|
||||||
|
****************************************************************************/
|
||||||
|
|
||||||
|
int mpfs_read_dsn(uint8_t *dsn, size_t len);
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
#undef EXTERN
|
||||||
|
|
||||||
|
#endif /* __ASSEMBLY__ */
|
||||||
|
#endif /* __ARCH_RISCV_SRC_MPFS_MPFS_DSN_H */
|
@ -53,6 +53,7 @@
|
|||||||
#include "riscv_internal.h"
|
#include "riscv_internal.h"
|
||||||
#include "mpfs_memorymap.h"
|
#include "mpfs_memorymap.h"
|
||||||
#include "mpfs_ethernet.h"
|
#include "mpfs_ethernet.h"
|
||||||
|
#include "mpfs_dsn.h"
|
||||||
|
|
||||||
#if defined(CONFIG_NET) && defined(CONFIG_MPFS_ETHMAC)
|
#if defined(CONFIG_NET) && defined(CONFIG_MPFS_ETHMAC)
|
||||||
|
|
||||||
@ -1482,7 +1483,7 @@ static int mpfs_ifup(struct net_driver_s *dev)
|
|||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Set the MAC address (should have been configured while we were down) */
|
/* Set the MAC address */
|
||||||
|
|
||||||
mpfs_macaddress(priv);
|
mpfs_macaddress(priv);
|
||||||
|
|
||||||
@ -3542,6 +3543,16 @@ int mpfs_ethinitialize(int intf)
|
|||||||
priv->queue[2].dma_rxbuf_size = (uint32_t *)(base + DMA_RXBUF_SIZE_Q2);
|
priv->queue[2].dma_rxbuf_size = (uint32_t *)(base + DMA_RXBUF_SIZE_Q2);
|
||||||
priv->queue[3].dma_rxbuf_size = (uint32_t *)(base + DMA_RXBUF_SIZE_Q3);
|
priv->queue[3].dma_rxbuf_size = (uint32_t *)(base + DMA_RXBUF_SIZE_Q3);
|
||||||
|
|
||||||
|
/* Generate a locally administrated MAC address for this ethernet if */
|
||||||
|
|
||||||
|
/* Set first byte to 0x02 or 0x06 acc. to the intf */
|
||||||
|
|
||||||
|
priv->dev.d_mac.ether.ether_addr_octet[0] = 0x02 | ((intf & 1) << 2);
|
||||||
|
|
||||||
|
/* Read the next 5 bytes from the S/N */
|
||||||
|
|
||||||
|
mpfs_read_dsn(&priv->dev.d_mac.ether.ether_addr_octet[1], 5);
|
||||||
|
|
||||||
/* MPU hack for ETH DMA if not enabled by bootloader */
|
/* MPU hack for ETH DMA if not enabled by bootloader */
|
||||||
|
|
||||||
#ifdef CONFIG_MPFS_MPU_DMA_ENABLE
|
#ifdef CONFIG_MPFS_MPU_DMA_ENABLE
|
||||||
|
Loading…
Reference in New Issue
Block a user