Netdev List
 help / color / mirror / Atom feed
* [PATCH 4/8] LLDP: PDU-handling routines
From: Eldad Zack @ 2012-06-25 18:28 UTC (permalink / raw)
  To: netdev; +Cc: Eldad Zack
In-Reply-To: <1340648900-6547-1-git-send-email-eldad@fogrefinery.com>

Routines for creation and parsing of LLPDUs.

Highlights:

* lldp_construct_pdu_list() constructs a list of TLVs
  according to device and configuration.

* lldp_tlv_list_len() calculates the space needed to
  send the above TLV list to the wire. Used when an sk_buff
  is allocated.

* lldp_put_tlv_skb_list() writes the TLV list to the sk_buff.

Signed-off-by: Eldad Zack <eldad@fogrefinery.com>
---
 net/lldp/lldpdu.c |  307 +++++++++++++++++++++++++++++++++++++++++++++++++++++
 1 file changed, 307 insertions(+)
 create mode 100644 net/lldp/lldpdu.c

diff --git a/net/lldp/lldpdu.c b/net/lldp/lldpdu.c
new file mode 100644
index 0000000..e71ddd7
--- /dev/null
+++ b/net/lldp/lldpdu.c
@@ -0,0 +1,307 @@
+/* LLDP		Link Layer Discovery Protocol impementation for Linux
+ *		IEEE Std 802.1ab
+ *
+ * Author:	Eldad Zack <eldad@fogrefinery.com>
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version
+ * 2 of the License, or (at your option) any later version.
+ */
+
+#include <linux/init.h>
+#include <linux/module.h>
+#include <linux/if_ether.h>
+#include <linux/if_vlan.h>
+#include <linux/netdevice.h>
+#include <linux/skbuff.h>
+#include <linux/utsname.h>
+#include "lldp.h"
+
+const unsigned char oui_802_1[LLDP_OUI_LEN] = LLDP_OUI_802_1;
+const unsigned char oui_802_3[LLDP_OUI_LEN] = LLDP_OUI_802_3;
+
+int lldp_tlv_list_len(struct list_head *head)
+{
+	struct lldp_tlv *tlv;
+	int len = 0;
+
+	list_for_each_entry(tlv, head, lh)
+		len += tlv->entry_len;
+
+	return len;
+}
+
+void lldp_tlv_calc_entry_len(struct lldp_tlv *tlv)
+{
+	uint16_t elen;
+
+	BUG_ON(tlv == NULL);
+	BUG_ON(tlv->len > LLDP_LEN_MAX);
+
+	elen = 2;		/* TLV Header */
+
+	if (tlv->subtype > 0)
+		elen += 1;
+
+	BUG_ON((tlv->oui != NULL) &&
+		(tlv->type != LLDP_TLV_ORGANIZATIONAL));
+	if (tlv->oui != NULL)
+		elen += LLDP_OUI_LEN;
+
+	elen += tlv->len;	/* Actual data length */
+
+	tlv->entry_len = elen;
+}
+
+void __lldp_add_tlv_list(struct list_head *head, unsigned short type,
+			unsigned short len, unsigned char *data,
+			unsigned char subtype, const unsigned char *oui)
+{
+	struct lldp_tlv *tlv;
+
+	BUG_ON(len > LLDP_LEN_MAX);
+	BUG_ON(head == NULL);
+
+	tlv = kzalloc(sizeof(struct lldp_tlv), GFP_ATOMIC);
+
+	tlv->type = type;
+	tlv->len = len;
+
+	tlv->val = kmalloc(len, GFP_ATOMIC);
+	memcpy(tlv->val, data, len);
+
+	tlv->subtype = subtype;
+
+	if (type == LLDP_TLV_ORGANIZATIONAL) {
+		BUG_ON(oui == NULL);
+
+		tlv->oui = kmalloc(LLDP_OUI_LEN, GFP_ATOMIC);
+		memcpy(tlv->oui, oui, LLDP_OUI_LEN);
+	}
+
+	lldp_tlv_calc_entry_len(tlv);
+
+	list_add_tail(&(tlv->lh), head);
+}
+
+inline void lldp_add_tlv_list(struct list_head *head, unsigned short type,
+			unsigned short len, unsigned char *data)
+{
+	__lldp_add_tlv_list(head, type, len, data, 0, NULL);
+}
+
+inline void lldp_add_tlv_subtype_list(struct list_head *head,
+				unsigned short type,
+				unsigned short len, unsigned char *data,
+				unsigned char subtype)
+{
+	__lldp_add_tlv_list(head, type, len, data, subtype, NULL);
+}
+
+inline void lldp_add_oui_tlv_list(struct list_head *head,
+				const unsigned char *oui,
+				unsigned short len, unsigned char *data,
+				unsigned char subtype)
+{
+	__lldp_add_tlv_list(head, LLDP_TLV_ORGANIZATIONAL, len, data,
+				subtype, oui);
+}
+
+inline void lldp_add_tlv_chassis_id(struct list_head *head,
+				struct net_device *dev)
+{
+	lldp_add_tlv_subtype_list(head, LLDP_TLV_CHASSIS_ID, ETH_ALEN,
+		dev->dev_addr, LLDP_ST_CHID_MAC_ADDR);
+}
+
+inline void lldp_add_tlv_port_id(struct list_head *head, struct net_device *dev)
+{
+	lldp_add_tlv_subtype_list(head, LLDP_TLV_PORT_ID, strlen(dev->name),
+		dev->name, LLDP_ST_PORTID_IFNAME);
+}
+
+inline void lldp_add_tlv_ttl(struct list_head *head, struct net_device *dev,
+				bool is_shutdown)
+{
+	uint16_t ttl;
+
+	if (is_shutdown) {
+		ttl = 0;
+	} else {
+		ttl = htons(sysctl_lldp_transmit_interval *
+				sysctl_lldp_hold_multiplier);
+	}
+
+	lldp_add_tlv_list(head, LLDP_TLV_TIME_TO_LIVE, sizeof(ttl),
+		(unsigned char *) &ttl);
+}
+
+inline void lldp_add_tlv_vlan(struct list_head *head, struct net_device *dev)
+{
+#if IS_ENABLED(CONFIG_VLAN_8021Q)
+	if (dev->flags & IFF_802_1Q_VLAN) {
+		uint16_t vlan = htons(vlan_dev_vlan_id(dev));
+		/* Clause F.2.1: Value of 0 signifies that the system
+		 * does not know the VLAN ID or doesn"t support it.
+		 */
+		if (vlan != 0) {
+			lldp_add_oui_tlv_list(head, oui_802_1, sizeof(vlan),
+				(unsigned char *) &vlan,
+				LLDP_802_1_PORT_VLANID);
+		}
+	}
+#endif
+}
+
+inline void lldp_add_tlv_mtu(struct list_head *head, struct net_device *dev)
+{
+	uint16_t mtu;
+
+	mtu = htons(dev->mtu);
+	lldp_add_oui_tlv_list(head, oui_802_3, sizeof(mtu),
+		(unsigned char *) &mtu, LLDP_802_3_MTU);
+}
+
+inline void lldp_add_tlv_port_description(struct list_head *head,
+					struct net_device *dev)
+{
+	char *desc = dev->ifalias;
+	if (desc == NULL)
+		return;
+
+	lldp_add_tlv_list(head, LLDP_TLV_PORT_DESCRIPTION, strlen(desc), desc);
+}
+
+inline void lldp_add_tlv_system_name(struct list_head *head,
+					struct net_device *dev)
+{
+	char *name = utsname()->nodename;
+	if (name == NULL)
+		return;
+
+	lldp_add_tlv_list(head, LLDP_TLV_SYSTEM_NAME, strlen(name), name);
+}
+
+inline void lldp_add_tlv_system_description(struct list_head *head,
+					struct net_device *dev)
+{
+	char *desc = utsname()->sysname;
+	if (desc == NULL)
+		return;
+
+	lldp_add_tlv_list(head, LLDP_TLV_SYSTEM_DESCRIPTION,
+		strlen(desc), desc);
+}
+
+inline void lldp_add_tlv_system_capabilities(struct list_head *head,
+					struct net_device *dev)
+{
+	struct lldp_caps caps;
+
+	caps.sys = htons(LLDP_CAP_BRIDGE | LLDP_CAP_ROUTER);
+	caps.enabled = htons(LLDP_CAP_ROUTER);
+
+	lldp_add_tlv_list(head, LLDP_TLV_SYSTEM_CAPABILITIES,
+		sizeof(struct lldp_caps), (unsigned char *) &caps);
+}
+
+void lldp_tlv_construct_list(struct list_head *head, struct net_device *dev,
+				bool is_shutdown)
+{
+	BUG_ON(head == NULL);
+
+	/* Mandatory TLVs with strict order */
+	lldp_add_tlv_chassis_id(head, dev);
+	lldp_add_tlv_port_id(head, dev);
+	lldp_add_tlv_ttl(head, dev, is_shutdown);
+
+	/* Shutdown PDU is limited to mandatory TLVs only */
+	if (is_shutdown)
+		goto end;
+
+	/* Optional TLVs */
+	lldp_add_tlv_port_description(head, dev);
+	lldp_add_tlv_system_name(head, dev);
+	lldp_add_tlv_system_description(head, dev);
+	lldp_add_tlv_system_capabilities(head, dev);
+
+	/* Additional 802.1 and 802.3 private TLVs */
+	lldp_add_tlv_vlan(head, dev);	/* Annex F.1 */
+	lldp_add_tlv_mtu(head, dev);	/* Annex G.5 */
+
+end:
+	/* End TLV */
+	lldp_add_tlv_list(head, LLDP_TLV_END, 0, NULL);
+}
+
+void lldp_tlv_destruct(struct lldp_tlv *tlv)
+{
+	if (tlv->oui != NULL)
+		kfree(tlv->oui);
+
+	if (tlv->val != NULL)
+		kfree(tlv->val);
+}
+
+void lldp_tlv_destruct_list(struct list_head *head)
+{
+	struct lldp_tlv *tlv, *tmp;
+
+	if (head == NULL)
+		return;
+
+	if (list_empty(head))
+		return;
+
+	list_for_each_entry_safe(tlv, tmp, head, lh) {
+		list_del(&tlv->lh);
+		lldp_tlv_destruct(tlv);
+		kfree(tlv);
+	}
+}
+
+inline uint16_t tlv_hdr(struct lldp_tlv *tlv)
+{
+	int len = tlv->entry_len - LLDP_TLV_HDR_LEN;
+
+	BUG_ON(tlv == NULL);
+	BUG_ON(len < 0);
+
+	return htons(((tlv->type << LLDP_TYPE_SHIFT) & LLDP_TYPE_MASK) |
+			(len & LLDP_LEN_MASK));
+}
+
+void lldp_tlv_put_skb_list(struct sk_buff *skb, struct list_head *head)
+{
+	struct lldp_tlv *tlv;
+	struct list_head *p;
+	unsigned char *buf;
+	u16 hdr;
+
+	list_for_each(p, head) {
+		tlv = list_entry(p, struct lldp_tlv, lh);
+
+		hdr = tlv_hdr(tlv);
+		buf = skb_put(skb, sizeof(hdr));
+		memcpy(buf, &hdr, sizeof(hdr));
+
+		BUG_ON((tlv->oui != NULL) &&
+			(tlv->type != LLDP_TLV_ORGANIZATIONAL));
+		if (tlv->oui != NULL) {
+			buf = skb_put(skb, LLDP_OUI_LEN);
+			memcpy(buf, tlv->oui, LLDP_OUI_LEN);
+		}
+
+		if (tlv->subtype > 0) {
+			buf = skb_put(skb, sizeof(unsigned char));
+			*buf = tlv->subtype;
+		}
+
+		if (tlv->len > 0) {
+			BUG_ON(tlv->val == NULL);
+			buf = skb_put(skb, tlv->len);
+			memcpy(buf, tlv->val, tlv->len);
+		}
+	}
+}
-- 
1.7.10

^ permalink raw reply related

* [PATCH 3/8] LLDP: Sysctl interface
From: Eldad Zack @ 2012-06-25 18:28 UTC (permalink / raw)
  To: netdev; +Cc: Eldad Zack
In-Reply-To: <1340648900-6547-1-git-send-email-eldad@fogrefinery.com>

Add 3 config items to LLDP via sysctl:
* Operational mode
* Message transmission interval
* Hold multiplier

Signed-off-by: Eldad Zack <eldad@fogrefinery.com>
---
 net/lldp/sysctl_net_lldp.c |   94 ++++++++++++++++++++++++++++++++++++++++++++
 1 file changed, 94 insertions(+)
 create mode 100644 net/lldp/sysctl_net_lldp.c

diff --git a/net/lldp/sysctl_net_lldp.c b/net/lldp/sysctl_net_lldp.c
new file mode 100644
index 0000000..dd5f5e3
--- /dev/null
+++ b/net/lldp/sysctl_net_lldp.c
@@ -0,0 +1,94 @@
+/* LLDP		Link Layer Discovery Protocol impementation for Linux
+ *		IEEE Std 802.1ab
+ *
+ * Author:	Eldad Zack <eldad@fogrefinery.com>
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version
+ * 2 of the License, or (at your option) any later version.
+ */
+
+#include <linux/sysctl.h>
+#include <linux/skbuff.h>
+#include <linux/socket.h>
+#include <linux/netdevice.h>
+#include <linux/init.h>
+#include "lldp.h"
+
+static int lldp_ttl_min = 1;
+static int lldp_ttl_max = 65535;
+
+/* Validate: (10.5.3, 10.5.4.1)
+ * 0 < transmit_interval * hold_multiplier <= 65535
+ */
+static int proc_dointvec_lldp_validate_ttl(ctl_table *table, int write,
+					void __user *buffer,
+					size_t *lenp, loff_t *ppos)
+{
+	int val, val2, ttl, ret;
+
+	ctl_table tmp = {
+		.data =		&val,
+		.maxlen =	sizeof(int),
+		.mode =		table->mode,
+		.extra1 =	&lldp_ttl_min,
+		.extra2 =	&lldp_ttl_max,
+	};
+
+	if (!write)
+		return proc_dointvec(table, write, buffer, lenp, ppos);
+
+	ret = proc_dointvec_minmax(&tmp, write, buffer, lenp, ppos);
+	if (ret == 0) {
+		val2 = *((int *)table->extra1);
+		ttl = val * val2;
+
+		if ((ttl >= lldp_ttl_min) && (ttl <= lldp_ttl_max))
+			*((int *)table->data) = val;
+		else
+			return -EINVAL;
+	}
+
+	return ret;
+}
+
+static struct ctl_table_header *lldp_table_header;
+
+static struct ctl_table lldp_table[] = {
+	{
+		.procname =	"lldp_op_mode",
+		.data =		&sysctl_lldp_operational_mode,
+		.maxlen =	sizeof(int),
+		.mode =		0644,
+		.proc_handler =	proc_dointvec,
+	},
+	{
+		.procname =	"transmit_interval",
+		.data =		&sysctl_lldp_transmit_interval,
+		.maxlen =	sizeof(int),
+		.mode =		0644,
+		.proc_handler =	proc_dointvec_lldp_validate_ttl,
+		.extra1 =	&sysctl_lldp_hold_multiplier,
+	},
+	{
+		.procname =	"hold_multiplier",
+		.data =		&sysctl_lldp_hold_multiplier,
+		.maxlen =	sizeof(int),
+		.mode =		0644,
+		.proc_handler =	proc_dointvec_lldp_validate_ttl,
+		.extra1 =	&sysctl_lldp_transmit_interval,
+	},
+	{ 0, },
+};
+
+void __init lldp_register_sysctl(void)
+{
+	lldp_table_header = register_net_sysctl(&init_net, "net/lldp",
+		lldp_table);
+}
+
+void __exit lldp_unregister_sysctl(void)
+{
+	unregister_net_sysctl_table(lldp_table_header);
+}
-- 
1.7.10

^ permalink raw reply related

* [PATCH 2/8] LLDP: Header
From: Eldad Zack @ 2012-06-25 18:28 UTC (permalink / raw)
  To: netdev; +Cc: Eldad Zack
In-Reply-To: <1340648900-6547-1-git-send-email-eldad@fogrefinery.com>

Constants and declarations for the Linux LLDP implementation.
The struct to be added netdevice is defined here.

Highlights:
* TLV struct
* TLV types
* TLV subtypes for Chassis ID and Port ID TLVs
* Capabilities bits and struct
* IEEE private OUIs and their subtypes (802.1, 802.3)
* Multicast address for LLDP

Signed-off-by: Eldad Zack <eldad@fogrefinery.com>
---
 net/lldp/lldp.h |  155 +++++++++++++++++++++++++++++++++++++++++++++++++++++++
 1 file changed, 155 insertions(+)
 create mode 100644 net/lldp/lldp.h

