Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 908517b4 authored by Rohit Vaswani's avatar Rohit Vaswani
Browse files

net: danipc: Receive only danipc protocol pkts from Linux



Set device attribute to not receive ARP protocol
packets, as danipc device is not really an ethernet
device. Without these changes danipc would receive
unexpected IPV6 multicast packets during device up.

Changes are made as protective measure to accept/process
only danipc packets (identified by danipc protocol)
from Linux. Packets from other Layer-3 protocol (IP etc)
are not supported in danipc.

Change-Id: I6bed639a3034f7638fb0b6879d727c1bfca95416
Acked-by: default avatarVijayapal Akula <akulav@qti.qualcomm.com>
Signed-off-by: default avatarRohit Vaswani <rvaswani@codeaurora.org>
parent 6eb2af6d
Loading
Loading
Loading
Loading
+17 −26
Original line number Diff line number Diff line
@@ -31,8 +31,6 @@
#include "danipc_k.h"
#include "danipc_lowlevel.h"

#define SPURIOUS_FRAME_WORKAROUND

void send_pkt(struct sk_buff *skb)
{
	struct danipc_pair	*pair = (struct danipc_pair *)
@@ -47,7 +45,6 @@ void send_pkt(struct sk_buff *skb)
			skb->data,
			skb->len,
			0x12,
			NULL,
			pair->prio
		);

@@ -97,34 +94,28 @@ int danipc_hard_start_xmit(struct sk_buff *skb, struct net_device *dev)
								[pair->prio];
	int			rc = NETDEV_TX_OK;

#ifdef SPURIOUS_FRAME_WORKAROUND
	/* After the device is opened (ifconfig danipc up) someone (kernel?)
	 * sends 6 weird packets to our interface. Meantime just discard
	 * these packages, afterwards will need to understand the source and
	 * handle them properly.
	 * Vladik, 27.11.2013
	/* DANICP is a network device, however it does not support regular IP
	 * packets. All packets not identified by DANIPC protcol (marked with
	 * COOKIE_BASE bits) are discarded.
	 */
	if (pair->prio == 13) {	/* TODO: replace to ">= IPC_trns_prio_1 */
		printk(
			"%s: unknown packet; pair {src=0x%x dst=0x%x prio=%u}, ignoring\n",
				__func__, pair->src, pair->dst, pair->prio);
		dev_kfree_skb(skb);
		return rc;
	}
#endif

	if ((skb->protocol & __constant_htons(0xf000)) ==
		__constant_htons(COOKIE_BASE)) {
		if (map->paddr && atomic_read(&map->pending_skbs) == 0)
			send_pkt(skb);
		else
			rc = delay_skb(skb, map);

	} else {
		dev_kfree_skb(skb);
		netdev_dbg(dev, "%s() discard packet with protocol=0x%x\n",
			__func__, ntohs(skb->protocol));
	}
	return rc;
}

