summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--cleopatre/devkit/plcdrv/arm/inc/common.h4
-rw-r--r--cleopatre/devkit/plcdrv/arm/inc/processing.h20
-rw-r--r--cleopatre/devkit/plcdrv/arm/src/linux_drv.c108
-rw-r--r--cleopatre/devkit/plcdrv/arm/src/processing.c60
4 files changed, 98 insertions, 94 deletions
diff --git a/cleopatre/devkit/plcdrv/arm/inc/common.h b/cleopatre/devkit/plcdrv/arm/inc/common.h
index 6c3276aba5..2124da891f 100644
--- a/cleopatre/devkit/plcdrv/arm/inc/common.h
+++ b/cleopatre/devkit/plcdrv/arm/inc/common.h
@@ -49,11 +49,11 @@ extern uint32_t trace;
#define NEARLY_FULL 2
/** Type of buffer */
-enum buffer_type {
+typedef enum buffer_type {
DATA = 0,
MME = 1,
INTERFACE = 2,
-};
+} buffer_type_t;
/** Initialization structure */
struct init_info {
diff --git a/cleopatre/devkit/plcdrv/arm/inc/processing.h b/cleopatre/devkit/plcdrv/arm/inc/processing.h
index 52ed11edb1..58d591c443 100644
--- a/cleopatre/devkit/plcdrv/arm/inc/processing.h
+++ b/cleopatre/devkit/plcdrv/arm/inc/processing.h
@@ -22,6 +22,16 @@
#include "processing_utests.h"
#endif
+/** Define HPAV Ethernet type */
+#define ETH_P_HPAV 0x88E1
+/** Define MME fcall type */
+#define HPAV_MME_P_FCALL 0xA006
+/** Define MME sniffer type */
+#define HPAV_MME_P_SNIFFER 0xA02C
+#define HPAV_MME_P_VS_BASE 0xA000
+#define HPAV_MME_P_DRV_BASE 0xB000
+#define HPAV_MME_P_MS_BASE 0x8000
+
/** processing layer context structure */
struct processctx {
uint8_t board_addr[ETH_ALEN];
@@ -29,6 +39,14 @@ struct processctx {
};
/**
+ * Find the Ethernet MME type.
+ *
+ * \param eth_frame Ethernet frame pointer.
+ * \return HPAV MME type.
+ */
+uint16_t get_eth_mme_type(uint8_t* eth_frame);
+
+/**
* Initialize the processing layer.
*
* \param info initialisation structure.
@@ -68,7 +86,7 @@ int processing_buffer_free(void *pointer);
* \param length length of the message pointed.
* \return status queue.
*/
-int processing_send(void *pointer, int length);
+int processing_send(void *pointer, int length, buffer_type_t type);
/**
* Processing procedure for a L->A message.
diff --git a/cleopatre/devkit/plcdrv/arm/src/linux_drv.c b/cleopatre/devkit/plcdrv/arm/src/linux_drv.c
index 0a2f5126a9..61f07e0102 100644
--- a/cleopatre/devkit/plcdrv/arm/src/linux_drv.c
+++ b/cleopatre/devkit/plcdrv/arm/src/linux_drv.c
@@ -952,6 +952,40 @@ int plcdrv_rx(void *packet, int length, enum pkt_dest dst)
return result;
}// plcdrv_rx
+static void plcdrv_post_tx (struct sk_buff *skb, struct net_device *dev, int status)
+{
+ struct net_priv *priv = NULL;
+ priv = (struct net_priv *)dev->priv;
+
+ //Tx queue is nearly full we must stop it
+ if(status == NEARLY_FULL ||
+ priv->plc_stats.tx_pool == MBX_TX_POOL - 1)
+ {
+ netif_stop_queue(dev);
+ priv->plc_stats.tx_pool++; // update plc stats
+ TRACE("TX queue nearly Full\n");
+ }
+ //Tx queue is full drop the frame
+ else if(status == FULL)
+ {
+ netif_stop_queue(dev);
+ priv->stats.tx_errors++;
+ priv->stats.tx_fifo_errors++;
+ kfree_skb(skb);
+ printk(KERN_WARNING DRV_NAME ": %s: TX queue is Full\n", dev->name);
+ }
+ // Transmit success
+ else
+ {
+ priv->plc_stats.tx_pool++; // update plc stats
+ }
+
+ //Handle transmit
+ dev->trans_start = jiffies;
+
+ return;
+}
+
/**
* Transmit frame procedure.
*
@@ -959,7 +993,7 @@ int plcdrv_rx(void *packet, int length, enum pkt_dest dst)
* \param dev device structure.
* \return error code.
*/
-int plcdrv_tx(struct sk_buff *skb, struct net_device *dev)
+int plcdrv_data_tx(struct sk_buff *skb, struct net_device *dev)
{
struct net_priv *priv = NULL;
int status;
@@ -983,36 +1017,13 @@ int plcdrv_tx(struct sk_buff *skb, struct net_device *dev)
}
//Send buffer to lower layers
- status = processing_send((void *)skb->data, skb->len);
-
- //Tx queue is nearly full we must stop it
- if(status == NEARLY_FULL ||
- priv->plc_stats.tx_pool == MBX_TX_POOL - 1)
- {
- netif_stop_queue(dev);
- priv->plc_stats.tx_pool++; // update plc stats
- TRACE("TX queue nearly Full\n");
- }
- //Tx queue is full drop the frame
- else if(status == FULL)
- {
- netif_stop_queue(dev);
- priv->stats.tx_errors++;
- priv->stats.tx_fifo_errors++;
- kfree_skb(skb);
- printk(KERN_WARNING DRV_NAME ": %s: TX queue is Full\n", dev->name);
- }
- // Transmit success
- else
- {
- priv->plc_stats.tx_pool++; // update plc stats
- }
+ status = processing_send((void *)skb->data, skb->len, DATA);
- //Handle transmit
- dev->trans_start = jiffies;
+ /* check result and update stats */
+ plcdrv_post_tx (skb, dev, status);
return 0;
-}// plcdrv_tx
+}// plcdrv_data_tx
/**
* Transmit a frame received from NETLINK.
@@ -1021,17 +1032,21 @@ int plcdrv_tx(struct sk_buff *skb, struct net_device *dev)
* \param dev net device structure
* \param sock netlink socket structure
*/
-void plcdrv_netlink_tx(struct sk_buff *nlskb, struct net_device *dev, struct sock *sock)
+int plcdrv_netlink_tx(struct sk_buff *nlskb, struct net_device *dev, struct sock *sock)
{
struct sk_buff *skb;
struct net_priv *priv;
+ buffer_type_t type;
+ int status;
//Check pointers
if(nlskb == NULL)
- return;
+ return -1;
if(dev == NULL)
- return;
+ return -1;
priv = (struct net_priv *)dev->priv;
+ if(priv == NULL)
+ return -1;
mutex_lock(&plcdrv_nl_mutex);
@@ -1043,7 +1058,7 @@ void plcdrv_netlink_tx(struct sk_buff *nlskb, struct net_device *dev, struct soc
if(!skb)
{
printk(KERN_ERR DRV_NAME": %s: Error allocating a netlink sk_buff\n", dev->name);
- return;
+ return -1;
}
//Fill this new sk_buff with the old one
@@ -1052,10 +1067,33 @@ void plcdrv_netlink_tx(struct sk_buff *nlskb, struct net_device *dev, struct soc
//Prepare this new sk_buff
skb_put(skb, nlskb->len);
- //Call standard TX procedure
- plcdrv_tx(skb, dev);
+ TRACE("\nTX: virt@skb=%x ; virt@skb->data=%x ; skb->len=%d\n",(uint32_t)skb, (uint32_t)skb->data, skb->len);
+ PRINTPKT("TX",skb, skb->len);
+
+ //Store the sk_buff in sk_buff list in used
+ if((status = put_skb_addr(skb)))
+ {
+ return status;
+ }
+
+ if((get_eth_mme_type(skb->data) == HPAV_MME_P_FCALL) ||
+ (get_eth_mme_type(skb->data) == HPAV_MME_P_SNIFFER))
+ {
+ type = INTERFACE;
+ }
+ else
+ {
+ type = MME;
+ }
+ //send buffer to lower layer
+ status = processing_send((void *)skb->data, skb->len, type);
+
+ /* check result and update stats */
+ plcdrv_post_tx (skb, dev, status);
mutex_unlock(&plcdrv_nl_mutex);
+
+ return 0;
}// plcdrv_netlink_tx
/**
@@ -1602,7 +1640,7 @@ int plcdrv_init(struct net_device *dev)
dev->stop = plcdrv_stop;
dev->do_ioctl = plcdrv_ioctl;
dev->set_mac_address = plcdrv_set_mac_address;
- dev->hard_start_xmit = plcdrv_tx;
+ dev->hard_start_xmit = plcdrv_data_tx;
dev->get_stats = plcdrv_stats;
/* dev->tx_timeout = plcdrv_tx_timeout; */
/* dev->watchdog_timeo = TX_TIMEOUT; */
diff --git a/cleopatre/devkit/plcdrv/arm/src/processing.c b/cleopatre/devkit/plcdrv/arm/src/processing.c
index a94ea3a585..6cfb8eea0c 100644
--- a/cleopatre/devkit/plcdrv/arm/src/processing.c
+++ b/cleopatre/devkit/plcdrv/arm/src/processing.c
@@ -61,16 +61,6 @@ static inline unsigned short int ntohs(unsigned short int x)
/** Define Debug/Trace Level */
#define TRACE(...) if(test_bit(TRACE_PROCESS, (const volatile unsigned long*)&trace)) printk(KERN_INFO "SPC300: PROC: " __VA_ARGS__)
-/** Define HPAV Ethernet type */
-#define ETH_P_HPAV 0x88E1
-/** Define MME fcall type */
-#define HPAV_MME_P_FCALL 0xA006
-/** Define MME sniffer type */
-#define HPAV_MME_P_SNIFFER 0xA02C
-#define HPAV_MME_P_VS_BASE 0xA000
-#define HPAV_MME_P_DRV_BASE 0xB000
-#define HPAV_MME_P_MS_BASE 0x8000
-
/** Define HPAV MME format */
#define ETH_MME_VERSION_OFFSET (sizeof(struct ethhdr))
#define ETH_MME_VERSION_SIZE (1)
@@ -258,11 +248,9 @@ int processing_buffer_free(void *pointer)
* \param length length of the message pointed.
* \return status queue.
*/
-int processing_send(void *pointer, int length)
+int processing_send(void *pointer, int length, buffer_type_t type)
{
- enum buffer_type type;
uint32_t phys_ptr;
- uint8_t is_for_us, is_mme, is_interface;
uint32_t vlan_prio = 0;
int result;
@@ -273,49 +261,9 @@ int processing_send(void *pointer, int length)
if((length <= 0) || (length > PKT_BUF_SZ))
return -1;
- //Analyse frame header
- is_for_us = !memcmp(get_eth_dst_addr((uint8_t*)pointer, NULL), glbctx.board_addr, ETH_ALEN);
- is_mme = (get_eth_type((uint8_t*)pointer) == ETH_P_HPAV);
- is_interface = (is_mme && ((get_eth_mme_type((uint8_t*)pointer) == HPAV_MME_P_FCALL) ||
- (get_eth_mme_type((uint8_t*)pointer) == HPAV_MME_P_SNIFFER)));
-
- //Check which type of frame is it
- if(is_interface)
- {
- if(is_for_us)
- {
- TRACE("In the processing_send : INTERFACE\n");
- type = INTERFACE;
- }
- else
- {
- TRACE("In the processing_send : DROP\n");
- return free_buffer(pointer, TX_DROP);
- }
- }
- else if(is_mme)
- {
- if(is_for_us)
- {
- //TODO:if frame not ok drop it with free_buffer(pointer, TX_DROP)
- TRACE("In the processing_send : MME\n");
- type = MME;
- }
- else
- {
- TRACE("In the processing_send : MME through DATA\n");
- type = DATA;
- }
- }
- else
- {
- TRACE("In the processing_send : DATA\n");
- type = DATA;
-
- //Check VLAN priority of VLAN frames
- if(get_eth_type((uint8_t*)pointer) == ETH_P_8021Q)
- vlan_prio = (uint32_t)VLAN_PRIO(ntohs(((struct vlan_ethhdr*)pointer)->h_vlan_TCI));
- }
+ //Check VLAN priority of VLAN frames
+ if(get_eth_type((uint8_t*)pointer) == ETH_P_8021Q)
+ vlan_prio = (uint32_t)VLAN_PRIO(ntohs(((struct vlan_ethhdr*)pointer)->h_vlan_TCI));
//Find phys address and invalide cache
if(!(phys_ptr = prepare_buffer_to_hw((uint32_t)pointer, length)))