diff --git a/net/lldp/lldp.h b/net/lldp/lldp.h
new file mode 100644
index 0000000..d88feea
--- /dev/null
+++ b/net/lldp/lldp.h
@@ -0,0 +1,155 @@
+/* LLDP		Link Layer Discovery Protocol impementation for Linux
+ *		IEEE Std 802.1ab
+ *
+ * Author:	Eldad Zack <eldad@fogrefinery.com>
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version
+ * 2 of the License, or (at your option) any later version.
+ */
+
+#ifndef _LINUX_LLDP_H
+#define _LINUX_LLDP_H
+#include <linux/types.h>
+
+/* LLDP Multicast Address (Clause 8.1) */
+#define LLDP_MULTICAST_ADDR	{ 0x01, 0x80, 0xc2, 0x00, 0x00, 0x0e }
+
+/* Basic TLV format (Clause 9.4)
+ * TLV header:			16 bits
+ *
+ * LSB
+ *  0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5
+ * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+ * :      Length       :   Type    :
+ * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+ *
+ * Information string		0-511 bytes
+ */
+#define LLDP_TLV_HDR_LEN		2
+#define LLDP_TYPE_MASK			0xfe00
+#define LLDP_TYPE_SHIFT			9
+#define LLDP_LEN_MASK			0x01ff
+#define LLDP_LEN_MAX			511
+
+/* LLDP TLV types (Clause 9.4.1)
+ * TLVs number 0 to 3 are mandatory, the rest are optional.
+ */
+#define LLDP_TLV_END			0
+#define LLDP_TLV_CHASSIS_ID		1
+#define LLDP_TLV_PORT_ID		2
+#define LLDP_TLV_TIME_TO_LIVE		3
+#define LLDP_TLV_PORT_DESCRIPTION	4
+#define LLDP_TLV_SYSTEM_NAME		5
+#define LLDP_TLV_SYSTEM_DESCRIPTION	6
+#define LLDP_TLV_SYSTEM_CAPABILITIES	7
+#define LLDP_TLV_MANAGEMENT_ADDRESS	8
+/* Reserved: 9-126 */
+#define LLDP_TLV_ORGANIZATIONAL		127	/* Private TLVs */
+
+/* Chassis ID Subtypes, Reserved: 0,8-255. (Clause 9.5.2) */
+#define LLDP_ST_CHID_COMPONENT		1	/* Chassis component */
+#define LLDP_ST_CHID_IFALIAS		2	/* ifAlias (RFC 2863) */
+#define LLDP_ST_CHID_PORT_COMPONENT	3
+#define LLDP_ST_CHID_MAC_ADDR		4
+#define LLDP_ST_CHID_NET_ADDR		5
+#define LLDP_ST_CHID_IFNAME		6
+#define LLDP_ST_CHID_LOCAL		7
+
+/* Port ID Subtypes, Reserved: 0,8-255. (Clause 9.5.3) */
+#define LLDP_ST_PORTID_IFALIAS		1	/* ifAlias (RFC 2863) */
+#define LLDP_ST_PORTID_PORT_COMPONENT	2
+#define LLDP_ST_PORTID_MAC_ADDR		3
+#define LLDP_ST_PORTID_NET_ADDR		4
+#define LLDP_ST_PORTID_IFNAME		5	/* ifName (RFC 2863) */
+#define LLDP_ST_PORTID_AGENT_CIR_ID	6	/* Agent Circuit ID */
+#define LLDP_ST_PORTID_LOCAL		7
+
+/* System Capabilities (Clause 9.5.8.1)
+ * "Station Only" (bit 7) is mutually exclusive with
+ * all the other options.
+ */
+#define LLDP_CAP_OTHER			0x0001
+#define LLDP_CAP_REPEATER		0x0002
+#define LLDP_CAP_BRIDGE			0x0004
+#define LLDP_CAP_WLAN_AP		0x0008
+#define LLDP_CAP_ROUTER			0x0010
+#define LLDP_CAP_TELEPHONE		0x0020
+#define LLDP_CAP_DOCSIS			0x0040
+#define LLDP_CAP_STATION_ONLY		0x0080
+
+/* Organizationally Specific TLVs (Clause 9.6)
+ */
+#define LLDP_OUI_LEN		3
+#define LLDP_OUI_802_1		{ 0x00, 0x80, 0xc2 }
+#define LLDP_OUI_802_3		{ 0x00, 0x12, 0x0f }
+
+/* Annex F: 802.1 OUI Subtypes */
+#define LLDP_802_1_PORT_VLANID		1
+#define LLDP_802_1_PORT_PROT_VLAID	2
+#define LLDP_802_1_VLAN_NAME		3
+#define LLDP_802_1_PROTOCOL_ID		4
+
+/* Annex G: 802.3 OUI Subtypes */
+#define LLDP_802_3_MAC_PHY		1
+#define LLDP_802_3_PMD			2
+#define LLDP_802_3_LAG			3
+#define LLDP_802_3_MTU			4
+
+/* Default transmission parameters (Clause 10.5.3.3) */
+#define LLDP_DEFAULT_MSG_TX_INTERVAL	30
+#define	LLDP_DEFAULT_MSG_TX_HOLD_MULT	4
+
+struct lldp_tlv {
+	struct list_head lh;
+	uint16_t type;
+	uint16_t len;
+	unsigned char *val;
+	unsigned char subtype;
+	unsigned char *oui;
+	uint16_t entry_len;
+};
+
+struct lldp_caps {
+	u16 sys;
+	u16 enabled;
+} __packed;
+
+/* lldp_tx */
+void __lldp_send(struct net_device *dev, bool is_shutdown);
+
+static inline void lldp_send(struct net_device *dev)
+{
+	__lldp_send(dev, false);
+}
+
+static inline void lldp_send_shutdown(struct net_device *dev)
+{
+	__lldp_send(dev, true);
+}
+
+/* lldpdu */
+void lldp_tlv_construct_list(struct list_head *head, struct net_device *dev,
+				bool is_shutdown);
+void lldp_tlv_destruct_list(struct list_head *head);
+void lldp_tlv_put_skb_list(struct sk_buff *skb, struct list_head *head);
+int lldp_tlv_list_len(struct list_head *head);
+
+/* netdevice */
+struct __rcu lldp_dev {
+	struct timer_list *tx_timer;
+};
+
+/* sysctl */
+void __init lldp_register_sysctl(void);
+void __exit lldp_unregister_sysctl(void);
+
+#define LLDP_SYSCTL_OP_SUPPRESS		0x00
+#define LLDP_SYSCTL_OP_TX		0x01
+
+extern int sysctl_lldp_operational_mode;
+extern int sysctl_lldp_transmit_interval;
+extern int sysctl_lldp_hold_multiplier;
+
+#endif /* _LINUX_LLDP_H */
-- 
1.7.10

^ permalink raw reply related

* [PATCH 1/8] if_ether.h: Add LLDP ethertype
From: Eldad Zack @ 2012-06-25 18:28 UTC (permalink / raw)
  To: netdev; +Cc: Eldad Zack
In-Reply-To: <1340648900-6547-1-git-send-email-eldad@fogrefinery.com>

The LLDP ethertype is defined in IEEE Std 802.1ab (2005), clause 8.3.

Signed-off-by: Eldad Zack <eldad@fogrefinery.com>
---
 include/linux/if_ether.h |    1 +
 1 file changed, 1 insertion(+)

diff --git a/include/linux/if_ether.h b/include/linux/if_ether.h
index 56d907a..a5f0612 100644
--- a/include/linux/if_ether.h
+++ b/include/linux/if_ether.h
@@ -81,6 +81,7 @@
 #define ETH_P_8021AD	0x88A8          /* 802.1ad Service VLAN		*/
 #define ETH_P_802_EX1	0x88B5		/* 802.1 Local Experimental 1.  */
 #define ETH_P_TIPC	0x88CA		/* TIPC 			*/
+#define ETH_P_LLDP	0x88CC		/* 802.1ab Link Layer Discovery	*/
 #define ETH_P_8021AH	0x88E7          /* 802.1ah Backbone Service Tag */
 #define ETH_P_1588	0x88F7		/* IEEE 1588 Timesync */
 #define ETH_P_FCOE	0x8906		/* Fibre Channel over Ethernet  */
-- 
1.7.10

^ permalink raw reply related

* [PATCH RFC 0/8] LLDP implementation for Linux
From: Eldad Zack @ 2012-06-25 18:28 UTC (permalink / raw)
  To: netdev; +Cc: Eldad Zack

Hi all,

This series of patches provides a partial LLDP (IEEE Std 802.1ab)
implementation.

I'd really appreciate a review of it.

LLDP is a simple discovery protocol which advertises the identification and
other info (such as MTU or capabilities) of device on the link. It can also
help debug misconfigurations on the link layer (wrong MTU, wrong VLAN).

Some notes/questions:

* Applies against net-next and mainline.

* Included in this series is only LLDP output code.
  This is not an issue since input and output are decoupled in LLDP anyway.
  I'm working on the input code as well and will post it at some point in the
  future.

* Sysctl is used to do (some) configuration. This is done globally right now.
  Before I add per-device sysctls: is it at all appropriate to use sysctl
  here?

* By default, transmission is suppressed. To arm it, set
	/proc/sys/net/lldp/lldp_op_mode
  to 1.

* I've tested it on x86_64 and (qemu'd) x86.

* I've tested it on my machine and it works with Ethernet and WLAN.

* The last patch ("8021q/vlan: process NETDEV_GOING_DOWN") is needed
  to be able to send shutdown PDU on VLAN interfaces, but has otherwise
  no effect.

* Is there a better way to deal with 16-bit endianness other than masking and
  shifting, when one field is more than a byte long (in this case 7/9)?

* I usually only work on it on weekends, so I might be slow in responding back.

Thanks in advance if you're taking the time to review it or test it!

Signed-off-by: Eldad Zack <eldad@fogrefinery.com>

^ permalink raw reply

* Re: [RFC net-next (v2) 14/14] ixgbevf: set maximal number of default RSS queues
From: Eilon Greenstein @ 2012-06-25 18:28 UTC (permalink / raw)
  To: Alexander Duyck; +Cc: Yuval Mintz, davem, netdev, Jeff Kirsher, Greg Rose
In-Reply-To: <4FE892CD.1020804@intel.com>

On Mon, 2012-06-25 at 09:33 -0700, Alexander Duyck wrote:
> I suggest you locate where we set "adapter->num_rx_queues" and attempt
> to address the issue there.

I see what you mean. On one hand, you use the num_rx_queues as if it can
get higher numbers and the code seems to be ready for that with all the
for loops in place, but on the other hand, it is hard coded to 1 at
ixgbevf_set_num_queues and it seems weird to add min function with
explicit '1'. Do you suggest to leave this driver alone hoping that if
in the future the '1' will change the author will remember to use the
default value?

Thanks,
Eilon

^ permalink raw reply

* RE: [RFC net-next (v2) 11/14] igb: set maximal number of default RSS queues
From: Eilon Greenstein @ 2012-06-25 18:20 UTC (permalink / raw)
  To: Vick, Matthew
  Cc: Yuval Mintz, davem@davemloft.net, netdev@vger.kernel.org,
	Kirsher, Jeffrey T
In-Reply-To: <06DFBC1E25D8024DB214DC7F41A3CD3448870CE4@ORSMSX101.amr.corp.intel.com>

