summaryrefslogtreecommitdiff
path: root/cleopatre
diff options
context:
space:
mode:
authorsave2009-01-14 10:03:59 +0000
committersave2009-01-14 10:03:59 +0000
commitdf0fb065c90f99077a2916713785a656f0715b12 (patch)
tree92353a6073bace3090ecfea2ac150f5946c3f2c9 /cleopatre
parenta2976f4ae7c106f0cd9442d8c50446afd5720266 (diff)
[CLEO][PLCDRV]Init structure pased from layer to layer init procedures + Alloc mailboxes ring memory
git-svn-id: svn+ssh://pessac/svn/cesar/trunk@3761 017c9cb6-072f-447c-8318-d5b54f68fe89
Diffstat (limited to 'cleopatre')
-rw-r--r--cleopatre/plcdrv/arm/inc/common.h15
-rw-r--r--cleopatre/plcdrv/arm/inc/hal.h27
-rw-r--r--cleopatre/plcdrv/arm/inc/mailbox.h4
-rw-r--r--cleopatre/plcdrv/arm/inc/processing.h4
-rw-r--r--cleopatre/plcdrv/arm/inc/registers.h3
-rw-r--r--cleopatre/plcdrv/arm/src/hal.c7
-rw-r--r--cleopatre/plcdrv/arm/src/linux_drv.c109
-rw-r--r--cleopatre/plcdrv/arm/src/mailbox.c10
-rw-r--r--cleopatre/plcdrv/arm/src/processing.c10
9 files changed, 159 insertions, 30 deletions
diff --git a/cleopatre/plcdrv/arm/inc/common.h b/cleopatre/plcdrv/arm/inc/common.h
index e8afc2afa3..8bdb0708df 100644
--- a/cleopatre/plcdrv/arm/inc/common.h
+++ b/cleopatre/plcdrv/arm/inc/common.h
@@ -18,6 +18,12 @@
/** Max size of an Ethernet frame (size for all buffers) must be align on 4 bytes */
#define PKT_BUF_SZ 1524
+/** Arm to Leon mailbox ring size */
+#define A2L_RING_SIZE 0x100
+
+/** Leon to Arm mailbox ring size */
+#define L2A_RING_SIZE 0x100
+
/** Define queue status */
#define NOT_FULL 0
#define FULL 1
@@ -30,4 +36,13 @@ enum buffer_type {
INTERFACE = 2,
};
+/** Initialization structure */
+struct init_info {
+ uint32_t ring_base_addr;
+ uint32_t mbx_reg_base_addr;
+ uint32_t mbx_leon_reg_base_addr;
+ uint32_t (*virt_to_phys)(uint32_t);
+ uint32_t (*phys_to_virt)(uint32_t);
+};
+
#endif /* common_h */
diff --git a/cleopatre/plcdrv/arm/inc/hal.h b/cleopatre/plcdrv/arm/inc/hal.h
index 26bac8e6f6..b4b648b800 100644
--- a/cleopatre/plcdrv/arm/inc/hal.h
+++ b/cleopatre/plcdrv/arm/inc/hal.h
@@ -20,15 +20,38 @@
#include "hal_utests.h"
#endif
+#define A2L_RING_MASK (A2L_RING_SIZE-1)
+#define L2A_RING_MASK (L2A_RING_SIZE-1)
+
+/** hal layer context structure */
+struct halctx {
+ uint32_t *A2L_ptr;
+ uint32_t *L2A_ptr;
+ const uint32_t *A2L_head;
+ uint32_t *A2L_tail;
+ uint32_t *L2A_head;
+ const uint32_t *L2A_tail;
+ uint32_t *A2L_it;
+ uint32_t *L2A_it;
+ uint32_t *L2A_it_mask;
+ uint32_t (*virt_to_phys)(uint32_t);
+ uint32_t (*phys_to_virt)(uint32_t);
+};
+
/**
* Initialize the hal layer
+ *
+ * \param init user information.
+ * \return hal context.
*/
-void halmbx_init(void);
+struct halctx* halmbx_init(struct init_info *info);
/**
* UnInitialize the hal layer
+ *
+ * \param ctx hal context.
*/
-void halmbx_uninit(void);
+void halmbx_uninit(struct halctx *ctx);
/**
* Check if Leon to Arm mailbox queue is empty.
diff --git a/cleopatre/plcdrv/arm/inc/mailbox.h b/cleopatre/plcdrv/arm/inc/mailbox.h
index f9a201b3aa..dfe9973307 100644
--- a/cleopatre/plcdrv/arm/inc/mailbox.h
+++ b/cleopatre/plcdrv/arm/inc/mailbox.h
@@ -24,8 +24,10 @@
/**
* Initialize the mailbox layer
+ *
+ * \param info initialisation structure.
*/
-void mailbox_init(void);
+void mailbox_init(struct init_info *info);
/**
* UnInitialize the mailbox layer
diff --git a/cleopatre/plcdrv/arm/inc/processing.h b/cleopatre/plcdrv/arm/inc/processing.h
index 3c587d436c..eed303333b 100644
--- a/cleopatre/plcdrv/arm/inc/processing.h
+++ b/cleopatre/plcdrv/arm/inc/processing.h
@@ -24,8 +24,10 @@
/**
* Initialize the processing layer.
+ *
+ * \param info initialisation structure.
*/
-void processing_init(void);
+void processing_init(struct init_info *info);
/**
* UnInitialize the processing layer.
diff --git a/cleopatre/plcdrv/arm/inc/registers.h b/cleopatre/plcdrv/arm/inc/registers.h
index c5e937543b..e9ad34f915 100644
--- a/cleopatre/plcdrv/arm/inc/registers.h
+++ b/cleopatre/plcdrv/arm/inc/registers.h
@@ -18,6 +18,9 @@
/** Physical Base Address for Mailboxes */
#define MBX_BASE_ADDR 0xC8030000
+/** Physical Base Address for Mailboxes */
+#define MBX_LEON_BASE_ADDR 0xB4000000
+
/** Number of registers present for mailboxes */
#define NB_MBX_REGISTERS 8
diff --git a/cleopatre/plcdrv/arm/src/hal.c b/cleopatre/plcdrv/arm/src/hal.c
index 7d1546acb8..7eda9d8c57 100644
--- a/cleopatre/plcdrv/arm/src/hal.c
+++ b/cleopatre/plcdrv/arm/src/hal.c
@@ -27,15 +27,18 @@
* Initialize the hal layer.
*
* \param init user information.
+ * \return hal context.
*/
-void halmbx_init(struct init_info *init)
+struct halctx* halmbx_init(struct init_info *info)
{
}
/**
* UnInitialize the hal layer.
+ *
+ * \param ctx hal context.
*/
-void halmbx_uninit(void)
+void halmbx_uninit(struct halctx *ctx)
{
}
diff --git a/cleopatre/plcdrv/arm/src/linux_drv.c b/cleopatre/plcdrv/arm/src/linux_drv.c
index 47b673cd09..0d0ddd3165 100644
--- a/cleopatre/plcdrv/arm/src/linux_drv.c
+++ b/cleopatre/plcdrv/arm/src/linux_drv.c
@@ -58,7 +58,10 @@ MODULE_LICENSE("SPiDCOM Technologies 2009");
#define TRACE(...) printk(DRV_NAME": " __VA_ARGS__)
//#define TRACE(...)
-/** Define default rings size */
+/** Define default leon translation address */
+#define DEFAULT_LEON_START_ADDRESS 0x00011000
+
+/** Define default numbers of buffers */
#define DEFAULT_NB_DATA_BUFFERS 5
#define DEFAULT_NB_MME_BUFFERS 5
#define DEFAULT_NB_INTERFACE_BUFFERS 5
@@ -70,6 +73,10 @@ static char version[] __devinitdata = DRV_NAME " PLC driver v" DRV_VERSION " ("
struct net_priv {
uint32_t num_mbx_it;
uint32_t num_mbx_it_ack;
+ uint32_t phys_ring_base_addr;
+ uint32_t virt_ring_base_addr;
+ uint32_t mbx_reg_base_addr;
+ uint32_t mbx_leon_reg_base_addr;
struct net_device_stats stats;
};
@@ -77,15 +84,18 @@ struct net_priv {
static struct net_device *plcdrv_device;
/** Parameters for the module */
-static int rx_data_skb_ring_size = DEFAULT_NB_DATA_BUFFERS;
-static int rx_mme_skb_ring_size = DEFAULT_NB_MME_BUFFERS;
-static int rx_interface_skb_ring_size = DEFAULT_NB_INTERFACE_BUFFERS;
-module_param(rx_data_skb_ring_size, int, 0644);
-MODULE_PARM_DESC(rx_data_skb_ring_size, "Number of Data Ethernet buffers for PLC -> ARM exchanges");
-module_param(rx_mme_skb_ring_size, int, 0644);
-MODULE_PARM_DESC(rx_mme_skb_ring_size, "Number of MME Ethernet buffers for PLC -> ARM exchanges");
-module_param(rx_interface_skb_ring_size, int, 0644);
-MODULE_PARM_DESC(rx_mme_skb_ring_size, "Number of Interface Ethernet buffers for PLC -> ARM exchanges");
+static int nb_rx_data_buffers = DEFAULT_NB_DATA_BUFFERS;
+static int nb_rx_mme_buffers = DEFAULT_NB_MME_BUFFERS;
+static int nb_rx_interface_buffers = DEFAULT_NB_INTERFACE_BUFFERS;
+static int leon_start_addr = DEFAULT_LEON_START_ADDRESS;
+module_param(nb_rx_data_buffers, int, 0644);
+MODULE_PARM_DESC(nb_rx_data_buffers, "Number of Data Ethernet buffers for PLC -> ARM exchanges");
+module_param(nb_rx_mme_buffers, int, 0644);
+MODULE_PARM_DESC(nb_rx_mme_buffers, "Number of MME Ethernet buffers for PLC -> ARM exchanges");
+module_param(nb_rx_interface_buffers, int, 0644);
+MODULE_PARM_DESC(nb_rx_interface_buffers, "Number of Interface Ethernet buffers for PLC -> ARM exchanges");
+module_param(leon_start_addr, uint32_t, 0644);
+MODULE_PARM_DESC(leon_start_addr, "PLC code start address");
/**
* Find with sk_buff data field address the sk_buff structure address.
@@ -99,6 +109,30 @@ static inline uint32_t get_skb_addr(uint32_t skbdata_addr)
}// get_skb_addr
/**
+ * Changed a virtual address to it physical one.
+ *
+ * \param addr virtual address.
+ * \return physical address.
+ */
+static inline uint32_t plcdrv_virt_to_phys(uint32_t addr)
+{
+ //Find the corresponding physical addr
+ return (uint32_t)(virt_to_dma(NULL, addr));
+}// plcdrv_virt_to_phys
+
+/**
+ * Changed a physical address to it virtual one.
+ *
+ * \param addr physical address.
+ * \return virtual address.
+ */
+static inline uint32_t plcdrv_phys_to_virt(uint32_t addr)
+{
+ //Find the corresponding virtual addr
+ return (uint32_t)(dma_to_virt(NULL, addr));
+}// plcdrv_phys_to_virt
+
+/**
* Changed a virtual address to its corresponding physical address
* and manage the cache.
* \param addr buffer virtual address.
@@ -478,6 +512,7 @@ int plcdrv_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd)
int plcdrv_open(struct net_device *dev)
{
struct net_priv *priv = NULL;
+ struct init_info info;
int i;
//Check pointers
@@ -489,11 +524,33 @@ int plcdrv_open(struct net_device *dev)
TRACE("%s: open\n", dev->name);
+ //Allocate rings for each mailbox
+ if((priv->virt_ring_base_addr =
+ (uint32_t)dma_alloc_coherent(NULL,
+ A2L_RING_SIZE+L2A_RING_SIZE,
+ &priv->phys_ring_base_addr,
+ GFP_KERNEL|GFP_DMA)
+ ) == NULL)
+ {
+ printk(KERN_ERR DRV_NAME": Error allocating mailboxes rings for %s\n", dev->name);
+ return -ENOMEM;
+ }
+
+ //Flush rings for each mailbox
+ memset(priv->virt_ring_base_addr, 0, A2L_RING_SIZE+L2A_RING_SIZE);
+
+ //Prepare init structure from lower layers
+ info.ring_base_addr = priv->virt_ring_base_addr;
+ info.mbx_reg_base_addr = priv->mbx_reg_base_addr;
+ info.mbx_leon_reg_base_addr = priv->mbx_leon_reg_base_addr;
+ info.virt_to_phys = &plcdrv_virt_to_phys;
+ info.phys_to_virt = &plcdrv_phys_to_virt;
+
//Start lower Layers
- processing_init();
+ processing_init(&info);
//Allocate RX buffer pool to give to CESAR
- for(i=0 ; i<rx_data_skb_ring_size ; i++)
+ for(i=0 ; i<nb_rx_data_buffers ; i++)
{
if(alloc_buffer(DATA))
{
@@ -501,7 +558,7 @@ int plcdrv_open(struct net_device *dev)
return -ENOMEM;
}
}
- for(i=0 ; i<rx_mme_skb_ring_size ; i++)
+ for(i=0 ; i<nb_rx_mme_buffers ; i++)
{
if(alloc_buffer(MME))
{
@@ -509,7 +566,7 @@ int plcdrv_open(struct net_device *dev)
return -ENOMEM;
}
}
- for(i=0 ; i<rx_interface_skb_ring_size ; i++)
+ for(i=0 ; i<nb_rx_interface_buffers ; i++)
{
if(alloc_buffer(INTERFACE))
{
@@ -566,6 +623,12 @@ int plcdrv_stop(struct net_device *dev)
//Stop lower layers
processing_uninit();
+ //Free mailboxes ring
+ dma_free_coherent(NULL,
+ A2L_RING_SIZE+L2A_RING_SIZE,
+ priv->virt_ring_base_addr,
+ priv->phys_ring_base_addr);
+
//Disconnect from IRQ
free_irq(priv->num_mbx_it, dev);
free_irq(priv->num_mbx_it_ack, dev);
@@ -600,7 +663,9 @@ int plcdrv_init(struct net_device *dev)
TRACE("%s: init\n", dev->name);
//Set IP base addresses
- dev->base_addr = (unsigned int)ioremap(MBX_BASE_ADDR, NB_MBX_REGISTERS);
+ priv->mbx_reg_base_addr = (unsigned int)ioremap(MBX_BASE_ADDR, NB_MBX_REGISTERS);
+ priv->mbx_leon_reg_base_addr = (unsigned int)ioremap(MBX_LEON_BASE_ADDR, NB_MBX_REGISTERS);
+ dev->base_addr = priv->mbx_reg_base_addr;
//Set Interrupts numbers
dev->irq = INT_MBX; //do not use dev->irq because there more than one IT given by the hardware
@@ -678,14 +743,18 @@ void __exit plcdrv_module_exit(void)
if(plcdrv_device)
{
- //Unmap IP address
- if(plcdrv_device->base_addr)
- iounmap((void*)plcdrv_device->base_addr);
-
- //Freeing private field of the net device structure
priv = plcdrv_device->priv;
if(priv)
+ {
+ //Unmap IP address
+ if(priv->mbx_reg_base_addr)
+ iounmap((void*)priv->mbx_reg_base_addr);
+ if(priv->mbx_leon_reg_base_addr)
+ iounmap((void*)priv->mbx_leon_reg_base_addr);
+
+ //Freeing private field of the net device structure
kfree(priv);
+ }
//Unregister net device
unregister_netdev(plcdrv_device);
diff --git a/cleopatre/plcdrv/arm/src/mailbox.c b/cleopatre/plcdrv/arm/src/mailbox.c
index 6d1f4c1134..72eefde9cc 100644
--- a/cleopatre/plcdrv/arm/src/mailbox.c
+++ b/cleopatre/plcdrv/arm/src/mailbox.c
@@ -98,11 +98,17 @@ typedef struct {
/**
* Initialize the mailbox layer
+ *
+ * \param info initialisation structure.
*/
-void mailbox_init(void)
+void mailbox_init(struct init_info *info)
{
+ //Check arguments
+ if(info == NULL)
+ return;
+
//Initialize registers
- halmbx_init();
+ halmbx_init(info);
//Stop all interrupts
A2La_it_disable();
diff --git a/cleopatre/plcdrv/arm/src/processing.c b/cleopatre/plcdrv/arm/src/processing.c
index 2b0256fd44..1f0aecf193 100644
--- a/cleopatre/plcdrv/arm/src/processing.c
+++ b/cleopatre/plcdrv/arm/src/processing.c
@@ -129,11 +129,17 @@ uint16_t get_eth_mme_fmi(uint8_t* eth_frame)
/**
* Initialize the processing layer
+ *
+ * \param info initialisation structure.
*/
-void processing_init(void)
+void processing_init(struct init_info *info)
{
+ //Check arguments
+ if(info == NULL)
+ return;
+
//Init lower layers
- mailbox_init();
+ mailbox_init(info);
}// processing_init
/**