Netdev List
 help / color / mirror / Atom feed
* [PATCH] can: make the number of echo skb's configurable
From: Wolfgang Grandegger @ 2009-10-09  8:17 UTC (permalink / raw)
  To: Linux Netdev List; +Cc: SocketCAN Core Mailing List

This patch allows the CAN controller driver to define the number of echo
skb's used for the local loopback (echo), as suggested by Kurt Van
Dijck, with the function:

  struct net_device *alloc_candev(int sizeof_priv,
                                  unsigned int echo_skb_max);

The CAN drivers have been adapted accordingly. For the ems_usb driver,
as suggested by Sebastian Haas, the number of echo skb's has been
increased to 10, which improves the transmission performance a lot.

Signed-off-by: Wolfgang Grandegger <wg-5Yr1BZd7O62+XT7JhA+gdA@public.gmane.org>
Signed-off-by: Kurt Van Dijck <kurt.van.dijck-/BeEPy95v10@public.gmane.org>
---

Resent with the proper prefix [PATCH]. Sorry for the noise.

Wolfgang.

 drivers/net/can/at91_can.c        |    2 +-
 drivers/net/can/dev.c             |   32 ++++++++++++++++++++++++++------
 drivers/net/can/sja1000/sja1000.c |    3 ++-
 drivers/net/can/sja1000/sja1000.h |    2 ++
 drivers/net/can/ti_hecc.c         |    6 +-----
 drivers/net/can/usb/ems_usb.c     |    4 ++--
 include/linux/can/dev.h           |   16 ++++++++--------
 7 files changed, 42 insertions(+), 23 deletions(-)