On Mon, 2012-06-25 at 17:31 +0000, Vick, Matthew wrote:
> > -----Original Message-----
> > From: netdev-owner@vger.kernel.org [mailto:netdev-
> > owner@vger.kernel.org] On Behalf Of Yuval Mintz
> > Sent: Monday, June 25, 2012 4:46 AM
> > To: davem@davemloft.net; netdev@vger.kernel.org
> > Cc: eilong@broadcom.com; Yuval Mintz; Kirsher, Jeffrey T
> > Subject: [RFC net-next (v2) 11/14] igb: set maximal number of default
> > RSS queues
> > 
> > Signed-off-by: Yuval Mintz <yuvalmin@broadcom.com>
> > Signed-off-by: Eilon Greenstein <eilong@broadcom.com>
> > 
> > Cc: Jeff Kirsher <jeffrey.t.kirsher@intel.com>
> > ---
> >  drivers/net/ethernet/intel/igb/igb_main.c |    3 ++-
> >  1 files changed, 2 insertions(+), 1 deletions(-)
> > 
> > diff --git a/drivers/net/ethernet/intel/igb/igb_main.c
> > b/drivers/net/ethernet/intel/igb/igb_main.c
> > index 01ced68..b11ee60 100644
> > --- a/drivers/net/ethernet/intel/igb/igb_main.c
> > +++ b/drivers/net/ethernet/intel/igb/igb_main.c
> > @@ -2465,7 +2465,8 @@ static int __devinit igb_sw_init(struct
> > igb_adapter *adapter)
> >  		break;
> >  	}
> > 
> > -	adapter->rss_queues = min_t(u32, max_rss_queues,
> > num_online_cpus());
> > +	adapter->rss_queues = min_t(u32, max_rss_queues,
> > +				    netif_get_num_default_rss_queues());
> > 
> >  	/* Determine if we need to pair queues. */
> >  	switch (hw->mac.type) {
> > --
> > 1.7.9.rc2
> 
> Since igb supports a maximum of 8 RSS queues anyway, it's generally unaffected by this change. That being said, I'm confused about what you're trying to accomplish--is it to standardize the number of RSS queues or limit the number of interrupts by default? Or is it the former with a hope that it will trickle down to the latter?
> 
> For example, if you take an igb device that supports 8 RSS queues (say, I350) and you change the default to 4 RSS queues, you will end up with the same number of interrupt vectors being requested as we will disable queue pairing and request separate vectors for Rx/Tx queues. I haven't looked at the other drivers affected by this RFC, but it's possible other drivers behave the same way.

The main motivation is the Rx rings that consume significant amount of
memory. The MSI-X vectors are a nice byproduct, but the logic you
describe still sounds good for this kind of low numbers.

^ permalink raw reply

* Re: [net-next RFC V4 PATCH 0/4] Multiqueue virtio-net
From: Shirley Ma @ 2012-06-25 18:01 UTC (permalink / raw)
  To: Jason Wang
  Cc: krkumar2, habanero, kvm, mst, netdev, linux-kernel,
	virtualization, edumazet, tahm, jwhan, davem
In-Reply-To: <20120625090829.7263.65026.stgit@amd-6168-8-1.englab.nay.redhat.com>

Hello Jason,

Good work. Do you have local guest to guest results?

Thanks
Shirley

^ permalink raw reply

* Re: [RFC net-next (v2) 12/14] ixgbe: set maximal number of default RSS queues
From: Eilon Greenstein @ 2012-06-25 17:53 UTC (permalink / raw)
  To: Alexander Duyck; +Cc: Yuval Mintz, davem, netdev, Jeff Kirsher, John Fastabend
In-Reply-To: <4FE88770.7070007@intel.com>

On Mon, 2012-06-25 at 08:44 -0700, Alexander Duyck wrote:
> This doesn't limit queues, only interrupt vectors.  As I told you before
> you should look at the ixgbe_set_rss_queues function if you actually
> want to limit the number of RSS queues.

How about this:
diff --git a/drivers/net/ethernet/intel/ixgbe/ixgbe_lib.c b/drivers/net/ethernet/intel/ixgbe/ixgbe_lib.c
index af1a531..23a8609 100644
--- a/drivers/net/ethernet/intel/ixgbe/ixgbe_lib.c
+++ b/drivers/net/ethernet/intel/ixgbe/ixgbe_lib.c
@@ -277,6 +277,8 @@ static inline bool ixgbe_set_rss_queues(struct ixgbe_adapter *adapter)
 	bool ret = false;
 	struct ixgbe_ring_feature *f = &adapter->ring_feature[RING_F_RSS];
 
+	f->indices = min_t(int, netif_get_num_default_rss_queues(), f->indices);
+
 	if (adapter->flags & IXGBE_FLAG_RSS_ENABLED) {
 		f->mask = 0xF;
 		adapter->num_rx_queues = f->indices;
@@ -302,7 +304,9 @@ static inline bool ixgbe_set_fdir_queues(struct ixgbe_adapter *adapter)
 	bool ret = false;
 	struct ixgbe_ring_feature *f_fdir = &adapter->ring_feature[RING_F_FDIR];
 
-	f_fdir->indices = min_t(int, num_online_cpus(), f_fdir->indices);
+	f_fdir->indices = min_t(int, netif_get_num_default_rss_queues(),
+				f_fdir->indices);
+
 	f_fdir->mask = 0;
 
 	/*
@@ -339,8 +343,7 @@ static inline bool ixgbe_set_fcoe_queues(struct ixgbe_adapter *adapter)
 	if (!(adapter->flags & IXGBE_FLAG_FCOE_ENABLED))
 		return false;
 
-	f->indices = min_t(int, num_online_cpus(), f->indices);
-
+	f->indices = min_t(int, f->indices, netif_get_num_default_rss_queues());
 	adapter->num_rx_queues = 1;
 	adapter->num_tx_queues = 1;
 

^ permalink raw reply related

* [net-next 11/11] caif-hsi: Remove use of module parameters
From: sjur.brandeland @ 2012-06-25 17:49 UTC (permalink / raw)
  To: davem; +Cc: netdev, sjurbren, Sjur Brændeland
In-Reply-To: <1340646583-21059-1-git-send-email-sjur.brandeland@stericsson.com>

From: Sjur Brændeland <sjur.brandeland@stericsson.com>

Remove use of module parameters on caif hsi device, as
rtnl configuration parameters are already supported.

All caif hsi configuration data is put in cfhsi_config,
and default values in hsi_default_config.

Signed-off-by: Sjur Brændeland <sjur.brandeland@stericsson.com>
---
 drivers/net/caif/caif_hsi.c |  151 ++++++++++++++++++++----------------------
 include/net/caif/caif_hsi.h |   14 +++-
 2 files changed, 82 insertions(+), 83 deletions(-)

diff --git a/drivers/net/caif/caif_hsi.c b/drivers/net/caif/caif_hsi.c
index 0927c10..1c2bd01 100644
--- a/drivers/net/caif/caif_hsi.c
+++ b/drivers/net/caif/caif_hsi.c
@@ -32,51 +32,39 @@ MODULE_DESCRIPTION("CAIF HSI driver");
 #define PAD_POW2(x, pow) ((((x)&((pow)-1)) == 0) ? 0 :\
 				(((pow)-((x)&((pow)-1)))))
 
-static int inactivity_timeout = 1000;
-module_param(inactivity_timeout, int, S_IRUGO | S_IWUSR);
-MODULE_PARM_DESC(inactivity_timeout, "Inactivity timeout on HSI, ms.");
+static const struct cfhsi_config  hsi_default_config = {
 
-static int aggregation_timeout = 1;
-module_param(aggregation_timeout, int, S_IRUGO | S_IWUSR);
-MODULE_PARM_DESC(aggregation_timeout, "Aggregation timeout on HSI, ms.");
+	/* Inactivity timeout on HSI, ms */
+	.inactivity_timeout = HZ,
 
-/*
- * HSI padding options.
- * Warning: must be a base of 2 (& operation used) and can not be zero !
- */
-static int hsi_head_align = 4;
-module_param(hsi_head_align, int, S_IRUGO);
-MODULE_PARM_DESC(hsi_head_align, "HSI head alignment.");
+	/* Aggregation timeout (ms) of zero means no aggregation is done*/
+	.aggregation_timeout = 1,
 
-static int hsi_tail_align = 4;
-module_param(hsi_tail_align, int, S_IRUGO);
-MODULE_PARM_DESC(hsi_tail_align, "HSI tail alignment.");
-
-/*
- * HSI link layer flowcontrol thresholds.
- * Warning: A high threshold value migth increase throughput but it will at
- * the same time prevent channel prioritization and increase the risk of
- * flooding the modem. The high threshold should be above the low.
- */
-static int hsi_high_threshold = 100;
-module_param(hsi_high_threshold, int, S_IRUGO);
-MODULE_PARM_DESC(hsi_high_threshold, "HSI high threshold (FLOW OFF).");
+	/*
+	 * HSI link layer flow-control thresholds.
+	 * Threshold values for the HSI packet queue. Flow-control will be
+	 * asserted when the number of packets exceeds q_high_mark. It will
+	 * not be de-asserted before the number of packets drops below
+	 * q_low_mark.
+	 * Warning: A high threshold value might increase throughput but it
+	 * will at the same time prevent channel prioritization and increase
+	 * the risk of flooding the modem. The high threshold should be above
+	 * the low.
+	 */
+	.q_high_mark = 100,
+	.q_low_mark = 50,
 
-static int hsi_low_threshold = 50;
-module_param(hsi_low_threshold, int, S_IRUGO);
-MODULE_PARM_DESC(hsi_low_threshold, "HSI high threshold (FLOW ON).");
+	/*
+	 * HSI padding options.
+	 * Warning: must be a base of 2 (& operation used) and can not be zero !
+	 */
+	.head_align = 4,
+	.tail_align = 4,
+};
 
 #define ON 1
 #define OFF 0
 
-/*
- * Threshold values for the HSI packet queue. Flowcontrol will be asserted
- * when the number of packets exceeds HIGH_WATER_MARK. It will not be
- * de-asserted before the number of packets drops below LOW_WATER_MARK.
- */
-#define LOW_WATER_MARK   hsi_low_threshold
-#define HIGH_WATER_MARK  hsi_high_threshold
-
 static LIST_HEAD(cfhsi_list);
 
 static void cfhsi_inactivity_tout(unsigned long arg)
@@ -99,8 +87,8 @@ static void cfhsi_update_aggregation_stats(struct cfhsi *cfhsi,
 	int hpad, tpad, len;
 
 	info = (struct caif_payload_info *)&skb->cb;
-	hpad = 1 + PAD_POW2((info->hdr_len + 1), hsi_head_align);
-	tpad = PAD_POW2((skb->len + hpad), hsi_tail_align);
+	hpad = 1 + PAD_POW2((info->hdr_len + 1), cfhsi->cfg.head_align);
+	tpad = PAD_POW2((skb->len + hpad), cfhsi->cfg.tail_align);
 	len = skb->len + hpad + tpad;
 
 	if (direction > 0)
@@ -113,7 +101,7 @@ static bool cfhsi_can_send_aggregate(struct cfhsi *cfhsi)
 {
 	int i;
 
-	if (cfhsi->aggregation_timeout == 0)
+	if (cfhsi->cfg.aggregation_timeout == 0)
 		return true;
 
 	for (i = 0; i < CFHSI_PRIO_BEBK; ++i) {
@@ -169,7 +157,7 @@ static void cfhsi_abort_tx(struct cfhsi *cfhsi)
 	cfhsi->tx_state = CFHSI_TX_STATE_IDLE;
 	if (!test_bit(CFHSI_SHUTDOWN, &cfhsi->bits))
 		mod_timer(&cfhsi->inactivity_timer,
-			jiffies + cfhsi->inactivity_timeout);
+			jiffies + cfhsi->cfg.inactivity_timeout);
 	spin_unlock_bh(&cfhsi->lock);
 }
 
@@ -250,8 +238,8 @@ static int cfhsi_tx_frm(struct cfhsi_desc *desc, struct cfhsi *cfhsi)
 		/* Calculate needed head alignment and tail alignment. */
 		info = (struct caif_payload_info *)&skb->cb;
 
-		hpad = 1 + PAD_POW2((info->hdr_len + 1), hsi_head_align);
-		tpad = PAD_POW2((skb->len + hpad), hsi_tail_align);
+		hpad = 1 + PAD_POW2((info->hdr_len + 1), cfhsi->cfg.head_align);
+		tpad = PAD_POW2((skb->len + hpad), cfhsi->cfg.tail_align);
 
 		/* Check if frame still fits with added alignment. */
 		if ((skb->len + hpad + tpad) <= CFHSI_MAX_EMB_FRM_SZ) {
@@ -292,8 +280,8 @@ static int cfhsi_tx_frm(struct cfhsi_desc *desc, struct cfhsi *cfhsi)
 		/* Calculate needed head alignment and tail alignment. */
 		info = (struct caif_payload_info *)&skb->cb;
 
-		hpad = 1 + PAD_POW2((info->hdr_len + 1), hsi_head_align);
-		tpad = PAD_POW2((skb->len + hpad), hsi_tail_align);
+		hpad = 1 + PAD_POW2((info->hdr_len + 1), cfhsi->cfg.head_align);
+		tpad = PAD_POW2((skb->len + hpad), cfhsi->cfg.tail_align);
 
 		/* Fill in CAIF frame length in descriptor. */
 		desc->cffrm_len[nfrms] = hpad + skb->len + tpad;
@@ -364,7 +352,7 @@ static void cfhsi_start_tx(struct cfhsi *cfhsi)
 			cfhsi->tx_state = CFHSI_TX_STATE_IDLE;
 			/* Start inactivity timer. */
 			mod_timer(&cfhsi->inactivity_timer,
-				jiffies + cfhsi->inactivity_timeout);
+				jiffies + cfhsi->cfg.inactivity_timeout);
 			spin_unlock_bh(&cfhsi->lock);
 			break;
 		}
@@ -390,7 +378,7 @@ static void cfhsi_tx_done(struct cfhsi *cfhsi)
 	 */
 	spin_lock_bh(&cfhsi->lock);
 	if (cfhsi->flow_off_sent &&
-			cfhsi_tx_queue_len(cfhsi) <= cfhsi->q_low_mark &&
+			cfhsi_tx_queue_len(cfhsi) <= cfhsi->cfg.q_low_mark &&
 			cfhsi->cfdev.flowctrl) {
 
 		cfhsi->flow_off_sent = 0;
@@ -402,7 +390,7 @@ static void cfhsi_tx_done(struct cfhsi *cfhsi)
 		cfhsi_start_tx(cfhsi);
 	} else {
 		mod_timer(&cfhsi->aggregation_timer,
-			jiffies + cfhsi->aggregation_timeout);
+			jiffies + cfhsi->cfg.aggregation_timeout);
 		spin_unlock_bh(&cfhsi->lock);
 	}
 
@@ -645,7 +633,7 @@ static void cfhsi_rx_done(struct cfhsi *cfhsi)
 	/* Update inactivity timer if pending. */
 	spin_lock_bh(&cfhsi->lock);
 	mod_timer_pending(&cfhsi->inactivity_timer,
-			jiffies + cfhsi->inactivity_timeout);
+			jiffies + cfhsi->cfg.inactivity_timeout);
 	spin_unlock_bh(&cfhsi->lock);
 
 	if (cfhsi->rx_state.state == CFHSI_RX_STATE_DESC) {
@@ -880,7 +868,7 @@ wake_ack:
 			__func__);
 		/* Start inactivity timer. */
 		mod_timer(&cfhsi->inactivity_timer,
-				jiffies + cfhsi->inactivity_timeout);
+				jiffies + cfhsi->cfg.inactivity_timeout);
 		spin_unlock_bh(&cfhsi->lock);
 		return;
 	}
@@ -1071,7 +1059,7 @@ static int cfhsi_xmit(struct sk_buff *skb, struct net_device *dev)
 
 	/* Send flow off if number of packets is above high water mark. */
 	if (!cfhsi->flow_off_sent &&
-		cfhsi_tx_queue_len(cfhsi) > cfhsi->q_high_mark &&
+		cfhsi_tx_queue_len(cfhsi) > cfhsi->cfg.q_high_mark &&
 		cfhsi->cfdev.flowctrl) {
 		cfhsi->flow_off_sent = 1;
 		cfhsi->cfdev.flowctrl(cfhsi->ndev, OFF);
@@ -1143,6 +1131,7 @@ static void cfhsi_setup(struct net_device *dev)
 	cfhsi->cfdev.use_stx = false;
 	cfhsi->cfdev.use_fcs = false;
 	cfhsi->ndev = dev;
+	cfhsi->cfg = hsi_default_config;
 }
 
 static int cfhsi_open(struct net_device *ndev)
@@ -1158,9 +1147,6 @@ static int cfhsi_open(struct net_device *ndev)
 
 	/* Set flow info */
 	cfhsi->flow_off_sent = 0;
-	cfhsi->q_low_mark = LOW_WATER_MARK;
-	cfhsi->q_high_mark = HIGH_WATER_MARK;
-
 
 	/*
 	 * Allocate a TX buffer with the size of a HSI packet descriptors
@@ -1188,20 +1174,8 @@ static int cfhsi_open(struct net_device *ndev)
 		goto err_alloc_rx_flip;
 	}
 
-	/* Pre-calculate inactivity timeout. */
-	if (inactivity_timeout != -1) {
-		cfhsi->inactivity_timeout =
-				inactivity_timeout * HZ / 1000;
-		if (!cfhsi->inactivity_timeout)
-			cfhsi->inactivity_timeout = 1;
-		else if (cfhsi->inactivity_timeout > NEXT_TIMER_MAX_DELTA)
-			cfhsi->inactivity_timeout = NEXT_TIMER_MAX_DELTA;
-	} else {
-		cfhsi->inactivity_timeout = NEXT_TIMER_MAX_DELTA;
-	}
-
 	/* Initialize aggregation timeout */
-	cfhsi->aggregation_timeout = aggregation_timeout;
+	cfhsi->cfg.aggregation_timeout = hsi_default_config.aggregation_timeout;
 
 	/* Initialize recieve vaiables. */
 	cfhsi->rx_ptr = cfhsi->rx_buf;
@@ -1350,24 +1324,39 @@ static void cfhsi_netlink_parms(struct nlattr *data[], struct cfhsi *cfhsi)
 	}
 
 	i = __IFLA_CAIF_HSI_INACTIVITY_TOUT;
-	if (data[i])
-		inactivity_timeout = nla_get_u32(data[i]);
+	/*
+	 * Inactivity timeout in millisecs. Lowest possible value is 1,
+	 * and highest possible is NEXT_TIMER_MAX_DELTA.
+	 */
+	if (data[i]) {
+		u32 inactivity_timeout = nla_get_u32(data[i]);
+		/* Pre-calculate inactivity timeout. */
+		cfhsi->cfg.inactivity_timeout =	inactivity_timeout * HZ / 1000;
+		if (cfhsi->cfg.inactivity_timeout == 0)
+			cfhsi->cfg.inactivity_timeout = 1;
+		else if (cfhsi->cfg.inactivity_timeout > NEXT_TIMER_MAX_DELTA)
+			cfhsi->cfg.inactivity_timeout = NEXT_TIMER_MAX_DELTA;
+	}
 
 	i = __IFLA_CAIF_HSI_AGGREGATION_TOUT;
 	if (data[i])
-		aggregation_timeout = nla_get_u32(data[i]);
+		cfhsi->cfg.aggregation_timeout = nla_get_u32(data[i]);
 
 	i = __IFLA_CAIF_HSI_HEAD_ALIGN;
 	if (data[i])
-		hsi_head_align = nla_get_u32(data[i]);
+		cfhsi->cfg.head_align = nla_get_u32(data[i]);
 
 	i = __IFLA_CAIF_HSI_TAIL_ALIGN;
 	if (data[i])
-		hsi_tail_align = nla_get_u32(data[i]);
+		cfhsi->cfg.tail_align = nla_get_u32(data[i]);
 
 	i = __IFLA_CAIF_HSI_QHIGH_WATERMARK;
 	if (data[i])
-		hsi_high_threshold = nla_get_u32(data[i]);
+		cfhsi->cfg.q_high_mark = nla_get_u32(data[i]);
+
+	i = __IFLA_CAIF_HSI_QLOW_WATERMARK;
+	if (data[i])
+		cfhsi->cfg.q_low_mark = nla_get_u32(data[i]);
 }
 
 static int caif_hsi_changelink(struct net_device *dev, struct nlattr *tb[],
@@ -1398,16 +1387,20 @@ static size_t caif_hsi_get_size(const struct net_device *dev)
 
 static int caif_hsi_fill_info(struct sk_buff *skb, const struct net_device *dev)
 {
+	struct cfhsi *cfhsi = netdev_priv(dev);
+
 	if (nla_put_u32(skb, __IFLA_CAIF_HSI_INACTIVITY_TOUT,
-			inactivity_timeout) ||
+			cfhsi->cfg.inactivity_timeout) ||
 	    nla_put_u32(skb, __IFLA_CAIF_HSI_AGGREGATION_TOUT,
-			aggregation_timeout) ||
-	    nla_put_u32(skb, __IFLA_CAIF_HSI_HEAD_ALIGN, hsi_head_align) ||
-	    nla_put_u32(skb, __IFLA_CAIF_HSI_TAIL_ALIGN, hsi_tail_align) ||
+			cfhsi->cfg.aggregation_timeout) ||
+	    nla_put_u32(skb, __IFLA_CAIF_HSI_HEAD_ALIGN,
+			cfhsi->cfg.head_align) ||
+	    nla_put_u32(skb, __IFLA_CAIF_HSI_TAIL_ALIGN,
+			cfhsi->cfg.tail_align) ||
 	    nla_put_u32(skb, __IFLA_CAIF_HSI_QHIGH_WATERMARK,
-			hsi_high_threshold) ||
+			cfhsi->cfg.q_high_mark) ||
 	    nla_put_u32(skb, __IFLA_CAIF_HSI_QLOW_WATERMARK,
-			hsi_low_threshold))
+			cfhsi->cfg.q_low_mark))
 		return -EMSGSIZE;
 
 	return 0;
diff --git a/include/net/caif/caif_hsi.h b/include/net/caif/caif_hsi.h
index 6dc7dc2..bcb9cc3 100644
--- a/include/net/caif/caif_hsi.h
+++ b/include/net/caif/caif_hsi.h
@@ -132,6 +132,15 @@ enum {
 	CFHSI_PRIO_LAST,
 };
 