static void
read_ipc_message(char *const packet, char *buf,
		struct ipc_msg_hdr *const first_hdr, const unsigned len,
		u8 cpu_id, enum ipc_trns_prio prio)
		u8 cpuid, enum ipc_trns_prio prio)
{
	unsigned		data_len = IPC_FIRST_BUF_DATA_SIZE_MAX;
	unsigned		total_len = 0;
@@ -134,7 +125,7 @@ read_ipc_message(char *const packet, char *buf,
	struct ipc_buf_hdr	*next_ptr = NULL;

	if (first_hdr->next)
		first_hdr->next = ipc_to_virt(cpu_id, prio,
		first_hdr->next = ipc_to_virt(cpuid, prio,
						(u32)first_hdr->next);
	next_ptr = first_hdr->next;

@@ -144,7 +135,7 @@ read_ipc_message(char *const packet, char *buf,
			data_ptr = (uint8_t *)(next_ptr) +
						sizeof(struct ipc_buf_hdr);
			if (next_ptr->next)
				next_ptr->next = ipc_to_virt(cpu_id, prio,
				next_ptr->next = ipc_to_virt(cpuid, prio,
						(u32)next_ptr->next);
			next_ptr = next_ptr->next;
		}
@@ -162,7 +153,7 @@ read_ipc_message(char *const packet, char *buf,
}

void
handle_incoming_packet(char *const packet, u8 cpu_id, enum ipc_trns_prio prio)
handle_incoming_packet(char *const packet, u8 cpuid, enum ipc_trns_prio prio)
{
	struct ipc_msg_hdr *const first_hdr = (struct ipc_msg_hdr *)packet;
	const unsigned			msg_len = first_hdr->msg_len;
@@ -176,7 +167,7 @@ handle_incoming_packet(char *const packet, u8 cpu_id, enum ipc_trns_prio prio)
		pair->dst = first_hdr->dest_aid;
		pair->src = first_hdr->src_aid;

		read_ipc_message(packet, skb->data, first_hdr, msg_len, cpu_id,
		read_ipc_message(packet, skb->data, first_hdr, msg_len, cpuid,
					prio);

		netdev_dbg(danipc_dev, "%s() pair={dst=0x%x src=0x%x}\n",
+2 −2
Original line number Diff line number Diff line
@@ -60,7 +60,7 @@ extern void *ipc_to_virt(const int cpuid, const unsigned prio,
				(0x0f & (lid)))

extern unsigned	ipc_init(void);
extern void	ipc_trns_fifo_buf_init(uint8_t cpu_id);
extern void	ipc_trns_fifo_buf_init(uint8_t cpuid);
extern void	ipc_route_table_init(struct ipc_trns_func const *ptr);
extern char	*ipc_trns_fifo_buf_alloc(uint8_t dest_aid,
						   enum ipc_trns_prio pri);
@@ -81,7 +81,7 @@ extern struct ipc_trns_func const *get_trns_funcs(uint8_t cpuid);


extern void	handle_incoming_packet(char *const packet,
					uint8_t cpu_id,
					uint8_t cpuid,
					enum ipc_trns_prio pri);

extern struct ipc_to_virt_map	ipc_to_virt_map[PLATFORM_MAX_NUM_OF_NODES][2];
+25 −18
Original line number Diff line number Diff line
@@ -30,6 +30,7 @@
#include <linux/platform_device.h>
#include <linux/interrupt.h>
#include <linux/ioctl.h>
#include <net/arp.h>

#include "danipc_k.h"
#include "ipc_api.h"
@@ -79,7 +80,6 @@ static int danipc_open(struct net_device *dev)
	return rc;
}


static int danipc_close(struct net_device *dev)
{
	struct danipc_priv	*priv = netdev_priv(dev);
@@ -92,6 +92,16 @@ static int danipc_close(struct net_device *dev)
	return 0;
}

static int danipc_set_mac_addr(struct net_device *dev, void *p)
{
	struct sockaddr *addr = p;

	if (!(dev->priv_flags & IFF_LIVE_ADDR_CHANGE) && netif_running(dev))
		return -EBUSY;

	memcpy(dev->dev_addr, addr->sa_data, dev->addr_len);
	return 0;
}

static const struct net_device_ops danipc_netdev_ops = {
	.ndo_open		= danipc_open,
@@ -99,23 +109,21 @@ static const struct net_device_ops danipc_netdev_ops = {
	.ndo_start_xmit		= danipc_hard_start_xmit,
	.ndo_do_ioctl		= danipc_ioctl,
	.ndo_change_mtu		= danipc_change_mtu,
	.ndo_validate_addr	= eth_validate_addr,
	.ndo_set_mac_address	= eth_mac_addr,
	.ndo_set_mac_address	= danipc_set_mac_addr,
};


static void __init
danipc_set_dev_addr(uint8_t *dev_addr)
static void danipc_setup(struct net_device *dev)
{
	/* DAN's OUI: 0x002486 */
	dev_addr[0] = 0x00;
	dev_addr[1] = 0x24;
	dev_addr[2] = 0x86;
	dev_addr[3] = 0x00;
	dev_addr[4] = 0x00;
	dev_addr[5] = 0x00;
}
	dev->netdev_ops         = &danipc_netdev_ops;

	dev->type		= ARPHRD_VOID;
	dev->hard_header_len    = sizeof(struct ipc_msg_hdr);
	dev->addr_len           = sizeof(danipc_addr_t);
	dev->tx_queue_len       = 1000;

	/* New-style flags. */
	dev->flags              = IFF_NOARP;
}

static void __init
danipc_dev_priv_init(struct net_device *dev)
@@ -258,15 +266,14 @@ static int parse_resources(struct platform_device *pdev,

static int danipc_probe(struct platform_device *pdev)
{
	struct net_device	*dev = alloc_etherdev(
						sizeof(struct danipc_priv));
	struct net_device	*dev = alloc_netdev(sizeof(struct danipc_priv),
					 "danipc", danipc_setup);
	int			rc;

	if (dev) {
		struct danipc_priv *priv = netdev_priv(dev);
		danipc_dev = dev;
		strlcpy(dev->name, "danipc", sizeof(dev->name));
		dev->netdev_ops		= &danipc_netdev_ops;
		dev->header_ops		= &danipc_header_ops;

		rc = parse_resources(pdev, priv);
@@ -274,7 +281,7 @@ static int danipc_probe(struct platform_device *pdev)
			rc = danipc_ll_init(priv);
			if (rc == 0) {
				dev->irq = priv->irq;
				danipc_set_dev_addr(dev->dev_addr);
				dev->dev_addr[0] = LOCAL_IPC_ID;

				rc = register_netdev(dev);
				if (rc == 0) {
+4 −6
Original line number Diff line number Diff line
@@ -96,7 +96,7 @@ char *ipc_buf_alloc(uint8_t dest_aid, enum ipc_trns_prio prio)
	if (likely(trns_funcs)) {
		alloc_func = trns_funcs->trns_alloc;
		if (likely(alloc_func)) {
			ptr = alloc_func(dest_aid, prio);
			ptr = alloc_func(cpuid, prio);

			/* Clear the 'Next buffer' field. */
			if (likely(ptr))
@@ -150,7 +150,7 @@ int32_t ipc_buf_free(char *buf_first, enum ipc_trns_prio prio)
					next_buf = ((struct ipc_msg_hdr *)
					 IPC_NEXT_PTR_PART(cur_buf))->next;
					free_func(IPC_NEXT_PTR_PART(cur_buf),
							dest_aid, prio);
							cpuid, prio);
					cur_buf = next_buf;
				} while ((uint32_t)cur_buf & IPC_BUF_TYPE_MTC);
				res = IPC_SUCCESS;
@@ -265,7 +265,6 @@ static int32_t ipc_msg_set_reply_ptr(
 *			msg		- Pointer to message data
 *			msg_len		- Message length
 *			msg_type	- Message type
 *			reply		- Pointer to allocated reply buffer
 *			prio		- Transport priority level
 *
 *
@@ -278,7 +277,6 @@ char *ipc_msg_alloc(
	char			*msg,
	size_t			msg_len,
	uint8_t			msg_type,
	char			*reply,
	enum ipc_trns_prio	prio
)
{
@@ -320,7 +318,7 @@ char *ipc_msg_alloc(
	} else if (first_buf) {
		ipc_msg_set_type(first_buf, msg_type);
		ipc_msg_set_len(first_buf, msg_len);
		ipc_msg_set_reply_ptr(first_buf, reply);
		ipc_msg_set_reply_ptr(first_buf, NULL);
		((struct ipc_msg_hdr *)first_buf)->dest_aid = dest_aid;
		((struct ipc_msg_hdr *)first_buf)->src_aid = src_aid;
		((struct ipc_msg_hdr *)first_buf)->request_num = ipc_req_sn;
@@ -388,7 +386,7 @@ int32_t ipc_msg_send(char *buf_first, enum ipc_trns_prio prio)
		if (likely(trns_funcs)) {
			send_func = trns_funcs->trns_send;
			if (send_func)
				res = send_func((char *)buf, dest_aid, prio);
				res = send_func((char *)buf, cpuid, prio);
		}
	}
	return res;
+0 −2
Original line number Diff line number Diff line
@@ -236,7 +236,6 @@ int32_t ipc_buf_free(char *buf_first, enum ipc_trns_prio pri);
 *			msg		- Pointer to message data (optional)
 *			msg_len		- Message length
 *			msg_type	- Message type
 *			reply		- Pointer to allocated reply buffer
 *			pri		- Transport priority level
 *
 *
@@ -250,7 +249,6 @@ char *ipc_msg_alloc
	char			*msg,
	size_t			msg_len,
	uint8_t			msg_type,
	char			*reply,
	enum ipc_trns_prio	pri
);

Loading