Index: net-next-2.6/drivers/net/can/dev.c
===================================================================
--- net-next-2.6.orig/drivers/net/can/dev.c
+++ net-next-2.6/drivers/net/can/dev.c
@@ -245,7 +245,7 @@ static void can_flush_echo_skb(struct ne
 	struct net_device_stats *stats = &dev->stats;
 	int i;
 
-	for (i = 0; i < CAN_ECHO_SKB_MAX; i++) {
+	for (i = 0; i < priv->echo_skb_max; i++) {
 		if (priv->echo_skb[i]) {
 			kfree_skb(priv->echo_skb[i]);
 			priv->echo_skb[i] = NULL;
@@ -262,10 +262,13 @@ static void can_flush_echo_skb(struct ne
  * of the device driver. The driver must protect access to
  * priv->echo_skb, if necessary.
  */
-void can_put_echo_skb(struct sk_buff *skb, struct net_device *dev, int idx)
+void can_put_echo_skb(struct sk_buff *skb, struct net_device *dev,
+		      unsigned int idx)
 {
 	struct can_priv *priv = netdev_priv(dev);
 
+	BUG_ON(idx >= priv->echo_skb_max);
+
 	/* check flag whether this packet has to be looped back */
 	if (!(dev->flags & IFF_ECHO) || skb->pkt_type != PACKET_LOOPBACK) {
 		kfree_skb(skb);
@@ -311,10 +314,12 @@ EXPORT_SYMBOL_GPL(can_put_echo_skb);
  * is handled in the device driver. The driver must protect
  * access to priv->echo_skb, if necessary.
  */
-void can_get_echo_skb(struct net_device *dev, int idx)
+void can_get_echo_skb(struct net_device *dev, unsigned int idx)
 {
 	struct can_priv *priv = netdev_priv(dev);
 
+	BUG_ON(idx >= priv->echo_skb_max);
+
 	if (priv->echo_skb[idx]) {
 		netif_rx(priv->echo_skb[idx]);
 		priv->echo_skb[idx] = NULL;
@@ -327,10 +332,12 @@ EXPORT_SYMBOL_GPL(can_get_echo_skb);
   *
   * The function is typically called when TX failed.
   */
-void can_free_echo_skb(struct net_device *dev, int idx)
+void can_free_echo_skb(struct net_device *dev, unsigned int idx)
 {
 	struct can_priv *priv = netdev_priv(dev);
 
+	BUG_ON(idx >= priv->echo_skb_max);
+
 	if (priv->echo_skb[idx]) {
 		kfree_skb(priv->echo_skb[idx]);
 		priv->echo_skb[idx] = NULL;
@@ -445,17 +452,30 @@ static void can_setup(struct net_device 
 /*
  * Allocate and setup space for the CAN network device
  */
-struct net_device *alloc_candev(int sizeof_priv)
+struct net_device *alloc_candev(int sizeof_priv, unsigned int echo_skb_max)
 {
 	struct net_device *dev;
 	struct can_priv *priv;
+	int size;
 
-	dev = alloc_netdev(sizeof_priv, "can%d", can_setup);
+	if (echo_skb_max)
+		size = ALIGN(sizeof_priv, sizeof(struct sk_buff *)) +
+			echo_skb_max * sizeof(struct sk_buff *);
+	else
+		size = sizeof_priv;
+
+	dev = alloc_netdev(size, "can%d", can_setup);
 	if (!dev)
 		return NULL;
 
 	priv = netdev_priv(dev);
 
+	if (echo_skb_max) {
+		priv->echo_skb_max = echo_skb_max;
+		priv->echo_skb = (void *)priv +
+			ALIGN(sizeof_priv, sizeof(struct sk_buff *));
+	}
+
 	priv->state = CAN_STATE_STOPPED;
 
 	init_timer(&priv->restart_timer);
Index: net-next-2.6/include/linux/can/dev.h
===================================================================
--- net-next-2.6.orig/include/linux/can/dev.h
+++ net-next-2.6/include/linux/can/dev.h
@@ -29,8 +29,6 @@ enum can_mode {
 /*
  * CAN common private data
  */
-#define CAN_ECHO_SKB_MAX  4
-
 struct can_priv {
 	struct can_device_stats can_stats;
 
@@ -44,15 +42,16 @@ struct can_priv {
 	int restart_ms;
 	struct timer_list restart_timer;
 
-	struct sk_buff *echo_skb[CAN_ECHO_SKB_MAX];
-
 	int (*do_set_bittiming)(struct net_device *dev);
 	int (*do_set_mode)(struct net_device *dev, enum can_mode mode);
 	int (*do_get_state)(const struct net_device *dev,
 			    enum can_state *state);
+
+	unsigned int echo_skb_max;
+	struct sk_buff **echo_skb;
 };
 
-struct net_device *alloc_candev(int sizeof_priv);
+struct net_device *alloc_candev(int sizeof_priv, unsigned int echo_skb_max);
 void free_candev(struct net_device *dev);
 
 int open_candev(struct net_device *dev);
@@ -64,8 +63,9 @@ void unregister_candev(struct net_device
 int can_restart_now(struct net_device *dev);
 void can_bus_off(struct net_device *dev);
 
-void can_put_echo_skb(struct sk_buff *skb, struct net_device *dev, int idx);
-void can_get_echo_skb(struct net_device *dev, int idx);
-void can_free_echo_skb(struct net_device *dev, int idx);
+void can_put_echo_skb(struct sk_buff *skb, struct net_device *dev,
+		      unsigned int idx);
+void can_get_echo_skb(struct net_device *dev, unsigned int idx);
+void can_free_echo_skb(struct net_device *dev, unsigned int idx);
 
 #endif /* CAN_DEV_H */
Index: net-next-2.6/drivers/net/can/at91_can.c
===================================================================
--- net-next-2.6.orig/drivers/net/can/at91_can.c
+++ net-next-2.6/drivers/net/can/at91_can.c
@@ -1087,7 +1087,7 @@ static int __init at91_can_probe(struct 
 		goto exit_release;
 	}
 
-	dev = alloc_candev(sizeof(struct at91_priv));
+	dev = alloc_candev(sizeof(struct at91_priv), AT91_MB_TX_NUM);
 	if (!dev) {
 		err = -ENOMEM;
 		goto exit_iounmap;
Index: net-next-2.6/drivers/net/can/sja1000/sja1000.c
===================================================================
--- net-next-2.6.orig/drivers/net/can/sja1000/sja1000.c
+++ net-next-2.6/drivers/net/can/sja1000/sja1000.c
@@ -565,7 +565,8 @@ struct net_device *alloc_sja1000dev(int 
 	struct net_device *dev;
 	struct sja1000_priv *priv;
 
-	dev = alloc_candev(sizeof(struct sja1000_priv) + sizeof_priv);
+	dev = alloc_candev(sizeof(struct sja1000_priv) + sizeof_priv,
+		SJA1000_ECHO_SKB_MAX);
 	if (!dev)
 		return NULL;
 
Index: net-next-2.6/drivers/net/can/sja1000/sja1000.h
===================================================================
--- net-next-2.6.orig/drivers/net/can/sja1000/sja1000.h
+++ net-next-2.6/drivers/net/can/sja1000/sja1000.h
@@ -50,6 +50,8 @@
 #include <linux/can/dev.h>
 #include <linux/can/platform/sja1000.h>
 
+#define SJA1000_ECHO_SKB_MAX	1 /* the SJA1000 has one TX buffer object */
+
 #define SJA1000_MAX_IRQ 20	/* max. number of interrupts handled in ISR */
 
 /* SJA1000 registers - manual section 6.4 (Pelican Mode) */
Index: net-next-2.6/drivers/net/can/usb/ems_usb.c
===================================================================
--- net-next-2.6.orig/drivers/net/can/usb/ems_usb.c
+++ net-next-2.6/drivers/net/can/usb/ems_usb.c
@@ -232,7 +232,7 @@ MODULE_DEVICE_TABLE(usb, ems_usb_table);
 #define INTR_IN_BUFFER_SIZE 4
 
 #define MAX_RX_URBS 10
-#define MAX_TX_URBS CAN_ECHO_SKB_MAX
+#define MAX_TX_URBS 10
 
 struct ems_usb;
 
@@ -1012,7 +1012,7 @@ static int ems_usb_probe(struct usb_inte
 	struct ems_usb *dev;
 	int i, err = -ENOMEM;
 
-	netdev = alloc_candev(sizeof(struct ems_usb));
+	netdev = alloc_candev(sizeof(struct ems_usb), MAX_TX_URBS);
 	if (!netdev) {
 		dev_err(netdev->dev.parent, "Couldn't alloc candev\n");
 		return -ENOMEM;
Index: net-next-2.6/drivers/net/can/ti_hecc.c
===================================================================
--- net-next-2.6.orig/drivers/net/can/ti_hecc.c
+++ net-next-2.6/drivers/net/can/ti_hecc.c
@@ -74,10 +74,6 @@ MODULE_VERSION(HECC_MODULE_VERSION);
 #define HECC_MB_TX_SHIFT	2 /* as per table above */
 #define HECC_MAX_TX_MBOX	BIT(HECC_MB_TX_SHIFT)
 
-#if (HECC_MAX_TX_MBOX > CAN_ECHO_SKB_MAX)
-#error "HECC: MAX TX mailboxes should be equal or less than CAN_ECHO_SKB_MAX"
-#endif
-
 #define HECC_TX_PRIO_SHIFT	(HECC_MB_TX_SHIFT)
 #define HECC_TX_PRIO_MASK	(MAX_TX_PRIO << HECC_MB_TX_SHIFT)
 #define HECC_TX_MB_MASK		(HECC_MAX_TX_MBOX - 1)
@@ -902,7 +898,7 @@ static int ti_hecc_probe(struct platform
 		goto probe_exit_free_region;
 	}
 
-	ndev = alloc_candev(sizeof(struct ti_hecc_priv));
+	ndev = alloc_candev(sizeof(struct ti_hecc_priv), HECC_MAX_TX_MBOX);
 	if (!ndev) {
 		dev_err(&pdev->dev, "alloc_candev failed\n");
 		err = -ENOMEM;

^ permalink raw reply

* Re: can: make the number of echo skb's configurable
From: Marc Kleine-Budde @ 2009-10-09  8:24 UTC (permalink / raw)
  To: Wolfgang Grandegger; +Cc: SocketCAN Core Mailing List, Linux Netdev List
In-Reply-To: <4ACEEFA6.1000904-5Yr1BZd7O62+XT7JhA+gdA@public.gmane.org>


[-- Attachment #1.1: Type: text/plain, Size: 6825 bytes --]

Wolfgang Grandegger wrote:
> This patch allows the CAN controller driver to define the number of echo
> skb's used for the local loopback (echo), as suggested by Kurt Van
> Dijck, with the function:
> 
>   struct net_device *alloc_candev(int sizeof_priv,
>                                   unsigned int echo_skb_max);
> 
> The CAN drivers have been adapted accordingly. For the ems_usb driver,
> as suggested by Sebastian Haas, the number of echo skb's has been
> increased to 10, which improves the transmission performance a lot.
> 
> Signed-off-by: Wolfgang Grandegger <wg-5Yr1BZd7O62+XT7JhA+gdA@public.gmane.org>
> Signed-off-by: Kurt Van Dijck <kurt.van.dijck-/BeEPy95v10@public.gmane.org>
> ---
>  drivers/net/can/at91_can.c        |    2 +-
>  drivers/net/can/dev.c             |   32 ++++++++++++++++++++++++++------
>  drivers/net/can/sja1000/sja1000.c |    3 ++-
>  drivers/net/can/sja1000/sja1000.h |    2 ++
>  drivers/net/can/ti_hecc.c         |    6 +-----
>  drivers/net/can/usb/ems_usb.c     |    4 ++--
>  include/linux/can/dev.h           |   16 ++++++++--------
>  7 files changed, 42 insertions(+), 23 deletions(-)
> 
> Index: net-next-2.6/drivers/net/can/dev.c
> ===================================================================
> --- net-next-2.6.orig/drivers/net/can/dev.c
> +++ net-next-2.6/drivers/net/can/dev.c
> @@ -245,7 +245,7 @@ static void can_flush_echo_skb(struct ne
>  	struct net_device_stats *stats = &dev->stats;
>  	int i;
>  
> -	for (i = 0; i < CAN_ECHO_SKB_MAX; i++) {
> +	for (i = 0; i < priv->echo_skb_max; i++) {
>  		if (priv->echo_skb[i]) {
>  			kfree_skb(priv->echo_skb[i]);
>  			priv->echo_skb[i] = NULL;
> @@ -262,10 +262,13 @@ static void can_flush_echo_skb(struct ne
>   * of the device driver. The driver must protect access to
>   * priv->echo_skb, if necessary.
>   */
> -void can_put_echo_skb(struct sk_buff *skb, struct net_device *dev, int idx)
> +void can_put_echo_skb(struct sk_buff *skb, struct net_device *dev,
> +		      unsigned int idx)
>  {
>  	struct can_priv *priv = netdev_priv(dev);
>  
> +	BUG_ON(idx >= priv->echo_skb_max);
> +
>  	/* check flag whether this packet has to be looped back */
>  	if (!(dev->flags & IFF_ECHO) || skb->pkt_type != PACKET_LOOPBACK) {
>  		kfree_skb(skb);
> @@ -311,10 +314,12 @@ EXPORT_SYMBOL_GPL(can_put_echo_skb);
>   * is handled in the device driver. The driver must protect
>   * access to priv->echo_skb, if necessary.
>   */
> -void can_get_echo_skb(struct net_device *dev, int idx)
> +void can_get_echo_skb(struct net_device *dev, unsigned int idx)
>  {
>  	struct can_priv *priv = netdev_priv(dev);
>  
> +	BUG_ON(idx >= priv->echo_skb_max);
> +
>  	if (priv->echo_skb[idx]) {
>  		netif_rx(priv->echo_skb[idx]);
>  		priv->echo_skb[idx] = NULL;
> @@ -327,10 +332,12 @@ EXPORT_SYMBOL_GPL(can_get_echo_skb);
>    *
>    * The function is typically called when TX failed.
>    */
> -void can_free_echo_skb(struct net_device *dev, int idx)
> +void can_free_echo_skb(struct net_device *dev, unsigned int idx)
>  {
>  	struct can_priv *priv = netdev_priv(dev);
>  
> +	BUG_ON(idx >= priv->echo_skb_max);
> +
>  	if (priv->echo_skb[idx]) {
>  		kfree_skb(priv->echo_skb[idx]);
>  		priv->echo_skb[idx] = NULL;
> @@ -445,17 +452,30 @@ static void can_setup(struct net_device 
>  /*
>   * Allocate and setup space for the CAN network device
>   */
> -struct net_device *alloc_candev(int sizeof_priv)
> +struct net_device *alloc_candev(int sizeof_priv, unsigned int echo_skb_max)
>  {
>  	struct net_device *dev;
>  	struct can_priv *priv;
> +	int size;
>  
> -	dev = alloc_netdev(sizeof_priv, "can%d", can_setup);
> +	if (echo_skb_max)
> +		size = ALIGN(sizeof_priv, sizeof(struct sk_buff *)) +
> +			echo_skb_max * sizeof(struct sk_buff *);
> +	else
> +		size = sizeof_priv;
> +
> +	dev = alloc_netdev(size, "can%d", can_setup);
>  	if (!dev)
>  		return NULL;
>  
>  	priv = netdev_priv(dev);
>  
> +	if (echo_skb_max) {
> +		priv->echo_skb_max = echo_skb_max;
> +		priv->echo_skb = (void *)priv +
> +			ALIGN(sizeof_priv, sizeof(struct sk_buff *));
> +	}
> +
>  	priv->state = CAN_STATE_STOPPED;
>  
>  	init_timer(&priv->restart_timer);
> Index: net-next-2.6/include/linux/can/dev.h
> ===================================================================
> --- net-next-2.6.orig/include/linux/can/dev.h
> +++ net-next-2.6/include/linux/can/dev.h
> @@ -29,8 +29,6 @@ enum can_mode {
>  /*
>   * CAN common private data
>   */
> -#define CAN_ECHO_SKB_MAX  4
> -
>  struct can_priv {
>  	struct can_device_stats can_stats;
>  
> @@ -44,15 +42,16 @@ struct can_priv {
>  	int restart_ms;
>  	struct timer_list restart_timer;
>  
> -	struct sk_buff *echo_skb[CAN_ECHO_SKB_MAX];
> -
>  	int (*do_set_bittiming)(struct net_device *dev);
>  	int (*do_set_mode)(struct net_device *dev, enum can_mode mode);
>  	int (*do_get_state)(const struct net_device *dev,
>  			    enum can_state *state);
> +
> +	unsigned int echo_skb_max;
> +	struct sk_buff **echo_skb;
>  };
>  
> -struct net_device *alloc_candev(int sizeof_priv);
> +struct net_device *alloc_candev(int sizeof_priv, unsigned int echo_skb_max);
>  void free_candev(struct net_device *dev);
>  
>  int open_candev(struct net_device *dev);
> @@ -64,8 +63,9 @@ void unregister_candev(struct net_device
>  int can_restart_now(struct net_device *dev);
>  void can_bus_off(struct net_device *dev);
>  
> -void can_put_echo_skb(struct sk_buff *skb, struct net_device *dev, int idx);
> -void can_get_echo_skb(struct net_device *dev, int idx);
> -void can_free_echo_skb(struct net_device *dev, int idx);
> +void can_put_echo_skb(struct sk_buff *skb, struct net_device *dev,
> +		      unsigned int idx);
> +void can_get_echo_skb(struct net_device *dev, unsigned int idx);
> +void can_free_echo_skb(struct net_device *dev, unsigned int idx);
>  
>  #endif /* CAN_DEV_H */
> Index: net-next-2.6/drivers/net/can/at91_can.c
> ===================================================================
> --- net-next-2.6.orig/drivers/net/can/at91_can.c
> +++ net-next-2.6/drivers/net/can/at91_can.c
> @@ -1087,7 +1087,7 @@ static int __init at91_can_probe(struct 
>  		goto exit_release;
>  	}
>  
> -	dev = alloc_candev(sizeof(struct at91_priv));
> +	dev = alloc_candev(sizeof(struct at91_priv), AT91_MB_TX_NUM);
>  	if (!dev) {
>  		err = -ENOMEM;
>  		goto exit_iounmap;

The at91 part looks okay.

Marc

-- 
Pengutronix e.K.                         | Marc Kleine-Budde           |
Linux Solutions for Science and Industry | Phone: +49-231-2826-924     |
Vertretung West/Dortmund                 | Fax:   +49-5121-206917-5555 |
Amtsgericht Hildesheim, HRA 2686         | http://www.pengutronix.de   |


[-- Attachment #1.2: OpenPGP digital signature --]
[-- Type: application/pgp-signature, Size: 260 bytes --]

[-- Attachment #2: Type: text/plain, Size: 188 bytes --]

_______________________________________________
Socketcan-core mailing list
Socketcan-core-0fE9KPoRgkgATYTw5x5z8w@public.gmane.org
https://lists.berlios.de/mailman/listinfo/socketcan-core

^ permalink raw reply

* Re: can: make the number of echo skb's configurable
From: Sebastian Haas @ 2009-10-09  8:28 UTC (permalink / raw)
  To: Wolfgang Grandegger; +Cc: SocketCAN Core Mailing List, Linux Netdev List
In-Reply-To: <4ACEEFA6.1000904-5Yr1BZd7O62+XT7JhA+gdA@public.gmane.org>

-----BEGIN PGP SIGNED MESSAGE-----
Hash: SHA1

Wolfgang Grandegger schrieb:
> This patch allows the CAN controller driver to define the number of echo
> skb's used for the local loopback (echo), as suggested by Kurt Van
> Dijck, with the function:
> 
>   struct net_device *alloc_candev(int sizeof_priv,
>                                   unsigned int echo_skb_max);
> 
> The CAN drivers have been adapted accordingly. For the ems_usb driver,
> as suggested by Sebastian Haas, the number of echo skb's has been
> increased to 10, which improves the transmission performance a lot.
> 
> Signed-off-by: Wolfgang Grandegger <wg-5Yr1BZd7O62+XT7JhA+gdA@public.gmane.org>
> Signed-off-by: Kurt Van Dijck <kurt.van.dijck-/BeEPy95v10@public.gmane.org>
Acked-by: Sebastian Haas <haas-zsNKPWJ8Pib6hrUXjxyGrA@public.gmane.org>

I added my "Acked-by" for the change on ems_usb.c MAX_TX_URBS.

Sebastan
-----BEGIN PGP SIGNATURE-----
Version: GnuPG v1.4.9 (GNU/Linux)
Comment: Using GnuPG with Mozilla - http://enigmail.mozdev.org

iEYEARECAAYFAkrO9A8ACgkQpqRB8PJG7XxrdACfaM8q9Yb+EI3v/yCP74NU0Taz
VowAn1lgWPsWramFos+WlFZ4UFMcEMi7
=gwCy
-----END PGP SIGNATURE-----
-- 
EMS Dr. Thomas Wuensche e.K.
Sonnenhang 3
85304 Ilmmuenster
HRA Neuburg a.d. Donau, HR-Nr. 70.106
Phone: +49-8441-490260
Fax  : +49-8441-81860
http://www.ems-wuensche.com

^ permalink raw reply

* [PATCH 2/8] bitmap: Introduce bitmap_set, bitmap_clear, bitmap_find_next_zero_area
From: Akinobu Mita @ 2009-10-09  8:29 UTC (permalink / raw)
  To: linux-kernel, akpm
  Cc: Fenghua Yu, Greg Kroah-Hartman, linux-ia64, Tony Luck, x86,
	netdev, Akinobu Mita, linux-altix, Yevgeny Petrilin,
	FUJITA Tomonori, linuxppc-dev, Ingo Molnar, Paul Mackerras,
	H. Peter Anvin, sparclinux, Thomas Gleixner, linux-usb,
	David S. Miller, Lothar Wassmann
In-Reply-To: <1255076961-21325-1-git-send-email-akinobu.mita@gmail.com>

This introduces new bitmap functions:

bitmap_set: Set specified bit area
bitmap_clear: Clear specified bit area
bitmap_find_next_zero_area: Find free bit area

These are stolen from iommu helper.

I changed the return value of bitmap_find_next_zero_area if there is
no zero area.

find_next_zero_area in iommu helper: returns -1
bitmap_find_next_zero_area: return >= bitmap size

Cc: FUJITA Tomonori <fujita.tomonori@lab.ntt.co.jp>
Cc: "David S. Miller" <davem@davemloft.net>
Cc: sparclinux@vger.kernel.org
Cc: Benjamin Herrenschmidt <benh@kernel.crashing.org>
Cc: Paul Mackerras <paulus@samba.org>
Cc: linuxppc-dev@ozlabs.org
Cc: Thomas Gleixner <tglx@linutronix.de>
Cc: Ingo Molnar <mingo@redhat.com>
Cc: "H. Peter Anvin" <hpa@zytor.com>
Cc: x86@kernel.org
Cc: Greg Kroah-Hartman <gregkh@suse.de>
Cc: Lothar Wassmann <LW@KARO-electronics.de>
Cc: linux-usb@vger.kernel.org
Cc: Roland Dreier <rolandd@cisco.com>
Cc: Yevgeny Petrilin <yevgenyp@mellanox.co.il>
Cc: netdev@vger.kernel.org
Cc: Tony Luck <tony.luck@intel.com>
Cc: Fenghua Yu <fenghua.yu@intel.com>
Cc: linux-ia64@vger.kernel.org
Cc: linux-altix@sgi.com
Signed-off-by: Akinobu Mita <akinobu.mita@gmail.com>
---
 include/linux/bitmap.h |   11 +++++++++++
 lib/bitmap.c           |   47 +++++++++++++++++++++++++++++++++++++++++++++++
 2 files changed, 58 insertions(+), 0 deletions(-)

diff --git a/include/linux/bitmap.h b/include/linux/bitmap.h
index 756d78b..daf8c48 100644
--- a/include/linux/bitmap.h
+++ b/include/linux/bitmap.h
@@ -42,6 +42,9 @@
  * bitmap_empty(src, nbits)			Are all bits zero in *src?
  * bitmap_full(src, nbits)			Are all bits set in *src?
  * bitmap_weight(src, nbits)			Hamming Weight: number set bits
+ * bitmap_set(dst, pos, nbits)			Set specified bit area
+ * bitmap_clear(dst, pos, nbits)		Clear specified bit area
+ * bitmap_find_next_zero_area(buf, len, pos, n, mask)	Find bit free area
  * bitmap_shift_right(dst, src, n, nbits)	*dst = *src >> n
  * bitmap_shift_left(dst, src, n, nbits)	*dst = *src << n
  * bitmap_remap(dst, src, old, new, nbits)	*dst = map(old, new)(src)
@@ -108,6 +111,14 @@ extern int __bitmap_subset(const unsigned long *bitmap1,
 			const unsigned long *bitmap2, int bits);
 extern int __bitmap_weight(const unsigned long *bitmap, int bits);
 
+extern void bitmap_set(unsigned long *map, int i, int len);
+extern void bitmap_clear(unsigned long *map, int start, int nr);
+extern unsigned long bitmap_find_next_zero_area(unsigned long *map,
+					 unsigned long size,
+					 unsigned long start,
+					 unsigned int nr,
+					 unsigned long align_mask);
+
 extern int bitmap_scnprintf(char *buf, unsigned int len,
 			const unsigned long *src, int nbits);
 extern int __bitmap_parse(const char *buf, unsigned int buflen, int is_user,
diff --git a/lib/bitmap.c b/lib/bitmap.c
index 7025658..95070fa 100644
--- a/lib/bitmap.c
+++ b/lib/bitmap.c
@@ -271,6 +271,53 @@ int __bitmap_weight(const unsigned long *bitmap, int bits)
 }
 EXPORT_SYMBOL(__bitmap_weight);
 
+void bitmap_set(unsigned long *map, int i, int len)
+{
+	int end = i + len;
+
+	while (i < end) {
+		__set_bit(i, map);
+		i++;
+	}
+}
+EXPORT_SYMBOL(bitmap_set);
+
+void bitmap_clear(unsigned long *map, int start, int nr)
+{
+	int end = start + nr;
+
+	while (start < end) {
+		__clear_bit(start, map);
+		start++;
+	}
+}
+EXPORT_SYMBOL(bitmap_clear);
+
+unsigned long bitmap_find_next_zero_area(unsigned long *map,
+					 unsigned long size,
+					 unsigned long start,
+					 unsigned int nr,
+					 unsigned long align_mask)
+{
+	unsigned long index, end, i;
+again:
+	index = find_next_zero_bit(map, size, start);
+
+	/* Align allocation */
+	index = (index + align_mask) & ~align_mask;
+
+	end = index + nr;
+	if (end >= size)
+		return end;
+	i = find_next_bit(map, end, index);
+	if (i < end) {
+		start = i + 1;
+		goto again;
+	}
+	return index;
+}
+EXPORT_SYMBOL(bitmap_find_next_zero_area);
+
 /*
  * Bitmap printing & parsing functions: first version by Bill Irwin,
  * second version by Paul Jackson, third by Joe Korty.
-- 
1.5.4.3

^ permalink raw reply related

* [PATCH 5/8] mlx4: Use bitmap_find_next_zero_area
From: Akinobu Mita @ 2009-10-09  8:29 UTC (permalink / raw)
  To: linux-kernel, akpm; +Cc: Akinobu Mita, Roland Dreier, Yevgeny Petrilin, netdev
In-Reply-To: <1255076961-21325-4-git-send-email-akinobu.mita@gmail.com>

Cc: Roland Dreier <rolandd@cisco.com>
Cc: Yevgeny Petrilin <yevgenyp@mellanox.co.il>
Cc: netdev@vger.kernel.org
Signed-off-by: Akinobu Mita <akinobu.mita@gmail.com>
---
 drivers/net/mlx4/alloc.c |   37 ++++---------------------------------
 1 files changed, 4 insertions(+), 33 deletions(-)

diff --git a/drivers/net/mlx4/alloc.c b/drivers/net/mlx4/alloc.c
index ad95d5f..8c85156 100644
--- a/drivers/net/mlx4/alloc.c
+++ b/drivers/net/mlx4/alloc.c
@@ -72,35 +72,6 @@ void mlx4_bitmap_free(struct mlx4_bitmap *bitmap, u32 obj)
 	mlx4_bitmap_free_range(bitmap, obj, 1);
 }
 
-static unsigned long find_aligned_range(unsigned long *bitmap,
-					u32 start, u32 nbits,
-					int len, int align)
-{
-	unsigned long end, i;
-
-again:
-	start = ALIGN(start, align);
-
-	while ((start < nbits) && test_bit(start, bitmap))
-		start += align;
-
-	if (start >= nbits)
-		return -1;
-
-	end = start+len;
-	if (end > nbits)
-		return -1;
-
-	for (i = start + 1; i < end; i++) {
-		if (test_bit(i, bitmap)) {
-			start = i + 1;
-			goto again;
-		}
-	}
-
-	return start;
-}
-
 u32 mlx4_bitmap_alloc_range(struct mlx4_bitmap *bitmap, int cnt, int align)
 {
 	u32 obj, i;
@@ -110,13 +81,13 @@ u32 mlx4_bitmap_alloc_range(struct mlx4_bitmap *bitmap, int cnt, int align)
 
 	spin_lock(&bitmap->lock);
 
-	obj = find_aligned_range(bitmap->table, bitmap->last,
-				 bitmap->max, cnt, align);
+	obj = bitmap_find_next_zero_area(bitmap->table, bitmap->max,
+				bitmap->last, cnt, align - 1);
 	if (obj >= bitmap->max) {
 		bitmap->top = (bitmap->top + bitmap->max + bitmap->reserved_top)
 				& bitmap->mask;
-		obj = find_aligned_range(bitmap->table, 0, bitmap->max,
-					 cnt, align);
+		obj = bitmap_find_next_zero_area(bitmap->table, bitmap->max,
+						0, cnt, align - 1);
 	}
 
 	if (obj < bitmap->max) {
-- 
1.5.4.3


^ permalink raw reply related

* Re: [PATCH] net: Fix struct sock bitfield annotation
From: Eric Dumazet @ 2009-10-09  8:50 UTC (permalink / raw)
  To: David Miller; +Cc: vegard.nossum, netdev, mingo
In-Reply-To: <20091009.005408.151610125.davem@davemloft.net>

David Miller a écrit :

> 
> I think from a practical standpoint, you are right.
> 
> But Vegard is right too, as we should be able to put the annotation
> right next to the ":" statements.
> 
> So if you really want why don't you put the sk_protocol and
> sk_type into the ":" block as you mentioned.
> 
> And then you can use Arnaldo's 'pahole' instead of the kludgy
> offsetof() which doesn't work with bitfields :-)
> 
> I want the 8 bytes back just like you, but seperating the annotation
> from the real C bitfields looks definitely wrong to me.


Let's hope nobody wants to use &sk->sk_protocol, &sk->sk_type,
(or offsetof(..., sk_somefield) if that matters)

Only compile tested on 'allyesconfig' build on x86_64

[PATCH] net: Fix struct sock bitfield annotation

Since commit a98b65a3 (net: annotate struct sock bitfield), we lost
8 bytes in struct sock on 64bit arches because of 
kmemcheck_bitfield_end(flags) misplacement.

Fix this by putting together sk_shutdown, sk_no_check, sk_userlocks,
sk_protocol and sk_type in the 'flags' 32bits bitfield

Signed-off-by: Eric Dumazet <eric.dumazet@gmail.com>
---
 include/net/sock.h |   10 +++++-----
 1 files changed, 5 insertions(+), 5 deletions(-)

diff --git a/include/net/sock.h b/include/net/sock.h
index 1621935..9f96394 100644
--- a/include/net/sock.h
+++ b/include/net/sock.h
@@ -226,12 +226,12 @@ struct sock {
 #define sk_prot			__sk_common.skc_prot
 #define sk_net			__sk_common.skc_net
 	kmemcheck_bitfield_begin(flags);
-	unsigned char		sk_shutdown : 2,
-				sk_no_check : 2,
-				sk_userlocks : 4;
+	unsigned int		sk_shutdown  : 2,
+				sk_no_check  : 2,
+				sk_userlocks : 4,
+				sk_protocol  : 8,
+				sk_type      : 16;
 	kmemcheck_bitfield_end(flags);
-	unsigned char		sk_protocol;
-	unsigned short		sk_type;
 	int			sk_rcvbuf;
 	socket_lock_t		sk_lock;
 	/*

^ permalink raw reply related

* Re: [RFC] multiqueue changes
From: Jarek Poplawski @ 2009-10-09  8:51 UTC (permalink / raw)
  To: Eric Dumazet; +Cc: David S. Miller, Patrick McHardy, Linux Netdev List
In-Reply-To: <20091008090344.GA7409@ff.dom.local>

On Thu, Oct 08, 2009 at 09:03:44AM +0000, Jarek Poplawski wrote:
> On Thu, Oct 08, 2009 at 09:18:45AM +0200, Eric Dumazet wrote:
...
> > Just wondering if it could hurt some people.
> > 
> > Anyway, should we change bnx2/tg3 drivers so that single queue devices
> > have same default qdisc/class than before ?
> > 
> > eg :
> > 
> > diff --git a/drivers/net/bnx2.c b/drivers/net/bnx2.c
> > index 08cddb6..7cac205 100644
> > --- a/drivers/net/bnx2.c
> > +++ b/drivers/net/bnx2.c
> > @@ -6152,6 +6152,7 @@ bnx2_setup_int_mode(struct bnx2 *bp, int dis_msi)
> >  
> >  	bp->num_tx_rings = rounddown_pow_of_two(bp->irq_nvecs);
> >  	bp->dev->real_num_tx_queues = bp->num_tx_rings;
> > +	bp->dev->num_tx_queues = bp->dev->real_num_tx_queues;
> >  
> >  	bp->num_rx_rings = bp->irq_nvecs;
> >  }
> 
> It doesn't look consistent to me wrt. the comment in netdevice.h on
> num_tx_queues. But it seems we should rather use more often
> real_num_tx_queue in schedulers code like dumps and maybe more
> (like e.g. sch_multiq does).

So, according to my current understanding, we should probably let
drivers to reset the tx_queues allocation with a new num_tx_queues
in a place like this (ndo_open).

Jarek P.

^ permalink raw reply

* Re: pull request: wireless-2.6 2009-10-08
From: Michael Buesch @ 2009-10-09  8:57 UTC (permalink / raw)
  To: David Miller; +Cc: linville, linux-wireless, netdev, linux-kernel
In-Reply-To: <20091008.180119.242402327.davem@davemloft.net>

On Friday 09 October 2009 03:01:19 David Miller wrote:
> From: Michael Buesch <mb@bu3sch.de>
> Date: Fri, 9 Oct 2009 01:08:06 +0200
> 
> > I was planning to do a better solution, but I didn't have the time, yet.
> 
> The change is harmless while we're twiddling our thumbs waiting
> for you to implement the fix "properly."
> 
> Not having the fix in is a developer burdon because people turn
> on the DMA API debugger and are going to keep reporting it's
> complaints here and elsewhere.
> 
> Get over your Napoleon complex, and let reasonable working fixes
> get into the tree even if you don't find them optimal.  You can
> always improve them later, "when you get around to it."
> 
> People put fixes in without my ACK in my areas of expertiece all
> the time.  I got over it a long time ago, it's OK, and not worth
> stressing out over.

Ok, that's enough. If you do not need a maintainer, then work without one.
What's a maintainer good for, if it's not for maintaining the code quality?

The patch needlessly moves huge chunks of crap, adds stupid comments, wastes memory.
If that's what you want just to remove a debugging message on devices that virtually
nobody owns, so be it.


---
 MAINTAINERS |    1 -
 1 file changed, 1 deletion(-)

--- wireless-testing.orig/MAINTAINERS
+++ wireless-testing/MAINTAINERS
@@ -1066,7 +1066,6 @@ F:	include/net/ax25.h
 F:	net/ax25/
 
 B43 WIRELESS DRIVER
-M:	Michael Buesch <mb@bu3sch.de>
 M:	Stefano Brivio <stefano.brivio@polimi.it>
 L:	linux-wireless@vger.kernel.org
 W:	http://linuxwireless.org/en/users/Drivers/b43


-- 
Greetings, Michael.

^ permalink raw reply

* RE: [PATCH] can: make the number of echo skb's configurable
From: Gole, Anant @ 2009-10-09  9:01 UTC (permalink / raw)
  To: Wolfgang Grandegger, Linux Netdev List
  Cc: SocketCAN Core Mailing List, Sebastian-XecQL68PM4x789tOGE2Ojw
In-Reply-To: <4ACEF187.207-5Yr1BZd7O62+XT7JhA+gdA@public.gmane.org>

>-----Original Message-----
>From: Wolfgang Grandegger [mailto:wg-5Yr1BZd7O62+XT7JhA+gdA@public.gmane.org]
>Sent: Friday, October 09, 2009 1:47 PM
>To: Linux Netdev List
>Cc: SocketCAN Core Mailing List; Gole, Anant; Sebastian Haas
>Subject: [PATCH] can: make the number of echo skb's configurable
>
>This patch allows the CAN controller driver to define the number of echo
>skb's used for the local loopback (echo), as suggested by Kurt Van
>Dijck, with the function:
>
>  struct net_device *alloc_candev(int sizeof_priv,
>                                  unsigned int echo_skb_max);
>
>The CAN drivers have been adapted accordingly. For the ems_usb driver,
>as suggested by Sebastian Haas, the number of echo skb's has been
>increased to 10, which improves the transmission performance a lot.
>
>Signed-off-by: Wolfgang Grandegger <wg-5Yr1BZd7O62+XT7JhA+gdA@public.gmane.org>
>Signed-off-by: Kurt Van Dijck <kurt.van.dijck-/BeEPy95v10@public.gmane.org>
>---

[snip]

>Index: net-next-2.6/drivers/net/can/ti_hecc.c
>===================================================================
>--- net-next-2.6.orig/drivers/net/can/ti_hecc.c
>+++ net-next-2.6/drivers/net/can/ti_hecc.c
>@@ -74,10 +74,6 @@ MODULE_VERSION(HECC_MODULE_VERSION);
> #define HECC_MB_TX_SHIFT	2 /* as per table above */
> #define HECC_MAX_TX_MBOX	BIT(HECC_MB_TX_SHIFT)
>
>-#if (HECC_MAX_TX_MBOX > CAN_ECHO_SKB_MAX)
>-#error "HECC: MAX TX mailboxes should be equal or less than
>CAN_ECHO_SKB_MAX"
>-#endif
>-
> #define HECC_TX_PRIO_SHIFT	(HECC_MB_TX_SHIFT)
> #define HECC_TX_PRIO_MASK	(MAX_TX_PRIO << HECC_MB_TX_SHIFT)
> #define HECC_TX_MB_MASK		(HECC_MAX_TX_MBOX - 1)
>@@ -902,7 +898,7 @@ static int ti_hecc_probe(struct platform
> 		goto probe_exit_free_region;
> 	}
>
>-	ndev = alloc_candev(sizeof(struct ti_hecc_priv));
>+	ndev = alloc_candev(sizeof(struct ti_hecc_priv), HECC_MAX_TX_MBOX);
> 	if (!ndev) {
> 		dev_err(&pdev->dev, "alloc_candev failed\n");
> 		err = -ENOMEM;

Ack for ti_hecc driver change. Thanks for the patch.

Regards,
Anant

^ permalink raw reply

* PACKET_TX_RING: packet size is too long
From: Gabor Gombas @ 2009-10-09  9:07 UTC (permalink / raw)
  To: netdev; +Cc: johann.baudy

Hi,

I have added PACKET_TX_RING support to ggaoed
(http://code.google.com/p/ggaoed) and it have worked nice when I have
tested it with a virtual ethernet pair (veth). However when testing it
on real hardware, I get:

Oct  8 17:30:52 storage2 kernel: [ 1083.714204] packet size is too long (8740 > 8472)

Kernel is 2.6.31 from Debian experimental. The socket is SOCK_RAW, the
MTU is 9000, I'm using TPACKET_V2 format, and the ring have been created
with the following parameters:

block_nr = 256, block_size = 65536, frame_nr = 1792, frame_size = 9056

Documentation/networking/packet_mmap.txt says that a frame for
PACKET_TX_RING consists of a struct tpacket[2]_hdr followed by the data
to send, so IMHO a frame size of 9056 should be enough to send 8740
bytes of data. However, net/packet/af_packet.c has in tpacket_snd():

	size_max = po->tx_ring.frame_size
		- sizeof(struct skb_shared_info)
		- po->tp_hdrlen
		- LL_ALLOCATED_SPACE(dev)
		- sizeof(struct sockaddr_ll);

which is much more than just the struct tpacket[2]_hdr. So which is
right? The code or the documentation? What is the official formula
to compute the required frame length for a SOCK_RAW socket, given the
MTU?

Gabor

-- 
     ---------------------------------------------------------
     MTA SZTAKI Computer and Automation Research Institute
                Hungarian Academy of Sciences
     ---------------------------------------------------------

^ permalink raw reply

* Re: pull request: wireless-2.6 2009-10-08
From: David Miller @ 2009-10-09  9:18 UTC (permalink / raw)
  To: mb-fseUSCV1ubazQB+pC5nmwQ
  Cc: linville-2XuSBdqkA4R54TAoqtyWWQ,
	linux-wireless-u79uwXL29TY76Z2rM5mHXA,
	netdev-u79uwXL29TY76Z2rM5mHXA,
	linux-kernel-u79uwXL29TY76Z2rM5mHXA
In-Reply-To: <200910091057.21269.mb-fseUSCV1ubazQB+pC5nmwQ@public.gmane.org>

From: Michael Buesch <mb-fseUSCV1ubazQB+pC5nmwQ@public.gmane.org>
Date: Fri, 9 Oct 2009 10:57:19 +0200

> What's a maintainer good for, if it's not for maintaining the code
> quality?

It does not mean you get total control over anything, ever.

That's my main point.

Every maintainer who loses his mind when some change goes in he
doesn't like has a serious control problem.  And yes, sometimes that
includes me.
--
To unsubscribe from this list: send the line "unsubscribe linux-wireless" in
the body of a message to majordomo-u79uwXL29TY76Z2rM5mHXA@public.gmane.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html

^ permalink raw reply

* Re: [RFC] multiqueue changes
From: Jarek Poplawski @ 2009-10-09  9:40 UTC (permalink / raw)
  To: Eric Dumazet; +Cc: David S. Miller, Patrick McHardy, Linux Netdev List
In-Reply-To: <20091009085107.GA7711@ff.dom.local>

On Fri, Oct 09, 2009 at 08:51:07AM +0000, Jarek Poplawski wrote:
> On Thu, Oct 08, 2009 at 09:03:44AM +0000, Jarek Poplawski wrote:
> > On Thu, Oct 08, 2009 at 09:18:45AM +0200, Eric Dumazet wrote:
> ...
> > > Just wondering if it could hurt some people.
> > > 
> > > Anyway, should we change bnx2/tg3 drivers so that single queue devices
> > > have same default qdisc/class than before ?
> > > 
> > > eg :
> > > 
> > > diff --git a/drivers/net/bnx2.c b/drivers/net/bnx2.c
> > > index 08cddb6..7cac205 100644
> > > --- a/drivers/net/bnx2.c
> > > +++ b/drivers/net/bnx2.c
> > > @@ -6152,6 +6152,7 @@ bnx2_setup_int_mode(struct bnx2 *bp, int dis_msi)
> > >  
> > >  	bp->num_tx_rings = rounddown_pow_of_two(bp->irq_nvecs);
> > >  	bp->dev->real_num_tx_queues = bp->num_tx_rings;
> > > +	bp->dev->num_tx_queues = bp->dev->real_num_tx_queues;
> > >  
> > >  	bp->num_rx_rings = bp->irq_nvecs;
> > >  }
> > 
> > It doesn't look consistent to me wrt. the comment in netdevice.h on
> > num_tx_queues. But it seems we should rather use more often
> > real_num_tx_queue in schedulers code like dumps and maybe more
> > (like e.g. sch_multiq does).
> 
> So, according to my current understanding, we should probably let
> drivers to reset the tx_queues allocation with a new num_tx_queues
> in a place like this (ndo_open).

Actually, it should be only for the first ndo_open.

Jarek P.

^ permalink raw reply

* Ping Is Broken
From: Rob Townley @ 2009-10-09 10:16 UTC (permalink / raw)
  To: netdev-u79uwXL29TY76Z2rM5mHXA; +Cc: CentOS mailing list, Omaha Linux User Group


[-- Attachment #1.1: Type: text/plain, Size: 135 bytes --]

i am hoping this attachment gets through.  It deals with bug in ping that
made it very difficult to set up a system with two gateways.

[-- Attachment #1.2: Type: text/html, Size: 146 bytes --]

[-- Attachment #2: ping-bug-demo.sh.post.html --]
[-- Type: text/html, Size: 4447 bytes --]

[-- Attachment #3: Type: text/plain, Size: 163 bytes --]

_______________________________________________
CentOS mailing list
CentOS-IFYaIzF+flcdnm+yROfE0A@public.gmane.org
http://lists.centos.org/mailman/listinfo/centos

^ permalink raw reply

* [PATCH net-nex-2.6] tcp: replace ehash_size by ehash_mask
From: Eric Dumazet @ 2009-10-09 10:16 UTC (permalink / raw)
  To: David S. Miller; +Cc: Linux Netdev List

Storing the mask (size - 1) instead of the size allows fast path to be a bit faster.

Signed-off-by: Eric Dumazet <eric.dumazet@gmail.com>
---
 include/net/inet_hashtables.h |    4 ++--
 net/dccp/proto.c              |   13 +++++++------
 net/ipv4/inet_diag.c          |    2 +-
 net/ipv4/inet_hashtables.c    |    2 +-
 net/ipv4/inet_timewait_sock.c |    2 +-
 net/ipv4/tcp.c                |   11 +++++------
 net/ipv4/tcp_ipv4.c           |    6 +++---
 net/ipv6/inet6_hashtables.c   |    2 +-
 8 files changed, 21 insertions(+), 21 deletions(-)

diff --git a/include/net/inet_hashtables.h b/include/net/inet_hashtables.h
index d522dcf..5f11c4a 100644
--- a/include/net/inet_hashtables.h
+++ b/include/net/inet_hashtables.h
@@ -125,7 +125,7 @@ struct inet_hashinfo {
 	 */
 	struct inet_ehash_bucket	*ehash;
 	spinlock_t			*ehash_locks;
-	unsigned int			ehash_size;
+	unsigned int			ehash_mask;
 	unsigned int			ehash_locks_mask;
 
 	/* Ok, let's try this, I give up, we do need a local binding
@@ -158,7 +158,7 @@ static inline struct inet_ehash_bucket *inet_ehash_bucket(
 	struct inet_hashinfo *hashinfo,
 	unsigned int hash)
 {
-	return &hashinfo->ehash[hash & (hashinfo->ehash_size - 1)];
+	return &hashinfo->ehash[hash & hashinfo->ehash_mask];
 }
 
 static inline spinlock_t *inet_ehash_lockp(
diff --git a/net/dccp/proto.c b/net/dccp/proto.c
index a156319..ecb203f 100644
--- a/net/dccp/proto.c
+++ b/net/dccp/proto.c
@@ -1060,11 +1060,12 @@ static int __init dccp_init(void)
 	for (ehash_order = 0; (1UL << ehash_order) < goal; ehash_order++)
 		;
 	do {
-		dccp_hashinfo.ehash_size = (1UL << ehash_order) * PAGE_SIZE /
+		unsigned long hash_size = (1UL << ehash_order) * PAGE_SIZE /
 					sizeof(struct inet_ehash_bucket);
-		while (dccp_hashinfo.ehash_size &
-		       (dccp_hashinfo.ehash_size - 1))
-			dccp_hashinfo.ehash_size--;
+
+		while (hash_size & (hash_size - 1))
+			hash_size--;
+		dccp_hashinfo.ehash_mask = hash_size - 1;
 		dccp_hashinfo.ehash = (struct inet_ehash_bucket *)
 			__get_free_pages(GFP_ATOMIC|__GFP_NOWARN, ehash_order);
 	} while (!dccp_hashinfo.ehash && --ehash_order > 0);
@@ -1074,7 +1075,7 @@ static int __init dccp_init(void)
 		goto out_free_bind_bucket_cachep;
 	}
 
-	for (i = 0; i < dccp_hashinfo.ehash_size; i++) {
+	for (i = 0; i <= dccp_hashinfo.ehash_mask; i++) {
 		INIT_HLIST_NULLS_HEAD(&dccp_hashinfo.ehash[i].chain, i);
 		INIT_HLIST_NULLS_HEAD(&dccp_hashinfo.ehash[i].twchain, i);
 	}
@@ -1153,7 +1154,7 @@ static void __exit dccp_fini(void)
 		   get_order(dccp_hashinfo.bhash_size *
 			     sizeof(struct inet_bind_hashbucket)));
 	free_pages((unsigned long)dccp_hashinfo.ehash,
-		   get_order(dccp_hashinfo.ehash_size *
+		   get_order((dccp_hashinfo.ehash_mask + 1) *
 			     sizeof(struct inet_ehash_bucket)));
 	inet_ehash_locks_free(&dccp_hashinfo);
 	kmem_cache_destroy(dccp_hashinfo.bind_bucket_cachep);
diff --git a/net/ipv4/inet_diag.c b/net/ipv4/inet_diag.c
index a706a47..cb73fde 100644
--- a/net/ipv4/inet_diag.c
+++ b/net/ipv4/inet_diag.c
@@ -774,7 +774,7 @@ skip_listen_ht:
 	if (!(r->idiag_states & ~(TCPF_LISTEN | TCPF_SYN_RECV)))
 		goto unlock;
 
-	for (i = s_i; i < hashinfo->ehash_size; i++) {
+	for (i = s_i; i <= hashinfo->ehash_mask; i++) {
 		struct inet_ehash_bucket *head = &hashinfo->ehash[i];
 		spinlock_t *lock = inet_ehash_lockp(hashinfo, i);
 		struct sock *sk;
diff --git a/net/ipv4/inet_hashtables.c b/net/ipv4/inet_hashtables.c
index 625cc5f..a45aaf3 100644
--- a/net/ipv4/inet_hashtables.c
+++ b/net/ipv4/inet_hashtables.c
@@ -209,7 +209,7 @@ struct sock * __inet_lookup_established(struct net *net,
 	 * have wildcards anyways.
 	 */
 	unsigned int hash = inet_ehashfn(net, daddr, hnum, saddr, sport);
-	unsigned int slot = hash & (hashinfo->ehash_size - 1);
+	unsigned int slot = hash & hashinfo->ehash_mask;
 	struct inet_ehash_bucket *head = &hashinfo->ehash[slot];
 
 	rcu_read_lock();
diff --git a/net/ipv4/inet_timewait_sock.c b/net/ipv4/inet_timewait_sock.c
index 13f0781..2fe5711 100644
--- a/net/ipv4/inet_timewait_sock.c
+++ b/net/ipv4/inet_timewait_sock.c
@@ -430,7 +430,7 @@ void inet_twsk_purge(struct net *net, struct inet_hashinfo *hashinfo,
 	int h;
 
 	local_bh_disable();
-	for (h = 0; h < (hashinfo->ehash_size); h++) {
+	for (h = 0; h <= hashinfo->ehash_mask; h++) {
 		struct inet_ehash_bucket *head =
 			inet_ehash_bucket(hashinfo, h);
 		spinlock_t *lock = inet_ehash_lockp(hashinfo, h);
diff --git a/net/ipv4/tcp.c b/net/ipv4/tcp.c
index 64d0af6..cf13726 100644
--- a/net/ipv4/tcp.c
+++ b/net/ipv4/tcp.c
@@ -2865,11 +2865,10 @@ void __init tcp_init(void)
 					(totalram_pages >= 128 * 1024) ?
 					13 : 15,
 					0,
-					&tcp_hashinfo.ehash_size,
 					NULL,
+					&tcp_hashinfo.ehash_mask,
 					thash_entries ? 0 : 512 * 1024);
-	tcp_hashinfo.ehash_size = 1 << tcp_hashinfo.ehash_size;
-	for (i = 0; i < tcp_hashinfo.ehash_size; i++) {
+	for (i = 0; i <= tcp_hashinfo.ehash_mask; i++) {
 		INIT_HLIST_NULLS_HEAD(&tcp_hashinfo.ehash[i].chain, i);
 		INIT_HLIST_NULLS_HEAD(&tcp_hashinfo.ehash[i].twchain, i);
 	}
@@ -2878,7 +2877,7 @@ void __init tcp_init(void)
 	tcp_hashinfo.bhash =
 		alloc_large_system_hash("TCP bind",
 					sizeof(struct inet_bind_hashbucket),
-					tcp_hashinfo.ehash_size,
+					tcp_hashinfo.ehash_mask + 1,
 					(totalram_pages >= 128 * 1024) ?
 					13 : 15,
 					0,
@@ -2933,8 +2932,8 @@ void __init tcp_init(void)
 	sysctl_tcp_rmem[2] = max(87380, max_share);
 
 	printk(KERN_INFO "TCP: Hash tables configured "
-	       "(established %d bind %d)\n",
-	       tcp_hashinfo.ehash_size, tcp_hashinfo.bhash_size);
+	       "(established %u bind %u)\n",
+	       tcp_hashinfo.ehash_mask + 1, tcp_hashinfo.bhash_size);
 
 	tcp_register_congestion_control(&tcp_reno);
 }
diff --git a/net/ipv4/tcp_ipv4.c b/net/ipv4/tcp_ipv4.c
index 7cda24b..9971870 100644
--- a/net/ipv4/tcp_ipv4.c
+++ b/net/ipv4/tcp_ipv4.c
@@ -2000,7 +2000,7 @@ static void *established_get_first(struct seq_file *seq)
 	struct net *net = seq_file_net(seq);
 	void *rc = NULL;
 
-	for (st->bucket = 0; st->bucket < tcp_hashinfo.ehash_size; ++st->bucket) {
+	for (st->bucket = 0; st->bucket <= tcp_hashinfo.ehash_mask; ++st->bucket) {
 		struct sock *sk;
 		struct hlist_nulls_node *node;
 		struct inet_timewait_sock *tw;
@@ -2061,10 +2061,10 @@ get_tw:
 		st->state = TCP_SEQ_STATE_ESTABLISHED;
 
 		/* Look for next non empty bucket */
-		while (++st->bucket < tcp_hashinfo.ehash_size &&
+		while (++st->bucket <= tcp_hashinfo.ehash_mask &&
 				empty_bucket(st))
 			;
-		if (st->bucket >= tcp_hashinfo.ehash_size)
+		if (st->bucket > tcp_hashinfo.ehash_mask)
 			return NULL;
 
 		spin_lock_bh(inet_ehash_lockp(&tcp_hashinfo, st->bucket));
diff --git a/net/ipv6/inet6_hashtables.c b/net/ipv6/inet6_hashtables.c
index 1bcc343..874aed8 100644
--- a/net/ipv6/inet6_hashtables.c
+++ b/net/ipv6/inet6_hashtables.c
@@ -73,7 +73,7 @@ struct sock *__inet6_lookup_established(struct net *net,
 	 * have wildcards anyways.
 	 */
 	unsigned int hash = inet6_ehashfn(net, daddr, hnum, saddr, sport);
-	unsigned int slot = hash & (hashinfo->ehash_size - 1);
+	unsigned int slot = hash & hashinfo->ehash_mask;
 	struct inet_ehash_bucket *head = &hashinfo->ehash[slot];
 
 

^ permalink raw reply related

* [PATCH] net: allow sh_eth to get mac address through platform data
From: Magnus Damm @ 2009-10-09 10:17 UTC (permalink / raw)
  To: netdev; +Cc: Magnus Damm, lethal, davem, linux-sh

From: Magnus Damm <damm@opensource.se>

Extend the sh_eth driver to allow passing the mac address
using the platform data structure. This to simplify board
setup code.

Signed-off-by: Magnus Damm <damm@opensource.se>
Tested-by: Kuninori Morimoto <morimoto.kuninori@renesas.com>
---

 arch/sh/include/asm/sh_eth.h |    1 +
 drivers/net/sh_eth.c         |   20 ++++++++++++--------
 2 files changed, 13 insertions(+), 8 deletions(-)

--- 0001/arch/sh/include/asm/sh_eth.h
+++ work/arch/sh/include/asm/sh_eth.h	2009-10-07 15:04:57.000000000 +0900
@@ -7,6 +7,7 @@ struct sh_eth_plat_data {
 	int phy;
 	int edmac_endian;
 
+	unsigned char mac_addr[6];
 	unsigned no_ether_link:1;
 	unsigned ether_link_active_low:1;
 };
--- 0001/drivers/net/sh_eth.c
+++ work/drivers/net/sh_eth.c	2009-10-07 16:54:29.000000000 +0900
@@ -298,16 +298,20 @@ static void update_mac_address(struct ne
  * When you want use this device, you must set MAC address in bootloader.
  *
  */
-static void read_mac_address(struct net_device *ndev)
+static void read_mac_address(struct net_device *ndev, unsigned char *mac)
 {
 	u32 ioaddr = ndev->base_addr;
 
-	ndev->dev_addr[0] = (ctrl_inl(ioaddr + MAHR) >> 24);
-	ndev->dev_addr[1] = (ctrl_inl(ioaddr + MAHR) >> 16) & 0xFF;
-	ndev->dev_addr[2] = (ctrl_inl(ioaddr + MAHR) >> 8) & 0xFF;
-	ndev->dev_addr[3] = (ctrl_inl(ioaddr + MAHR) & 0xFF);
-	ndev->dev_addr[4] = (ctrl_inl(ioaddr + MALR) >> 8) & 0xFF;
-	ndev->dev_addr[5] = (ctrl_inl(ioaddr + MALR) & 0xFF);
+	if (mac[0] || mac[1] || mac[2] || mac[3] || mac[4] || mac[5]) {
+		memcpy(ndev->dev_addr, mac, 6);
+	} else {
+		ndev->dev_addr[0] = (ctrl_inl(ioaddr + MAHR) >> 24);
+		ndev->dev_addr[1] = (ctrl_inl(ioaddr + MAHR) >> 16) & 0xFF;
+		ndev->dev_addr[2] = (ctrl_inl(ioaddr + MAHR) >> 8) & 0xFF;
+		ndev->dev_addr[3] = (ctrl_inl(ioaddr + MAHR) & 0xFF);
+		ndev->dev_addr[4] = (ctrl_inl(ioaddr + MALR) >> 8) & 0xFF;
+		ndev->dev_addr[5] = (ctrl_inl(ioaddr + MALR) & 0xFF);
+	}
 }
 
 struct bb_info {
@@ -1427,7 +1431,7 @@ static int sh_eth_drv_probe(struct platf
 	mdp->post_fw = POST_FW >> (devno << 1);
 
 	/* read and set MAC address */
-	read_mac_address(ndev);
+	read_mac_address(ndev, pd->mac_addr);
 
 	/* First device only init */
 	if (!devno) {

^ permalink raw reply

* [PATCH] net: add Runtime PM to the sh_eth driver
From: Magnus Damm @ 2009-10-09 10:20 UTC (permalink / raw)
  To: netdev; +Cc: Magnus Damm, lethal, davem, linux-sh

From: Magnus Damm <damm@opensource.se>

Add Runtime PM support to the sh_eth driver.

The clock to the ethernet hardware block will be
enabled as long as the network device is up.

Signed-off-by: Magnus Damm <damm@opensource.se>
Tested-by: Kuninori Morimoto <morimoto.kuninori@renesas.com>
---

 drivers/net/sh_eth.c |   35 +++++++++++++++++++++++++++++++++--
 drivers/net/sh_eth.h |    1 +
 2 files changed, 34 insertions(+), 2 deletions(-)

--- 0003/drivers/net/sh_eth.c
+++ work/drivers/net/sh_eth.c	2009-10-07 17:25:34.000000000 +0900
@@ -30,7 +30,7 @@
 #include <linux/phy.h>
 #include <linux/cache.h>
 #include <linux/io.h>
-
+#include <linux/pm_runtime.h>
 #include "sh_eth.h"
 
 /* There is CPU dependent code */
@@ -1012,6 +1012,8 @@ static int sh_eth_open(struct net_device
 	int ret = 0;
 	struct sh_eth_private *mdp = netdev_priv(ndev);
 
+	pm_runtime_get_sync(&mdp->pdev->dev);
+
 	ret = request_irq(ndev->irq, &sh_eth_interrupt,
 #if defined(CONFIG_CPU_SUBTYPE_SH7763) || defined(CONFIG_CPU_SUBTYPE_SH7764)
 				IRQF_SHARED,
@@ -1048,6 +1050,7 @@ static int sh_eth_open(struct net_device
 
 out_free_irq:
 	free_irq(ndev->irq, ndev);
+	pm_runtime_put_sync(&mdp->pdev->dev);
 	return ret;
 }
 
@@ -1179,6 +1182,8 @@ static int sh_eth_close(struct net_devic
 	ringsize = sizeof(struct sh_eth_txdesc) * TX_RING_SIZE;
 	dma_free_coherent(NULL, ringsize, mdp->tx_ring, mdp->tx_desc_dma);
 
+	pm_runtime_put_sync(&mdp->pdev->dev);
+
 	return 0;
 }
 
@@ -1187,6 +1192,8 @@ static struct net_device_stats *sh_eth_g
 	struct sh_eth_private *mdp = netdev_priv(ndev);
 	u32 ioaddr = ndev->base_addr;
 
+	pm_runtime_get_sync(&mdp->pdev->dev);
+
 	mdp->stats.tx_dropped += ctrl_inl(ioaddr + TROCR);
 	ctrl_outl(0, ioaddr + TROCR);	/* (write clear) */
 	mdp->stats.collisions += ctrl_inl(ioaddr + CDCR);
@@ -1202,6 +1209,8 @@ static struct net_device_stats *sh_eth_g
 	mdp->stats.tx_carrier_errors += ctrl_inl(ioaddr + CNDCR);
 	ctrl_outl(0, ioaddr + CNDCR);	/* (write clear) */
 #endif
+	pm_runtime_put_sync(&mdp->pdev->dev);
+
 	return &mdp->stats;
 }
 
@@ -1410,6 +1419,9 @@ static int sh_eth_drv_probe(struct platf
 
 	mdp = netdev_priv(ndev);
 	spin_lock_init(&mdp->lock);
+	mdp->pdev = pdev;
+	pm_runtime_enable(&pdev->dev);
+	pm_runtime_resume(&pdev->dev);
 
 	pd = (struct sh_eth_plat_data *)(pdev->dev.platform_data);
 	/* get PHY ID */
@@ -1485,18 +1497,37 @@ static int sh_eth_drv_remove(struct plat
 	sh_mdio_release(ndev);
 	unregister_netdev(ndev);
 	flush_scheduled_work();
-
+	pm_runtime_disable(&pdev->dev);
 	free_netdev(ndev);
 	platform_set_drvdata(pdev, NULL);
 
 	return 0;
 }
 
+static int sh_eth_runtime_nop(struct device *dev)
+{
+	/*
+	 * Runtime PM callback shared between ->runtime_suspend()
+	 * and ->runtime_resume(). Simply returns success.
+	 *
+	 * This driver re-initializes all registers after
+	 * pm_runtime_get_sync() anyway so there is no need
+	 * to save and restore registers here.
+	 */
+	return 0;
+}
+
+static struct dev_pm_ops sh_eth_dev_pm_ops = {
+	.runtime_suspend = sh_eth_runtime_nop,
+	.runtime_resume = sh_eth_runtime_nop,
+};
+
 static struct platform_driver sh_eth_driver = {
 	.probe = sh_eth_drv_probe,
 	.remove = sh_eth_drv_remove,
 	.driver = {
 		   .name = CARDNAME,
+		   .pm = &sh_eth_dev_pm_ops,
 	},
 };
 
--- 0001/drivers/net/sh_eth.h
+++ work/drivers/net/sh_eth.h	2009-10-07 17:22:24.000000000 +0900
@@ -703,6 +703,7 @@ struct sh_eth_cpu_data {
 };
 
 struct sh_eth_private {
+	struct platform_device *pdev;
 	struct sh_eth_cpu_data *cd;
 	dma_addr_t rx_desc_dma;
 	dma_addr_t tx_desc_dma;

^ permalink raw reply

* Re: [PATCH] irda/sa1100_ir: check return value of startup hook
From: Sergei Shtylyov @ 2009-10-09 12:14 UTC (permalink / raw)
  To: Dmitry Artamonow
  Cc: netdev, Samuel Ortiz, Russell King, David S. Miller,
	linux-arm-kernel
In-Reply-To: <1255073153-24962-1-git-send-email-mad_soft@inbox.ru>

Hello.

Dmitry Artamonow wrote:

> Signed-off-by: Dmitry Artamonow <mad_soft@inbox.ru>
[...]
> diff --git a/drivers/net/irda/sa1100_ir.c b/drivers/net/irda/sa1100_ir.c
> index 38bf7cf..df5db2d 100644
> --- a/drivers/net/irda/sa1100_ir.c
> +++ b/drivers/net/irda/sa1100_ir.c
> @@ -232,8 +232,11 @@ static int sa1100_irda_startup(struct sa1100_irda *si)
>  	/*
>  	 * Ensure that the ports for this device are setup correctly.
>  	 */
> -	if (si->pdata->startup)
> -		si->pdata->startup(si->dev);
> +	if (si->pdata->startup)	{
> +		ret = si->pdata->startup(si->dev);
> +		if (ret)
> +			return ret;
> +		}

    Overindented brace.

>  
>  	/*
>  	 * Configure PPC for IRDA - we want to drive TXD2 low.

WBR, Sergei

^ permalink raw reply

* RE: [7/8,RFC] CAIF Protocol Stack
From: Sjur Brændeland @ 2009-10-09 12:37 UTC (permalink / raw)
  To: Stefano Babic; +Cc: netdev, Kim Lilliestierna XX
In-Reply-To: <4ACDF12A.6030906@babic.homelinux.org>

Hi Stefano.
Thank you very much for looking into this!
I find this as very valuable feedback.

Stefano Babic wrote:
> I discovered there is a production bug in the Makefile and the setup
> of the extract function in cfcnfg_get_packet_funcs() is inconsistent. 
> Indeed, I traced the address of the extract function and I can find
> that the address does not point to cfpkt_extract(), as I assumed. 
> 
> The problem is due to the usage of the define CAIF_USE_SKB. This is
> used in caif_layer.h, but some files (net/caif/*) are compiled with
> the macro defined, while the drivers (drivers/net/caif/*) not.  
> Rather I did not get an "oops", because a valid pointer was
> set....but to the wrong function ! 
> I have also seen that CAIF_USE_SKB is not used in
> cfpkt_get_packet_funcs, and this generates a problem if CAIF_USE_SKB
> is not set, because the "fromnative" and "tonative" functions are
> always set, even if they do not belong to the structure.   

Well done finding this! I have corrected this as suggested in the new patch-set.

> 
> IMHO should be possible to get rid of the usage of CAIF_USE_SKB in
> the structure definition (in caif_layer.h) and to provide always the
> same structure definition in both case. I would prefer to set the
> values of cfpkt_fromnative and cfpkt_tonative to NULL, instead of
> reducing the size of the structure.    

Agree, and done.
> 
> I am not sure I understood the meaning of using this structure,
> because at the moment the setup is fixed and I cannot find any point
> in code where the structure is assigned to another set of functions.
> Probably you arrange to have multiple choices in future, I can
> suppose.    
> 

The choices are decided compile time from Kconfig.

> What about to pass directly the pointer to the structure instead of
> copying returning its value ? It seems not necessary to me, I changed
> cfpkt_get_packet_funcs in this direction.  

I haven't done this yet, but it seems reasonable.

> 
> Meanwhile, it seems some bytes are sent now to the physical interface.
> 
> <caif_chropen:797, TRACE> [caif_chropen:797] WAIT FOR CONNECT
> RESPONSE <caif_chropen:820, TRACE> caif_open: connect timed out 
> 
> However, I get no connection, but probably this is another problem....
> 

Do you have a (ST-)Ericsson modem talking CAIF connected?
The correct behavior is to wait for the CONNECT_RESPONSE, and time out.

BR/Sjur Brændeland

^ permalink raw reply

* Re: [Patch-next] Fix the size overflow of addrconf_sysctl array
From: Cosmin Ratiu @ 2009-10-09 13:11 UTC (permalink / raw)
  To: David Miller, opurdila
  Cc: jin.dongming, kaneshige.kenji, seto.hidetoshi, netdev
In-Reply-To: <20091008.224415.205034676.davem@davemloft.net>

[-- Attachment #1: Type: Text/Plain, Size: 3799 bytes --]

Shouldn't this be changed too then?

Or better yet, wouldn't a change that eliminates the need of adding a new 
option in two separate places be useful?

I see the only use for that DEVCONF enum is to dump the settings via netlink.
Wouldn't a memcpy suffice?

Cosmin.

On Friday 09 October 2009 08:44:15 David Miller wrote:
> From: Jin Dongming <jin.dongming@np.css.fujitsu.com>
> Date: Fri, 09 Oct 2009 11:37:59 +0900
> 
> Please post networking patches always CC:'d to netdev@vger.kernel.org
> so that it gets added to our networking patch tracking system at:
> 
> 	http://patchwork.ozlabs.org/project/netdev/list/
> 
> Thank you.
> 
> I've applied your fix, thanks!
> 
> > (This patch fixes bug of commit f7734fdf61ec6bb848e0bafc1fb8bad2c124bb50
> >  title "make TLLAO option for NA packets configurable")
> >
> > When the IPV6 conf is used, the function sysctl_set_parent is called and
> > the array addrconf_sysctl is used as a parameter of the function.
> >
> > The above patch added new conf "force_tllao" into the array
> > addrconf_sysctl, but the size of the array was not modified, the static
> > allocated size is DEVCONF_MAX + 1 but the real size is DEVCONF_MAX + 2,
> > so the problem is that the function sysctl_set_parent accessed wrong
> > address.
> >
> > I got the following information.
> > Call Trace:
> >     [<ffffffff8106085d>] sysctl_set_parent+0x29/0x3e
> >     [<ffffffff8106085d>] sysctl_set_parent+0x29/0x3e
> >     [<ffffffff8106085d>] sysctl_set_parent+0x29/0x3e
> >     [<ffffffff8106085d>] sysctl_set_parent+0x29/0x3e
> >     [<ffffffff8106085d>] sysctl_set_parent+0x29/0x3e
> >     [<ffffffff810622d5>] __register_sysctl_paths+0xde/0x272
> >     [<ffffffff8110892d>] ? __kmalloc_track_caller+0x16e/0x180
> >     [<ffffffffa00cfac3>] ? __addrconf_sysctl_register+0xc5/0x144 [ipv6]
> >     [<ffffffff8141f2c9>] register_net_sysctl_table+0x48/0x4b
> >     [<ffffffffa00cfaf5>] __addrconf_sysctl_register+0xf7/0x144 [ipv6]
> >     [<ffffffffa00cfc16>] addrconf_init_net+0xd4/0x104 [ipv6]
> >     [<ffffffff8139195f>] setup_net+0x35/0x82
> >     [<ffffffff81391f6c>] copy_net_ns+0x76/0xe0
> >     [<ffffffff8107ad60>] create_new_namespaces+0xf0/0x16e
> >     [<ffffffff8107afee>] copy_namespaces+0x65/0x9f
> >     [<ffffffff81056dff>] copy_process+0xb2c/0x12c3
> >     [<ffffffff810576e1>] do_fork+0x14b/0x2d2
> >     [<ffffffff8107ac4e>] ? up_read+0xe/0x10
> >     [<ffffffff81438e73>] ? do_page_fault+0x27a/0x2aa
> >     [<ffffffff8101044b>] sys_clone+0x28/0x2a
> >     [<ffffffff81011fb3>] stub_clone+0x13/0x20
> >     [<ffffffff81011c72>] ? system_call_fastpath+0x16/0x1b
> >
> > And the information of IPV6 in .config is as following.
> > IPV6 in .config:
> >     CONFIG_IPV6=m
> >     CONFIG_IPV6_PRIVACY=y
> >     CONFIG_IPV6_ROUTER_PREF=y
> >     CONFIG_IPV6_ROUTE_INFO=y
> >     CONFIG_IPV6_OPTIMISTIC_DAD=y
> >     CONFIG_IPV6_MIP6=m
> >     CONFIG_IPV6_SIT=m
> >     # CONFIG_IPV6_SIT_6RD is not set
> >     CONFIG_IPV6_NDISC_NODETYPE=y
> >     CONFIG_IPV6_TUNNEL=m
> >     CONFIG_IPV6_MULTIPLE_TABLES=y
> >     CONFIG_IPV6_SUBTREES=y
> >     CONFIG_IPV6_MROUTE=y
> >     CONFIG_IPV6_PIMSM_V2=y
> >     # CONFIG_IP_VS_IPV6 is not set
> >     CONFIG_NF_CONNTRACK_IPV6=m
> >     CONFIG_IP6_NF_MATCH_IPV6HEADER=m
> >
> > I confirmed this patch fixes this problem.
> >
> > Signed-off-by: Jin Dongming <jin.dongming@np.css.fujitsu.com>
> > ---
> >  include/linux/ipv6.h |    1 +
> >  1 files changed, 1 insertions(+), 0 deletions(-)
> >
> > diff --git a/include/linux/ipv6.h b/include/linux/ipv6.h
> > index ae74ede..5640425 100644
> > --- a/include/linux/ipv6.h
> > +++ b/include/linux/ipv6.h
> > @@ -208,6 +208,7 @@ enum {
> >  	DEVCONF_MC_FORWARDING,
> >  	DEVCONF_DISABLE_IPV6,
> >  	DEVCONF_ACCEPT_DAD,
> > +	DEVCONF_FORCE_TLLAO,
> >  	DEVCONF_MAX
> >  };
> 

[-- Attachment #2: 0001-ipv6-fix-devconf-after-adding-force_tllao-option.patch --]
[-- Type: text/x-patch, Size: 823 bytes --]

From f72949922a102ee9e728a2805287a9bd9a4d2e67 Mon Sep 17 00:00:00 2001
From: Cosmin Ratiu <cratiu@ixiacom.com>
Date: Fri, 9 Oct 2009 15:57:09 +0300
Subject: [PATCH] [ipv6]: fix devconf after adding force_tllao option


Signed-off-by: Cosmin Ratiu <cratiu@ixiacom.com>
---
 net/ipv6/addrconf.c |    1 +
 1 files changed, 1 insertions(+), 0 deletions(-)

diff --git a/net/ipv6/addrconf.c b/net/ipv6/addrconf.c
index 1fd0a3d..a065f40 100644
--- a/net/ipv6/addrconf.c
+++ b/net/ipv6/addrconf.c
@@ -3708,6 +3708,7 @@ static inline void ipv6_store_devconf(struct ipv6_devconf *cnf,
 #endif
 	array[DEVCONF_DISABLE_IPV6] = cnf->disable_ipv6;
 	array[DEVCONF_ACCEPT_DAD] = cnf->accept_dad;
+	array[DEVCONF_FORCE_TLLAO] = cnf->force_tllao;
 }
 
 static inline size_t inet6_if_nlmsg_size(void)
-- 
1.6.3.3


^ permalink raw reply related

* [net-next-2.6 PATCH] be2net:patch to implement ethtool get_phys_id function.
From: Sarveshwar Bandi @ 2009-10-09 13:13 UTC (permalink / raw)
  To: netdev; +Cc: davem

please accept patch, implements port beacon functionality for be2net driver.

Signed-off-by: sarveshwarb <sarveshwarb@serverengines.com>
---
 drivers/net/benet/be_cmds.c    |   59 ++++++++++++++++++++++++++++++++++++++++
 drivers/net/benet/be_cmds.h    |   37 +++++++++++++++++++++++++
 drivers/net/benet/be_ethtool.c |   30 ++++++++++++++++++++
 3 files changed, 126 insertions(+), 0 deletions(-)

diff --git a/drivers/net/benet/be_cmds.c b/drivers/net/benet/be_cmds.c
index 89876ad..25b6602 100644
--- a/drivers/net/benet/be_cmds.c
+++ b/drivers/net/benet/be_cmds.c
@@ -1118,6 +1118,65 @@ int be_cmd_reset_function(struct be_adap
 	return status;
 }
 
+/* Uses sync mcc */
+int be_cmd_set_beacon_state(struct be_adapter *adapter, u8 port_num,
+			u8 bcn, u8 sts, u8 state)
+{
+	struct be_mcc_wrb *wrb;
+	struct be_cmd_req_enable_disable_beacon *req;
+	int status;
+
+	spin_lock_bh(&adapter->mcc_lock);
+
+	wrb = wrb_from_mccq(adapter);
+	req = embedded_payload(wrb);
+
+	be_wrb_hdr_prepare(wrb, sizeof(*req), true, 0);
+
+	be_cmd_hdr_prepare(&req->hdr, CMD_SUBSYSTEM_COMMON,
+		OPCODE_COMMON_ENABLE_DISABLE_BEACON, sizeof(*req));
+
+	req->port_num = port_num;
+	req->beacon_state = state;
+	req->beacon_duration = bcn;
+	req->status_duration = sts;
+
+	status = be_mcc_notify_wait(adapter);
+
+	spin_unlock_bh(&adapter->mcc_lock);
+	return status;
+}
+
+/* Uses sync mcc */
+int be_cmd_get_beacon_state(struct be_adapter *adapter, u8 port_num, u32 *state)
+{
+	struct be_mcc_wrb *wrb;
+	struct be_cmd_req_get_beacon_state *req;
+	int status;
+
+	spin_lock_bh(&adapter->mcc_lock);
+
+	wrb = wrb_from_mccq(adapter);
+	req = embedded_payload(wrb);
+
+	be_wrb_hdr_prepare(wrb, sizeof(*req), true, 0);
+
+	be_cmd_hdr_prepare(&req->hdr, CMD_SUBSYSTEM_COMMON,
+		OPCODE_COMMON_GET_BEACON_STATE, sizeof(*req));
+
+	req->port_num = port_num;
+
+	status = be_mcc_notify_wait(adapter);
+	if (!status) {
+		struct be_cmd_resp_get_beacon_state *resp =
+						embedded_payload(wrb);
+		*state = resp->beacon_state;
+	}
+
+	spin_unlock_bh(&adapter->mcc_lock);
+	return status;
+}
+
 int be_cmd_write_flashrom(struct be_adapter *adapter, struct be_dma_mem *cmd,
 			u32 flash_type, u32 flash_opcode, u32 buf_size)
 {
diff --git a/drivers/net/benet/be_cmds.h b/drivers/net/benet/be_cmds.h
index a86f917..a1e78cc 100644
--- a/drivers/net/benet/be_cmds.h
+++ b/drivers/net/benet/be_cmds.h
@@ -138,6 +138,8 @@ #define OPCODE_COMMON_QUERY_FIRMWARE_CON
 #define OPCODE_COMMON_NTWK_PMAC_ADD			59
 #define OPCODE_COMMON_NTWK_PMAC_DEL			60
 #define OPCODE_COMMON_FUNCTION_RESET			61
+#define OPCODE_COMMON_ENABLE_DISABLE_BEACON		69
+#define OPCODE_COMMON_GET_BEACON_STATE			70
 
 #define OPCODE_ETH_ACPI_CONFIG				2
 #define OPCODE_ETH_PROMISCUOUS				3
@@ -699,6 +701,37 @@ struct be_cmd_resp_query_fw_cfg {
 	u32 rsvd[26];
 };
 
+/******************** Port Beacon ***************************/
+
+#define BEACON_STATE_ENABLED		0x1
+#define BEACON_STATE_DISABLED		0x0
+
+struct be_cmd_req_enable_disable_beacon {
+	struct be_cmd_req_hdr hdr;
+	u8  port_num;
+	u8  beacon_state;
+	u8  beacon_duration;
+	u8  status_duration;
+} __packed;
+
+struct be_cmd_resp_enable_disable_beacon {
+	struct be_cmd_resp_hdr resp_hdr;
+	u32 rsvd0;
+} __packed;
+
+struct be_cmd_req_get_beacon_state {
+	struct be_cmd_req_hdr hdr;
+	u8  port_num;
+	u8  rsvd0;
+	u16 rsvd1;
+} __packed;
+
+struct be_cmd_resp_get_beacon_state {
+	struct be_cmd_resp_hdr resp_hdr;
+	u8 beacon_state;
+	u8 rsvd0[3];
+} __packed;
+
 /****************** Firmware Flash ******************/
 struct flashrom_params {
 	u32 op_code;
@@ -764,6 +797,10 @@ extern int be_cmd_query_fw_cfg(struct be
 			u32 *port_num, u32 *cap);
 extern int be_cmd_reset_function(struct be_adapter *adapter);
 extern int be_process_mcc(struct be_adapter *adapter);
+extern int be_cmd_set_beacon_state(struct be_adapter *adapter,
+			u8 port_num, u8 beacon, u8 status, u8 state);
+extern int be_cmd_get_beacon_state(struct be_adapter *adapter,
+			u8 port_num, u32 *state);
 extern int be_cmd_write_flashrom(struct be_adapter *adapter,
 			struct be_dma_mem *cmd, u32 flash_oper,
 			u32 flash_opcode, u32 buf_size);
diff --git a/drivers/net/benet/be_ethtool.c b/drivers/net/benet/be_ethtool.c
index 333729b..280471e 100644
--- a/drivers/net/benet/be_ethtool.c
+++ b/drivers/net/benet/be_ethtool.c
@@ -338,6 +338,35 @@ be_set_pauseparam(struct net_device *net
 }
 
 static int
+be_phys_id(struct net_device *netdev, u32 data)
+{
+	struct be_adapter *adapter = netdev_priv(netdev);
+	int status;
+	u32 cur;
+
+	if (!netif_running(netdev))
+		return 0;
+
+	be_cmd_get_beacon_state(adapter, adapter->port_num, &cur);
+
+	if (cur == BEACON_STATE_ENABLED)
+		return 0;
+
+	if (data < 2)
+		data = 2;
+
+	status = be_cmd_set_beacon_state(adapter, adapter->port_num, 0, 0,
+			BEACON_STATE_ENABLED);
+	set_current_state(TASK_INTERRUPTIBLE);
+	schedule_timeout(data*HZ);
+
+	status = be_cmd_set_beacon_state(adapter, adapter->port_num, 0, 0,
+			BEACON_STATE_DISABLED);
+
+	return status;
+}
+
+static int
 be_do_flash(struct net_device *netdev, struct ethtool_flash *efl)
 {
 	struct be_adapter *adapter = netdev_priv(netdev);
@@ -369,6 +398,7 @@ const struct ethtool_ops be_ethtool_ops 
 	.get_tso = ethtool_op_get_tso,
 	.set_tso = ethtool_op_set_tso,
 	.get_strings = be_get_stat_strings,
+	.phys_id = be_phys_id,
 	.get_sset_count = be_get_sset_count,
 	.get_ethtool_stats = be_get_ethtool_stats,
 	.flash_device = be_do_flash,
-- 
1.4.0


^ permalink raw reply related

* Re: pull request: wireless-2.6 2009-10-08
From: John W. Linville @ 2009-10-09 13:23 UTC (permalink / raw)
  To: Michael Buesch; +Cc: davem, linux-wireless, netdev, linux-kernel
In-Reply-To: <200910090108.08838.mb@bu3sch.de>

On Fri, Oct 09, 2009 at 01:08:06AM +0200, Michael Buesch wrote:
> On Friday 09 October 2009 00:34:54 John W. Linville wrote:
> > Albert Herranz (1):
> >       b43: do not stack-allocate pio rx/tx header and tail buffers
> 
> Come on, this is _not_ funny anymore. I did _not_ ack this patch, because I do _not_ like it.
> I was planning to do a better solution, but I didn't have the time, yet.
> Can you _please_ either:
> - Wait for my ack before you apply random b43 patches
> or
> - Remove me from MAINTAINERS

Michael,

After Albert posted his first version of the patch, you said:

"Just embed it into struct b43_wl (surround it by #ifdef CONFIG_B43_PIO). No need
to kzalloc then and it saves some memory.
You also need to alloc 4 bytes for the tail buffer (that currently is on the stack, too)."

AFAICT he complied with that request when he posted the second version.
Since the patch seemed fine otherwise, I applied it; and since it is
a fix I sent it on for 2.6.32.

As Dave suggested, there is plenty of time to fix it "properly"
for 2.6.33 and beyond.  I'm happy to accomodate you.

John

P.S.  Please understand that while some driver maintainers want to
ack every patch, others see that as a burden and get annoyed with me
if I don't apply reasonable patches without bothering them.  It can
be a bit difficult these things...
-- 
John W. Linville		Someday the world will need a hero, and you
linville@tuxdriver.com			might be all we have.  Be ready.

^ permalink raw reply

* [PATCH] [CAIF-RFC 0/8-v2] CAIF Protocol Stack
From: sjur.brandeland @ 2009-10-09 13:39 UTC (permalink / raw)
  To: netdev, netdev
  Cc: stefano.babic, randy.dunlap, kim.xx.lilliestierna,
	christian.bejram, daniel.martensson, Sjur Braendeland

From: Sjur Braendeland <sjur.brandeland@stericsson.com>

This is the second version of the CAIF patch set.
The patch set is compiled on 386 for 2.6.31.
All feedback is apreciated.

Change log:
* Minor documentation updates
* Character device chnl_chr.c now supports non-blocking open/close.
* Net device chnl_net.c now support multiple instances.
* Cleanup of create_channel.cnf
* Spelling issues in Kconfig files
* Compilation problems in chardevconfig 
* Makefile problems compiling Net and Char dev
* Removed obsolete chnl_tty.c
* Removed shared memory physical interface
* Remove #ifdef CAIF_USE_SKB from caif_layer.h
* Changed #include statements all over.


BR/Sjur Brændeland

^ permalink raw reply

* [PATCH] [CAIF-RFC 1/8-v2] CAIF Protocol Stack
From: sjur.brandeland @ 2009-10-09 13:39 UTC (permalink / raw)
  To: netdev
  Cc: stefano.babic, randy.dunlap, kim.xx.lilliestierna,
	christian.bejram, daniel.martensson, Sjur Braendeland
In-Reply-To: <1255095571-6501-1-git-send-email-sjur.brandeland@stericsson.com>

From: Sjur Braendeland <sjur.brandeland@stericsson.com>

Change-Id: I305056f116a11c31265f65ac0fe285e2b655dd54
Signed-off-by: Sjur Braendeland <sjur.brandeland@stericsson.com>
---
 include/linux/caif/caif_config.h |  203 ++++++++++++++++++++++++++++++++++++++
 include/linux/caif/caif_ioctl.h  |  113 +++++++++++++++++++++
 2 files changed, 316 insertions(+), 0 deletions(-)
 create mode 100644 include/linux/caif/caif_config.h
 create mode 100644 include/linux/caif/caif_ioctl.h

diff --git a/include/linux/caif/caif_config.h b/include/linux/caif/caif_config.h
new file mode 100644
index 0000000..6ea934b
--- /dev/null
+++ b/include/linux/caif/caif_config.h
@@ -0,0 +1,203 @@
+/*
+ *	Copyright (C) ST-Ericsson AB 2009
+ *
+ *	CAIF Channel Configuration definitions.
+ *
+ *	Author: Sjur Brendeland/ sjur.brandeland@stericsson.com
+ *
+ *	License terms: GNU General Public License (GPL), version 2.
+ *
+ */
+
+#ifndef CAIF_CONFIG_H_
+#define CAIF_CONFIG_H_
+
+/**
+ * enum caif_phy_preference -	Types of Physical HW Interfaces
+ *				towards modem defined in CAIF Stack,
+ * @CAIF_PHYPREF_UNSPECIFIED:	Default Physical Interface
+ * @CAIF_PHYPREF_LOW_LAT:	Default Physical Interface for Low Latency
+ *				Traffic
+ * @CAIF_PHYPREF_HIGH_BW:	Default Physical Interface for High Bandwidth
+ *				Traffic
+ * @_CAIF_PHYPREF_LOOP:		TEST Loop-back Interface Simulating Acc side
+ *				responses
+ * @_CAIF_PHYPREF_RAW_LOOP:	TEST ONLY Raw loopback interface
+ *
+ * For Client convenience to special types are defined:
+ * CAIF_PHYPREF_LOW_LAT is the preferred low latency physical link.
+ * Typically used for "control" purposes.
+ * CAIF_PHYPREF_HIGH_BW is the preferred high bandwidth physical link.
+ * Typically used for "payload" purposes.
+ *
+ */
+enum caif_phy_preference {
+	CAIF_PHYPREF_UNSPECIFIED	= 0x00,
+	CAIF_PHYPREF_LOW_LAT		= 0xd0,
+	CAIF_PHYPREF_HIGH_BW		= 0xe0,
+	_CAIF_PHYPREF_LOOP		= 0x70,
+	_CAIF_PHYPREF_RAW_LOOP		= 0x80
+};
+
+
+/*!
+ * define CAIF Channel Priority.
+ * Used when setting up a Channel to specify the
+ * priority level of the channel.
+ */
+
+#define CAIF_PRIO_UNSPCEIFIED  0x0
+#define CAIF_PRIO_MIN	       0x01	/*! Minimum Priority Level */
+#define CAIF_PRIO_LOW	       0x04	/*!< Suggested Priority Level for
+					 *   Low Priority Channel */
+#define CAIF_PRIO_NORMAL       0x0f	/*!< Suggested Normal/Default
+					 *   priority Level */
+#define CAIF_PRIO_HIGH	       0x14	/*!< Suggested High Priority Level */
+#define CAIF_PRIO_MAX	       0x1F	/*!< Max Priority for Channel
+					   (do not use)
+					 */
+
+/**
+ * enum caif_channel_type  Types of CAIF Channel type defined in CAIF Stack.
+ * @CAIF_CHTY_AT:		Classical AT
+ * @CAIF_CHTY_AT_CTRL:		AT Control only
+ * @CAIF_CHTY_AT_PAIRED:	Paired control and data
+ * @CAIF_CHTY_DATAGRAM:		Datagram, Requires: connection_id
+ * @CAIF_CHTY_DATAGRAM_LOOP:	Datagram Loopback (testing purposes only)
+ * @CAIF_CHTY_VIDEO:		Video Channel
+ * @CAIF_CHTY_DEBUG:		Debug Service (Debug Server and
+ *					       Interactive Debug)
+ * @CAIF_CHTY_DEBUG_TRACE:	Debug Server only
+ * @CAIF_CHTY_DEBUG_INTERACT:	Debug Interactive
+ * @CAIF_CHTY_RFM:		RFM Service. Params: connection_id, volume
+ * @CAIF_CHTY_UTILITY:		Utility (Psock) Service.
+ *				Params: fifo_kb,fifo_pkt, name, psock_param
+ * @CAIF_CHTY_RAW:		DO NOT USE. This is for testing only
+ *
+ * This is used for Channel Configuration specifying the type of channel.
+ */
+
+enum caif_channel_type {
+	CAIF_CHTY_AT,
+	CAIF_CHTY_AT_CTRL,
+	CAIF_CHTY_AT_PAIRED,
+	CAIF_CHTY_DATAGRAM,
+	CAIF_CHTY_DATAGRAM_LOOP,
+	CAIF_CHTY_VIDEO,
+	CAIF_CHTY_DEBUG,
+	CAIF_CHTY_DEBUG_TRACE,
+	CAIF_CHTY_DEBUG_INTERACT,
+	CAIF_CHTY_RFM,
+	CAIF_CHTY_UTILITY,
+	CAIF_CHTY_RAW
+};
+
+/**
+ *struct caif_channel_config This structures is used for configuring
+ *			     CAIF Channels.
+ * @name: Mandatory:	     Nickname for this device
+ * @type:		     Mandatory Define the type of caif service
+ * @priority:		     Mandatory Value between  CAIF_PRIO_MIN and
+ *			     CAIF_PRIO_MAX,
+ *			     CAIF_PRIO_LOW, CAIF_PRIO_NORMAL, CAIF_PRIO_HIGH
+ *			     are suggested values.
+ * @phy_pref:		     Either: Specify type of physical interface to use.
+ * @phy_name:		     Or: Specify identity of the physical interface.
+ *
+ * @u:			     Union of Channel Type Specific configuration
+ *			     parameters
+ *
+ * @u.dgm:		     CAIF_CHTYPE_DATAGRAM
+ * @u.dgm.connection_id:     Mandatory Connection ID must be specified.
+ *
+ * @u.video:		     CAIF_CHTYPE_VIDEO
+ * @u.video.connection_id:   Mandatory Connection ID must be specified.
+ *
+ * @u.rfm		     CAIF_CHTYPE_RFM
+ * @u.rfm.connection_id:     Mandatory Connection ID must be specified.
+ * @u.rfm.volume:	     Mandatory Volume to mount.
+ *
+ * @u.utility:		     CAIF_CHTYPE_UTILITY
+ * @u.utility.fifosize_kb:   Psock: FIFO size in KB
+ * @u.utility.fifosize_bufs: Psock: # signal buffers
+ * @u.utility.name:	     Psock: Name of service
+ * @u.utility.params:	     Psock: Channel Config Parameters
+ * @u.utility.paramlen:	     Psock: Length of Channel Config Parameters
+ *
+ *
+ * It holds configuration parameters for setting up all devined CAIF
+ * Channel types.
+ * The four first fields are mandatory, then Physical Device can be specified
+ * either by name
+ * or by prefered characteristics.
+ * The rest of the configuration fields are hold in a union for each
+ * channel type and are channel type specific.
+ * \b Documentation see STE Doc No: 155 19-CRH 109 913.
+ */
+
+struct caif_channel_config {
+       /* Mandatory: Nickname for this device */
+	char name[16];
+	/* Mandatory: Define the type of caif service */
+	enum caif_channel_type type;
+	/** Mandatory: Mandatory - Value between
+	  * CAIF_PRIO_MIN and CAIF_PRIO_MAX, CAIF_PRIO_LOW, CAIF_PRIO_NORMAL,
+	  *  CAIF_PRIO_HIGH are suggested values. */
+	unsigned priority;
+
+	/** Either: Specify type of physical interface to use. */
+	enum caif_phy_preference phy_pref;
+	/** Or: Specify identity of the physical interface. */
+	char phy_name[16];
+
+	/** Union of Channel Type Specific configuration parameters
+	* 'switched' by attribute type */
+	union {
+		/* CAIF_CHTYPE_DATAGRAM */
+		struct {
+		       /**  Mandatory Connection ID  must be specified. */
+			unsigned connection_id;
+		} dgm;
+		/* CAIF_CHTYPE_VIDEO */
+		struct {
+			/** Datagram:  Mandatory Connection ID Must be
+			 *  specified. */
+			unsigned connection_id;
+		} video;
+		/* CAIF_CHTYPE_RFM */
+		struct {
+			/** RFM: Mandatory Connection ID. */
+			unsigned connection_id;
+			/** RFM: Mandatory Volume to mount. */
+			char volume[20];
+		} rfm;
+		/* CAIF_CHTYPE_UTILITY */
+		struct {
+/** Psock: FIFO size in KB */
+			unsigned fifosize_kb;
+/** Psock: # signal buffers */
+			unsigned fifosize_bufs;
+/** Psock: Name of service */
+			char name[16];
+/** Psock: Channel Config Parameters> */
+			unsigned char params[256];
+/** Psock: Length of Channel Config Parameters */
+			int paramlen;
+		} utility;
+
+
+		/* Raw Data configuration: DO NOT USE,
+		 * applies for testing only */
+
+		struct raw {
+			unsigned channeltype;
+			unsigned char endpoint:2;
+			unsigned char subtype:2;
+			unsigned char serviceconfig[512];
+			unsigned int service_length;
+		} _raw;
+	} u;
+
+};
+
+#endif				/* CAIF_CONFIG_H_ */
diff --git a/include/linux/caif/caif_ioctl.h b/include/linux/caif/caif_ioctl.h
new file mode 100644
index 0000000..421a4b2
--- /dev/null
+++ b/include/linux/caif/caif_ioctl.h
@@ -0,0 +1,113 @@
+/*
+*      Copyright (C) ST-Ericsson AB 2009
+*
+*      Author: Daniel Martensson / Daniel.Martensson@stericsson.com
+*
+*      License terms: GNU General Public License (GPL), version 2.
+*
+*/
+
+
+
+
+
+
+#ifndef CAIF_IOCTL_H_
+#define CAIF_IOCTL_H_
+#include <linux/caif/caif_config.h>
+
+
+/*!\page  caif_ioctl.h
+ * This file defines the management interface to CAIF.
+ * It defines how CAIF Channels are configured and become visible in Linux
+ * file system under "/dev/caifconfig".
+ *
+ *\b Example - creating a new AT character device:
+ * \code
+   fd = open("/dev/caifconfig",..);
+   struct caif_channel_create_action at_config = {
+	 .name = "cnhl2",
+	 .config = {
+	    .channel = CAIF_CHTY_AT,
+	    .phy_ref = CAIF_PHY_LOW_LAT,
+	    .priority = CAIF_PRIO_HIGH
+	 }};
+   ioctl(fd, CAIF_IOC_CONFIG_DEVICE,&at_config);
+   close(fd);
+ * \endcode
+ * This will cause a new AT channel to be available in at "/dev/chnl2".
+ * This CAIF channel can then be connected by using \ref open.
+ *
+*/
+
+/*! \addtogroup caif_ioctl
+ *  Additional documentation for group `caif_config.h'
+ *  @{
+ */
+
+
+
+/* Use 'g' as magic number. 'g' is the first free letter in
+ * Documentation/ioctl-number.txt*/
+#define CAIF_IOC_MAGIC 'g'
+#define DEVICE_NAME_LEN 16
+
+/* Specifies the type of device to create NET device or CHAR device*/
+enum caif_dev_type {
+	CAIF_DEV_CHR = 1,
+	CAIF_DEV_NET = 2
+};
+
+
+/** Used for identifying devices, PHY interfaces etc*/
+struct caif_device_name {
+	char name[DEVICE_NAME_LEN];	/*!< Device name */
+	enum caif_dev_type devtype;	/*!< Device type */
+};
+
+
+/**
+ * CAIF ACTION for \ref CAIF_ACT_CHANNEL_CONFIG.
+ * This structure is used to configure a new CAIF Channel and
+ * create the corresponding character device.
+ */
+struct caif_channel_create_action {
+	/** \b in  CAIF Configuration Request */
+	struct caif_channel_config config;
+	/** \b in/out Device name returned from ACTION */
+	struct caif_device_name name;
+	/** \b out Major device id */
+	int major;
+	/** \b out Minor device id */
+	int minor;
+};
+
+/**
+ * union caif_action
+ * This union is used to configure a new CAIF Channel and
+ */
+
+union caif_action {
+	struct caif_device_name delete_channel;
+	struct caif_channel_create_action create_channel;
+};
+
+
+/**
+ * CAIF IOCTL for \ref CAIF_IOC_CHANNEL_CONFIG.
+ * This structure is used to configure a new CAIF Channel and
+ * create the corresponding character device.
+ */
+
+/** Create and Configure a new CAIF device.
+ * Note that the device is not implicitly connected. */
+#define CAIF_IOC_CONFIG_DEVICE		_IOWR(CAIF_IOC_MAGIC, 1,\
+struct caif_channel_create_action)
+
+/** Remove a CAIF device. Requires the device to be previously disconnected. */
+#define CAIF_IOC_REMOVE_DEVICE		_IOWR(CAIF_IOC_MAGIC, 2,\
+		struct caif_device_name)
+#define CAIF__IOC_MAXNR				9
+/*! @} */
+
+#endif				/* CAIF_IOCTL_H_ */
-- 
1.6.0.4


^ permalink raw reply related

* [PATCH] [CAIF-RFC 2/8-v2] CAIF Protocol Stack
From: sjur.brandeland @ 2009-10-09 13:39 UTC (permalink / raw)
  To: netdev
  Cc: stefano.babic, randy.dunlap, kim.xx.lilliestierna,
	christian.bejram, daniel.martensson, Sjur Braendeland
In-Reply-To: <1255095571-6501-2-git-send-email-sjur.brandeland@stericsson.com>

From: Sjur Braendeland <sjur.brandeland@stericsson.com>

Change-Id: Ic66e718f40015c433b1464d0ea3af96431a407a8
Signed-off-by: Sjur Braendeland <sjur.brandeland@stericsson.com>
---
 include/net/caif/generic/caif_layer.h |  378 +++++++++++++++++++++++++++++++++
 include/net/caif/generic/cfcnfg.h     |  223 +++++++++++++++++++
 include/net/caif/generic/cfctrl.h     |  139 ++++++++++++
 include/net/caif/generic/cffrml.h     |   29 +++
 include/net/caif/generic/cfglue.h     |  206 ++++++++++++++++++
 include/net/caif/generic/cfloopcfg.h  |   28 +++
 include/net/caif/generic/cflst.h      |   27 +++
 include/net/caif/generic/cfmsll.h     |   22 ++
 include/net/caif/generic/cfmuxl.h     |   30 +++
 include/net/caif/generic/cfpkt.h      |  246 +++++++++++++++++++++
 include/net/caif/generic/cfserl.h     |   22 ++
 include/net/caif/generic/cfshml.h     |   21 ++
 include/net/caif/generic/cfspil.h     |   80 +++++++
 include/net/caif/generic/cfsrvl.h     |   48 ++++
 include/net/caif/generic/fcs.h        |   22 ++
 15 files changed, 1521 insertions(+), 0 deletions(-)
 create mode 100644 include/net/caif/generic/caif_layer.h
 create mode 100644 include/net/caif/generic/cfcnfg.h
 create mode 100644 include/net/caif/generic/cfctrl.h
 create mode 100644 include/net/caif/generic/cffrml.h
 create mode 100644 include/net/caif/generic/cfglue.h
 create mode 100644 include/net/caif/generic/cfloopcfg.h
 create mode 100644 include/net/caif/generic/cflst.h
 create mode 100644 include/net/caif/generic/cfmsll.h
 create mode 100644 include/net/caif/generic/cfmuxl.h
 create mode 100644 include/net/caif/generic/cfpkt.h
 create mode 100644 include/net/caif/generic/cfserl.h
 create mode 100644 include/net/caif/generic/cfshml.h
 create mode 100644 include/net/caif/generic/cfspil.h
 create mode 100644 include/net/caif/generic/cfsrvl.h
 create mode 100644 include/net/caif/generic/fcs.h

diff --git a/include/net/caif/generic/caif_layer.h b/include/net/caif/generic/caif_layer.h
new file mode 100644
index 0000000..0918f6a
--- /dev/null
+++ b/include/net/caif/generic/caif_layer.h
@@ -0,0 +1,378 @@
+/*
+*      Copyright (C) ST-Ericsson AB 2009
+*
+*      Author: Sjur Braendeland/sjur.brandeland@stericsson.com
+*
+*      License terms: GNU General Public License (GPL), version 2.
+*
+*/
+
+
+#ifndef CAIF_LAYER_H_
+#define CAIF_LAYER_H_
+
+#include <net/caif/generic/cfglue.h>
+/* Forward Declaration */
+struct _layer_t;
+struct _cfpkt_t;
+struct _cfpktq_t;
+struct _transmt_info;
+struct _caif_packet_funcs_t;
+typedef struct _cfpktq_t cfpktq_t;
+/* Type definitions*/
+typedef struct _transmt_info transmt_info;
+
+typedef struct _layer_t layer_t;
+typedef struct _caif_packet_funcs_t caif_packet_funcs_t;
+typedef struct _cfpkt_t cfpkt_t;
+
+#define CAIF_MAX_FRAMESIZE 4096
+#define CAIF_MAX_PAYLOAD_SIZE (4096 - 64)
+#define CAIF_NEEDED_HEADROOM (10)
+#define CAIF_NEEDED_TAILROOM (2)
+
+/*! \addtogroup GenCaifExternal
+ *  Additional documentation for group `GenCaifExternal'
+ *  @{
+ */
+
+
+/** CAIF Control Signaling.
+ *  These commands are sent upwards in the CAIF stack. They are used for
+ *  Signaling originating from Modem.
+ *  These are either responses (*_RSP) or events (*_IND).
+
+ */
+typedef enum _caif_ctrlcmd_t {
+	/** Flow Control is OFF, transmit function should stop sending data */
+	CAIF_CTRLCMD_FLOW_OFF_IND = 0,
+	/** Flow Control is ON, transmit function can start sending data */
+	CAIF_CTRLCMD_FLOW_ON_IND = 1,
+	/** Remote end CCPU has decided to close down channel */
+	CAIF_CTRLCMD_REMOTE_SHUTDOWN_IND = 5,
+	/** Called initially when the layer below has finished initialization */
+	CAIF_CTRLCMD_INIT_RSP = 3,
+	/** Called when de-initialization is complete */
+	CAIF_CTRLCMD_DEINIT_RSP = 4,
+	/** Called if initialization failes */
+	CAIF_CTRLCMD_INIT_FAIL_RSP = 6,
+	/** Note: Only used internally in GenCaif.
+	 * Called if physical interface cannot send more packets */
+	_CAIF_CTRLCMD_PHYIF_FLOW_OFF_IND = 7,
+	/** Note: Only used internally in GenCaif.
+	 * Called if physical interface is able to send packets again */
+	_CAIF_CTRLCMD_PHYIF_FLOW_ON_IND = 8
+} caif_ctrlcmd_t;
+
+
+
+/** Modem Control Signaling.
+ *  These are requests sent 'down-wards' in the stack.
+ *  Flow ON, OFF can be indicated to the modem.
+ *
+ */
+typedef enum _caif_modemcmd_t {
+	/** Flow Control is ON, transmit function can start sending data */
+	CAIF_MODEMCMD_FLOW_ON_REQ = 0,
+	/** Flow Control is OFF, transmit function should stop sending data */
+	CAIF_MODEMCMD_FLOW_OFF_REQ = 1,
+	/** Notify physical layer that it is in use */
+	_CAIF_MODEMCMD_PHYIF_USEFULL = 3,
+	/** Notify physical layer that it is no longer in use */
+	_CAIF_MODEMCMD_PHYIF_USELESS = 4
+} caif_modemcmd_t;
+
+/** CAIF Packet Direction.
+ *  Indicate if a packet is to be sent \b out or to be received \b in.
+ *
+ *
+ */
+typedef enum _caif_direction_t {
+	CAIF_DIR_IN = 0,	/*!< Incoming packet received. */
+	CAIF_DIR_OUT = 1	/*!< Outgoing packet to be transmitted. */
+} caif_direction_t;
+
+/*!
+ *  Receive Function.
+ *  Contract: Each layer must implement a receive function passing the Caif
+ *  Packets upwards in the stack.
+ *	Packet handling rules:
+ *	      -# The CAIF Packet (cfpkt) cannot be accessed after passing i
+ *		     to the next layer using up->receive().
+ *	      -# If parsing of the packet fail, the packet must be destroyed
+ *		     and -1 returned from the function.
+ *	      -# If parsing succeeds (and above layers return ok) function
+ *		     must return value > 0.
+ *
+ *  @param[in] layr Pointer to the current layer the receive function is
+ *		implemented for (this pointer).
+ *  @param[in] cfpkt Pointer to CaifPacket to be handled.
+ *  @return result < 0 indicates an error, 0 or positive value indicate success.
+ */
+typedef int (*receive_cb_t) (layer_t *layr, struct _cfpkt_t *cfpkt);
+
+/*!
+ *  Transmit Function.
+ *  Contract: Each layer must implement a transmit function passing the Caif
+ *	Packet downwards in the stack.
+ *	Packet handling rules:
+ *	      -# The CAIF Packet (cfpkt) ownership is passed to the transmit
+ *		 function. This means that the the packet cannot be access
+ *		 after passing it to the below layer using dn->transmit().
+ *
+ *
+ *	      -# However if transmit failes, the ownership is returned to
+ *		 caller. The caller of "dn->transmit()" must destroy or
+ *		 resend packet.
+ *
+ *	      -# Return less than zero means error, greater than zero means OK.
+ *
+ *  @param[in] layr  Pointer to the current layer the receive function is
+ *			     implemented for (this pointer).
+ *  @param[in] cfpkt Pointer to CaifPacket to be handled.
+ *  @param[in] info  Info about physical layer (filled in by MUX layer) and
+			     CAIF header size (each layer adds to hdr_len).
+ *  @return	     result < 0 indicates an error, 0 or positive value
+ *		     indicate success.
+ */
+typedef int (*transmit_cb_t) (layer_t *layr, transmt_info *info,
+		      struct _cfpkt_t *cfpkt);
+
+/*!
+ *  Control Function used to signal upwards in the CAIF stack.
+ *  Used for signaling responses (CAIF_CTRLCMD_*_RSP)
+ *  and asynchronous events from the modem  (CAIF_CTRLCMD_*_IND)
+ *
+ *  @param[in] layr  Pointer to the current layer the receive function is
+ *		     implemented for (this pointer).
+ *  @param[in] ctrl  Control Command.
+ */
+typedef void
+ (*ctrlcmd_cb_t) (layer_t *layr, caif_ctrlcmd_t ctrl, int phyid);
+
+/*!
+ *  Control Function used for controlling the modem. Used to signal down-wards
+ *  in the CAIF stack.
+ *  @returns 0 on success, < 0 upon failure.
+ *  @param[in] layr  Pointer to the current layer the receive function is
+ *		     implemented for (this pointer).
+ *  @param[in] ctrl  Control Command.
+ */
+typedef int (*modemcmd_cb_t) (layer_t *layr, caif_modemcmd_t ctrl);
+
+/*!
+ *  This function is used by the CAIF-Manager for initiating the adaptation
+ *  layer.
+ *  @param in caifstack The instance of layer below the adaptation layer in
+ *  the CAIF stack (service layer)
+ *  @param in pktfuncs The packet functions needed to create a packet is
+ *  passed in this structure
+ *  @param out adap_layer This layer is allocated and returned from the
+ *  adaptaion layer, and is inserted
+ *  in the CAIF stack as the topmost layer.
+ *
+ */
+typedef void
+ (*init_adaptation_layer) (layer_t *caifstack,
+			   caif_packet_funcs_t *pktfuncs,
+			   layer_t **adap_layer);
+
+
+/** This structure defines the generic layered structure in CAIF.
+ *  It is inspired by the "Protocol Layer Design Pattern" (Streams).
+ *
+ *  It defines a generic layering structure, used by all CAIF Layers and the
+ *  layers interfacing CAIF.
+ *
+ *  In order to integrate with CAIF an adaptation layer on top of the CAIF stack
+ *  and PHY layer below the CAIF stack
+ *  must be implemented. These layer must follow the design principles below.
+ *
+ *  Principles for layering of protocol layers:
+ *    -# All layers must use this structure. If embedding it, then place this
+ *	     structure first in the layer specific structure.
+ *    -# Each layer should not depend on any others layer private data.
+ *    -# In order to send data upwards do
+ *       \code layer->up->receive(layer->up, packet); \endcode
+ *       \see {receive_cb_t }
+ *    -# In order to send data downwards do
+ *       \code layer->dn->transmit(layer->dn, info, packet); \endcode
+ *       \see {transmit_cb_t }
+ *
+ *
+ *
+ */
+struct _layer_t {
+
+	struct _layer_t *up;	/*!< Pointer to the layer above */
+	struct _layer_t *dn;	/*!< Pointer to the layer below */
+	receive_cb_t receive;	/*!< Pointer to the receive function for this
+				 *   layer,used by the layer below to pass data
+				 *   upwards in the CAIF stack.*/
+	transmit_cb_t transmit;	/*!< Pointer to the transmit function used for
+				 *   the layer above to pass packet to be
+				 *   sent out on the stack.*/
+	ctrlcmd_cb_t ctrlcmd;	/*!< Pointer to function used by the CAIF stack
+				 *    to signal to the layer above.*/
+	modemcmd_cb_t modemcmd;	/*!< Pointer to function used by the CAIF stack
+				 * to signal to the layer below. */
+	struct _layer_t *next;	/*!< Pointer to chain of layers, up/dn will
+				 *   then point at the first element of a
+				 *   which then should be iterated through
+				 * the next pointer.*/
+	unsigned short prio;	/*!< Priority of this layer */
+	unsigned int id;	/*!< The identity of this layer. */
+	unsigned int type;	/*<! The type of this layer */
+	char name[9];		/*!< Name of the layer */
+};
+
+/** Set the up pointer for a specified layer.
+ *  @param layr Layer where up pointer shall be set.
+ *  @param above Layer above.
+ */
+#define layer_set_up(layr, above) ((layr)->up = (struct _layer_t *)(above))
+
+/** Set the dn pointer for a specified layer.
+ *  @param layr Layer where down pointer shall be set.
+ *  @param below Layer below.
+ */
+#define layer_set_dn(layr, below) ((layr)->dn = (struct _layer_t *)(below))
+
+/**
+ *  Transmit info, passed down-wards in protocol layers.
+ */
+struct _transmt_info {
+  /** Channel ID of the logical CAIF connection.
+   *  Is used by Service Layer to indicate to mux the PHY-layer
+   *  (Physical-ID) to send packet over.
+   */
+	unsigned short channel_id;
+
+  /** Physical ID of the logical physical connection.
+   *  Used by Service Layers to identify their physical id to Caif MUX (CFMUXL)
+   *  so that the MUX can add the
+   *  correct physical Id to the packet.
+   */
+
+	unsigned short phid;
+  /** Header Length, used to align pay load on 32bit boundary.
+   *  Used by SPI Layer (CFSPIL) to align start of pay-load data (IP header
+   *  start) to 16 or 32 bits boundary.
+   *  All layers add the number of header bytes they are using, then SPI
+   *  layer adds padding to get correct alignment.
+   */
+
+	unsigned short hdr_len;
+	/** Packet priority. */
+	unsigned char prio;
+};
+
+/** Packet functions needed by Adaptation layer and PHY layer are exported in
+ *  this structure
+ *
+ */
+struct _caif_packet_funcs_t {
+
+
+  /** Used map from a "native" packet e.g. Linux Socket Buffer to a CAIF packet.
+   *  @param dir - Direction telling if this is an packet to be sent or received
+   *  @param nativepkt	- The native packet to be transformed to a CAIF packe
+   *  @returns the mapped CAIF Packet CFPKT.
+   */
+	cfpkt_t *
+	    (*cfpkt_fromnative)(caif_direction_t dir, void *nativepkt);
+
+  /** Used map from a CAIF packet to a "native" packet e.g. Linux Socket Buffer.
+   *  @param pkt  - The CAIF packet to be transformed to a "native" packet.
+   *  @returns The native packet transformed from a CAIF packet.
+   */
+	void *(*cfpkt_tonative)(cfpkt_t *pkt);
+
+  /** Used by "app" layer to create an outgoing CAIF packet to be sent ou
+   *  of the CAIF Stack.
+   *  @param data - Packet data to copy into the packet. If NULL copying will
+   *		     not take place.
+   *  @param len  - Length of data to copy into the packe
+   *  @returns a new CAIF Packet CFPKT.
+   *  @deprecated Use \b cfpkt_create_pkt (above) instead.
+   */
+	cfpkt_t *
+	    (*cfpkt_create_recv_pkt)(const unsigned char *data,
+				      unsigned int len);
+
+  /** Used by PHY layer to create an incoming CAIF packet to be processed by
+   *  the CAIF Stack.
+   *  @param data - Packet data to copy into the packet. If NULL copying
+   *  will not take place.
+   *  @param len  - Length of data to copy into the packe
+   *  @returns a new CAIF Packet CFPKT.
+   *  @deprecated Use \b cfpkt_create_pkt (above) instead.
+   */
+	cfpkt_t *
+	    (*cfpkt_create_xmit_pkt)(const unsigned char *data,
+				      unsigned int len);
+
+  /** Used to extract data from a CAIF packe
+   *  @param cfpkt	 Packet to extract data from.
+   *  @param buf	 Buffer to hold the data to be extracted from the
+   *			 CAIF packet.
+   *  @param buflen	 Length of the buffer (maximum length of the data to
+   *			 copy into the buffer).
+   *  @param actual_len	 Amount of bytes copied from the packet into the buffer.
+   */
+	void
+	 (*cfpkt_extract)(cfpkt_t *cfpkt, void *buf, unsigned int buflen,
+			   unsigned int *actual_len);
+
+  /** Releases a CAIF Packe
+   *  @param cfpkt	 Packet to destroy.
+   */
+	void
+	 (*cfpkt_destroy)(cfpkt_t *cfpkt);
+
+
+
+/** Append by giving user access to packet buffer
+ * @param pkt Packet to append to
+ * @param buf Buffer inside pkt that user shall copy data into
+ * @param buflen Length of buffer and number of bytes added to packe
+ * @return < 0 on error
+ */
+
+	 int (*cfpkt_raw_append)(cfpkt_t *cfpkt, void **buf,
+				unsigned int buflen);
+
+/** Extract by giving user access to packet buffer
+ * @param pkt Packet to extract from
+ * @param buf Buffer inside pkt that user shall copy data from
+ * @param buflen Length of buffer and number of bytes removed from packe
+ * @return < 0 on error
+ */
+	 int (*cfpkt_raw_extract)(cfpkt_t *cfpkt, void **buf,
+				 unsigned int buflen);
+
+
+  /** Creates a packet queue */
+	cfpktq_t *(*cfpktq_create)(void);
+
+  /** Inserts a packet into the packet queue, packets are ordered by priority.
+   *  If the same priority is used packets are ordered as a FIFO.
+   */
+	void (*cfpkt_queue)(cfpktq_t *pktq, cfpkt_t *pkt,
+			     unsigned short prio);
+
+
+  /** Peek into the first packet in the queue */
+	cfpkt_t *(*cfpkt_qpeek)(cfpktq_t *pktq);
+
+  /** Dequeue a packet from the queue */
+	cfpkt_t *(*cfpkt_dequeue)(cfpktq_t *pktq);
+
+  /** Get length of a packet */
+	uint16(*cfpkt_getlen)(cfpkt_t *pkt);
+
+};
+
+/*! @} */
+
+#endif				/* CAIF_LAYER_H_ */
diff --git a/include/net/caif/generic/cfcnfg.h b/include/net/caif/generic/cfcnfg.h
new file mode 100644
index 0000000..9c3aeb3
--- /dev/null
+++ b/include/net/caif/generic/cfcnfg.h
@@ -0,0 +1,223 @@
+/*
+*      Copyright (C) ST-Ericsson AB 2009
+*
+*      Author: Sjur Brendeland/sjur.brandeland@stericsson.com
+*
+*      License terms: GNU General Public License (GPL), version 2.
+*
+*/
+
+
+
+
+
+
+
+
+#ifndef CFCNFG_H_
+#define CFCNFG_H_
+#include <net/caif/generic/caif_layer.h>
+#include <net/caif/generic/cfctrl.h>
+struct _cfctrl_t;
+struct _cfcnfg_t;
+
+/** CAIF Configuration Layer (CFCNFG)*/
+typedef struct _cfcnfg_t cfcnfg_t;
+
+/*! \addtogroup GenCaifExternal
+ *  Additional documentation for group `GenCaifExternal'
+ *  @{
+ */
+
+
+/** Types of Physical Layers defined in CAIF Stack */
+typedef enum _cfcnfg_phy_type_t {
+	CFPHYTYPE_UNKNOWN = 0,
+	CFPHYTYPE_SERIAL = 1,	/*!< Serial Physical Interface */
+	CFPHYTYPE_SPI = 2,	/*!< SPI Physical Interface */
+	CFPHYTYPE_MSL = 3,	/*!< MSL Physical Interface */
+	CFPHYTYPE_SHM = 4,	/*!< Shared Memory Physical Interface */
+	CFPHYTYPE_LOOP = 5,	/*!< Loopback Physical Interface */
+	_CFPHYTYPE_MAX = 6
+} cfcnfg_phy_type_t;
+
+/** Physical Preference - HW Abstraction */
+typedef enum _cfcnfg_phy_preference_t {
+	/** Default Physical Interface */
+	CFPHYPREF_UNSPECIFIED = 0xa0,
+	/** Default Physical Interface for Low Latency Traffic */
+	CFPHYPREF_LOW_LAT = 0xd0,
+	/** Default Physical Interface for High Bandwidth Traffic */
+	CFPHYPREF_HIGH_BW = 0xe0,
+	/** \b TEST \b ONLY Loop-back Interface Simulating Acc side responses */
+	CFPHYPREF_LOOP = 0x70,
+	/** \b TEST \b ONLY Raw loopback interface */
+	CFPHYPREF_RAW_LOOP = 0x80
+} cfcnfg_phy_preference_t;
+
+/** Types of CAIF Links defined in CAIF Stack
+ * @obsolete
+ */
+typedef enum _cfcnfg_link_type_t {
+	_CF_DECM = 0,		/*!< DECM link - NOT SUPPORTED */
+	CF_VEI = CFCTRL_SRV_VEI,	/*!< VEI link - AT */
+	CF_VIDEO = CFCTRL_SRV_VIDEO,	/*!< Video Link */
+	CF_DEBUG = CFCTRL_SRV_DBG,	/*!< Debug Link */
+	CF_DATAGRAM = CFCTRL_SRV_DATAGRAM,	/*!< Datagram link */
+	CF_RFM = CFCTRL_SRV_RFM,	/*!< RFM link */
+	CF_UTILITY = CFCTRL_SRV_UTIL	/*!< Utility link */
+} cfcnfg_link_type_t;
+
+
+/** Configuration parameters for a physical layer (e.g. Serial) */
+typedef struct cfcnfg_phy_param_t {
+	int foo;
+} cfcnfg_phy_param_t;
+
+/** Configuration information used to setup the CAIF Physical Interface */
+typedef struct cfcnfg_phy_config {
+	/** CAIF Physical Type */
+	cfcnfg_phy_type_t phy_type;
+	/** Instance Number, e.g. Uart Number */
+	uint8 phy_sub_instance;
+	/** Preference LowLatency/HighBandwithd */
+	cfcnfg_phy_preference_t pref;
+	/** Device Name */
+	char name[20];
+	/** Cheksum is used for Interface */
+	bool checksum;
+	/** Configuration param specific for the PHY Type */
+	cfcnfg_phy_param_t param;
+	/** Pointer to layer above */
+	layer_t *up;
+} cfcnfg_phy_config_t;
+
+/** Registration information used to setup the CAIF Physical Interface */
+typedef struct cfcnfg_phy_mgmt {
+	/** Registation of type */
+	cfcnfg_phy_type_t type;
+	/** Creates an instance of the physical layer (e.g. Serial)
+	 * and configures it */
+	layer_t *(*create_phy) (cfcnfg_phy_config_t *config);
+	 /** Delete an instance of the physical layer (e.g. Serial) */
+	int (*delete_phy) (layer_t *l);
+} cfcnfg_phy_mgmt_t;
+
+
+
+
+/**
+ * This variable is used as a global flag in order to set if STX is used on
+ * serial communication.
+ *  NOTE: This is not a fully future proof solution.
+ */
+
+extern int serial_use_stx;
+
+
+/**
+ * Create the CAIF Configuration Object.
+ * \image html CreateCaifConfig.jpg "Create Caif Configuration Object."
+ * @returns the created instance of a CFCNFG object.
+ */
+cfcnfg_t *cfcnfg_create(void);
+
+/**
+ * Adds a physical layer to the CAIF stack.
+ * \image html AddPhyCaifConfig.jpg "Add a PHY layer to CAIF Stack."
+ * @param cnfg Pointer to the Caif Configuration Class, created by
+ *				fcnfg_create().
+ * @param phy_type Specifies the type of physical interface e.g.
+ *		    CFPHYTYPE_SERIAL.
+ * @param phy_layer Specify the physical layer, the transmit function
+ *		    MUST be set in the structure.
+ * @param phyid [out] The assigned physical ID for this layer,
+ *		      used in \ref cfcnfg_add_adapt_layer to specify
+ *		      PHY for the link.
+ */
+
+void
+cfcnfg_add_phy_layer(cfcnfg_t *cnfg, cfcnfg_phy_type_t phy_type,
+		     layer_t *phy_layer, uint16 *phyid,
+		     cfcnfg_phy_preference_t pref);
+
+/**
+ * Deletes a Adaptation Layer from the CAIF Stack.
+ *
+ * @param cnfg Pointer to the CAIF Configuration Class, created by
+ *			   cfcnfg_create().
+ * @param adap_layer Adaptation layer to be removed.
+ * @return true on success, false upon failure.
+ */
+
+bool cfcnfg_del_adapt_layer(struct _cfcnfg_t *cnfg, layer_t *adap_layer);
+
+/**
+ * Adds a Adaptation Layer to the CAIF Stack.
+ * The Adaptation Layer is where the interface to application or higher-level
+ * driver functionality is implemented.
+ * \image html AddVeiCaifConfig.jpg "Add an Adaptation layer to CAIF Stack."
+ *
+ * @param cnfg	     Pointer to the CAIF Configuration Class, created by
+ *		     cfcnfg_create().
+ * @param linktype   Type of link which is set up e.g. CF_AT_PLAIN.
+ * @param connid     Connection ID, used for data-gram links.
+ * @param phyid	     PHY ID received from \ref	cfcnfg_add_phy_layer,
+ *		     specifying the PHY device to use for this link.
+ * @param adap_layer Specify the adaptation layer, the receive
+ *		     and flow-control functions MUST be set in the structure.
+ * @return	     true on success, false upon failure.
+ */
+bool
+cfcnfg_add_adapt_layer(cfcnfg_t *cnfg, cfcnfg_link_type_t linktype,
+		       uint32 connid, uint16 phyid, layer_t *adap_layer);
+
+
+
+/**
+ * Adds a Adaptation Layer to the CAIF Stack.
+ * The Adaptation Layer is where the interface to application or higher-level
+ * driver functionality is implemented.
+ * \image html AddVeiCaifConfig.jpg "Add an Adaptation layer to CAIF Stack."
+ *
+ * @param cnfg			Pointer to the CAIF Configuration Class, created by
+ *						cfcnfg_create().
+ * @param param			Link setup parameters.
+ * @param adap_layer	Specify the adaptation layer, the receive and flow-control functions MUST be set in the structure.
+ * @return				true on success, false upon failure.
+ */
+bool
+cfcnfg_add_adaptation_layer(cfcnfg_t *cnfg, cfctrl_link_param_t *param,
+			    layer_t *adap_layer);
+
+
+/**
+ * Returns a handle to the Packet Functions used to create packets with
+ * content, and extract information from packets.
+ */
+caif_packet_funcs_t cfcnfg_get_packet_funcs(void);
+
+/** Get Physical Id given type.
+ * @return Returns one of the physical interfaces matching the given type.
+ *	   Zero if no match is found.
+ */
+int cfcnfg_get_phyid(cfcnfg_t *cnfg, cfcnfg_phy_preference_t phy_pref);
+
+
+/** Get Physical Id given name.
+ * @return Returns the physical interface matching the specified name.
+ */
+int cfcnfg_get_named(cfcnfg_t *cnfg, char *name);
+
+int cfcnfg_instanciate(cfcnfg_t *cnfg, cfcnfg_phy_config_t *phy_config);
+int cfcnfg_instanciate2(cfcnfg_t *cnfg, cfcnfg_phy_type_t phy_type,
+			uint8 instance, char *name, bool checksum,
+			cfcnfg_phy_preference_t pref,
+			cfcnfg_phy_param_t *param);
+int cfcnfg_delete_phy_inst(cfcnfg_t *cfg, char *name);
+int cfcnfg_unregister_phy_type(cfcnfg_t *cfg, cfcnfg_phy_type_t type);
+int cfcnfg_register_phy_type(cfcnfg_t *cfg, cfcnfg_phy_mgmt_t *mgmt);
+int cfcnfg_del_phy_layer(struct _cfcnfg_t *cnfg, layer_t *phy_layer);
+
+/*! @} */
+#endif				/* CFCNFG_H_ */
diff --git a/include/net/caif/generic/cfctrl.h b/include/net/caif/generic/cfctrl.h
new file mode 100644
index 0000000..e9444ea
--- /dev/null
+++ b/include/net/caif/generic/cfctrl.h
@@ -0,0 +1,139 @@
+/*
+*      Copyright (C) ST-Ericsson AB 2009
+*
+*      Author: Sjur Brendeland/sjur.brandeland@stericsson.com
+*
+*      License terms: GNU General Public License (GPL), version 2.
+*
+*/
+
+
+
+
+
+
+
+#ifndef CFCTRL_H_
+#define CFCTRL_H_
+#include <net/caif/generic/caif_layer.h>
+#include <net/caif/generic/cfsrvl.h>
+
+
+/* CAIF Control packet commands*/
+typedef enum {
+	CFCTRL_CMD_LINK_SETUP = 0,
+	CFCTRL_CMD_LINK_DESTROY = 1,
+	CFCTRL_CMD_LINK_ERR = 2,
+	CFCTRL_CMD_ENUM = 3,
+	CFCTRL_CMD_SLEEP = 4,
+	CFCTRL_CMD_WAKE = 5,
+	CFCTRL_CMD_LINK_RECONF = 6,
+	CFCTRL_CMD_START_REASON = 7,
+	CFCTRL_CMD_RADIO_SET = 8,
+	CFCTRL_CMD_MODEM_SET = 9,
+	CFCTRL_CMD_DATA = 0,
+	CFCTRL_CMD_MASK = 0xf
+} cfctrl_cmd_t;
+
+typedef enum {
+	CFCTRL_SRV_DECM = 0,
+	CFCTRL_SRV_VEI = 1,
+	CFCTRL_SRV_VIDEO = 2,
+	CFCTRL_SRV_DBG = 3,
+	CFCTRL_SRV_DATAGRAM = 4,
+	CFCTRL_SRV_RFM = 5,
+	CFCTRL_SRV_UTIL = 6,
+	CFCTRL_SRV_MASK = 0xf
+} cfctrl_srv_t;
+
+#define CFCTRL_RSP_BIT 0x20
+#define CFCTRL_ERR_BIT 0x10
+typedef void
+ (*cfctrl_rspcp_t) (void);
+
+
+
+typedef void
+ (*cfctrl_linkdestroy_rspcb_t) (layer_t *layer, uint8 linkid,
+				layer_t *client_layer);
+
+typedef void
+ (*cfctrl_linksetup_rspcb_t) (layer_t *layer, uint8 linkid,
+			      cfctrl_srv_t serv, uint8 phyid,
+			      layer_t *adapt_layer);
+
+typedef struct _cfctrl_rsp_t {
+	cfctrl_linksetup_rspcb_t linksetup_rsp;
+	cfctrl_linkdestroy_rspcb_t linkdestroy_rsp;
+	cfctrl_rspcp_t linkerror_ind;
+	cfctrl_rspcp_t enum_rsp;
+	cfctrl_rspcp_t sleep_rsp;
+	cfctrl_rspcp_t wake_rsp;
+	cfctrl_rspcp_t restart_rsp;
+	cfctrl_rspcp_t radioset_rsp;
+	cfctrl_linkdestroy_rspcb_t reject_rsp;
+} cfctrl_rsp_t;
+
+/** Link Setup Parameters for CAIF-Links. */
+typedef struct _cfctrl_link_param_t {
+	cfctrl_srv_t linktype;/*!< (T3,T0) Type of Channel */
+	uint8 priority;		  /*!< (P4,P0) Priority of the channel */
+	uint8 phyid;		  /*!< (U2-U0) Physical interface to connect */
+	uint8 endpoint;		  /*!< (E1,E0) Endpoint for data channels */
+	uint8 chtype;		  /*!< (H1,H0) Channel-Type,
+					       applies to VEI, DEBUG */
+	union {
+		struct {
+			uint8 connid;	/*!<  (D7,D0) Video LinkId */
+		} video;
+
+		struct {
+			uint32 connid;	/*!< (N31,Ngit0) Connection ID used
+					 *		  for Datagram */
+		} datagram;
+
+		struct {
+			uint32 connid;	/*!< Connection ID used for RFM */
+			char volume[20];	/*!< Volume to mount for RFM */
+		} rfm;		/*!< Configuration for RFM */
+
+		struct {
+			uint16 fifosize_kb;	/*!< Psock FIFO size in KB */
+			uint16 fifosize_bufs;	/*!< Psock # signal buffers */
+			char name[16];	/*!< Name of the PSOCK service */
+			uint8 params[255];	/*!< Link setup Parameters> */
+			uint16 paramlen;	/*!< Length of Link Setup
+						 *    Parameters */
+		} utility;	/*!< Configuration for Utility Links (Psock) */
+	} u;
+} cfctrl_link_param_t;
+
+/** This structure is used internally in CFCTRL */
+struct cfctrl_request_info {
+	int sequence_no;
+	cfctrl_cmd_t cmd;
+	uint8 channel_id;
+	cfctrl_link_param_t param;
+	struct cfctrl_request_info *next;
+	layer_t *client_layer;
+};
+
+
+void cfctrl_enum_req(layer_t *cfctrl, uint8 physlinkid);
+
+
+
+void cfctrl_linkup_request(layer_t *cfctrl, cfctrl_link_param_t *param,
+			   layer_t *user_layer);
+
+
+void cfctrl_linkdown_req(layer_t *cfctrl, uint8 linkid, layer_t *client);
+void cfctrl_sleep_req(layer_t *cfctrl);
+void cfctrl_wake_req(layer_t *cfctrl);
+void cfctrl_getstartreason_req(layer_t *cfctrl);
+
+layer_t *cfctrl_create(void);
+void cfctrl_set_dnlayer(layer_t *this, layer_t *dn);
+void cfctrl_set_uplayer(layer_t *this, layer_t *up);
+void cfctrl_set_respfuncs(layer_t *this, cfctrl_rsp_t *respfuncs);
+#endif				/* CFCTRL_H_ */
diff --git a/include/net/caif/generic/cffrml.h b/include/net/caif/generic/cffrml.h
new file mode 100644
index 0000000..35e2e8a
--- /dev/null
+++ b/include/net/caif/generic/cffrml.h
@@ -0,0 +1,29 @@
+/*
+*      Copyright (C) ST-Ericsson AB 2009
+*
+*      Author: Sjur Brendeland/sjur.brandeland@stericsson.com
+*
+*      License terms: GNU General Public License (GPL), version 2.
+*
+*/
+
+
+
+
+
+
+
+#ifndef CFFRM_H_
+#define CFFRM_H_
+#include <net/caif/generic/cfglue.h>
+#include <net/caif/generic/caif_layer.h>
+#include <net/caif/generic/cflst.h>
+
+struct _cffrml_t;
+typedef struct _cffrml_t cffrml_t;
+layer_t *cffrml_create(uint16 phyid, bool DoFCS);
+void cffrml_set_uplayer(layer_t *this, layer_t *up);
+void cffrml_set_dnlayer(layer_t *this, layer_t *dn);
+void cffrml_destroy(layer_t *layer);
+
+#endif				/* CFFRM_H_ */
diff --git a/include/net/caif/generic/cfglue.h b/include/net/caif/generic/cfglue.h
new file mode 100644
index 0000000..0930309
--- /dev/null
+++ b/include/net/caif/generic/cfglue.h
@@ -0,0 +1,206 @@
+/*
+ *      Copyright (C) ST-Ericsson AB 2009
+ *
+ *      Author: Sjur Brendeland/sjur.brandeland@stericsson.com
+ *
+ *      License terms: GNU General Public License (GPL), version 2.
+ *
+ */
+
+/*
+ *    Description: This file contains the OS and HW dependencies for CAIF.
+ */
+
+
+#ifndef CFGLU_H_
+#define CFGLU_H_
+
+/*! \addtogroup GenCaifGlue
+ *  Additional documentation for group `GenCaifGlue'
+ *  @{
+ */
+
+
+#define CFLOG_LEVEL_ERROR   1
+#define CFLOG_LEVEL_WARNING 2
+#define CFLOG_LEVEL_TRACE   3
+#define CFLOG_LEVEL_TRACE2  4
+#define CFLOG_LEVEL_TRACE3  5
+#define CFLOG_LEVEL_FUNC    6
+
+
+#include <linux/string.h>
+#include <linux/slab.h>
+#include <linux/spinlock.h>
+#include <linux/kernel.h>
+#include "linux/stddef.h"
+#include "linux/types.h"
+
+
+/** Unsigned 8 bit */
+typedef __u8 uint8;
+
+/** Unsigned 16 bit */
+typedef __u16 uint16;
+
+/** Unsigned 32 bit */
+typedef __u32 uint32;
+
+
+/******************************************
+ *  HANDLING ENDIANNES.
+ *  CAIF uses little-endian byte order.
+ ******************************************/
+
+/** CAIF Endian handling Net to Host of 16 bits unsigned */
+#define cfglu_le16_to_cpu(v)  le16_to_cpu(v)
+
+/** CAIF Endian handling Host to Net of 16 bits unsigned */
+#define cfglu_cpu_to_le16(v)  cpu_to_le16(v)
+
+/** CAIF Endian handling Host to Net of 32 bits unsigned */
+#define cfglu_le32_to_cpu(v)  le32_to_cpu(v)
+
+/** CAIF Endian handling Net to Host of 32 bits unsigned */
+#define cfglu_cpu_to_le32(v)  cpu_to_le32(v)
+
+extern int caif_dbg_level;
+
+
+/* LOGGING */
+
+#define _CFLOG_FATAL(format, args...) \
+	do {if (caif_dbg_level > CFLOG_LEVEL_ERROR) {\
+		printk(KERN_ERR "<%s:%d, FATAL> " format "\n",\
+				__func__, __LINE__ ,  ## args); } } while (0)
+
+#define CFLOG_FATAL(format) _CFLOG_FATAL format
+
+/** CAIF Error Logging. */
+#define _CFLOG_ERROR(format, args...)\
+	do {if (caif_dbg_level > CFLOG_LEVEL_ERROR) {\
+		printk(KERN_ERR "<%s:%d, ERROR> " format "\n",\
+				__func__, __LINE__ ,  ## args); } }  while (0)
+
+#define CFLOG_ERROR(format)  _CFLOG_ERROR format
+
+/** CAIF Warning Logging. */
+#define _CFLOG_WARN(format, args...)\
+	do {if (caif_dbg_level > CFLOG_LEVEL_WARNING) {\
+		printk(KERN_WARNING "<%s:%d, WARN> "  format "\n",\
+				__func__, __LINE__ ,  ## args); } }  while (0)
+
+#ifdef CAIF_DEBUG_ON
+#define CFLOG_WARN(format)   _CFLOG_WARN format
+
+/** CAIF Trace Control Logging. Level 1 control trace (Channel setup etc) */
+#define _CFLOG_TRACE(format, args...)  \
+	do { if (caif_dbg_level > CFLOG_LEVEL_TRACE) {\
+		printk(KERN_INFO "<%s:%d, TRACE> " format, \
+				__func__, __LINE__ ,  ## args); } }  while (0)
+
+#define CFLOG_TRACE(format)  _CFLOG_TRACE format
+
+/** CAIF Trace Payload Logging. Level payload trace */
+#define _CFLOG_TRACE2(format, args...) \
+	do {if (caif_dbg_level > CFLOG_LEVEL_TRACE2) {\
+		printk(KERN_INFO "<%s:%d, TRACE2> " format, \
+				__func__, __LINE__ ,  ## args); } }  while (0)
+
+#define CFLOG_TRACE2(format) _CFLOG_TRACE2 format
+
+/** CAIF Trace Detailed Logging including packet dumps */
+#define _CFLOG_TRACE3(format, args...)\
+	do {if (caif_dbg_level > CFLOG_LEVEL_TRACE3) {\
+		printk(KERN_INFO "<%s:%d, TRACE3> " format, \
+				__func__, __LINE__ ,  ## args); } }  while (0)
+
+#define CFLOG_TRACE3(format) _CFLOG_TRACE3 format
+
+/** CAIF Trace Entering Function */
+#define _CFLOG_ENTER(format, args...) \
+	do {if (caif_dbg_level > CFLOG_LEVEL_FUNC) {\
+		printk("KERN_INFO <%s:%d, ENTER> " format, \
+				__func__, __LINE__ ,  ## args); } }  while (0)
+#define CFLOG_ENTER(format)  _CFLOG_ENTER format
+
+/** CAIF Trace Exiting Function */
+
+#define _CFLOG_EXIT(format, args...)  \
+	do {if (caif_dbg_level > CFLOG_LEVEL_FUNC) {\
+		printk("KERN_INFO <%s:%d, EXIT> "  format "\n",\
+				__func__, __LINE__ ,  ## args); } }  while (0)
+#define CFLOG_EXIT(format)   _CFLOG_EXIT format
+
+#else
+
+#define CFLOG_WARN(args)
+#define CFLOG_TRACE(args)
+#define CFLOG_TRACE2(args)
+#define CFLOG_TRACE3(args)
+#define CFLOG_ENTER(args)
+#define CFLOG_EXIT(args)
+
+#endif
+
+
+
+
+
+/* Critical Section support, one thread only between startsync
+ * and endsync */
+#define cfglu_lock_t spinlock_t
+#define cfglu_init_lock(sync) spin_lock_init(&(sync))
+#define cfglu_lock(sync) spin_lock(&(sync))
+#define cfglu_unlock(sync) spin_unlock(&(sync))
+#define cfglu_deinit_lock(sync)
+
+/* Read/Write lock, allows multiple readers, one writer */
+#define cfglu_rwlock_t rwlock_t
+#define cfglu_init_rwlock(rwlock) rwlock_init(&(rwlock))
+#define cfglu_deinit_rwlock(rwlock)
+#define cfglu_read_lock(rwlock)   read_lock(&rwlock)
+#define cfglu_read_unlock(rwlock) read_unlock(&rwlock)
+#define cfglu_write_lock(rwlock)    write_lock(&rwlock)
+#define cfglu_write_unlock(rwlock)  write_unlock(&rwlock)
+
+
+
+/* Atomic counting */
+#define cfglu_atomic_t atomic_t
+#define cfglu_atomic_read(a) atomic_read(&a)
+#define cfglu_atomic_set(a, val) atomic_set(&a, val)
+#define cfglu_atomic_inc(a) atomic_inc(&a)
+#define cfglu_atomic_dec(a) atomic_dec(&a)
+
+/* HEAP */
+#define cfglu_alloc(size) kmalloc(size, GFP_KERNEL)
+#define cfglu_free(ptr) kfree(ptr)
+
+/* ASSERT */
+#define cfglu_assert(exp) BUG_ON(!(exp))
+
+
+#define cfglu_container_of(p, t, m) container_of(p, t, m)
+
+/*FIXME: Comment error codes*/
+enum cfglu_errno {
+	CFGLU_EOK = 0,
+	CFGLU_EPKT = -EPROTO,
+	CFGLU_EADDRINUSE = -EADDRINUSE,
+	CFGLU_EIO = -EIO,
+	CFGLU_EFCS = -EILSEQ,
+	CFGLU_EBADPARAM = -EINVAL,
+	CFGLU_EINVAL = -EINVAL,
+	CFGLU_ENODEV = -ENODEV,
+	CFGLU_ENOTCONN = -ENOTCONN,
+	CFGLU_EPROTO = -EPROTO,
+	CFGLU_EOVERFLOW = -EOVERFLOW,
+	CFGLU_ENOMEM = -ENOMEM,
+	CFGLU_ERETRY = -EAGAIN,
+	CFGLU_ENOSPC = -ENOSPC,
+	CFGLU_ENXIO = -ENXIO
+
+};
+
+#endif				/* CFGLU_H_ */
diff --git a/include/net/caif/generic/cfloopcfg.h b/include/net/caif/generic/cfloopcfg.h
new file mode 100644
index 0000000..a041f49
--- /dev/null
+++ b/include/net/caif/generic/cfloopcfg.h
@@ -0,0 +1,28 @@
+/*
+*      Copyright (C) ST-Ericsson AB 2009
+*
+*      Author: Sjur Brendeland/sjur.brandeland@stericsson.com
+*
+*      License terms: GNU General Public License (GPL), version 2.
+*
+*/
+
+
+
+
+
+
+
+#ifndef CFLOOPCFG_H_
+#define CFLOOPCFG_H_
+#include <net/caif/generic/caif_layer.h>
+struct _cfloopcfg_t {
+	layer_t *loop;
+};
+typedef struct _cfloopcfg_t cfloopcfg_t;
+cfloopcfg_t *cfloopcfg_create(void);
+void cfloopcfg_add_phy_layer(cfloopcfg_t *cnfg,
+			     cfcnfg_phy_type_t phy_type,
+			     layer_t *phy_layer);
+
+#endif				/* CFLOOPCFG_H_ */
diff --git a/include/net/caif/generic/cflst.h b/include/net/caif/generic/cflst.h
new file mode 100644
index 0000000..073fa22
--- /dev/null
+++ b/include/net/caif/generic/cflst.h
@@ -0,0 +1,27 @@
+/*
+*      Copyright (C) ST-Ericsson AB 2009
+*
+*      Author: Sjur Brendeland/sjur.brandeland@stericsson.com
+*
+*      License terms: GNU General Public License (GPL), version 2.
+*
+*/
+
+
+
+
+
+
+
+#ifndef CFLST_H_
+#define CFLST_H_
+
+#include <net/caif/generic/cfglue.h>
+bool cflst_put(layer_t **lst, uint8 id, layer_t *node);
+layer_t *cflst_get(layer_t **lst, uint8 id);
+layer_t *cflst_del(layer_t **lst, uint8 id);
+#define CFLST_FIRST(lst) lst
+#define CFLST_MORE(node) ((node) != NULL)
+#define CFLST_NEXT(node) ((node)->next)
+void cflst_init(layer_t **lst);
+#endif				/* CFLST_H_ */
diff --git a/include/net/caif/generic/cfmsll.h b/include/net/caif/generic/cfmsll.h
new file mode 100644
index 0000000..ad207c2
--- /dev/null
+++ b/include/net/caif/generic/cfmsll.h
@@ -0,0 +1,22 @@
+/*
+*      Copyright (C) ST-Ericsson AB 2009
+*
+*      Author: Sjur Brendeland/sjur.brandeland@stericsson.com
+*
+*      License terms: GNU General Public License (GPL), version 2.
+*
+*/
+
+
+
+
+
+
+
+#ifndef CFMSLL_H_
+#define CFMSLL_H_
+#include <net/caif/generic/caif_layer.h>
+#include <net/caif/generic/cfglue.h>
+layer_t *cfmsll_create(int type, int instance);
+
+#endif				/* CFMSLL_H_ */
diff --git a/include/net/caif/generic/cfmuxl.h b/include/net/caif/generic/cfmuxl.h
new file mode 100644
index 0000000..06747d3
--- /dev/null
+++ b/include/net/caif/generic/cfmuxl.h
@@ -0,0 +1,30 @@
+/*
+*      Copyright (C) ST-Ericsson AB 2009
+*
+*      Author: Sjur Brendeland/sjur.brandeland@stericsson.com
+*
+*      License terms: GNU General Public License (GPL), version 2.
+*
+*/
+
+
+
+
+
+
+
+#ifndef CFMUXL_H_
+#define CFMUXL_H_
+#include <net/caif/generic/caif_layer.h>
+struct _cfsrvl_t;
+struct _cffrml_t;
+
+layer_t *cfmuxl_create(void);
+bool cfmuxl_set_uplayer(layer_t *layr, layer_t *up, uint8 linkid);
+layer_t *cfmuxl_remove_dnlayer(layer_t *layr, uint8 phyid);
+bool cfmuxl_set_dnlayer(layer_t *layr, layer_t *up, uint8 phyid);
+layer_t *cfmuxl_remove_uplayer(layer_t *layr, uint8 linkid);
+bool cfmuxl_is_phy_inuse(layer_t *layr, uint8 phyid);
+uint8 cfmuxl_get_phyid(layer_t *layr, uint8 channel_id);
+
+#endif				/* CFMUXL_H_ */
diff --git a/include/net/caif/generic/cfpkt.h b/include/net/caif/generic/cfpkt.h
new file mode 100644
index 0000000..d8079c8
--- /dev/null
+++ b/include/net/caif/generic/cfpkt.h
@@ -0,0 +1,246 @@
+/*
+*      Copyright (C) ST-Ericsson AB 2009
+*
+*      Author: Sjur Brendeland/sjur.brandeland@stericsson.com
+*
+*      License terms: GNU General Public License (GPL), version 2.
+*
+*/
+
+
+
+
+
+
+
+#ifndef CFPKT_H_
+#define CFPKT_H_
+#include <net/caif/generic/caif_layer.h>
+
+
+struct _cfpkt_t;
+/*! \addtogroup GenCaifGlue
+ *  Additional documentation for group `GenCaifGlue'
+ *  @{
+ */
+
+/** Checksum iteration function used to iterate buffers
+ * (we may have packets consisting of a chain of buffers)
+ * @param chs Checksum calculated so far.
+ * @param buf pointer to the buffer to checksum
+ * @param len length of buf.
+ * @return checksum of buffer
+ */
+typedef uint16(*iterfunc_t)(uint16 chks, void *buf, uint16 len);
+
+caif_packet_funcs_t caif_get_packet_funcs(void);
+/** Create a Caif packet.
+ * @param len Length of packet to be created
+ * @returns new packet.
+ */
+cfpkt_t *cfpkt_create(uint16 len);
+/**
+ * Destroy a CAIF Packet.
+ * @param pkt Packet to be destoyed.
+ */
+void cfpkt_destroy(cfpkt_t *pkt);
+
+/**
+ * Extract header from packet.
+ *  \image html ExtractCaifPacketHeader.jpg "Extract Caif Packet Header"
+ *
+ * @param pkt Packet to extract header data from.
+ * @param data pointer to copy the header data into.
+ * @param len length of head data to copy.
+ * @return \ref true on success \ref false on failure
+ */
+bool cfpkt_extr_head(cfpkt_t *pkt, void *data, uint16 len);
+
+/**
+ * Peek header from packet.
+ * Reads data from packet without changing packet.
+ *
+ * @param pkt Packet to extract header data from.
+ * @param data pointer to copy the header data into.
+ * @param len length of head data to copy.
+ * @return \ref true on success \ref false on failure
+ */
+bool cfpkt_peek_head(cfpkt_t *pkt, void *data, uint16 len);
+
+/**
+ * Extract header from trailer (end of packet).
+ *  \image html ExtractCaifPacketTrailer.jpg "Extract Caif Packet Trailer"
+ *
+ * @param pkt Packet to extract header data from.
+ * @param data pointer to copy the trailer data into.
+ * @param len length of head data to copy.
+ * @return \ref true on success \ref false on failure
+ */
+bool cfpkt_extr_trail(cfpkt_t *pkt, void *data, uint16 len);
+/**
+ * Add header to packet.
+ *
+ *
+ * @param pkt Packet to add header data to.
+ * @param data pointer to copy into the header.
+ * @param len length of head data to copy.
+ * @return \ref true on success \ref false on failure
+ */
+bool cfpkt_add_head(cfpkt_t *pkt, const void *data, uint16 len);
+
+/**
+ * Add trailer to packet.
+ *
+ *
+ * @param pkt Packet to add trailer data from.
+ * @param data pointer to copy into the trailer.
+ * @param len length of head data to copy.
+ * @return \ref true on success \ref false on failure
+ */
+bool cfpkt_add_trail(cfpkt_t *pkt, const void *data, uint16 len);
+
+/**
+ * Pad trailer on packet.
+ * Moves data pointer in packet, no content copied.
+ *
+ * @param pkt Packet to add trailer data from.
+ * @param data pointer to copy into the trailer.
+ * @param len length of head data to copy.
+ * @return \ref true on success \ref false on failure
+ */
+bool cfpkt_pad_trail(cfpkt_t *pkt, uint16 len);
+
+/**
+ * Add a single byte to packet body (tail).
+ */
+
+bool cfpkt_addbdy(cfpkt_t *pkt, const uint8 data);
+
+/**
+ * Add a data to packet body (tail).
+ */
+bool cfpkt_add_body(cfpkt_t *pkt, const void *data, uint16 len);
+
+/**
+ * Checks if there is more data to process in packet.
+ * @param pkt Packet to check.
+ * @return \ref true on if more data is available in packet \ref false if no more data can be extracted
+ */
+bool cfpkt_more(cfpkt_t *pkt);
+/**
+ * Checks if the packet is erroneous, i.e. if it has been attempted to extract more data than available in packet
+ * or writing more data than has been allocated in \ref cfpkt_create().
+ * @param pkt Packet to check.
+ * @return \ref true on error \ref false otherwise
+ */
+bool cfpkt_erroneous(cfpkt_t *pkt);
+
+/**
+ * Get the packet length.
+ * @param pkt Packet to get lenght from.
+ * @return number of bytes in packet.
+ */
+uint16 cfpkt_getlen(cfpkt_t *pkt);
+
+/**
+ * Set the packet length, by adjusting the tailer pointer according to length.
+ * @param pkt Packet to set lenght.
+ * @param len Packet length.
+ * @return number of bytes in packet.
+ */
+int cfpkt_setlen(cfpkt_t *pkt, uint16 len);
+
+/**
+ * Appends a packet's data to another packet.
+ * NB: Input packets will be destroyed after appending and cannot be used
+ * after calling this function.
+ * @param dstpkt Packet to append data into, WILL BE FREED BY THIS FUNCTION
+ * @param addpkt Packet to be appended and automatically released, WILL BE FREED BY THIS FUNCTION.
+ * @param expectlen Packet's expected total length, this should be considered a hint.
+ * @returns the new appended packet.
+ */
+cfpkt_t *cfpkt_append(cfpkt_t *dstpkt, cfpkt_t *addpkt,
+		      uint16 expectlen);
+/**
+ * Split a packet into two packet at the specified split point.
+ * @param pkt Packet to be split
+ * @param pos Position to split packet in two part.
+ */
+cfpkt_t *cfpkt_split(cfpkt_t *pkt, uint16 pos);
+
+/** Iteration function, iterates the packet buffers from start to end*/
+uint16 cfpkt_iterate(cfpkt_t *pkt, iterfunc_t func, uint16 data);
+
+void
+cfpkt_extract(cfpkt_t *cfpkt, void *buf, unsigned int buflen,
+	      unsigned int *actual_len);
+
+/** Append by giving user access to packet buffer
+ * @param pkt Packet to append to
+ * @param buf Buffer inside pkt that user shall copy data into
+ * @param buflen Length of buffer and number of bytes added to packet
+ * @return 0 on error, 1 on success
+ */
+
+int cfpkt_raw_append(cfpkt_t *cfpkt, void **buf, unsigned int buflen);
+
+/** Extract by giving user access to packet buffer
+ * @param pkt Packet to extract from
+ * @param buf Buffer inside pkt that user shall copy data from
+ * @param buflen Length of buffer and number of bytes removed from packet
+ * @return 0 on error, 1 on success
+ */
+int cfpkt_raw_extract(cfpkt_t *cfpkt, void **buf, unsigned int buflen);
+
+
+
+/** Used map from a "native" packet e.g. Linux Socket Buffer to a CAIF packet.
+ *  @param dir - Direction telling if this is an packet to be sent or received.
+ *  @param nativepkt  - The native packet to be transformed to a CAIF packet
+ *  @returns the mapped CAIF Packet CFPKT.
+ */
+cfpkt_t *cfpkt_fromnative(caif_direction_t dir, void *nativepkt);
+
+/** Used map from a CAIF packet to a "native" packet e.g. Linux Socket Buffer.
+ *  @param pkt  - The CAIF packet to be transformed to a "native" packet.
+ *  @returns The native packet transformed from a CAIF packet.
+ */
+void *cfpkt_tonative(cfpkt_t *pkt);
+
+
+caif_packet_funcs_t cfpkt_get_packet_funcs(void);
+
+/**
+ * Insert a packet in the packet queue.
+ * @param pkt Packet to be inserted in queue
+ * @param pktq Packet queue to insert into
+ * @param prio Priority of packet
+ */
+void cfpkt_queue(cfpktq_t *pktq, cfpkt_t *pkt, unsigned short prio);
+
+/**
+ * Remove a packet from the packet queue.
+ * @param pktq Packet queue to fetch packets from.
+ * @returns dequeued packet.
+ */
+cfpkt_t *cfpkt_dequeue(cfpktq_t *pktq);
+
+/**
+ * Peek into a packet from the packet queue.
+ * @param pktq Packet queue to fetch packets from.
+ * @returns peek'ed packet.
+ */
+cfpkt_t *cfpkt_qpeek(cfpktq_t *pktq);
+
+/**
+ * Initiates the packet queue.
+ * @param pktq Packet queue to fetch packets from.
+ */
+cfpktq_t *cfpkt_queuecreate(void);
+
+/** Put content of packet into buffer for debuging purposes */
+char *cfpkt_log_pkt(cfpkt_t *pkt, char *buf, int buflen);
+
+
+/*! @} */
+#endif				/* CFPKT_H_ */
diff --git a/include/net/caif/generic/cfserl.h b/include/net/caif/generic/cfserl.h
new file mode 100644
index 0000000..e93500d
--- /dev/null
+++ b/include/net/caif/generic/cfserl.h
@@ -0,0 +1,22 @@
+/*
+*      Copyright (C) ST-Ericsson AB 2009
+*
+*      Author: Sjur Brendeland/sjur.brandeland@stericsson.com
+*
+*      License terms: GNU General Public License (GPL), version 2.
+*
+*/
+
+
+
+
+
+
+
+#ifndef CFSERL_H_
+#define CFSERL_H_
+#include <net/caif/generic/caif_layer.h>
+#include <net/caif/generic/cfglue.h>
+layer_t *cfserl_create(int type, int instance, bool use_stx);
+
+#endif				/* CFSERL_H_ */
diff --git a/include/net/caif/generic/cfshml.h b/include/net/caif/generic/cfshml.h
new file mode 100644
index 0000000..d7e0247
--- /dev/null
+++ b/include/net/caif/generic/cfshml.h
@@ -0,0 +1,21 @@
+/*
+*      Copyright (C) ST-Ericsson AB 2009
+*
+*      Author: Sjur Brendeland/sjur.brandeland@stericsson.com
+*
+*      License terms: GNU General Public License (GPL), version 2.
+*
+*/
+
+
+
+
+
+
+
+#ifndef CFSHML_H_
+#define CFSHML_H_
+
+layer_t *cfshml_create(int type, int instance);
+
+#endif				/* CFSHML_H_ */
diff --git a/include/net/caif/generic/cfspil.h b/include/net/caif/generic/cfspil.h
new file mode 100644
index 0000000..293e2b5
--- /dev/null
+++ b/include/net/caif/generic/cfspil.h
@@ -0,0 +1,80 @@
+/*
+*      Copyright (C) ST-Ericsson AB 2009
+*
+*      Author: Sjur Brendeland/sjur.brandeland@stericsson.com
+*
+*      License terms: GNU General Public License (GPL), version 2.
+*
+*/
+
+
+
+
+
+
+
+#ifndef CFSPIL_H_
+#define CFSPIL_H_
+#include <net/caif/generic/cfpkt.h>
+#define CAIF_MAX_SPI_FRAME 4096
+
+/* Forward declaration */
+struct _cfspil_t;
+
+typedef struct _cfspil_t cfspil_t;
+
+/** @page SPI PHY Layer description.
+ *
+ *  SPI Physical layer is not implemented in GenCaif. The SPI PHY Layer
+ *  is HW dependent. But the CFSPIL (Caif SPI Layer) provides support for
+ *  implementing the SPI Layer Protocol.
+ *
+ *  SPI PHY uses a different paradigm for transmit than the rest of GenCaif.
+ *  SPI PHY is pulling packets from CFSPIL. The SPI-PHY get a notification
+ *  about a transfer, and then request transfer length, and data to transfer
+ *  in the following way:
+ * \image html caif-spi.jpg "CAIF SPI Flow"
+ *
+ *  -# Wait for transmit request (packet will be \b null pointer) indicating
+ *     GenCaif want something to be sent to the modem.
+ *  -# Request the transfer length by using function \ref cfspil_xmitlen,
+ *  -# Add Caif SPI Command to SPI transfer.
+ *  -# When SPI is ready for transfer, call \ref cfspil_getxmitpkt to get
+ *      the transfer packet.
+ *  -# Request new transfer length ( \ref cfspil_xmitlen) unless zero
+ *     length is returned.
+ *  -# Wait for next transfer request.
+ *
+ *
+ *   * CFSPIL Specification:
+ * \see { GenCaifSPI }
+ *
+ */
+/*! \addtogroup GenCaifSPI
+ *  Additional documentation for group `GenCaifSPI'
+ *  @{
+ */
+
+/** SPI-Layer
+ * Create and initializes SPI layer.
+ */
+layer_t *cfspil_create(int type, int instance);
+
+/**
+ *  Check the length of the next SPI frame to send.
+ *  @param layr Pointer to SPI layer
+ *  @return Length of next SPI transfer, 0 if nothink to  send.
+ */
+int cfspil_xmitlen(cfspil_t *layr);
+
+/**
+ *  Get the next CAIF SPI frame to send. This packet is guaranteed to have equal size to the
+ *  length given in \ref cfspil_getxmitpkt.
+ *  @param layr Pointer to SPI layer
+ *  @return The CAIF Packet to be sent.
+ */
+cfpkt_t *cfspil_getxmitpkt(cfspil_t *layr);
+
+/*! @} */
+
+#endif				/* CFSPIL_H_ */
diff --git a/include/net/caif/generic/cfsrvl.h b/include/net/caif/generic/cfsrvl.h
new file mode 100644
index 0000000..bf25671
--- /dev/null
+++ b/include/net/caif/generic/cfsrvl.h
@@ -0,0 +1,48 @@
+/*
+*      Copyright (C) ST-Ericsson AB 2009
+*
+*      Author: Sjur Brendeland/sjur.brandeland@stericsson.com
+*
+*      License terms: GNU General Public License (GPL), version 2.
+*
+*/
+
+
+
+
+
+
+
+#ifndef CFSRVL_H_
+#define CFSRVL_H_
+#include <net/caif/generic/cflst.h>
+#include <net/caif/generic/cfglue.h>
+#include <stddef.h>
+
+
+
+typedef struct _cfsrvl_t {
+	layer_t layer;
+	/** Physical ID of the logical physical connection */
+	uint8 phid;
+	bool open;
+	bool phy_flow_on;
+	bool modem_flow_on;
+} cfsrvl_t;
+
+layer_t *cfvei_create(uint8 linkid, uint8 phyid);
+layer_t *cfdgml_create(uint8 linkid, uint8 phyid);
+
+layer_t *cfutill_create(uint8 linkid, uint8 phyid);
+layer_t *cfvidl_create(uint8 linkid, uint8 phyid);
+layer_t *cfrfml_create(uint8 linkid, uint8 phyid);
+bool cfsrvl_phyid_match(layer_t *layer, int phyid);
+void cfservl_destroy(layer_t *layer);
+
+
+void cfsrvl_init(cfsrvl_t *service, uint8 channel_id, uint8 phyid);
+bool cfsrvl_ready(cfsrvl_t *service, int *err);
+uint8 cfsrvl_getphyid(layer_t *layer);
+
+
+#endif				/* CFSRVL_H_ */
diff --git a/include/net/caif/generic/fcs.h b/include/net/caif/generic/fcs.h
new file mode 100644
index 0000000..0b82e2d
--- /dev/null
+++ b/include/net/caif/generic/fcs.h
@@ -0,0 +1,22 @@
+/*
+*      Copyright (C) ST-Ericsson AB 2009
+*
+*      Author: Sjur Brendeland/sjur.brandeland@stericsson.com
+*
+*      License terms: GNU General Public License (GPL), version 2.
+*
+*/
+
+
+
+
+
+
+
+#ifndef FCS_H_
+#define FCS_H_
+
+uint16
+fcs16(uint16 fcs, uint8 *cp, uint16 len);
+
+#endif				/* FCS_H_ */
-- 
1.6.0.4


^ permalink raw reply related

* [PATCH] [CAIF-RFC 3/8-v2] CAIF Protocol Stack
From: sjur.brandeland @ 2009-10-09 13:39 UTC (permalink / raw)
  To: netdev
  Cc: stefano.babic, randy.dunlap, kim.xx.lilliestierna,
	christian.bejram, daniel.martensson, Sjur Braendeland
In-Reply-To: <1255095571-6501-3-git-send-email-sjur.brandeland@stericsson.com>

From: Sjur Braendeland <sjur.brandeland@stericsson.com>

Change-Id: I63d22d52ce77e51238c842fad8319690d768e791
Signed-off-by: Sjur Braendeland <sjur.brandeland@stericsson.com>
---
 include/net/caif/caif_actions.h     |   75 ++++++++
 include/net/caif/caif_chr.h         |   52 ++++++
 include/net/caif/caif_config_util.h |   27 +++
 include/net/caif/caif_kernel.h      |  324 +++++++++++++++++++++++++++++++++++
 include/net/caif/caif_log.h         |   83 +++++++++
 5 files changed, 561 insertions(+), 0 deletions(-)
 create mode 100644 include/net/caif/caif_actions.h
 create mode 100644 include/net/caif/caif_chr.h
 create mode 100644 include/net/caif/caif_config_util.h
 create mode 100644 include/net/caif/caif_kernel.h
 create mode 100644 include/net/caif/caif_log.h

diff --git a/include/net/caif/caif_actions.h b/include/net/caif/caif_actions.h
new file mode 100644
index 0000000..897f6f8
--- /dev/null
+++ b/include/net/caif/caif_actions.h
@@ -0,0 +1,75 @@
+/*
+*      Copyright (C) ST-Ericsson AB 2009
+*
+*      Author: Daniel Martensson / Daniel.Martensson@stericsson.com
+*
+*      License terms: GNU General Public License (GPL), version 2.
+*
+*/
+
+#ifndef CAIF_ACTION_H_
+#define CAIF_ACTION_H_
+#include <linux/caif/caif_config.h>
+#include <linux/caif/caif_ioctl.h>
+
+#define DEVICE_NAME_LEN 16
+
+/**
+ * Types of Physical HW Interfaces towards modem defined in CAIF Stack,
+ * used when CAIF enumerates Interfaces and for Channel Configuration.
+ *
+ * For Client convenience to special types are defined:
+ *  - \ref CAIF_PHY_LOW_LAT is the preferred low latency physical link.
+ *         Typically used for "control" purposes.
+ *  - \ref CAIF_PHY_HIGH_BW is the preferred high bandwidth physical link.
+ *         Typically used for "payload" purposes.
+ *  - \ref CAIF_PHY_UNCPECIFIED CAIF Stack implementation will assign link
+ *         for you.
+ *
+ */
+enum caif_phy_type {
+	CAIF_PHY_UNSPECIFIED = 0x00,	/*!< Default Physical Interface */
+	CAIF_PHY_SERIAL = 0x10,	/*!< Serial Physical Interface */
+	CAIF_PHY_SPI = 0x20,	/*!< SPI Physical Interface */
+	CAIF_PHY_MSL = 0x30,	/*!< MSL Physical Interface */
+	CAIF_PHY_SHM = 0x40,	/*!< Shared Memory Interface */
+	CAIF_PHY_LOOP = 0x70,	/*!< Loop-back Interface Simulating ACC side
+				   responses */
+	CAIF_PHY_RAW_LOOP = 0x80,	/*!< Raw loop-back interface */
+};
+#define CAIF_PHY_MASK  0xf0
+
+
+
+
+
+
+/** Query the names of the Enumerated CAIF Physical Interfaces. */
+#define CAIF_ACT_LIST_PHYIFS 	         1	/*struct caif_device_list_action) */
+
+/** Get the physical interface information, given the name. */
+#define CAIF_ACT_GET_PHYIF_INFO 	 2	/*struct caif_phyif_info_action) */
+
+/** Enumerate a physical interface. */
+#define CAIF_ACT_ACTIVATE_PHYIF 		  3	/*struct caif_phy_activate) */
+
+/** Removes (De-Enumerates) a physical interface. */
+#define CAIF_ACT_DEACT_DEVICE 		 4	/*struct caif_device_name) */
+
+/** Get the device names of configured devices */
+#define CAIF_ACT_LIST_DEVICE_NAMES 	  5	/*struct caif_device_list_action) */
+
+/** Get configuration and status information for a specified CAIF device */
+#define CAIF_ACT_GET_DEVICE_INFO  	 6	/*struct caif_device_info_action) */
+
+/** Create and Configure a new CAIF device. Note that the device is not
+ * implicitly connected. */
+
+#define CAIF_ACT_CREATE_DEVICE 		 7 /*struct caif_channel_create_action*/
+
+/** Remove a CAIF device. Requires the device to be previously disconnected. */
+#define CAIF_ACT_DELETE_DEVICE           8	/*struct caif_device_name) */
+
+
+
+#endif
diff --git a/include/net/caif/caif_chr.h b/include/net/caif/caif_chr.h
new file mode 100644
index 0000000..62f1821
--- /dev/null
+++ b/include/net/caif/caif_chr.h
@@ -0,0 +1,52 @@
+/*
+*      Copyright (C) ST-Ericsson AB 2009
+*
+*      Author: Daniel Martensson / Daniel.Martensson@stericsson.com
+*
+*      License terms: GNU General Public License (GPL), version 2.
+*
+*/
+
+
+
+
+
+#ifndef CAIF_CHR_H_
+#define CAIF_CHR_H_
+
+#include <net/caif/generic/caif_layer.h>
+#include <net/caif/generic/cfcnfg.h>
+#include <net/caif/generic/cfspil.h>
+#include <linux/caif/caif_config.h>
+#include <net/caif/caif_actions.h>
+struct caif_service_config;
+
+typedef enum _cf_chr_dev_type_t {
+	CFDEVTYPE_CHR,
+	CFDEVTYPE_TTY,
+	CFDEVTYPE_NET
+} cf_chr_dev_type_t;
+
+extern int serial_use_stx;
+
+int caifdev_phy_reg(layer_t *phyif, cfcnfg_phy_mgmt_t *mgmt);
+int caifdev_phy_instanciate(cfcnfg_phy_config_t *phy_config);
+int caifdev_phy_register(layer_t *phyif, cfcnfg_phy_type_t phy_type,
+			 cfcnfg_phy_preference_t phy_pref);
+int caifdev_phy_unregister(layer_t *phyif);
+int caifdev_phy_loop_register(layer_t *phyif, cfcnfg_phy_type_t phy_type);
+int caifdev_phy_spi_xmitlen(cfspil_t *layr);
+cfpkt_t *caifdev_phy_spi_getxmitpkt(cfspil_t *layr);
+int caifdev_adapt_register(struct caif_channel_config *config,
+			   layer_t *adap_layer);
+int caifdev_adapt_unregister(layer_t *adap_layer);
+
+int caif_register_chrdev(int (*chrdev_mgmt)
+			  (int action, union caif_action *param));
+void caif_unregister_chrdev(void);
+
+int caif_register_netdev(int (*netdev_mgmt)
+		     (int action, union caif_action *param));
+void caif_unregister_netdev(void);
+
+#endif				/* CAIF_CHR_H_ */
diff --git a/include/net/caif/caif_config_util.h b/include/net/caif/caif_config_util.h
new file mode 100644
index 0000000..e012079
--- /dev/null
+++ b/include/net/caif/caif_config_util.h
@@ -0,0 +1,27 @@
+/*
+*      Copyright (C) ST-Ericsson AB 2009
+*
+*      Author: Daniel Martensson / Daniel.Martensson@stericsson.com
+*
+*      License terms: GNU General Public License (GPL), version 2.
+*
+*/
+
+
+
+
+
+#ifndef CAIF_CONFIG_UTIL_H_
+#define CAIF_CONFIG_UTIL_H_
+
+#include <linux/caif/caif_config.h>
+#include <linux/caif/caif_ioctl.h>
+#include <net/caif/generic/cfcnfg.h>
+#include <net/caif/generic/cfctrl.h>
+#include <net/caif/caif_actions.h>
+
+int channel_config_2_link_param(cfcnfg_t *cnfg,
+				struct caif_channel_config *s,
+				cfctrl_link_param_t *l);
+
+#endif
diff --git a/include/net/caif/caif_kernel.h b/include/net/caif/caif_kernel.h
new file mode 100644
index 0000000..8fcbd60
--- /dev/null
+++ b/include/net/caif/caif_kernel.h
@@ -0,0 +1,324 @@
+/*
+ *      Copyright (C) ST-Ericsson AB 2009
+ *
+ *      CAIF Kernel Internal interface for configuring and accessing
+ *      CAIF Channels.
+ *
+ *      Author: Sjur Brendeland/ sjur.brandeland@stericsson.com
+ *
+ *      License terms: GNU General Public License (GPL), version 2.
+ */
+
+#ifndef CAIF_KERNEL_H_
+#define CAIF_KERNEL_H_
+#include <linux/caif/caif_config.h>
+struct sk_buff;
+
+/*!\page  caif_kernel.h
+ * This is the specification of the CAIF Kernel internal interface to
+ * CAIF Channels.
+ * This interface follows the pattern used in Linux Device Drivers with a
+ *  struct \ref caif_device
+ * holding control data handling each device instance.
+ *
+ * The functional interface consist of a few basic functions:
+ *  - \ref caif_add_device             Configures and Connect the CAIF
+ *               Channel to the remote end. Configuration is described in
+ *               \ref caif_channel_config.
+ *  - \ref caif_remove_device          Disconnect and remove the Channel.
+ *  - \ref caif_transmit               Sends a CAIF message on the link.
+ *  - \ref caif_device.receive_cb      Receive Callback function for
+ *                receiving packets.
+ *  - \ref caif_device.control_cb      Control information from the CAIF stack.
+ *  - \ref caif_flow_control           Send Flow Control mesasge to remote end.
+ *
+ *
+ * Details:
+ * \see { caif_kernel }
+ *
+ * \code
+ *
+#include <net/caif/caif_kernel.h>"
+
+
+static void my_receive(struct caif_device *dev, struct sk_buff *skb)
+{
+...
+}
+
+static void my_control(struct caif_device *dev, enum caif_control ctrl)
+{
+....
+}
+
+int kernel_caif_usage_exampe()
+{
+struct sk_buff *skb;
+char *message = "hello";
+
+
+// Connect the Channel
+struct caif_device caif_dev = {
+.caif_config = {
+.name = "MYDEV",
+.priority = CAIF_PRIO_NORMAL,
+.type = CAIF_CHTY_UTILITY,
+.phy_pref = CAIF_PHYPREF_LOW_LAT,
+.u.utility.name = "CAIF_PSOCK_TEST",
+.u.utility.params = {0x01},
+.u.utility.paramlen = 1,
+},
+
+.receive_cb = my_receive,
+.control_cb = my_control,
+
+};
+ret = caif_add_device(&caif_dev);
+if (ret)
+goto error;
+
+// Send a packet
+skb = caif_create_skb(message, strlen(message));
+ret = caif_transmit(&caif_dev, skb);
+if (ret)
+goto error;
+
+
+// Remove device
+ret = caif_remove_device(&caif_dev);
+if (ret)
+goto error;
+
+}
+
+* \endcode
+*
+* \section Linux Socket Buffer (SKB)
+    *          When sending out packets on a connection (\ref caif_transmit)
+    *          the CAIF stack will add CAIF protocol headers.
+    *          This requires space in the SKB.
+    *          Caif has defined \ref CAIF_SKB_HEAD_RESERVE for minimum
+    *          required reserved head-space in the packet and
+    *          \ref CAIF_SKB_TAIL_RESERVE for minimum reserved tail-space.
+    *
+    *          \b NOTE The Linux kernel SKB operations panics if not
+    *                  enough space is available!
+    *
+    */
+
+    /*! \addtogroup caif_kernel
+     *  @{
+     */
+
+struct caif_device;
+
+
+    /** Minimum required CAIF Socket Buffer head-space */
+#define CAIF_SKB_HEAD_RESERVE 32
+
+    /** Minimum required CAIF Socket Buffer tail-space */
+#define CAIF_SKB_TAIL_RESERVE 32
+
+    /** CAIF Control information (used in \ref caif_device.control_cb)
+     *   used for receiving control information from Modem. */
+enum caif_control {
+	/** Modem has sent Flow-ON, Clients can start transmitting
+	 *  data using \ref caif_transmit. */
+	CAIF_CONTROL_FLOW_ON = 0,
+	/** Modem has sent Flow-OFF, Clients must stop transmitting
+	 * data using \ref caif_transmit. */
+	CAIF_CONTROL_FLOW_OFF = 1,
+
+	/** Channel Creation is complete. This is an acknowledge to
+	 *  (\ref caif_add_device) from Modem.
+	 *  and the Channel is ready for transmit (Flow-state is ON). */
+	CAIF_CONTROL_DEV_INIT = 3,
+
+	/** Spontaneous close request from Modem, only applicable
+	 *   for Utility Link. The Client should respond by calling
+	 *   \ref caif_remove_device */
+	CAIF_CONTROL_REMOTE_SHUTDOWN = 4,
+
+	/** Channel disconnect is complete. This is an acknowledge to
+	 *  (\ref caif_remove_device) from Modem.
+	 *  \ref caif_transmit or \ref caif_flow_control must not be
+	 *  called after this. */
+	CAIF_CONTROL_DEV_DEINIT = 5,
+
+	/** Channel Creation has failed. This is an negative acknowledge
+	 *  to (\ref caif_add_device) from Modem. */
+	CAIF_CONTROL_DEV_INIT_FAILED = 6
+};
+
+
+/** Flow Control information (used in \ref caif_device.control_cb) used
+ *  for controlling outgoing flow */
+enum caif_flowctrl {
+	/** Flow Control is ON, transmit function can start sending data */
+	CAIF_FLOWCTRL_ON = 0,
+	/** Flow Control is OFF, transmit function should stop sending data */
+	CAIF_FLOWCTRL_OFF = 1,
+};
+
+/** Transmits CAIF Packets on Channel.
+ * This function is non-blocking and safe to use in tasklet context.
+ * The CAIF Stack takes ownership of the Socket Buffer (SKB) after calling
+ * \ref caif_transmit.
+ * This means that the user cannot access the SKB afterwards, this applies
+ * even in error situations.
+ *
+ * @return 0 on success, < 0 upon error.
+ *
+ * @param[in] skb         Socket Buffer holding data to be written.
+ * @param[in] dev         Structure used when creating the channel
+ *
+ *
+ * Error codes:
+ *  - \b ENOTCONN,   The Channel is not connected.
+ *  - \b EPROTO,     Protocol error (or skb is faulty)
+ *  - \b EIO         IO Error (unspecified error)
+ */
+int caif_transmit(struct caif_device *dev, struct sk_buff *skb);
+
+
+/** Function for sending flow ON / OFF to remote end.
+ * This function is non-blocking and safe to use in tasklet context.
+ *
+ * @param[in] dev        Reference to device data.
+ * @param[in] flow       Flow Control information.
+
+ * @return 0 on success, < 0 upon error.
+ * Error codes:
+ *  - \b ENOTCONN,   The Channel is not connected.
+ *  - \b EPROTO,     Protocol error.
+ *  - \b EIO         IO Error (unspecified error).
+ */
+int caif_flow_control(struct caif_device *dev, enum caif_flowctrl flow);
+
+
+
+/** Handle for Kernel Internal CAIF Channels.
+ * All fields in this structure must be filled in by Client before calling
+ * \ref caif_add_device (except _caif_handle).
+ */
+struct caif_device {
+
+    /** Channel Configuration Parameter. Contains information about type
+     *	and configuration of the channel.
+     *  This must be set before calling \ref caif_add_device. */
+	struct caif_channel_config caif_config;
+
+
+    /** Callback Function for receiving CAIF Packets from Channel.
+     * This callback is called from softirq context (tasklet).
+     * The receiver <b> must </b> free the skb.
+     * <b> DO NOT BLOCK IN THIS FUNCTION! </b>
+     *
+     * If client has to do blocking operations
+     * it must start it's own work queue (or kernel thread).
+     *
+     * @param[in] dev        Reference to device data.
+     * @param[in] skb       Socket Buffer with received data.
+     */
+	void (*receive_cb) (struct caif_device *dev, struct sk_buff *skb);
+
+
+    /** Callback Function for notifying flow control from remote end see
+     *  \ref caif_control.
+     * This callback is called from from softirq context (tasklet).
+     *
+     * <b> DO NOT BLOCK IN THIS FUNCTION! </b>
+     *
+     * Client must not call \ref caif_transmit from this function.
+     *
+     * If client has queued packets to send
+     * it must start its own thread to do \ref caif_transmit from.
+     *
+     * @param[in] dev        Reference to device data.
+     * @param[in] ctrl       CAIF Control info \ref caif_control.
+     *                       e.g. Flow control
+     *                       \ref CAIF_CONTROL_FLOW_ON or
+     *                       \ref CAIF_CONTROL_FLOW_OFF
+     *
+     */
+	void (*control_cb) (struct caif_device *dev, enum caif_control ctrl);
+
+    /** This is a CAIF private attribute, holding CAIF internal reference
+     * to the CAIF stack. Do not update this field */
+
+	void *_caif_handle;
+
+    /** This field may be filled in by Client for their own usage. */
+	void *user_data;
+};
+
+
+
+/** Add (Connects) a CAIF Channel.
+ * This function is non-blocking. The channel connect is reported in
+ * \ref caif_device.control_cb.
+ * The channel is not open until \ref caif_device.control_cb is called with
+ * \ref CAIF_CONTROL_DEV_INIT.
+ * If setting up the channel fails \ref caif_device.control_cb is called with
+ * \ref CAIF_CONTROL_DEV_INIT_FAILED.
+ *
+ * \ref caif_transmit, \ref caif_flow_control or \ref caif_remove_device must
+ * not be called before receiveing CAIF_CONTROL_DEV_INIT.
+ * @return 0 on success, < 0 on failure.
+ *
+ * Error codes:
+ * - \b -EINVAL    Invalid Arguments
+ * - \b -ENODEV    No PHY Device exists.
+ * - \b -EIO       IO Error (unspecified error)
+ *
+ */
+int caif_add_device(struct caif_device *dev);
+
+
+
+/** Disconnect a CAIF Channel
+ * This function is non-blocking.
+ * The channel is not disconnected until \ref caif_device : control_cb is
+ * called with \ref CAIF_CONTROL_DEV_DEINIT.
+ * \ref caif_transmit or \ref caif_flow_control \b must not be called after
+ * receiving \ref CAIF_CONTROL_DEV_DEINIT.
+ * The Client is responsible for freeing the \ref caif_device structure after
+ * receiving  \ref CAIF_CONTROL_DEV_DEINIT (if applicable).
+ * @return 0 on success.
+ *
+ * - \b EIO       IO Error (unspecified error)
+ *
+ */
+int caif_remove_device(struct caif_device *caif_dev);
+
+
+
+/** Convenience function for allocating a socket buffer for usage with CAIF
+ * and copy user data into the socket buffer.
+ * @param[in] data User data to send with CAIF.
+ * @param[in] data_length of data to send.
+ * @return socket buffer .
+ *
+ */
+struct sk_buff *caif_create_skb(unsigned char *data, unsigned int data_length);
+
+
+/** Convenience function for extracting data from a socket buffer (SKB) and
+ *  then destroy it.
+ *  Copies data from the SKB frees the SKB.
+ * @param[in] skb SKB to extract data from. SKB will be freed after extracting
+ *            data.
+ *
+ * @param[in] data User data buffer to extract packet data into.
+ * @param[in] max_length User data buffer length,
+ * @return number of bytes extracted; < 0 upon error.
+ *
+ */
+int caif_extract_and_destroy_skb(struct sk_buff *skb, unsigned char *data,
+				 unsigned int max_length);
+
+
+
+/*! @} */
+
+#endif				/* CAIF_KERNEL_H_ */
diff --git a/include/net/caif/caif_log.h b/include/net/caif/caif_log.h
new file mode 100644
index 0000000..d62770e
--- /dev/null
+++ b/include/net/caif/caif_log.h
@@ -0,0 +1,83 @@
+/*
+*      Copyright (C) ST-Ericsson AB 2009
+*
+*      Author: Daniel Martensson / Daniel.Martensson@stericsson.com
+*
+*      License terms: GNU General Public License (GPL), version 2.
+*
+*/
+
+
+
+
+
+#ifndef CAIF_LOG_H_
+#define CAIF_LOG_H_
+
+extern int caif_dbg_level;
+
+#define CAIFLOG_ON 1
+
+#define CAIFLOG_MIN_LEVEL     1
+#define CAIFLOG_LEVEL_ERROR   1
+#define CAIFLOG_LEVEL_WARNING 2
+#define CAIFLOG_LEVEL_TRACE   3
+#define CAIFLOG_LEVEL_TRACE2  4
+#define CAIFLOG_LEVEL_TRACE3  5
+#define CAIFLOG_LEVEL_FUNC    6
+#define CAIFLOG_MAX_LEVEL     6
+
+/** Fatal error condition, halt the kernel */
+#define CAIFLOG_FATAL(format, args...) do if ( \
+	caif_dbg_level > CAIFLOG_LEVEL_ERROR)  \
+	printk(KERN_ERR "<%s:%d, FATAL> " format, __func__, __LINE__ , \
+	## args);\
+  while (0)
+
+/** CAIF Error Logging. */
+#define CAIFLOG_ERROR(format, args...)	do if (\
+caif_dbg_level > CAIFLOG_LEVEL_ERROR)  \
+printk(KERN_ERR "<%s:%d, ERROR> " format, __func__, __LINE__ , ## args);\
+  while (0)
+
+/** CAIF Warning Logging. */
+#define CAIFLOG_WARN(format, args...)	do if (\
+caif_dbg_level > CAIFLOG_LEVEL_WARNING)	 \
+printk(KERN_WARNING "<%s:%d, WARN> "  format, __func__, __LINE__ , ## args);\
+  while (0)
+
+/** CAIF Trace Control Logging. Level 1 control trace (Channel setup etc) */
+#define CAIFLOG_TRACE(format, args...)	do if (\
+caif_dbg_level > CAIFLOG_LEVEL_TRACE)  \
+printk(KERN_WARNING "<%s:%d, TRACE> " format, __func__, __LINE__ , ## args); \
+ while (0)
+
+/** CAIF Trace Payload Logging. Level payload trace */
+#define CAIFLOG_TRACE2(format, args...) do if ( \
+caif_dbg_level > CAIFLOG_LEVEL_TRACE2)	\
+printk(KERN_WARNING "<%s:%d, TRACE2> " format, __func__, __LINE__ , ## args);\
+  while (0)
+
+/** CAIF Trace Detailed Logging including packet dumps */
+#define CAIFLOG_TRACE3(format, args...) do if ( \
+caif_dbg_level > CAIFLOG_LEVEL_TRACE3)	\
+printk(KERN_WARNING "<%s:%d, TRACE3> " format, __func__, __LINE__ , ## args); \
+ while (0)
+
+/** CAIF Trace Entering Function */
+#define CAIFLOG_ENTER(format, args...)	do if (\
+caif_dbg_level > CAIFLOG_LEVEL_FUNC)  \
+printk(KERN_WARNING "<%s:%d, ENTER> " format, __func__, __LINE__ , ## args); \
+ while (0)
+
+/** CAIF Trace Exiting Function */
+#define CAIFLOG_EXIT(format, args...)	do if (\
+caif_dbg_level > CAIFLOG_LEVEL_FUNC)  \
+printk(KERN_WARNING "<%s:%d, EXIT> "  format, __func__, __LINE__ , ## args);\
+  while (0)
+
+#define IF_CAIF_TRACE(cmd) do if (\
+caif_dbg_level > CAIFLOG_LEVEL_TRACE) { cmd; } \
+  while (0)
+
+#endif				/*CAIF_LOG_H_ */
-- 
1.6.0.4


^ permalink raw reply related


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