+struct cfhsi_config {
+	u32 inactivity_timeout;
+	u32 aggregation_timeout;
+	u32 head_align;
+	u32 tail_align;
+	u32 q_high_mark;
+	u32 q_low_mark;
+};
+
 /* Structure implemented by CAIF HSI drivers. */
 struct cfhsi {
 	struct caif_dev_common cfdev;
@@ -142,7 +151,7 @@ struct cfhsi {
 	struct cfhsi_ops *ops;
 	int tx_state;
 	struct cfhsi_rx_state rx_state;
-	unsigned long inactivity_timeout;
+	struct cfhsi_config cfg;
 	int rx_len;
 	u8 *rx_ptr;
 	u8 *tx_buf;
@@ -150,8 +159,6 @@ struct cfhsi {
 	u8 *rx_flip_buf;
 	spinlock_t lock;
 	int flow_off_sent;
-	u32 q_low_mark;
-	u32 q_high_mark;
 	struct list_head list;
 	struct work_struct wake_up_work;
 	struct work_struct wake_down_work;
@@ -164,7 +171,6 @@ struct cfhsi {
 	struct timer_list rx_slowpath_timer;
 
 	/* TX aggregation */
-	unsigned long aggregation_timeout;
 	int aggregation_len;
 	struct timer_list aggregation_timer;
 
-- 
1.7.5.4

^ permalink raw reply related

* [net-next 10/11] caif-hsi: Replace platform device with ops structure.
From: sjur.brandeland @ 2012-06-25 17:49 UTC (permalink / raw)
  To: davem; +Cc: netdev, sjurbren, Sjur Brændeland
In-Reply-To: <1340646583-21059-1-git-send-email-sjur.brandeland@stericsson.com>

From: Sjur Brændeland <sjur.brandeland@stericsson.com>

Remove use of struct platform_device, and replace it with
struct cfhsi_ops. Updated variable names in the same
spirit:
cfhsi_get_dev to cfhsi_get_ops,
cfhsi->dev to cfhsi->ops and,
cfhsi->dev.drv to cfhsi->ops->cb_ops.

Signed-off-by: Sjur Brændeland <sjur.brandeland@stericsson.com>
---
 drivers/net/caif/caif_hsi.c |  109 ++++++++++++++++++++-----------------------
 include/net/caif/caif_hsi.h |   38 ++++++++--------
 2 files changed, 70 insertions(+), 77 deletions(-)

diff --git a/drivers/net/caif/caif_hsi.c b/drivers/net/caif/caif_hsi.c
index a14f85c..0927c10 100644
--- a/drivers/net/caif/caif_hsi.c
+++ b/drivers/net/caif/caif_hsi.c
@@ -11,7 +11,6 @@
 #include <linux/init.h>
 #include <linux/module.h>
 #include <linux/device.h>
-#include <linux/platform_device.h>
 #include <linux/netdevice.h>
 #include <linux/string.h>
 #include <linux/list.h>
@@ -184,7 +183,7 @@ static int cfhsi_flush_fifo(struct cfhsi *cfhsi)
 		__func__);
 
 	do {
-		ret = cfhsi->dev->cfhsi_fifo_occupancy(cfhsi->dev,
+		ret = cfhsi->ops->cfhsi_fifo_occupancy(cfhsi->ops,
 				&fifo_occupancy);
 		if (ret) {
 			netdev_warn(cfhsi->ndev,
@@ -197,8 +196,8 @@ static int cfhsi_flush_fifo(struct cfhsi *cfhsi)
 
 		fifo_occupancy = min(sizeof(buffer), fifo_occupancy);
 		set_bit(CFHSI_FLUSH_FIFO, &cfhsi->bits);
-		ret = cfhsi->dev->cfhsi_rx(buffer, fifo_occupancy,
-				cfhsi->dev);
+		ret = cfhsi->ops->cfhsi_rx(buffer, fifo_occupancy,
+				cfhsi->ops);
 		if (ret) {
 			clear_bit(CFHSI_FLUSH_FIFO, &cfhsi->bits);
 			netdev_warn(cfhsi->ndev,
@@ -371,7 +370,7 @@ static void cfhsi_start_tx(struct cfhsi *cfhsi)
 		}
 
 		/* Set up new transfer. */
-		res = cfhsi->dev->cfhsi_tx(cfhsi->tx_buf, len, cfhsi->dev);
+		res = cfhsi->ops->cfhsi_tx(cfhsi->tx_buf, len, cfhsi->ops);
 		if (WARN_ON(res < 0))
 			netdev_err(cfhsi->ndev, "%s: TX error %d.\n",
 				__func__, res);
@@ -410,11 +409,11 @@ static void cfhsi_tx_done(struct cfhsi *cfhsi)
 	return;
 }
 
-static void cfhsi_tx_done_cb(struct cfhsi_drv *drv)
+static void cfhsi_tx_done_cb(struct cfhsi_cb_ops *cb_ops)
 {
 	struct cfhsi *cfhsi;
 
-	cfhsi = container_of(drv, struct cfhsi, drv);
+	cfhsi = container_of(cb_ops, struct cfhsi, cb_ops);
 	netdev_dbg(cfhsi->ndev, "%s.\n",
 		__func__);
 
@@ -476,8 +475,8 @@ static int cfhsi_rx_desc(struct cfhsi_desc *desc, struct cfhsi *cfhsi)
 		skb->dev = cfhsi->ndev;
 
 		/*
-		 * We are called from a arch specific platform device.
-		 * Unfortunately we don't know what context we're
+		 * We are in a callback handler and
+		 * unfortunately we don't know what context we're
 		 * running in.
 		 */
 		if (in_interrupt())
@@ -607,7 +606,7 @@ static int cfhsi_rx_pld(struct cfhsi_desc *desc, struct cfhsi *cfhsi)
 		skb->dev = cfhsi->ndev;
 
 		/*
-		 * We're called from a platform device,
+		 * We're called in callback from HSI
 		 * and don't know the context we're running in.
 		 */
 		if (in_interrupt())
@@ -711,8 +710,8 @@ static void cfhsi_rx_done(struct cfhsi *cfhsi)
 		netdev_dbg(cfhsi->ndev, "%s: Start RX.\n",
 				__func__);
 
-		res = cfhsi->dev->cfhsi_rx(rx_ptr, rx_len,
-				cfhsi->dev);
+		res = cfhsi->ops->cfhsi_rx(rx_ptr, rx_len,
+				cfhsi->ops);
 		if (WARN_ON(res < 0)) {
 			netdev_err(cfhsi->ndev, "%s: RX error %d.\n",
 				__func__, res);
@@ -765,11 +764,11 @@ static void cfhsi_rx_slowpath(unsigned long arg)
 	cfhsi_rx_done(cfhsi);
 }
 
-static void cfhsi_rx_done_cb(struct cfhsi_drv *drv)
+static void cfhsi_rx_done_cb(struct cfhsi_cb_ops *cb_ops)
 {
 	struct cfhsi *cfhsi;
 
-	cfhsi = container_of(drv, struct cfhsi, drv);
+	cfhsi = container_of(cb_ops, struct cfhsi, cb_ops);
 	netdev_dbg(cfhsi->ndev, "%s.\n",
 		__func__);
 
@@ -803,7 +802,7 @@ static void cfhsi_wake_up(struct work_struct *work)
 	}
 
 	/* Activate wake line. */
-	cfhsi->dev->cfhsi_wake_up(cfhsi->dev);
+	cfhsi->ops->cfhsi_wake_up(cfhsi->ops);
 
 	netdev_dbg(cfhsi->ndev, "%s: Start waiting.\n",
 		__func__);
@@ -819,7 +818,7 @@ static void cfhsi_wake_up(struct work_struct *work)
 			__func__, ret);
 
 		clear_bit(CFHSI_WAKE_UP, &cfhsi->bits);
-		cfhsi->dev->cfhsi_wake_down(cfhsi->dev);
+		cfhsi->ops->cfhsi_wake_down(cfhsi->ops);
 		return;
 	} else if (!ret) {
 		bool ca_wake = false;
@@ -830,14 +829,14 @@ static void cfhsi_wake_up(struct work_struct *work)
 			__func__);
 
 		/* Check FIFO to check if modem has sent something. */
-		WARN_ON(cfhsi->dev->cfhsi_fifo_occupancy(cfhsi->dev,
+		WARN_ON(cfhsi->ops->cfhsi_fifo_occupancy(cfhsi->ops,
 					&fifo_occupancy));
 
 		netdev_dbg(cfhsi->ndev, "%s: Bytes in FIFO: %u.\n",
 				__func__, (unsigned) fifo_occupancy);
 
 		/* Check if we misssed the interrupt. */
-		WARN_ON(cfhsi->dev->cfhsi_get_peer_wake(cfhsi->dev,
+		WARN_ON(cfhsi->ops->cfhsi_get_peer_wake(cfhsi->ops,
 							&ca_wake));
 
 		if (ca_wake) {
@@ -852,7 +851,7 @@ static void cfhsi_wake_up(struct work_struct *work)
 		}
 
 		clear_bit(CFHSI_WAKE_UP, &cfhsi->bits);
-		cfhsi->dev->cfhsi_wake_down(cfhsi->dev);
+		cfhsi->ops->cfhsi_wake_down(cfhsi->ops);
 		return;
 	}
 wake_ack:
@@ -865,7 +864,7 @@ wake_ack:
 
 	/* Resume read operation. */
 	netdev_dbg(cfhsi->ndev, "%s: Start RX.\n", __func__);
-	res = cfhsi->dev->cfhsi_rx(cfhsi->rx_ptr, cfhsi->rx_len, cfhsi->dev);
+	res = cfhsi->ops->cfhsi_rx(cfhsi->rx_ptr, cfhsi->rx_len, cfhsi->ops);
 
 	if (WARN_ON(res < 0))
 		netdev_err(cfhsi->ndev, "%s: RX err %d.\n", __func__, res);
@@ -896,7 +895,7 @@ wake_ack:
 
 	if (likely(len > 0)) {
 		/* Set up new transfer. */
-		res = cfhsi->dev->cfhsi_tx(cfhsi->tx_buf, len, cfhsi->dev);
+		res = cfhsi->ops->cfhsi_tx(cfhsi->tx_buf, len, cfhsi->ops);
 		if (WARN_ON(res < 0)) {
 			netdev_err(cfhsi->ndev, "%s: TX error %d.\n",
 				__func__, res);
@@ -923,7 +922,7 @@ static void cfhsi_wake_down(struct work_struct *work)
 		return;
 
 	/* Deactivate wake line. */
-	cfhsi->dev->cfhsi_wake_down(cfhsi->dev);
+	cfhsi->ops->cfhsi_wake_down(cfhsi->ops);
 
 	/* Wait for acknowledge. */
 	ret = CFHSI_WAKE_TOUT;
@@ -942,7 +941,7 @@ static void cfhsi_wake_down(struct work_struct *work)
 		netdev_err(cfhsi->ndev, "%s: Timeout.\n", __func__);
 
 		/* Check if we misssed the interrupt. */
-		WARN_ON(cfhsi->dev->cfhsi_get_peer_wake(cfhsi->dev,
+		WARN_ON(cfhsi->ops->cfhsi_get_peer_wake(cfhsi->ops,
 							&ca_wake));
 		if (!ca_wake)
 			netdev_err(cfhsi->ndev, "%s: CA Wake missed !.\n",
@@ -951,7 +950,7 @@ static void cfhsi_wake_down(struct work_struct *work)
 
 	/* Check FIFO occupancy. */
 	while (retry) {
-		WARN_ON(cfhsi->dev->cfhsi_fifo_occupancy(cfhsi->dev,
+		WARN_ON(cfhsi->ops->cfhsi_fifo_occupancy(cfhsi->ops,
 							&fifo_occupancy));
 
 		if (!fifo_occupancy)
@@ -969,8 +968,7 @@ static void cfhsi_wake_down(struct work_struct *work)
 	clear_bit(CFHSI_AWAKE, &cfhsi->bits);
 
 	/* Cancel pending RX requests. */
-	cfhsi->dev->cfhsi_rx_cancel(cfhsi->dev);
-
+	cfhsi->ops->cfhsi_rx_cancel(cfhsi->ops);
 }
 
 static void cfhsi_out_of_sync(struct work_struct *work)
@@ -984,11 +982,11 @@ static void cfhsi_out_of_sync(struct work_struct *work)
 	rtnl_unlock();
 }
 
-static void cfhsi_wake_up_cb(struct cfhsi_drv *drv)
+static void cfhsi_wake_up_cb(struct cfhsi_cb_ops *cb_ops)
 {
 	struct cfhsi *cfhsi = NULL;
 
-	cfhsi = container_of(drv, struct cfhsi, drv);
+	cfhsi = container_of(cb_ops, struct cfhsi, cb_ops);
 	netdev_dbg(cfhsi->ndev, "%s.\n",
 		__func__);
 
@@ -1003,11 +1001,11 @@ static void cfhsi_wake_up_cb(struct cfhsi_drv *drv)
 		queue_work(cfhsi->wq, &cfhsi->wake_up_work);
 }
 
-static void cfhsi_wake_down_cb(struct cfhsi_drv *drv)
+static void cfhsi_wake_down_cb(struct cfhsi_cb_ops *cb_ops)
 {
 	struct cfhsi *cfhsi = NULL;
 
-	cfhsi = container_of(drv, struct cfhsi, drv);
+	cfhsi = container_of(cb_ops, struct cfhsi, cb_ops);
 	netdev_dbg(cfhsi->ndev, "%s.\n",
 		__func__);
 
@@ -1110,7 +1108,7 @@ static int cfhsi_xmit(struct sk_buff *skb, struct net_device *dev)
 		WARN_ON(!len);
 
 		/* Set up new transfer. */
-		res = cfhsi->dev->cfhsi_tx(cfhsi->tx_buf, len, cfhsi->dev);
+		res = cfhsi->ops->cfhsi_tx(cfhsi->tx_buf, len, cfhsi->ops);
 		if (WARN_ON(res < 0)) {
 			netdev_err(cfhsi->ndev, "%s: TX error %d.\n",
 				__func__, res);
@@ -1125,19 +1123,19 @@ static int cfhsi_xmit(struct sk_buff *skb, struct net_device *dev)
 	return 0;
 }
 
-static const struct net_device_ops cfhsi_ops;
+static const struct net_device_ops cfhsi_netdevops;
 
 static void cfhsi_setup(struct net_device *dev)
 {
 	int i;
 	struct cfhsi *cfhsi = netdev_priv(dev);
 	dev->features = 0;
-	dev->netdev_ops = &cfhsi_ops;
 	dev->type = ARPHRD_CAIF;
 	dev->flags = IFF_POINTOPOINT | IFF_NOARP;
 	dev->mtu = CFHSI_MAX_CAIF_FRAME_SZ;
 	dev->tx_queue_len = 0;
 	dev->destructor = free_netdev;
+	dev->netdev_ops = &cfhsi_netdevops;
 	for (i = 0; i < CFHSI_PRIO_LAST; ++i)
 		skb_queue_head_init(&cfhsi->qhead[i]);
 	cfhsi->cfdev.link_select = CAIF_LINK_HIGH_BANDW;
@@ -1213,10 +1211,10 @@ static int cfhsi_open(struct net_device *ndev)
 	spin_lock_init(&cfhsi->lock);
 
 	/* Set up the driver. */
-	cfhsi->drv.tx_done_cb = cfhsi_tx_done_cb;
-	cfhsi->drv.rx_done_cb = cfhsi_rx_done_cb;
-	cfhsi->drv.wake_up_cb = cfhsi_wake_up_cb;
-	cfhsi->drv.wake_down_cb = cfhsi_wake_down_cb;
+	cfhsi->cb_ops.tx_done_cb = cfhsi_tx_done_cb;
+	cfhsi->cb_ops.rx_done_cb = cfhsi_rx_done_cb;
+	cfhsi->cb_ops.wake_up_cb = cfhsi_wake_up_cb;
+	cfhsi->cb_ops.wake_down_cb = cfhsi_wake_down_cb;
 
 	/* Initialize the work queues. */
 	INIT_WORK(&cfhsi->wake_up_work, cfhsi_wake_up);
@@ -1230,7 +1228,7 @@ static int cfhsi_open(struct net_device *ndev)
 	clear_bit(CFHSI_AWAKE, &cfhsi->bits);
 
 	/* Create work thread. */
-	cfhsi->wq = create_singlethread_workqueue(cfhsi->pdev->name);
+	cfhsi->wq = create_singlethread_workqueue(cfhsi->ndev->name);
 	if (!cfhsi->wq) {
 		netdev_err(cfhsi->ndev, "%s: Failed to create work queue.\n",
 			__func__);
@@ -1257,7 +1255,7 @@ static int cfhsi_open(struct net_device *ndev)
 	cfhsi->aggregation_timer.function = cfhsi_aggregation_tout;
 
 	/* Activate HSI interface. */
-	res = cfhsi->dev->cfhsi_up(cfhsi->dev);
+	res = cfhsi->ops->cfhsi_up(cfhsi->ops);
 	if (res) {
 		netdev_err(cfhsi->ndev,
 			"%s: can't activate HSI interface: %d.\n",
@@ -1275,7 +1273,7 @@ static int cfhsi_open(struct net_device *ndev)
 	return res;
 
  err_net_reg:
-	cfhsi->dev->cfhsi_down(cfhsi->dev);
+	cfhsi->ops->cfhsi_down(cfhsi->ops);
  err_activate:
 	destroy_workqueue(cfhsi->wq);
  err_create_wq:
@@ -1305,7 +1303,7 @@ static int cfhsi_close(struct net_device *ndev)
 	del_timer_sync(&cfhsi->aggregation_timer);
 
 	/* Cancel pending RX request (if any) */
-	cfhsi->dev->cfhsi_rx_cancel(cfhsi->dev);
+	cfhsi->ops->cfhsi_rx_cancel(cfhsi->ops);
 
 	/* Destroy workqueue */
 	destroy_workqueue(cfhsi->wq);
@@ -1318,7 +1316,7 @@ static int cfhsi_close(struct net_device *ndev)
 	cfhsi_abort_tx(cfhsi);
 
 	/* Deactivate interface */
-	cfhsi->dev->cfhsi_down(cfhsi->dev);
+	cfhsi->ops->cfhsi_down(cfhsi->ops);
 
 	/* Free buffers. */
 	kfree(tx_buf);
@@ -1335,7 +1333,7 @@ static void cfhsi_uninit(struct net_device *dev)
 	list_del(&cfhsi->list);
 }
 
-static const struct net_device_ops cfhsi_ops = {
+static const struct net_device_ops cfhsi_netdevops = {
 	.ndo_uninit = cfhsi_uninit,
 	.ndo_open = cfhsi_open,
 	.ndo_stop = cfhsi_close,
@@ -1419,7 +1417,7 @@ static int caif_hsi_newlink(struct net *src_net, struct net_device *dev,
 			  struct nlattr *tb[], struct nlattr *data[])
 {
 	struct cfhsi *cfhsi = NULL;
-	struct platform_device *(*get_dev)(void);
+	struct cfhsi_ops *(*get_ops)(void);
 
 	ASSERT_RTNL();
 
@@ -1427,36 +1425,31 @@ static int caif_hsi_newlink(struct net *src_net, struct net_device *dev,
 	cfhsi_netlink_parms(data, cfhsi);
 	dev_net_set(cfhsi->ndev, src_net);
 
-	get_dev = symbol_get(cfhsi_get_device);
-	if (!get_dev) {
-		pr_err("%s: failed to get the cfhsi device symbol\n", __func__);
+	get_ops = symbol_get(cfhsi_get_ops);
+	if (!get_ops) {
+		pr_err("%s: failed to get the cfhsi_ops\n", __func__);
 		return -ENODEV;
 	}
 
 	/* Assign the HSI device. */
-	cfhsi->pdev = (*get_dev)();
-	if (!cfhsi->pdev) {
-		pr_err("%s: failed to get the cfhsi device\n", __func__);
+	cfhsi->ops = (*get_ops)();
+	if (!cfhsi->ops) {
+		pr_err("%s: failed to get the cfhsi_ops\n", __func__);
 		goto err;
 	}
 
-	/* Assign the HSI device. */
-	cfhsi->dev = cfhsi->pdev->dev.platform_data;
-
 	/* Assign the driver to this HSI device. */
-	cfhsi->dev->drv = &cfhsi->drv;
-
+	cfhsi->ops->cb_ops = &cfhsi->cb_ops;
 	if (register_netdevice(dev)) {
-		pr_warn("%s: device rtml registration failed\n", __func__);
+		pr_warn("%s: caif_hsi device registration failed\n", __func__);
 		goto err;
-
 	}
 	/* Add CAIF HSI device to list. */
 	list_add_tail(&cfhsi->list, &cfhsi_list);
 
 	return 0;
 err:
-	symbol_put(cfhsi_get_device);
+	symbol_put(cfhsi_get_ops);
 	return -ENODEV;
 }
 
diff --git a/include/net/caif/caif_hsi.h b/include/net/caif/caif_hsi.h
index a77b2bd..6dc7dc2 100644
--- a/include/net/caif/caif_hsi.h
+++ b/include/net/caif/caif_hsi.h
@@ -93,25 +93,25 @@ struct cfhsi_desc {
 #endif
 
 /* Structure implemented by the CAIF HSI driver. */
-struct cfhsi_drv {
-	void (*tx_done_cb) (struct cfhsi_drv *drv);
-	void (*rx_done_cb) (struct cfhsi_drv *drv);
-	void (*wake_up_cb) (struct cfhsi_drv *drv);
-	void (*wake_down_cb) (struct cfhsi_drv *drv);
+struct cfhsi_cb_ops {
+	void (*tx_done_cb) (struct cfhsi_cb_ops *drv);
+	void (*rx_done_cb) (struct cfhsi_cb_ops *drv);
+	void (*wake_up_cb) (struct cfhsi_cb_ops *drv);
+	void (*wake_down_cb) (struct cfhsi_cb_ops *drv);
 };
 
 /* Structure implemented by HSI device. */
-struct cfhsi_dev {
-	int (*cfhsi_up) (struct cfhsi_dev *dev);
-	int (*cfhsi_down) (struct cfhsi_dev *dev);
-	int (*cfhsi_tx) (u8 *ptr, int len, struct cfhsi_dev *dev);
-	int (*cfhsi_rx) (u8 *ptr, int len, struct cfhsi_dev *dev);
-	int (*cfhsi_wake_up) (struct cfhsi_dev *dev);
-	int (*cfhsi_wake_down) (struct cfhsi_dev *dev);
-	int (*cfhsi_get_peer_wake) (struct cfhsi_dev *dev, bool *status);
-	int (*cfhsi_fifo_occupancy)(struct cfhsi_dev *dev, size_t *occupancy);
-	int (*cfhsi_rx_cancel)(struct cfhsi_dev *dev);
-	struct cfhsi_drv *drv;
+struct cfhsi_ops {
+	int (*cfhsi_up) (struct cfhsi_ops *dev);
+	int (*cfhsi_down) (struct cfhsi_ops *dev);
+	int (*cfhsi_tx) (u8 *ptr, int len, struct cfhsi_ops *dev);
+	int (*cfhsi_rx) (u8 *ptr, int len, struct cfhsi_ops *dev);
+	int (*cfhsi_wake_up) (struct cfhsi_ops *dev);
+	int (*cfhsi_wake_down) (struct cfhsi_ops *dev);
+	int (*cfhsi_get_peer_wake) (struct cfhsi_ops *dev, bool *status);
+	int (*cfhsi_fifo_occupancy) (struct cfhsi_ops *dev, size_t *occupancy);
+	int (*cfhsi_rx_cancel)(struct cfhsi_ops *dev);
+	struct cfhsi_cb_ops *cb_ops;
 };
 
 /* Structure holds status of received CAIF frames processing */
@@ -138,8 +138,8 @@ struct cfhsi {
 	struct net_device *ndev;
 	struct platform_device *pdev;
 	struct sk_buff_head qhead[CFHSI_PRIO_LAST];
-	struct cfhsi_drv drv;
-	struct cfhsi_dev *dev;
+	struct cfhsi_cb_ops cb_ops;
+	struct cfhsi_ops *ops;
 	int tx_state;
 	struct cfhsi_rx_state rx_state;
 	unsigned long inactivity_timeout;
@@ -190,6 +190,6 @@ enum ifla_caif_hsi {
 	__IFLA_CAIF_HSI_MAX
 };
 
-extern struct platform_device *cfhsi_get_device(void);
+extern struct cfhsi_ops *cfhsi_get_ops(void);
 
 #endif		/* CAIF_HSI_H_ */
-- 
1.7.5.4

^ permalink raw reply related

* [net-next 09/11] caif-hsi: Add rtnl support
From: sjur.brandeland @ 2012-06-25 17:49 UTC (permalink / raw)
  To: davem; +Cc: netdev, sjurbren, Sjur Brændeland
In-Reply-To: <1340646583-21059-1-git-send-email-sjur.brandeland@stericsson.com>

From: Sjur Brændeland <sjur.brandeland@stericsson.com>

Add RTNL support for managing the caif hsi interface.
The HSI HW interface is no longer registering as a device,
instead we use symbol_get to get hold of the HSI API.

Signed-off-by: Sjur Brændeland <sjur.brandeland@stericsson.com>
---
 drivers/net/caif/caif_hsi.c |  226 ++++++++++++++++++++++++++-----------------
 include/net/caif/caif_hsi.h |   21 ++++-
 2 files changed, 157 insertions(+), 90 deletions(-)

diff --git a/drivers/net/caif/caif_hsi.c b/drivers/net/caif/caif_hsi.c
index d80759e..a14f85c 100644
--- a/drivers/net/caif/caif_hsi.c
+++ b/drivers/net/caif/caif_hsi.c
@@ -20,7 +20,7 @@
 #include <linux/sched.h>
 #include <linux/if_arp.h>
 #include <linux/timer.h>
-#include <linux/rtnetlink.h>
+#include <net/rtnetlink.h>
 #include <linux/pkt_sched.h>
 #include <net/caif/caif_layer.h>
 #include <net/caif/caif_hsi.h>
@@ -79,7 +79,6 @@ MODULE_PARM_DESC(hsi_low_threshold, "HSI high threshold (FLOW ON).");
 #define HIGH_WATER_MARK  hsi_high_threshold
 
 static LIST_HEAD(cfhsi_list);
-static spinlock_t cfhsi_list_lock;
 
 static void cfhsi_inactivity_tout(unsigned long arg)
 {
@@ -1148,42 +1147,6 @@ static void cfhsi_setup(struct net_device *dev)
 	cfhsi->ndev = dev;
 }
 
-int cfhsi_probe(struct platform_device *pdev)
-{
-	struct cfhsi *cfhsi = NULL;
-	struct net_device *ndev;
-
-	int res;
-
-	ndev = alloc_netdev(sizeof(struct cfhsi), "cfhsi%d", cfhsi_setup);
-	if (!ndev)
-		return -ENODEV;
-
-	cfhsi = netdev_priv(ndev);
-	cfhsi->ndev = ndev;
-	cfhsi->pdev = pdev;
-
-	/* Assign the HSI device. */
-	cfhsi->dev = pdev->dev.platform_data;
-
-	/* Assign the driver to this HSI device. */
-	cfhsi->dev->drv = &cfhsi->drv;
-
-	/* Register network device. */
-	res = register_netdev(ndev);
-	if (res) {
-		dev_err(&ndev->dev, "%s: Registration error: %d.\n",
-			__func__, res);
-		free_netdev(ndev);
-	}
-	/* Add CAIF HSI device to list. */
-	spin_lock(&cfhsi_list_lock);
-	list_add_tail(&cfhsi->list, &cfhsi_list);
-	spin_unlock(&cfhsi_list_lock);
-
-	return res;
-}
-
 static int cfhsi_open(struct net_device *ndev)
 {
 	struct cfhsi *cfhsi = netdev_priv(ndev);
@@ -1364,85 +1327,170 @@ static int cfhsi_close(struct net_device *ndev)
 	return 0;
 }
 
+static void cfhsi_uninit(struct net_device *dev)
+{
+	struct cfhsi *cfhsi = netdev_priv(dev);
+	ASSERT_RTNL();
+	symbol_put(cfhsi_get_device);
+	list_del(&cfhsi->list);
+}
+
 static const struct net_device_ops cfhsi_ops = {
+	.ndo_uninit = cfhsi_uninit,
 	.ndo_open = cfhsi_open,
 	.ndo_stop = cfhsi_close,
 	.ndo_start_xmit = cfhsi_xmit
 };
 
-int cfhsi_remove(struct platform_device *pdev)
+static void cfhsi_netlink_parms(struct nlattr *data[], struct cfhsi *cfhsi)
 {
-	struct list_head *list_node;
-	struct list_head *n;
-	struct cfhsi *cfhsi = NULL;
-	struct cfhsi_dev *dev;
+	int i;
 
-	dev = (struct cfhsi_dev *)pdev->dev.platform_data;
-	spin_lock(&cfhsi_list_lock);
-	list_for_each_safe(list_node, n, &cfhsi_list) {
-		cfhsi = list_entry(list_node, struct cfhsi, list);
-		/* Find the corresponding device. */
-		if (cfhsi->dev == dev) {
-			/* Remove from list. */
-			list_del(list_node);
-			spin_unlock(&cfhsi_list_lock);
-			return 0;
-		}
+	if (!data) {
+		pr_debug("no params data found\n");
+		return;
 	}
-	spin_unlock(&cfhsi_list_lock);
-	return -ENODEV;
+
+	i = __IFLA_CAIF_HSI_INACTIVITY_TOUT;
+	if (data[i])
+		inactivity_timeout = nla_get_u32(data[i]);
+
+	i = __IFLA_CAIF_HSI_AGGREGATION_TOUT;
+	if (data[i])
+		aggregation_timeout = nla_get_u32(data[i]);
+
+	i = __IFLA_CAIF_HSI_HEAD_ALIGN;
+	if (data[i])
+		hsi_head_align = nla_get_u32(data[i]);
+
+	i = __IFLA_CAIF_HSI_TAIL_ALIGN;
+	if (data[i])
+		hsi_tail_align = nla_get_u32(data[i]);
+
+	i = __IFLA_CAIF_HSI_QHIGH_WATERMARK;
+	if (data[i])
+		hsi_high_threshold = nla_get_u32(data[i]);
+}
+
+static int caif_hsi_changelink(struct net_device *dev, struct nlattr *tb[],
+				struct nlattr *data[])
+{
+	cfhsi_netlink_parms(data, netdev_priv(dev));
+	netdev_state_change(dev);
+	return 0;
 }
 
-struct platform_driver cfhsi_plat_drv = {
-	.probe = cfhsi_probe,
-	.remove = cfhsi_remove,
-	.driver = {
-		   .name = "cfhsi",
-		   .owner = THIS_MODULE,
-		   },
+static const struct nla_policy caif_hsi_policy[__IFLA_CAIF_HSI_MAX + 1] = {
+	[__IFLA_CAIF_HSI_INACTIVITY_TOUT] = { .type = NLA_U32, .len = 4 },
+	[__IFLA_CAIF_HSI_AGGREGATION_TOUT] = { .type = NLA_U32, .len = 4 },
+	[__IFLA_CAIF_HSI_HEAD_ALIGN] = { .type = NLA_U32, .len = 4 },
+	[__IFLA_CAIF_HSI_TAIL_ALIGN] = { .type = NLA_U32, .len = 4 },
+	[__IFLA_CAIF_HSI_QHIGH_WATERMARK] = { .type = NLA_U32, .len = 4 },
+	[__IFLA_CAIF_HSI_QLOW_WATERMARK] = { .type = NLA_U32, .len = 4 },
 };
 
-static void __exit cfhsi_exit_module(void)
+static size_t caif_hsi_get_size(const struct net_device *dev)
+{
+	int i;
+	size_t s = 0;
+	for (i = __IFLA_CAIF_HSI_UNSPEC + 1; i < __IFLA_CAIF_HSI_MAX; i++)
+		s += nla_total_size(caif_hsi_policy[i].len);
+	return s;
+}
+
+static int caif_hsi_fill_info(struct sk_buff *skb, const struct net_device *dev)
+{
+	if (nla_put_u32(skb, __IFLA_CAIF_HSI_INACTIVITY_TOUT,
+			inactivity_timeout) ||
+	    nla_put_u32(skb, __IFLA_CAIF_HSI_AGGREGATION_TOUT,
+			aggregation_timeout) ||
+	    nla_put_u32(skb, __IFLA_CAIF_HSI_HEAD_ALIGN, hsi_head_align) ||
+	    nla_put_u32(skb, __IFLA_CAIF_HSI_TAIL_ALIGN, hsi_tail_align) ||
+	    nla_put_u32(skb, __IFLA_CAIF_HSI_QHIGH_WATERMARK,
+			hsi_high_threshold) ||
+	    nla_put_u32(skb, __IFLA_CAIF_HSI_QLOW_WATERMARK,
+			hsi_low_threshold))
+		return -EMSGSIZE;
+
+	return 0;
+}
+
+static int caif_hsi_newlink(struct net *src_net, struct net_device *dev,
+			  struct nlattr *tb[], struct nlattr *data[])
 {
-	struct list_head *list_node;
-	struct list_head *n;
 	struct cfhsi *cfhsi = NULL;
+	struct platform_device *(*get_dev)(void);
 
-	spin_lock(&cfhsi_list_lock);
-	list_for_each_safe(list_node, n, &cfhsi_list) {
-		cfhsi = list_entry(list_node, struct cfhsi, list);
+	ASSERT_RTNL();
+
+	cfhsi = netdev_priv(dev);
+	cfhsi_netlink_parms(data, cfhsi);
+	dev_net_set(cfhsi->ndev, src_net);
+
+	get_dev = symbol_get(cfhsi_get_device);
+	if (!get_dev) {
+		pr_err("%s: failed to get the cfhsi device symbol\n", __func__);
+		return -ENODEV;
+	}
+
+	/* Assign the HSI device. */
+	cfhsi->pdev = (*get_dev)();
+	if (!cfhsi->pdev) {
+		pr_err("%s: failed to get the cfhsi device\n", __func__);
+		goto err;
+	}
 
-		/* Remove from list. */
-		list_del(list_node);
-		spin_unlock(&cfhsi_list_lock);
+	/* Assign the HSI device. */
+	cfhsi->dev = cfhsi->pdev->dev.platform_data;
+
+	/* Assign the driver to this HSI device. */
+	cfhsi->dev->drv = &cfhsi->drv;
 
-		unregister_netdevice(cfhsi->ndev);
+	if (register_netdevice(dev)) {
+		pr_warn("%s: device rtml registration failed\n", __func__);
+		goto err;
 
-		spin_lock(&cfhsi_list_lock);
 	}
-	spin_unlock(&cfhsi_list_lock);
+	/* Add CAIF HSI device to list. */
+	list_add_tail(&cfhsi->list, &cfhsi_list);
 
-	/* Unregister platform driver. */
-	platform_driver_unregister(&cfhsi_plat_drv);
+	return 0;
+err:
+	symbol_put(cfhsi_get_device);
+	return -ENODEV;
 }
 
-static int __init cfhsi_init_module(void)
+static struct rtnl_link_ops caif_hsi_link_ops __read_mostly = {
+	.kind		= "cfhsi",
+	.priv_size	= sizeof(struct cfhsi),
+	.setup		= cfhsi_setup,
+	.maxtype	= __IFLA_CAIF_HSI_MAX,
+	.policy	= caif_hsi_policy,
+	.newlink	= caif_hsi_newlink,
+	.changelink	= caif_hsi_changelink,
+	.get_size	= caif_hsi_get_size,
+	.fill_info	= caif_hsi_fill_info,
+};
+
+static void __exit cfhsi_exit_module(void)
 {
-	int result;
+	struct list_head *list_node;
+	struct list_head *n;
+	struct cfhsi *cfhsi;
 
-	/* Initialize spin lock. */
-	spin_lock_init(&cfhsi_list_lock);
+	rtnl_link_unregister(&caif_hsi_link_ops);
 
-	/* Register platform driver. */
-	result = platform_driver_register(&cfhsi_plat_drv);
-	if (result) {
-		printk(KERN_ERR "Could not register platform HSI driver: %d.\n",
-			result);
-		goto err_dev_register;
+	rtnl_lock();
+	list_for_each_safe(list_node, n, &cfhsi_list) {
+		cfhsi = list_entry(list_node, struct cfhsi, list);
+		unregister_netdev(cfhsi->ndev);
 	}
+	rtnl_unlock();
+}
 
- err_dev_register:
-	return result;
+static int __init cfhsi_init_module(void)
+{
+	return rtnl_link_register(&caif_hsi_link_ops);
 }
 
 module_init(cfhsi_init_module);
diff --git a/include/net/caif/caif_hsi.h b/include/net/caif/caif_hsi.h
index 439dadc..a77b2bd 100644
--- a/include/net/caif/caif_hsi.h
+++ b/include/net/caif/caif_hsi.h
@@ -170,7 +170,26 @@ struct cfhsi {
 
 	unsigned long bits;
 };
-
 extern struct platform_driver cfhsi_driver;
 
+/**
+ * enum ifla_caif_hsi - CAIF HSI NetlinkRT parameters.
+ * @IFLA_CAIF_HSI_INACTIVITY_TOUT: Inactivity timeout before
+ *			taking the HSI wakeline down, in milliseconds.
+ * When using RT Netlink to create, destroy or configure a CAIF HSI interface,
+ * enum ifla_caif_hsi is used to specify the configuration attributes.
+ */
+enum ifla_caif_hsi {
+	__IFLA_CAIF_HSI_UNSPEC,
+	__IFLA_CAIF_HSI_INACTIVITY_TOUT,
+	__IFLA_CAIF_HSI_AGGREGATION_TOUT,
+	__IFLA_CAIF_HSI_HEAD_ALIGN,
+	__IFLA_CAIF_HSI_TAIL_ALIGN,
+	__IFLA_CAIF_HSI_QHIGH_WATERMARK,
+	__IFLA_CAIF_HSI_QLOW_WATERMARK,
+	__IFLA_CAIF_HSI_MAX
+};
+
+extern struct platform_device *cfhsi_get_device(void);
+
 #endif		/* CAIF_HSI_H_ */
-- 
1.7.5.4

^ permalink raw reply related

* [net-next 08/11] Documentation/networking/caif: Update documentation
From: sjur.brandeland @ 2012-06-25 17:49 UTC (permalink / raw)
  To: davem; +Cc: netdev, sjurbren, Sjur Brændeland, Sjur Brændeland
In-Reply-To: <1340646583-21059-1-git-send-email-sjur.brandeland@stericsson.com>

From: Sjur Brændeland <sjur.brandeland@stericsson.com>

Update drawing and remove description of old features.
Add HSI and USB link layers to the drawing.

Reported-by: Joerg Reisenweber <joerg.reisenweber@stericssion.com>
Signed-off-by: Sjur Brændeland <sjur.brandeland@stericssion.com>
---
 Documentation/networking/caif/Linux-CAIF.txt |   91 ++++++++------------------
 1 files changed, 27 insertions(+), 64 deletions(-)

diff --git a/Documentation/networking/caif/Linux-CAIF.txt b/Documentation/networking/caif/Linux-CAIF.txt
index e52fd62..0aa4bd3 100644
--- a/Documentation/networking/caif/Linux-CAIF.txt
+++ b/Documentation/networking/caif/Linux-CAIF.txt
@@ -19,60 +19,36 @@ and host. Currently, UART and Loopback are available for Linux.
 Architecture:
 ------------
 The implementation of CAIF is divided into:
-* CAIF Socket Layer, Kernel API, and  Net Device.
+* CAIF Socket Layer and GPRS IP Interface.
 * CAIF Core Protocol Implementation
 * CAIF Link Layer, implemented as NET devices.
 
 
   RTNL
    !
-   !	 +------+   +------+   +------+
-   !	+------+!  +------+!  +------+!
-   !	! Sock !!  !Kernel!!  ! Net  !!
-   !	! API  !+  ! API  !+  ! Dev  !+	  <- CAIF Client APIs
-   !	+------+   +------!   +------+
-   !	   !	      !		 !
-   !	   +----------!----------+
-   !		   +------+		  <- CAIF Protocol Implementation
-   +------->	   ! CAIF !
-		   ! Core !
-		   +------+
-	     +--------!--------+
-	     !		       !
-	  +------+	    +-----+
-	  !    	 !	    ! TTY !	  <- Link Layer (Net Devices)
-	  +------+	    +-----+
-
-
-Using the Kernel API
-----------------------
-The Kernel API is used for accessing CAIF channels from the
-kernel.
-The user of the API has to implement two callbacks for receive
-and control.
-The receive callback gives a CAIF packet as a SKB. The control
-callback will
-notify of channel initialization complete, and flow-on/flow-
-off.
-
-
-  struct caif_device caif_dev = {
-    .caif_config = {
-     .name = "MYDEV"
-     .type = CAIF_CHTY_AT
-    }
-   .receive_cb = my_receive,
-   .control_cb = my_control,
-  };
-  caif_add_device(&caif_dev);
-  caif_transmit(&caif_dev, skb);
-
-See the caif_kernel.h for details about the CAIF kernel API.
+   !	      +------+	 +------+
+   !	     +------+!	+------+!
+   !	     !	IP  !!	!Socket!!
+   +-------> !interf!+	! API  !+	<- CAIF Client APIs
+   !	     +------+	+------!
+   !		!	    !
+   !		+-----------+
+   !		      !
+   !		   +------+		<- CAIF Core Protocol
+   !		   ! CAIF !
+   !		   ! Core !
+   !		   +------+
+   !	   +----------!---------+
+   !	   !	      !		!
+   !	+------+   +-----+   +------+
+   +--> ! HSI  !   ! TTY !   ! USB  !	<- Link Layer (Net Devices)
+	+------+   +-----+   +------+
+
 
 
 I M P L E M E N T A T I O N
 ===========================
-===========================
+
 
 CAIF Core Protocol Layer
 =========================================
@@ -88,17 +64,13 @@ The Core CAIF implementation contains:
       -	Simple implementation of CAIF.
       -	Layered architecture (a la Streams), each layer in the CAIF
 	specification is implemented in a separate c-file.
-      -	Clients must implement PHY layer to access physical HW
-	with receive and transmit functions.
       -	Clients must call configuration function to add PHY layer.
       -	Clients must implement CAIF layer to consume/produce
 	CAIF payload with receive and transmit functions.
       -	Clients must call configuration function to add and connect the
 	Client layer.
       - When receiving / transmitting CAIF Packets (cfpkt), ownership is passed
-	to the called function (except for framing layers' receive functions
-	or if a transmit function returns an error, in which case the caller
-	must free the packet).
+	to the called function (except for framing layers' receive function)
 
 Layered Architecture
 --------------------
@@ -109,11 +81,6 @@ Implementation. The support functions include:
 	CAIF Packet has functions for creating, destroying and adding content
 	and for adding/extracting header and trailers to protocol packets.
 
-      - CFLST CAIF list implementation.
-
-      - CFGLUE CAIF Glue. Contains OS Specifics, such as memory
-	allocation, endianness, etc.
-
 The CAIF Protocol implementation contains:
 
       - CFCNFG CAIF Configuration layer. Configures the CAIF Protocol
@@ -128,7 +95,7 @@ The CAIF Protocol implementation contains:
 	control and remote shutdown requests.
 
       - CFVEI CAIF VEI layer. Handles CAIF AT Channels on VEI (Virtual
-        External Interface). This layer encodes/decodes VEI frames.
+	External Interface). This layer encodes/decodes VEI frames.
 
       - CFDGML CAIF Datagram layer. Handles CAIF Datagram layer (IP
 	traffic), encodes/decodes Datagram frames.
@@ -170,7 +137,7 @@ The CAIF Protocol implementation contains:
 	    +---------+	    +---------+
 		 !		!
 	    +---------+	    +---------+
-	    |         |	    | Serial  |
+	    |	      |	    | Serial  |
 	    |	      |	    | CFSERL  |
 	    +---------+	    +---------+
 
@@ -186,24 +153,20 @@ In this layered approach the following "rules" apply.
 		 layer->dn->transmit(layer->dn, packet);
 
 
-Linux Driver Implementation
+CAIF Socket and IP interface
 ===========================
 
-Linux GPRS Net Device and CAIF socket are implemented on top of the
-CAIF Core protocol. The Net device and CAIF socket have an instance of
+The IP interface and CAIF socket API are implemented on top of the
+CAIF Core protocol. The IP Interface and CAIF socket have an instance of
 'struct cflayer', just like the CAIF Core protocol stack.
 Net device and Socket implement the 'receive()' function defined by
 'struct cflayer', just like the rest of the CAIF stack. In this way, transmit and
 receive of packets is handled as by the rest of the layers: the 'dn->transmit()'
 function is called in order to transmit data.
 
-The layer on top of the CAIF Core implementation is
-sometimes referred to as the "Client layer".
-
-
 Configuration of Link Layer
 ---------------------------
-The Link Layer is implemented as Linux net devices (struct net_device).
+The Link Layer is implemented as Linux network devices (struct net_device).
 Payload handling and registration is done using standard Linux mechanisms.
 
 The CAIF Protocol relies on a loss-less link layer without implementing
-- 
1.7.5.4

^ permalink raw reply related

* [net-next 07/11] caif-hsi: Remove uncecessary assignments
From: sjur.brandeland @ 2012-06-25 17:49 UTC (permalink / raw)
  To: davem; +Cc: netdev, sjurbren, Sjur Brændeland, Sjur Brændeland
In-Reply-To: <1340646583-21059-1-git-send-email-sjur.brandeland@stericsson.com>

From: Sjur Brændeland <sjur.brandeland@stericsson.com>

Remove assignment at declaration when not needed.

Signed-off-by: Sjur Brændeland <sjur.brandeland@stericssion.com>
---
 drivers/net/caif/caif_hsi.c |   10 +++++-----
 1 files changed, 5 insertions(+), 5 deletions(-)

diff --git a/drivers/net/caif/caif_hsi.c b/drivers/net/caif/caif_hsi.c
index f7997a7..d80759e 100644
--- a/drivers/net/caif/caif_hsi.c
+++ b/drivers/net/caif/caif_hsi.c
@@ -246,8 +246,8 @@ static int cfhsi_tx_frm(struct cfhsi_desc *desc, struct cfhsi *cfhsi)
 	/* Check if we can embed a CAIF frame. */
 	if (skb->len < CFHSI_MAX_EMB_FRM_SZ) {
 		struct caif_payload_info *info;
-		int hpad = 0;
-		int tpad = 0;
+		int hpad;
+		int tpad;
 
 		/* Calculate needed head alignment and tail alignment. */
 		info = (struct caif_payload_info *)&skb->cb;
@@ -282,8 +282,8 @@ static int cfhsi_tx_frm(struct cfhsi_desc *desc, struct cfhsi *cfhsi)
 	pfrm = desc->emb_frm + CFHSI_MAX_EMB_FRM_SZ;
 	while (nfrms < CFHSI_MAX_PKTS) {
 		struct caif_payload_info *info;
-		int hpad = 0;
-		int tpad = 0;
+		int hpad;
+		int tpad;
 
 		if (!skb)
 			skb = cfhsi_dequeue(cfhsi);
@@ -573,7 +573,7 @@ static int cfhsi_rx_pld(struct cfhsi_desc *desc, struct cfhsi *cfhsi)
 		struct sk_buff *skb;
 		u8 *dst = NULL;
 		u8 *pcffrm = NULL;
-		int len = 0;
+		int len;
 
 		/* CAIF frame starts after head padding. */
 		pcffrm = pfrm + *pfrm + 1;
-- 
1.7.5.4

^ permalink raw reply related

* [net-next 06/11] caif-hsi: Use netdev_X instead of dev_X for printing
From: sjur.brandeland @ 2012-06-25 17:49 UTC (permalink / raw)
  To: davem; +Cc: netdev, sjurbren, Sjur Brændeland, Sjur Brændeland
In-Reply-To: <1340646583-21059-1-git-send-email-sjur.brandeland@stericsson.com>

From: Sjur Brændeland <sjur.brandeland@stericsson.com>

Replace dev_X with the corresponding netdev_X print
function when applicable.

Signed-off-by: Sjur Brændeland <sjur.brandeland@stericssion.com>
---
 drivers/net/caif/caif_hsi.c |   94 +++++++++++++++++++++---------------------
 1 files changed, 47 insertions(+), 47 deletions(-)

diff --git a/drivers/net/caif/caif_hsi.c b/drivers/net/caif/caif_hsi.c
index 56cc941..f7997a7 100644
--- a/drivers/net/caif/caif_hsi.c
+++ b/drivers/net/caif/caif_hsi.c
@@ -85,7 +85,7 @@ static void cfhsi_inactivity_tout(unsigned long arg)
 {
 	struct cfhsi *cfhsi = (struct cfhsi *)arg;
 
-	dev_dbg(&cfhsi->ndev->dev, "%s.\n",
+	netdev_dbg(cfhsi->ndev, "%s.\n",
 		__func__);
 
 	/* Schedule power down work queue. */
@@ -181,14 +181,14 @@ static int cfhsi_flush_fifo(struct cfhsi *cfhsi)
 	size_t fifo_occupancy;
 	int ret;
 
-	dev_dbg(&cfhsi->ndev->dev, "%s.\n",
+	netdev_dbg(cfhsi->ndev, "%s.\n",
 		__func__);
 
 	do {
 		ret = cfhsi->dev->cfhsi_fifo_occupancy(cfhsi->dev,
 				&fifo_occupancy);
 		if (ret) {
-			dev_warn(&cfhsi->ndev->dev,
+			netdev_warn(cfhsi->ndev,
 				"%s: can't get FIFO occupancy: %d.\n",
 				__func__, ret);
 			break;
@@ -202,7 +202,7 @@ static int cfhsi_flush_fifo(struct cfhsi *cfhsi)
 				cfhsi->dev);
 		if (ret) {
 			clear_bit(CFHSI_FLUSH_FIFO, &cfhsi->bits);
-			dev_warn(&cfhsi->ndev->dev,
+			netdev_warn(cfhsi->ndev,
 				"%s: can't read data: %d.\n",
 				__func__, ret);
 			break;
@@ -213,13 +213,13 @@ static int cfhsi_flush_fifo(struct cfhsi *cfhsi)
 			 !test_bit(CFHSI_FLUSH_FIFO, &cfhsi->bits), ret);
 
 		if (ret < 0) {
-			dev_warn(&cfhsi->ndev->dev,
+			netdev_warn(cfhsi->ndev,
 				"%s: can't wait for flush complete: %d.\n",
 				__func__, ret);
 			break;
 		} else if (!ret) {
 			ret = -ETIMEDOUT;
-			dev_warn(&cfhsi->ndev->dev,
+			netdev_warn(cfhsi->ndev,
 				"%s: timeout waiting for flush complete.\n",
 				__func__);
 			break;
@@ -348,7 +348,7 @@ static void cfhsi_start_tx(struct cfhsi *cfhsi)
 	struct cfhsi_desc *desc = (struct cfhsi_desc *)cfhsi->tx_buf;
 	int len, res;
 
-	dev_dbg(&cfhsi->ndev->dev, "%s.\n", __func__);
+	netdev_dbg(cfhsi->ndev, "%s.\n", __func__);
 
 	if (test_bit(CFHSI_SHUTDOWN, &cfhsi->bits))
 		return;
@@ -374,14 +374,14 @@ static void cfhsi_start_tx(struct cfhsi *cfhsi)
 		/* Set up new transfer. */
 		res = cfhsi->dev->cfhsi_tx(cfhsi->tx_buf, len, cfhsi->dev);
 		if (WARN_ON(res < 0))
-			dev_err(&cfhsi->ndev->dev, "%s: TX error %d.\n",
+			netdev_err(cfhsi->ndev, "%s: TX error %d.\n",
 				__func__, res);
 	} while (res < 0);
 }
 
 static void cfhsi_tx_done(struct cfhsi *cfhsi)
 {
-	dev_dbg(&cfhsi->ndev->dev, "%s.\n", __func__);
+	netdev_dbg(cfhsi->ndev, "%s.\n", __func__);
 
 	if (test_bit(CFHSI_SHUTDOWN, &cfhsi->bits))
 		return;
@@ -416,7 +416,7 @@ static void cfhsi_tx_done_cb(struct cfhsi_drv *drv)
 	struct cfhsi *cfhsi;
 
 	cfhsi = container_of(drv, struct cfhsi, drv);
-	dev_dbg(&cfhsi->ndev->dev, "%s.\n",
+	netdev_dbg(cfhsi->ndev, "%s.\n",
 		__func__);
 
 	if (test_bit(CFHSI_SHUTDOWN, &cfhsi->bits))
@@ -433,7 +433,7 @@ static int cfhsi_rx_desc(struct cfhsi_desc *desc, struct cfhsi *cfhsi)
 
 	if ((desc->header & ~CFHSI_PIGGY_DESC) ||
 			(desc->offset > CFHSI_MAX_EMB_FRM_SZ)) {
-		dev_err(&cfhsi->ndev->dev, "%s: Invalid descriptor.\n",
+		netdev_err(cfhsi->ndev, "%s: Invalid descriptor.\n",
 			__func__);
 		return -EPROTO;
 	}
@@ -455,7 +455,7 @@ static int cfhsi_rx_desc(struct cfhsi_desc *desc, struct cfhsi *cfhsi)
 
 		/* Sanity check length of CAIF frame. */
 		if (unlikely(len > CFHSI_MAX_CAIF_FRAME_SZ)) {
-			dev_err(&cfhsi->ndev->dev, "%s: Invalid length.\n",
+			netdev_err(cfhsi->ndev, "%s: Invalid length.\n",
 				__func__);
 			return -EPROTO;
 		}
@@ -463,7 +463,7 @@ static int cfhsi_rx_desc(struct cfhsi_desc *desc, struct cfhsi *cfhsi)
 		/* Allocate SKB (OK even in IRQ context). */
 		skb = alloc_skb(len + 1, GFP_ATOMIC);
 		if (!skb) {
-			dev_err(&cfhsi->ndev->dev, "%s: Out of memory !\n",
+			netdev_err(cfhsi->ndev, "%s: Out of memory !\n",
 				__func__);
 			return -ENOMEM;
 		}
@@ -504,7 +504,7 @@ static int cfhsi_rx_desc(struct cfhsi_desc *desc, struct cfhsi *cfhsi)
 		xfer_sz += CFHSI_DESC_SZ;
 
 	if ((xfer_sz % 4) || (xfer_sz > (CFHSI_BUF_SZ_RX - CFHSI_DESC_SZ))) {
-		dev_err(&cfhsi->ndev->dev,
+		netdev_err(cfhsi->ndev,
 				"%s: Invalid payload len: %d, ignored.\n",
 			__func__, xfer_sz);
 		return -EPROTO;
@@ -551,7 +551,7 @@ static int cfhsi_rx_pld(struct cfhsi_desc *desc, struct cfhsi *cfhsi)
 	/* Sanity check header and offset. */
 	if (WARN_ON((desc->header & ~CFHSI_PIGGY_DESC) ||
 			(desc->offset > CFHSI_MAX_EMB_FRM_SZ))) {
-		dev_err(&cfhsi->ndev->dev, "%s: Invalid descriptor.\n",
+		netdev_err(cfhsi->ndev, "%s: Invalid descriptor.\n",
 			__func__);
 		return -EPROTO;
 	}
@@ -585,7 +585,7 @@ static int cfhsi_rx_pld(struct cfhsi_desc *desc, struct cfhsi *cfhsi)
 
 		/* Sanity check length of CAIF frames. */
 		if (unlikely(len > CFHSI_MAX_CAIF_FRAME_SZ)) {
-			dev_err(&cfhsi->ndev->dev, "%s: Invalid length.\n",
+			netdev_err(cfhsi->ndev, "%s: Invalid length.\n",
 				__func__);
 			return -EPROTO;
 		}
@@ -593,7 +593,7 @@ static int cfhsi_rx_pld(struct cfhsi_desc *desc, struct cfhsi *cfhsi)
 		/* Allocate SKB (OK even in IRQ context). */
 		skb = alloc_skb(len + 1, GFP_ATOMIC);
 		if (!skb) {
-			dev_err(&cfhsi->ndev->dev, "%s: Out of memory !\n",
+			netdev_err(cfhsi->ndev, "%s: Out of memory !\n",
 				__func__);
 			cfhsi->rx_state.nfrms = nfrms;
 			return -ENOMEM;
@@ -639,7 +639,7 @@ static void cfhsi_rx_done(struct cfhsi *cfhsi)
 
 	desc = (struct cfhsi_desc *)cfhsi->rx_buf;
 
-	dev_dbg(&cfhsi->ndev->dev, "%s\n", __func__);
+	netdev_dbg(cfhsi->ndev, "%s\n", __func__);
 
 	if (test_bit(CFHSI_SHUTDOWN, &cfhsi->bits))
 		return;
@@ -709,13 +709,13 @@ static void cfhsi_rx_done(struct cfhsi *cfhsi)
 	/* Initiate next read */
 	if (test_bit(CFHSI_AWAKE, &cfhsi->bits)) {
 		/* Set up new transfer. */
-		dev_dbg(&cfhsi->ndev->dev, "%s: Start RX.\n",
+		netdev_dbg(cfhsi->ndev, "%s: Start RX.\n",
 				__func__);
 
 		res = cfhsi->dev->cfhsi_rx(rx_ptr, rx_len,
 				cfhsi->dev);
 		if (WARN_ON(res < 0)) {
-			dev_err(&cfhsi->ndev->dev, "%s: RX error %d.\n",
+			netdev_err(cfhsi->ndev, "%s: RX error %d.\n",
 				__func__, res);
 			cfhsi->ndev->stats.rx_errors++;
 			cfhsi->ndev->stats.rx_dropped++;
@@ -750,7 +750,7 @@ static void cfhsi_rx_done(struct cfhsi *cfhsi)
 	return;
 
 out_of_sync:
-	dev_err(&cfhsi->ndev->dev, "%s: Out of sync.\n", __func__);
+	netdev_err(cfhsi->ndev, "%s: Out of sync.\n", __func__);
 	print_hex_dump_bytes("--> ", DUMP_PREFIX_NONE,
 			cfhsi->rx_buf, CFHSI_DESC_SZ);
 	schedule_work(&cfhsi->out_of_sync_work);
@@ -760,7 +760,7 @@ static void cfhsi_rx_slowpath(unsigned long arg)
 {
 	struct cfhsi *cfhsi = (struct cfhsi *)arg;
 
-	dev_dbg(&cfhsi->ndev->dev, "%s.\n",
+	netdev_dbg(cfhsi->ndev, "%s.\n",
 		__func__);
 
 	cfhsi_rx_done(cfhsi);
@@ -771,7 +771,7 @@ static void cfhsi_rx_done_cb(struct cfhsi_drv *drv)
 	struct cfhsi *cfhsi;
 
 	cfhsi = container_of(drv, struct cfhsi, drv);
-	dev_dbg(&cfhsi->ndev->dev, "%s.\n",
+	netdev_dbg(cfhsi->ndev, "%s.\n",
 		__func__);
 
 	if (test_bit(CFHSI_SHUTDOWN, &cfhsi->bits))
@@ -806,7 +806,7 @@ static void cfhsi_wake_up(struct work_struct *work)
 	/* Activate wake line. */
 	cfhsi->dev->cfhsi_wake_up(cfhsi->dev);
 
-	dev_dbg(&cfhsi->ndev->dev, "%s: Start waiting.\n",
+	netdev_dbg(cfhsi->ndev, "%s: Start waiting.\n",
 		__func__);
 
 	/* Wait for acknowledge. */
@@ -816,7 +816,7 @@ static void cfhsi_wake_up(struct work_struct *work)
 							&cfhsi->bits), ret);
 	if (unlikely(ret < 0)) {
 		/* Interrupted by signal. */
-		dev_err(&cfhsi->ndev->dev, "%s: Signalled: %ld.\n",
+		netdev_err(cfhsi->ndev, "%s: Signalled: %ld.\n",
 			__func__, ret);
 
 		clear_bit(CFHSI_WAKE_UP, &cfhsi->bits);
@@ -827,14 +827,14 @@ static void cfhsi_wake_up(struct work_struct *work)
 		size_t fifo_occupancy = 0;
 
 		/* Wakeup timeout */
-		dev_dbg(&cfhsi->ndev->dev, "%s: Timeout.\n",
+		netdev_dbg(cfhsi->ndev, "%s: Timeout.\n",
 			__func__);
 
 		/* Check FIFO to check if modem has sent something. */
 		WARN_ON(cfhsi->dev->cfhsi_fifo_occupancy(cfhsi->dev,
 					&fifo_occupancy));
 
-		dev_dbg(&cfhsi->ndev->dev, "%s: Bytes in FIFO: %u.\n",
+		netdev_dbg(cfhsi->ndev, "%s: Bytes in FIFO: %u.\n",
 				__func__, (unsigned) fifo_occupancy);
 
 		/* Check if we misssed the interrupt. */
@@ -842,7 +842,7 @@ static void cfhsi_wake_up(struct work_struct *work)
 							&ca_wake));
 
 		if (ca_wake) {
-			dev_err(&cfhsi->ndev->dev, "%s: CA Wake missed !.\n",
+			netdev_err(cfhsi->ndev, "%s: CA Wake missed !.\n",
 				__func__);
 
 			/* Clear the CFHSI_WAKE_UP_ACK bit to prevent race. */
@@ -857,7 +857,7 @@ static void cfhsi_wake_up(struct work_struct *work)
 		return;
 	}
 wake_ack:
-	dev_dbg(&cfhsi->ndev->dev, "%s: Woken.\n",
+	netdev_dbg(cfhsi->ndev, "%s: Woken.\n",
 		__func__);
 
 	/* Clear power up bit. */
@@ -865,11 +865,11 @@ wake_ack:
 	clear_bit(CFHSI_WAKE_UP, &cfhsi->bits);
 
 	/* Resume read operation. */
-	dev_dbg(&cfhsi->ndev->dev, "%s: Start RX.\n", __func__);
+	netdev_dbg(cfhsi->ndev, "%s: Start RX.\n", __func__);
 	res = cfhsi->dev->cfhsi_rx(cfhsi->rx_ptr, cfhsi->rx_len, cfhsi->dev);
 
 	if (WARN_ON(res < 0))
-		dev_err(&cfhsi->ndev->dev, "%s: RX err %d.\n", __func__, res);
+		netdev_err(cfhsi->ndev, "%s: RX err %d.\n", __func__, res);
 
 	/* Clear power up acknowledment. */
 	clear_bit(CFHSI_WAKE_UP_ACK, &cfhsi->bits);
@@ -878,7 +878,7 @@ wake_ack:
 
 	/* Resume transmit if queues are not empty. */
 	if (!cfhsi_tx_queue_len(cfhsi)) {
-		dev_dbg(&cfhsi->ndev->dev, "%s: Peer wake, start timer.\n",
+		netdev_dbg(cfhsi->ndev, "%s: Peer wake, start timer.\n",
 			__func__);
 		/* Start inactivity timer. */
 		mod_timer(&cfhsi->inactivity_timer,
@@ -887,7 +887,7 @@ wake_ack:
 		return;
 	}
 
-	dev_dbg(&cfhsi->ndev->dev, "%s: Host wake.\n",
+	netdev_dbg(cfhsi->ndev, "%s: Host wake.\n",
 		__func__);
 
 	spin_unlock_bh(&cfhsi->lock);
@@ -899,12 +899,12 @@ wake_ack:
 		/* Set up new transfer. */
 		res = cfhsi->dev->cfhsi_tx(cfhsi->tx_buf, len, cfhsi->dev);
 		if (WARN_ON(res < 0)) {
-			dev_err(&cfhsi->ndev->dev, "%s: TX error %d.\n",
+			netdev_err(cfhsi->ndev, "%s: TX error %d.\n",
 				__func__, res);
 			cfhsi_abort_tx(cfhsi);
 		}
 	} else {
-		dev_err(&cfhsi->ndev->dev,
+		netdev_err(cfhsi->ndev,
 				"%s: Failed to create HSI frame: %d.\n",
 				__func__, len);
 	}
@@ -918,7 +918,7 @@ static void cfhsi_wake_down(struct work_struct *work)
 	int retry = CFHSI_WAKE_TOUT;
 
 	cfhsi = container_of(work, struct cfhsi, wake_down_work);
-	dev_dbg(&cfhsi->ndev->dev, "%s.\n", __func__);
+	netdev_dbg(cfhsi->ndev, "%s.\n", __func__);
 
 	if (test_bit(CFHSI_SHUTDOWN, &cfhsi->bits))
 		return;
@@ -933,20 +933,20 @@ static void cfhsi_wake_down(struct work_struct *work)
 							&cfhsi->bits), ret);
 	if (ret < 0) {
 		/* Interrupted by signal. */
-		dev_err(&cfhsi->ndev->dev, "%s: Signalled: %ld.\n",
+		netdev_err(cfhsi->ndev, "%s: Signalled: %ld.\n",
 			__func__, ret);
 		return;
 	} else if (!ret) {
 		bool ca_wake = true;
 
 		/* Timeout */
-		dev_err(&cfhsi->ndev->dev, "%s: Timeout.\n", __func__);
+		netdev_err(cfhsi->ndev, "%s: Timeout.\n", __func__);
 
 		/* Check if we misssed the interrupt. */
 		WARN_ON(cfhsi->dev->cfhsi_get_peer_wake(cfhsi->dev,
 							&ca_wake));
 		if (!ca_wake)
-			dev_err(&cfhsi->ndev->dev, "%s: CA Wake missed !.\n",
+			netdev_err(cfhsi->ndev, "%s: CA Wake missed !.\n",
 				__func__);
 	}
 
@@ -964,7 +964,7 @@ static void cfhsi_wake_down(struct work_struct *work)
 	}
 
 	if (!retry)
-		dev_err(&cfhsi->ndev->dev, "%s: FIFO Timeout.\n", __func__);
+		netdev_err(cfhsi->ndev, "%s: FIFO Timeout.\n", __func__);
 
 	/* Clear AWAKE condition. */
 	clear_bit(CFHSI_AWAKE, &cfhsi->bits);
@@ -990,7 +990,7 @@ static void cfhsi_wake_up_cb(struct cfhsi_drv *drv)
 	struct cfhsi *cfhsi = NULL;
 
 	cfhsi = container_of(drv, struct cfhsi, drv);
-	dev_dbg(&cfhsi->ndev->dev, "%s.\n",
+	netdev_dbg(cfhsi->ndev, "%s.\n",
 		__func__);
 
 	set_bit(CFHSI_WAKE_UP_ACK, &cfhsi->bits);
@@ -1009,7 +1009,7 @@ static void cfhsi_wake_down_cb(struct cfhsi_drv *drv)
 	struct cfhsi *cfhsi = NULL;
 
 	cfhsi = container_of(drv, struct cfhsi, drv);
-	dev_dbg(&cfhsi->ndev->dev, "%s.\n",
+	netdev_dbg(cfhsi->ndev, "%s.\n",
 		__func__);
 
 	/* Initiating low power is only permitted by the host (us). */
@@ -1021,7 +1021,7 @@ static void cfhsi_aggregation_tout(unsigned long arg)
 {
 	struct cfhsi *cfhsi = (struct cfhsi *)arg;
 
-	dev_dbg(&cfhsi->ndev->dev, "%s.\n",
+	netdev_dbg(cfhsi->ndev, "%s.\n",
 		__func__);
 
 	cfhsi_start_tx(cfhsi);
@@ -1113,7 +1113,7 @@ static int cfhsi_xmit(struct sk_buff *skb, struct net_device *dev)
 		/* Set up new transfer. */
 		res = cfhsi->dev->cfhsi_tx(cfhsi->tx_buf, len, cfhsi->dev);
 		if (WARN_ON(res < 0)) {
-			dev_err(&cfhsi->ndev->dev, "%s: TX error %d.\n",
+			netdev_err(cfhsi->ndev, "%s: TX error %d.\n",
 				__func__, res);
 			cfhsi_abort_tx(cfhsi);
 		}
@@ -1269,7 +1269,7 @@ static int cfhsi_open(struct net_device *ndev)
 	/* Create work thread. */
 	cfhsi->wq = create_singlethread_workqueue(cfhsi->pdev->name);
 	if (!cfhsi->wq) {
-		dev_err(&cfhsi->ndev->dev, "%s: Failed to create work queue.\n",
+		netdev_err(cfhsi->ndev, "%s: Failed to create work queue.\n",
 			__func__);
 		res = -ENODEV;
 		goto err_create_wq;
@@ -1296,7 +1296,7 @@ static int cfhsi_open(struct net_device *ndev)
 	/* Activate HSI interface. */
 	res = cfhsi->dev->cfhsi_up(cfhsi->dev);
 	if (res) {
-		dev_err(&cfhsi->ndev->dev,
+		netdev_err(cfhsi->ndev,
 			"%s: can't activate HSI interface: %d.\n",
 			__func__, res);
 		goto err_activate;
@@ -1305,7 +1305,7 @@ static int cfhsi_open(struct net_device *ndev)
 	/* Flush FIFO */
 	res = cfhsi_flush_fifo(cfhsi);
 	if (res) {
-		dev_err(&cfhsi->ndev->dev, "%s: Can't flush FIFO: %d.\n",
+		netdev_err(cfhsi->ndev, "%s: Can't flush FIFO: %d.\n",
 			__func__, res);
 		goto err_net_reg;
 	}
-- 
1.7.5.4

^ permalink raw reply related

* [net-next 05/11] caif-hsi: changed test on aggregation_timeout
From: sjur.brandeland @ 2012-06-25 17:49 UTC (permalink / raw)
  To: davem; +Cc: netdev, sjurbren, Kim Lilliestierna XX, Sjur Brændeland
In-Reply-To: <1340646583-21059-1-git-send-email-sjur.brandeland@stericsson.com>

From: Kim Lilliestierna XX <kim.xx.lilliestierna@stericsson.com>

Aggregation_timeout is an unsigned long,
a test for less than zero can never become true,
compare with zero instead.

Signed-off-by: Kim Lilliestierna <kim.xx.lilliestierna@stericsson.com>
Signed-off-by: Sjur Brændeland <sjur.brandeland@stericsson.com>
---
 drivers/net/caif/caif_hsi.c |    2 +-
 1 files changed, 1 insertions(+), 1 deletions(-)

diff --git a/drivers/net/caif/caif_hsi.c b/drivers/net/caif/caif_hsi.c
index f81f61f..56cc941 100644
--- a/drivers/net/caif/caif_hsi.c
+++ b/drivers/net/caif/caif_hsi.c
@@ -115,7 +115,7 @@ static bool cfhsi_can_send_aggregate(struct cfhsi *cfhsi)
 {
 	int i;
 
-	if (cfhsi->aggregation_timeout < 0)
+	if (cfhsi->aggregation_timeout == 0)
 		return true;
 
 	for (i = 0; i < CFHSI_PRIO_BEBK; ++i) {
-- 
1.7.5.4

^ permalink raw reply related

* [net-next 04/11] caif-hsi: Removed dead code
From: sjur.brandeland @ 2012-06-25 17:49 UTC (permalink / raw)
  To: davem; +Cc: netdev, sjurbren, Kim Lilliestierna XX, Sjur Brændeland
In-Reply-To: <1340646583-21059-1-git-send-email-sjur.brandeland@stericsson.com>

From: Kim Lilliestierna XX <kim.xx.lilliestierna@stericsson.com>

Simplify logic and remove dead code.

Signed-off-by: Kim Lilliestierna <kim.xx.lilliestierna@stericsson.com>
Signed-off-by: Sjur Brændeland <sjur.brandeland@stericsson.com>
---
 drivers/net/caif/caif_hsi.c |   11 ++++-------
 1 files changed, 4 insertions(+), 7 deletions(-)

diff --git a/drivers/net/caif/caif_hsi.c b/drivers/net/caif/caif_hsi.c
index 1520814..f81f61f 100644
--- a/drivers/net/caif/caif_hsi.c
+++ b/drivers/net/caif/caif_hsi.c
@@ -680,12 +680,11 @@ static void cfhsi_rx_done(struct cfhsi *cfhsi)
 			if (desc_pld_len < 0)
 				goto out_of_sync;
 
-			if (desc_pld_len > 0)
+			if (desc_pld_len > 0) {
 				rx_len = desc_pld_len;
-
-			if (desc_pld_len > 0 &&
-					(piggy_desc->header & CFHSI_PIGGY_DESC))
-				rx_len += CFHSI_DESC_SZ;
+				if (piggy_desc->header & CFHSI_PIGGY_DESC)
+					rx_len += CFHSI_DESC_SZ;
+			}
 
 			/*
 			 * Copy needed information from the piggy-backed
@@ -695,8 +694,6 @@ static void cfhsi_rx_done(struct cfhsi *cfhsi)
 					CFHSI_DESC_SHORT_SZ);
 			/* Mark no embedded frame here */
 			piggy_desc->offset = 0;
-			if (desc_pld_len == -EPROTO)
-				goto out_of_sync;
 		}
 	}
 
-- 
1.7.5.4

^ permalink raw reply related

* [net-next 03/11] caif: Fixed potential memory leak
From: sjur.brandeland @ 2012-06-25 17:49 UTC (permalink / raw)
  To: davem; +Cc: netdev, sjurbren, Kim Lilliestierna XX, Sjur Brændeland
In-Reply-To: <1340646583-21059-1-git-send-email-sjur.brandeland@stericsson.com>

From: Kim Lilliestierna XX <kim.xx.lilliestierna@stericsson.com>

Rearranged the allocation and packet creations to
avoid potential leaks in error path.

Signed-off-by: Kim Lilliestierna <kim.xx.lilliestierna@stericsson.com>
Signed-off-by: Sjur Brændeland <sjur.brandeland@stericssion.com>
---
 net/caif/cfctrl.c |   17 +++++++++--------
 1 files changed, 9 insertions(+), 8 deletions(-)

diff --git a/net/caif/cfctrl.c b/net/caif/cfctrl.c
index 047cd0e..44f270f 100644
--- a/net/caif/cfctrl.c
+++ b/net/caif/cfctrl.c
@@ -175,15 +175,17 @@ static void init_info(struct caif_payload_info *info, struct cfctrl *cfctrl)
 
 void cfctrl_enum_req(struct cflayer *layer, u8 physlinkid)
 {
+	struct cfpkt *pkt;
 	struct cfctrl *cfctrl = container_obj(layer);
-	struct cfpkt *pkt = cfpkt_create(CFPKT_CTRL_PKT_LEN);
 	struct cflayer *dn = cfctrl->serv.layer.dn;
-	if (!pkt)
-		return;
+
 	if (!dn) {
 		pr_debug("not able to send enum request\n");
 		return;
 	}
+	pkt = cfpkt_create(CFPKT_CTRL_PKT_LEN);
+	if (!pkt)
+		return;
 	caif_assert(offsetof(struct cfctrl, serv.layer) == 0);
 	init_info(cfpkt_info(pkt), cfctrl);
 	cfpkt_info(pkt)->dev_info->id = physlinkid;
@@ -302,18 +304,17 @@ int cfctrl_linkdown_req(struct cflayer *layer, u8 channelid,
 				struct cflayer *client)
 {
 	int ret;
+	struct cfpkt *pkt;
 	struct cfctrl *cfctrl = container_obj(layer);
-	struct cfpkt *pkt = cfpkt_create(CFPKT_CTRL_PKT_LEN);
 	struct cflayer *dn = cfctrl->serv.layer.dn;
 
-	if (!pkt)
-		return -ENOMEM;
-
 	if (!dn) {
 		pr_debug("not able to send link-down request\n");
 		return -ENODEV;
 	}
-
+	pkt = cfpkt_create(CFPKT_CTRL_PKT_LEN);
+	if (!pkt)
+		return -ENOMEM;
 	cfpkt_addbdy(pkt, CFCTRL_CMD_LINK_DESTROY);
 	cfpkt_addbdy(pkt, channelid);
 	init_info(cfpkt_info(pkt), cfctrl);
-- 
1.7.5.4

^ permalink raw reply related

* [net-next 02/11] caif: added check for potential null return
From: sjur.brandeland @ 2012-06-25 17:49 UTC (permalink / raw)
  To: davem
  Cc: netdev, sjurbren, Kim Lilliestierna XX, Kim Lilliestierna,
	Sjur Brændeland
In-Reply-To: <1340646583-21059-1-git-send-email-sjur.brandeland@stericsson.com>

From: Kim Lilliestierna XX <kim.xx.lilliestierna@stericsson.com>

Add check on NULL return from caif_get().

Signed-off-by: Kim Lilliestierna <Kim.xx.Lilliestierna@stericsson.com>
Signed-off-by: Sjur Brændeland <sjur.brandeland@stericssion.com>
---
 net/caif/caif_dev.c |    5 +++++
 1 files changed, 5 insertions(+), 0 deletions(-)

diff --git a/net/caif/caif_dev.c b/net/caif/caif_dev.c
index 92c9397..0f010af 100644
--- a/net/caif/caif_dev.c
+++ b/net/caif/caif_dev.c
@@ -129,6 +129,11 @@ void caif_flow_cb(struct sk_buff *skb)
 
 	rcu_read_lock();
 	caifd = caif_get(skb->dev);
+
+	WARN_ON(caifd == NULL);
+	if (caifd == NULL)
+		return;
+
 	caifd_hold(caifd);
 	rcu_read_unlock();
 
-- 
1.7.5.4

^ permalink raw reply related

* [net-next 01/11] caif: Remove unused pointer and code
From: sjur.brandeland @ 2012-06-25 17:49 UTC (permalink / raw)
  To: davem; +Cc: netdev, sjurbren, Kim Lilliestierna XX, Sjur Brændeland
In-Reply-To: <1340646583-21059-1-git-send-email-sjur.brandeland@stericsson.com>

From: Kim Lilliestierna XX <kim.xx.lilliestierna@stericsson.com>

Removed surplus call to caif_device_list() in caif_dev.c

Signed-off-by: Kim Lilliestierna <kim.xx.lilliestierna@stericsson.com>
Signed-off-by: Sjur Brændeland <sjur.brandeland@stericsson.com>
---
 net/caif/caif_dev.c |    3 ---
 1 files changed, 0 insertions(+), 3 deletions(-)

diff --git a/net/caif/caif_dev.c b/net/caif/caif_dev.c
index aa6f716..92c9397 100644
--- a/net/caif/caif_dev.c
+++ b/net/caif/caif_dev.c
@@ -91,11 +91,8 @@ static int caifd_refcnt_read(struct caif_device_entry *e)
 /* Allocate new CAIF device. */
 static struct caif_device_entry *caif_device_alloc(struct net_device *dev)
 {
-	struct caif_device_entry_list *caifdevs;
 	struct caif_device_entry *caifd;
 
-	caifdevs = caif_device_list(dev_net(dev));
-
 	caifd = kzalloc(sizeof(*caifd), GFP_KERNEL);
 	if (!caifd)
 		return NULL;
-- 
1.7.5.4

^ permalink raw reply related

* [net-next 00/11] caif patch-set for net-next
From: sjur.brandeland @ 2012-06-25 17:49 UTC (permalink / raw)
  To: davem; +Cc: netdev, sjurbren, Sjur Brændeland

From: Sjur Brændeland <sjur.brandeland@stericsson.com>

The first 8 patches are fixes,
there are a couple of fixes for issues found by static code analysis (coverity),
and some other misc cleanups/fixes.

The three last patches introduces rtnl for managing
the HSI interface and removes the use of module parameters.

Regards,
Sjur Brændeland

Kim Lilliestierna XX (5):
  caif: Remove unused pointer and code
  caif: added check for potential null return
  caif: Fixed potential memory leak
  caif-hsi: Removed dead code
  caif-hsi: changed test on aggregation_timeout

Sjur Brændeland (6):
  caif-hsi: Use netdev_X instead of dev_X for printing
  caif-hsi: Remove uncecessary assignments
  Documentation/networking/caif: Update documentation
  caif-hsi: Add rtnl support
  caif-hsi: Replace platform device with ops structure.
  caif-hsi: Remove use of module parameters

 Documentation/networking/caif/Linux-CAIF.txt |   91 ++---
 drivers/net/caif/caif_hsi.c                  |  547 ++++++++++++++------------
 include/net/caif/caif_hsi.h                  |   71 +++--
 net/caif/caif_dev.c                          |    8 +-
 net/caif/cfctrl.c                            |   17 +-
 5 files changed, 378 insertions(+), 356 deletions(-)

-- 
1.7.5.4

^ permalink raw reply

* Re: [net-next RFC V4 PATCH 0/4] Multiqueue virtio-net
From: Sridhar Samudrala @ 2012-06-25 17:49 UTC (permalink / raw)
  To: Jason Wang
  Cc: krkumar2, habanero, kvm, mst, netdev, mashirle, linux-kernel,
	virtualization, edumazet, tahm, jwhan, davem
In-Reply-To: <20120625090829.7263.65026.stgit@amd-6168-8-1.englab.nay.redhat.com>

On 6/25/2012 2:16 AM, Jason Wang wrote:
> Hello All:
>
> This series is an update version of multiqueue virtio-net driver based on
> Krishna Kumar's work to let virtio-net use multiple rx/tx queues to do the
> packets reception and transmission. Please review and comments.
>
> Test Environment:
> - Intel(R) Xeon(R) CPU E5620 @ 2.40GHz, 8 cores 2 numa nodes
> - Two directed connected 82599
>
> Test Summary:
>
> - Highlights: huge improvements on TCP_RR test
> - Lowlights: regression on small packet transmission, higher cpu utilization
>               than single queue, need further optimization
Does this also scale with increased number of VMs?

Thanks
Sridhar
>
> Analysis of the performance result:
>
> - I count the number of packets sending/receiving during the test, and
>    multiqueue show much more ability in terms of packets per second.
>
> - For the tx regression, multiqueue send about 1-2 times of more packets
>    compared to single queue, and the packets size were much smaller than single
>    queue does. I suspect tcp does less batching in multiqueue, so I hack the
>    tcp_write_xmit() to forece more batching, multiqueue works as well as
>    singlequeue for both small transmission and throughput
>
> - I didn't pack the accelerate RFS with virtio-net in this sereis as it still
>    need further shaping, for the one that interested in this please see:
>    http://www.mail-archive.com/kvm@vger.kernel.org/msg64111.html
>
>

^ permalink raw reply

* RE: [RFC net-next (v2) 11/14] igb: set maximal number of default RSS queues
From: Vick, Matthew @ 2012-06-25 17:31 UTC (permalink / raw)
  To: Yuval Mintz, davem@davemloft.net, netdev@vger.kernel.org
  Cc: eilong@broadcom.com, Kirsher, Jeffrey T
In-Reply-To: <1340624745-8650-12-git-send-email-yuvalmin@broadcom.com>

> -----Original Message-----
> From: netdev-owner@vger.kernel.org [mailto:netdev-
> owner@vger.kernel.org] On Behalf Of Yuval Mintz
> Sent: Monday, June 25, 2012 4:46 AM
> To: davem@davemloft.net; netdev@vger.kernel.org
> Cc: eilong@broadcom.com; Yuval Mintz; Kirsher, Jeffrey T
> Subject: [RFC net-next (v2) 11/14] igb: set maximal number of default
> RSS queues
> 
> Signed-off-by: Yuval Mintz <yuvalmin@broadcom.com>
> Signed-off-by: Eilon Greenstein <eilong@broadcom.com>
> 
> Cc: Jeff Kirsher <jeffrey.t.kirsher@intel.com>
> ---
>  drivers/net/ethernet/intel/igb/igb_main.c |    3 ++-
>  1 files changed, 2 insertions(+), 1 deletions(-)
> 
> diff --git a/drivers/net/ethernet/intel/igb/igb_main.c
> b/drivers/net/ethernet/intel/igb/igb_main.c
> index 01ced68..b11ee60 100644
> --- a/drivers/net/ethernet/intel/igb/igb_main.c
> +++ b/drivers/net/ethernet/intel/igb/igb_main.c
> @@ -2465,7 +2465,8 @@ static int __devinit igb_sw_init(struct
> igb_adapter *adapter)
>  		break;
>  	}
> 
> -	adapter->rss_queues = min_t(u32, max_rss_queues,
> num_online_cpus());
> +	adapter->rss_queues = min_t(u32, max_rss_queues,
> +				    netif_get_num_default_rss_queues());
> 
>  	/* Determine if we need to pair queues. */
>  	switch (hw->mac.type) {
> --
> 1.7.9.rc2

Since igb supports a maximum of 8 RSS queues anyway, it's generally unaffected by this change. That being said, I'm confused about what you're trying to accomplish--is it to standardize the number of RSS queues or limit the number of interrupts by default? Or is it the former with a hope that it will trickle down to the latter?

For example, if you take an igb device that supports 8 RSS queues (say, I350) and you change the default to 4 RSS queues, you will end up with the same number of interrupt vectors being requested as we will disable queue pairing and request separate vectors for Rx/Tx queues. I haven't looked at the other drivers affected by this RFC, but it's possible other drivers behave the same way.

Matthew

Matthew Vick
Linux Development
LAN Access Division
Intel Corporation

^ permalink raw reply

* Re: [PATCH] NFC: only put local on destruction if it was created before
From: Samuel Ortiz @ 2012-06-25 17:29 UTC (permalink / raw)
  To: Sasha Levin
  Cc: lauro.venancio, aloisio.almeida, linville, davej, linux-wireless,
	netdev, linux-kernel
In-Reply-To: <1340644546.31710.6.camel@lappy>

On Mon, Jun 25, 2012 at 07:15:46PM +0200, Sasha Levin wrote:
> On Mon, 2012-06-25 at 19:17 +0200, Samuel Ortiz wrote:
> > Hi Sasha,
> > 
> > On Tue, Jun 12, 2012 at 10:08:19PM +0200, Sasha Levin wrote:
> > > Not having 'local' is a valid case when a socket was created but never
> > > bound or connected to anything, so avoid putting 'local' if it was
> > > never created.
> > > 
> > > Signed-off-by: Sasha Levin <levinsasha928@gmail.com>
> > > ---
> > >  net/nfc/llcp/sock.c |    3 ++-
> > >  1 files changed, 2 insertions(+), 1 deletions(-)
> > > 
> > > diff --git a/net/nfc/llcp/sock.c b/net/nfc/llcp/sock.c
> > > index 2c0b317..54daa10 100644
> > > --- a/net/nfc/llcp/sock.c
> > > +++ b/net/nfc/llcp/sock.c
> > > @@ -710,7 +710,8 @@ void nfc_llcp_sock_free(struct nfc_llcp_sock *sock)
> > >  
> > >  	sock->parent = NULL;
> > >  
> > > -	nfc_llcp_local_put(sock->local);
> > > +	if (sock->local)
> > > +		nfc_llcp_local_put(sock->local);
> > nfc_llcp_local_put() already checks for its argument being NULL or not.
> 
> nfc_llcp_local_put() triggers a warning in this case as well, which
> means that this code path shouldn't be happening.
> 
> Should we remove the WARN_ON from nfc_llcp_local_put() instead?
Yes, that would be better.

Cheers,
Samuel.

-- 
Intel Open Source Technology Centre
http://oss.intel.com/

^ permalink raw reply

* Re: [PATCH] NFC: only put local on destruction if it was created before
From: Samuel Ortiz @ 2012-06-25 17:17 UTC (permalink / raw)
  To: Sasha Levin
  Cc: lauro.venancio, aloisio.almeida, linville, davej, linux-wireless,
	netdev, linux-kernel
In-Reply-To: <1339531699-7377-1-git-send-email-levinsasha928@gmail.com>

Hi Sasha,

On Tue, Jun 12, 2012 at 10:08:19PM +0200, Sasha Levin wrote:
> Not having 'local' is a valid case when a socket was created but never
> bound or connected to anything, so avoid putting 'local' if it was
> never created.
> 
> Signed-off-by: Sasha Levin <levinsasha928@gmail.com>
> ---
>  net/nfc/llcp/sock.c |    3 ++-
>  1 files changed, 2 insertions(+), 1 deletions(-)
> 
> diff --git a/net/nfc/llcp/sock.c b/net/nfc/llcp/sock.c
> index 2c0b317..54daa10 100644
> --- a/net/nfc/llcp/sock.c
> +++ b/net/nfc/llcp/sock.c
> @@ -710,7 +710,8 @@ void nfc_llcp_sock_free(struct nfc_llcp_sock *sock)
>  
>  	sock->parent = NULL;
>  
> -	nfc_llcp_local_put(sock->local);
> +	if (sock->local)
> +		nfc_llcp_local_put(sock->local);
nfc_llcp_local_put() already checks for its argument being NULL or not.

Cheers,
Samuel.

-- 
Intel Open Source Technology Centre
http://oss.intel.com/

^ permalink raw reply


This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox