Netdev List
 help / color / mirror / Atom feed
* [net-next-2.6 v2 13/15] ixgbe: cleanup namespace complaint by removing little used function
From: Jeff Kirsher @ 2011-02-11 17:21 UTC (permalink / raw)
  To: davem; +Cc: Don Skidmore, netdev, gospo, bphilips, Jeff Kirsher
In-Reply-To: <1297444862-32091-1-git-send-email-jeffrey.t.kirsher@intel.com>

From: Don Skidmore <donald.c.skidmore@intel.com>

We had a support function that just walked a few pointers to get
from the ixgbe_hw struct to the netdev pointer.  This was causing
a namespace warning so I removed it and just reference the pointers
directly.

Signed-off-by: Don Skidmore <donald.c.skidmore@intel.com>
Tested-by: Stephen Ko <stephen.s.ko@intel.com>
Signed-off-by: Jeff Kirsher <jeffrey.t.kirsher@intel.com>
---
 drivers/net/ixgbe/ixgbe_common.h |    4 ++--
 drivers/net/ixgbe/ixgbe_main.c   |   10 ----------
 2 files changed, 2 insertions(+), 12 deletions(-)

diff --git a/drivers/net/ixgbe/ixgbe_common.h b/drivers/net/ixgbe/ixgbe_common.h
index 66ed045..90cceb4 100644
--- a/drivers/net/ixgbe/ixgbe_common.h
+++ b/drivers/net/ixgbe/ixgbe_common.h
@@ -29,6 +29,7 @@
 #define _IXGBE_COMMON_H_
 
 #include "ixgbe_type.h"
+#include "ixgbe.h"
 
 u32 ixgbe_get_pcie_msix_count_generic(struct ixgbe_hw *hw);
 s32 ixgbe_init_ops_generic(struct ixgbe_hw *hw);
@@ -110,9 +111,8 @@ void ixgbe_set_vlan_anti_spoofing(struct ixgbe_hw *hw, bool enable, int vf);
 
 #define IXGBE_WRITE_FLUSH(a) IXGBE_READ_REG(a, IXGBE_STATUS)
 
-extern struct net_device *ixgbe_get_hw_dev(struct ixgbe_hw *hw);
 #define hw_dbg(hw, format, arg...) \
-	netdev_dbg(ixgbe_get_hw_dev(hw), format, ##arg)
+	netdev_dbg(((struct ixgbe_adapter *)(hw->back))->netdev, format, ##arg)
 #define e_dev_info(format, arg...) \
 	dev_info(&adapter->pdev->dev, format, ## arg)
 #define e_dev_warn(format, arg...) \
diff --git a/drivers/net/ixgbe/ixgbe_main.c b/drivers/net/ixgbe/ixgbe_main.c
index 34fdda2..4a6bcb6 100644
--- a/drivers/net/ixgbe/ixgbe_main.c
+++ b/drivers/net/ixgbe/ixgbe_main.c
@@ -7707,16 +7707,6 @@ static int ixgbe_notify_dca(struct notifier_block *nb, unsigned long event,
 
 #endif /* CONFIG_IXGBE_DCA */
 
-/**
- * ixgbe_get_hw_dev return device
- * used by hardware layer to print debugging information
- **/
-struct net_device *ixgbe_get_hw_dev(struct ixgbe_hw *hw)
-{
-	struct ixgbe_adapter *adapter = hw->back;
-	return adapter->netdev;
-}
-
 module_exit(ixgbe_exit_module);
 
 /* ixgbe_main.c */
-- 
1.7.4


^ permalink raw reply related

* [net-next-2.6 v2 12/15] ixgbe: fix namespace issue with ixgbe_dcb_txq_to_tc
From: Jeff Kirsher @ 2011-02-11 17:20 UTC (permalink / raw)
  To: davem; +Cc: Don Skidmore, netdev, gospo, bphilips, Jeff Kirsher
In-Reply-To: <1297444862-32091-1-git-send-email-jeffrey.t.kirsher@intel.com>

From: Don Skidmore <donald.c.skidmore@intel.com>

We didn't need the prototype and it was causing namespace complaints so
I made it static.

Signed-off-by: Don Skidmore <donald.c.skidmore@intel.com>
Tested-by: Stephen Ko <stephen.s.ko@intel.com>
Signed-off-by: Jeff Kirsher <jeffrey.t.kirsher@intel.com>
---
 drivers/net/ixgbe/ixgbe.h      |    1 -
 drivers/net/ixgbe/ixgbe_main.c |    2 +-
 2 files changed, 1 insertions(+), 2 deletions(-)

diff --git a/drivers/net/ixgbe/ixgbe.h b/drivers/net/ixgbe/ixgbe.h
index d04afde..12769b5 100644
--- a/drivers/net/ixgbe/ixgbe.h
+++ b/drivers/net/ixgbe/ixgbe.h
@@ -525,7 +525,6 @@ extern void ixgbe_unmap_and_free_tx_resource(struct ixgbe_ring *,
 extern void ixgbe_alloc_rx_buffers(struct ixgbe_ring *, u16);
 extern void ixgbe_write_eitr(struct ixgbe_q_vector *);
 extern int ethtool_ioctl(struct ifreq *ifr);
-extern u8 ixgbe_dcb_txq_to_tc(struct ixgbe_adapter *adapter, u8 index);
 extern s32 ixgbe_reinit_fdir_tables_82599(struct ixgbe_hw *hw);
 extern s32 ixgbe_init_fdir_signature_82599(struct ixgbe_hw *hw, u32 pballoc);
 extern s32 ixgbe_init_fdir_perfect_82599(struct ixgbe_hw *hw, u32 pballoc);
diff --git a/drivers/net/ixgbe/ixgbe_main.c b/drivers/net/ixgbe/ixgbe_main.c
index c2e09b9..34fdda2 100644
--- a/drivers/net/ixgbe/ixgbe_main.c
+++ b/drivers/net/ixgbe/ixgbe_main.c
@@ -648,7 +648,7 @@ void ixgbe_unmap_and_free_tx_resource(struct ixgbe_ring *tx_ring,
  *
  * Returns : a tc index for use in range 0-7, or 0-3
  */
-u8 ixgbe_dcb_txq_to_tc(struct ixgbe_adapter *adapter, u8 reg_idx)
+static u8 ixgbe_dcb_txq_to_tc(struct ixgbe_adapter *adapter, u8 reg_idx)
 {
 	int tc = -1;
 	int dcb_i = adapter->ring_feature[RING_F_DCB].indices;
-- 
1.7.4


^ permalink raw reply related

* [net-next-2.6 v2 14/15] ixgbe: cleanup ixgbe_init_mbx_params_pf namespace issue
From: Jeff Kirsher @ 2011-02-11 17:21 UTC (permalink / raw)
  To: davem; +Cc: Don Skidmore, netdev, gospo, bphilips, Jeff Kirsher
In-Reply-To: <1297444862-32091-1-git-send-email-jeffrey.t.kirsher@intel.com>

From: Don Skidmore <donald.c.skidmore@intel.com>

The function ixgbe_init_mbx_params_pf isn't used unless CONFIG_PCI_IOV
is defined.  This is causing namespace warnings.  So I wrapped its
definition in CONFIG_PCI_IOV too.

Signed-off-by: Don Skidmore <donald.c.skidmore@intel.com>
Tested-by: Stephen Ko <stephen.s.ko@intel.com>
Signed-off-by: Jeff Kirsher <jeffrey.t.kirsher@intel.com>
---
 drivers/net/ixgbe/ixgbe_mbx.c |    2 ++
 drivers/net/ixgbe/ixgbe_mbx.h |    2 ++
 2 files changed, 4 insertions(+), 0 deletions(-)

diff --git a/drivers/net/ixgbe/ixgbe_mbx.c b/drivers/net/ixgbe/ixgbe_mbx.c
index ea82c5a..f215c4c 100644
--- a/drivers/net/ixgbe/ixgbe_mbx.c
+++ b/drivers/net/ixgbe/ixgbe_mbx.c
@@ -437,6 +437,7 @@ out_no_read:
 	return ret_val;
 }
 
+#ifdef CONFIG_PCI_IOV
 /**
  *  ixgbe_init_mbx_params_pf - set initial values for pf mailbox
  *  @hw: pointer to the HW structure
@@ -465,6 +466,7 @@ void ixgbe_init_mbx_params_pf(struct ixgbe_hw *hw)
 		break;
 	}
 }
+#endif /* CONFIG_PCI_IOV */
 
 struct ixgbe_mbx_operations mbx_ops_generic = {
 	.read                   = ixgbe_read_mbx_pf,
diff --git a/drivers/net/ixgbe/ixgbe_mbx.h b/drivers/net/ixgbe/ixgbe_mbx.h
index 3df9b15..ada0ce3 100644
--- a/drivers/net/ixgbe/ixgbe_mbx.h
+++ b/drivers/net/ixgbe/ixgbe_mbx.h
@@ -86,7 +86,9 @@ s32 ixgbe_write_mbx(struct ixgbe_hw *, u32 *, u16, u16);
 s32 ixgbe_check_for_msg(struct ixgbe_hw *, u16);
 s32 ixgbe_check_for_ack(struct ixgbe_hw *, u16);
 s32 ixgbe_check_for_rst(struct ixgbe_hw *, u16);
+#ifdef CONFIG_PCI_IOV
 void ixgbe_init_mbx_params_pf(struct ixgbe_hw *);
+#endif /* CONFIG_PCI_IOV */
 
 extern struct ixgbe_mbx_operations mbx_ops_generic;
 
-- 
1.7.4


^ permalink raw reply related

* [net-next-2.6 v2 15/15] ixgbe: Adding 100MB FULL support in ethtool
From: Jeff Kirsher @ 2011-02-11 17:21 UTC (permalink / raw)
  To: davem; +Cc: Atita Shirwaikar, netdev, gospo, bphilips, Jeff Kirsher
In-Reply-To: <1297444862-32091-1-git-send-email-jeffrey.t.kirsher@intel.com>

From: Atita Shirwaikar <atita.shirwaikar@intel.com>

Current driver does not show 100MB support in ethtool.
Adding support for the same.

Signed-off-by: Atita Shirwaikar <atita.shirwaikar@intel.com>
Tested-by: Stephen Ko <stephen.s.ko@intel.com>
Signed-off-by: Jeff Kirsher <jeffrey.t.kirsher@intel.com>
---
 drivers/net/ixgbe/ixgbe_ethtool.c |   34 ++++++++++++++++++++++++++++++++--
 drivers/net/ixgbe/ixgbe_main.c    |    5 ++++-
 2 files changed, 36 insertions(+), 3 deletions(-)

diff --git a/drivers/net/ixgbe/ixgbe_ethtool.c b/drivers/net/ixgbe/ixgbe_ethtool.c
index 2002ea8..309272f 100644
--- a/drivers/net/ixgbe/ixgbe_ethtool.c
+++ b/drivers/net/ixgbe/ixgbe_ethtool.c
@@ -152,7 +152,17 @@ static int ixgbe_get_settings(struct net_device *netdev,
 		ecmd->supported |= (SUPPORTED_1000baseT_Full |
 		                    SUPPORTED_Autoneg);
 
+		switch (hw->mac.type) {
+		case ixgbe_mac_X540:
+			ecmd->supported |= SUPPORTED_100baseT_Full;
+			break;
+		default:
+			break;
+		}
+
 		ecmd->advertising = ADVERTISED_Autoneg;
+		if (hw->phy.autoneg_advertised & IXGBE_LINK_SPEED_100_FULL)
+			ecmd->advertising |= ADVERTISED_100baseT_Full;
 		if (hw->phy.autoneg_advertised & IXGBE_LINK_SPEED_10GB_FULL)
 			ecmd->advertising |= ADVERTISED_10000baseT_Full;
 		if (hw->phy.autoneg_advertised & IXGBE_LINK_SPEED_1GB_FULL)
@@ -167,6 +177,15 @@ static int ixgbe_get_settings(struct net_device *netdev,
 			ecmd->advertising |= (ADVERTISED_10000baseT_Full |
 					      ADVERTISED_1000baseT_Full);
 
+		switch (hw->mac.type) {
+		case ixgbe_mac_X540:
+			if (!(ecmd->advertising & ADVERTISED_100baseT_Full))
+				ecmd->advertising |= (ADVERTISED_100baseT_Full);
+			break;
+		default:
+			break;
+		}
+
 		if (hw->phy.media_type == ixgbe_media_type_copper) {
 			ecmd->supported |= SUPPORTED_TP;
 			ecmd->advertising |= ADVERTISED_TP;
@@ -271,8 +290,19 @@ static int ixgbe_get_settings(struct net_device *netdev,
 
 	hw->mac.ops.check_link(hw, &link_speed, &link_up, false);
 	if (link_up) {
-		ecmd->speed = (link_speed == IXGBE_LINK_SPEED_10GB_FULL) ?
-		               SPEED_10000 : SPEED_1000;
+		switch (link_speed) {
+		case IXGBE_LINK_SPEED_10GB_FULL:
+			ecmd->speed = SPEED_10000;
+			break;
+		case IXGBE_LINK_SPEED_1GB_FULL:
+			ecmd->speed = SPEED_1000;
+			break;
+		case IXGBE_LINK_SPEED_100_FULL:
+			ecmd->speed = SPEED_100;
+			break;
+		default:
+			break;
+		}
 		ecmd->duplex = DUPLEX_FULL;
 	} else {
 		ecmd->speed = -1;
diff --git a/drivers/net/ixgbe/ixgbe_main.c b/drivers/net/ixgbe/ixgbe_main.c
index 4a6bcb6..4f81b5a 100644
--- a/drivers/net/ixgbe/ixgbe_main.c
+++ b/drivers/net/ixgbe/ixgbe_main.c
@@ -6102,7 +6102,10 @@ static void ixgbe_watchdog_task(struct work_struct *work)
 			       (link_speed == IXGBE_LINK_SPEED_10GB_FULL ?
 			       "10 Gbps" :
 			       (link_speed == IXGBE_LINK_SPEED_1GB_FULL ?
-			       "1 Gbps" : "unknown speed")),
+			       "1 Gbps" :
+			       (link_speed == IXGBE_LINK_SPEED_100_FULL ?
+			       "100 Mbps" :
+			       "unknown speed"))),
 			       ((flow_rx && flow_tx) ? "RX/TX" :
 			       (flow_rx ? "RX" :
 			       (flow_tx ? "TX" : "None"))));
-- 
1.7.4


^ permalink raw reply related

* Re: [PATCH 2/2] network: Allow af_packet to transmit +4 bytes for VLAN packets.
From: Ben Greear @ 2011-02-11 17:38 UTC (permalink / raw)
  To: Eric Dumazet; +Cc: netdev
In-Reply-To: <1297407446.2493.5.camel@edumazet-laptop>

On 02/10/2011 10:57 PM, Eric Dumazet wrote:
> Le jeudi 10 février 2011 à 13:59 -0800, greearb@candelatech.com a
> écrit :
>> From: Ben Greear<greearb@candelatech.com>
>>
>> This allows user-space to send a '1500' MTU VLAN packet on a
>> 1500 MTU ethernet frame.  The extra 4 bytes of a VLAN header is
>> not usually charged against the MTU when other parts of the
>> network stack is transmitting vlans...
>>
>> Signed-off-by: Ben Greear<greearb@candelatech.com>
>> ---
>> :100644 100644 91cb1d7... ef7f378... M	net/packet/af_packet.c
>>   net/packet/af_packet.c |   31 +++++++++++++++++++++++++++++--
>>   1 files changed, 29 insertions(+), 2 deletions(-)
>>
>> diff --git a/net/packet/af_packet.c b/net/packet/af_packet.c
>> index 91cb1d7..ef7f378 100644
>> --- a/net/packet/af_packet.c
>> +++ b/net/packet/af_packet.c
>> @@ -466,7 +466,7 @@ retry:
>>   	 */
>>
>>   	err = -EMSGSIZE;
>> -	if (len>  dev->mtu + dev->hard_header_len)
>> +	if (len>  dev->mtu + dev->hard_header_len + VLAN_HLEN)
>>   		goto out_unlock;
>>
>>   	if (!skb) {
>> @@ -497,6 +497,19 @@ retry:
>>   		goto retry;
>>   	}
>>
>> +	if (len>  (dev->mtu + dev->hard_header_len)) {
>> +		/* Earlier code assumed this would be a VLAN pkt,
>> +		 * double-check this now that we have the actual
>> +		 * packet in hand.
>> +		 */
>> +		struct ethhdr *ehdr;
>> +		skb_reset_mac_header(skb);
>> +		ehdr = eth_hdr(skb);
>> +		if (ehdr->h_proto != htons(ETH_P_8021Q)) {
>> +			err = -EMSGSIZE;
>> +			goto out_unlock;
>
> This would leak skb.
>
>> +		}
>> +	}
>>
>>   	skb->protocol = proto;
>>   	skb->dev = dev;

Can you double-check that?  Seems to me that in that method the out_unlock
falls through to the out_free case.  The other method is the opposite, funny
enough...

Thanks,
Ben

>
> --
> To unsubscribe from this list: send the line "unsubscribe netdev" in
> the body of a message to majordomo@vger.kernel.org
> More majordomo info at  http://vger.kernel.org/majordomo-info.html


-- 
Ben Greear <greearb@candelatech.com>
Candela Technologies Inc  http://www.candelatech.com


^ permalink raw reply

* [PATCH] arp_notify: unconditionally send gratuitous ARP for NETDEV_NOTIFY_PEERS.
From: Ian Campbell @ 2011-02-11 17:44 UTC (permalink / raw)
  To: netdev; +Cc: Ian Campbell

NETDEV_NOTIFY_PEER is an explicit request by the driver to send a link
notification while NETDEV_UP/NETDEV_CHANGEADDR generate link
notifications as a sort of side effect.

In the later cases the sysctl option is present because link
notification events can have undesired effects e.g. if the link is
flapping. I don't think this applies in the case of an explicit
request from a driver.

This patch makes NETDEV_NOTIFY_PEER unconditional, if preferred we
could add a new sysctl for this case which defaults to on.

This change causes Xen post-migration ARP notifications (which cause
switches to relearn their MAC tables etc) to be sent by default.

Signed-off-by: Ian Campbell <ian.campbell@citrix.com>
---
 net/ipv4/devinet.c |   30 ++++++++++++++++++++----------
 1 files changed, 20 insertions(+), 10 deletions(-)

diff --git a/net/ipv4/devinet.c b/net/ipv4/devinet.c
index 748cb5b..df4616f 100644
--- a/net/ipv4/devinet.c
+++ b/net/ipv4/devinet.c
@@ -1030,6 +1030,21 @@ static inline bool inetdev_valid_mtu(unsigned mtu)
 	return mtu >= 68;
 }
 
+static void inetdev_send_gratuitous_arp(struct net_device *dev,
+					struct in_device *in_dev)
+
+{
+	struct in_ifaddr *ifa = in_dev->ifa_list;
+
+	if (!ifa)
+		return;
+
+	arp_send(ARPOP_REQUEST, ETH_P_ARP,
+		 ifa->ifa_address, dev,
+		 ifa->ifa_address, NULL,
+		 dev->dev_addr, NULL);
+}
+
 /* Called only under RTNL semaphore */
 
 static int inetdev_event(struct notifier_block *this, unsigned long event,
@@ -1082,18 +1097,13 @@ static int inetdev_event(struct notifier_block *this, unsigned long event,
 		}
 		ip_mc_up(in_dev);
 		/* fall through */
-	case NETDEV_NOTIFY_PEERS:
 	case NETDEV_CHANGEADDR:
+		if (!IN_DEV_ARP_NOTIFY(in_dev))
+			break;
+		/* fall through */
+	case NETDEV_NOTIFY_PEERS:
 		/* Send gratuitous ARP to notify of link change */
-		if (IN_DEV_ARP_NOTIFY(in_dev)) {
-			struct in_ifaddr *ifa = in_dev->ifa_list;
-
-			if (ifa)
-				arp_send(ARPOP_REQUEST, ETH_P_ARP,
-					 ifa->ifa_address, dev,
-					 ifa->ifa_address, NULL,
-					 dev->dev_addr, NULL);
-		}
+		inetdev_send_gratuitous_arp(dev, in_dev);
 		break;
 	case NETDEV_DOWN:
 		ip_mc_down(in_dev);
-- 
1.5.6.5


^ permalink raw reply related

* Re: [PATCH 2/2] network: Allow af_packet to transmit +4 bytes for VLAN packets.
From: Eric Dumazet @ 2011-02-11 18:18 UTC (permalink / raw)
  To: Ben Greear; +Cc: netdev
In-Reply-To: <4D557412.7000209@candelatech.com>

Le vendredi 11 février 2011 à 09:38 -0800, Ben Greear a écrit :

> Can you double-check that?  Seems to me that in that method the out_unlock
> falls through to the out_free case.  The other method is the opposite, funny
> enough...

Oops you're right, sorry.

Reading again your patch, I see you used one ETH_HLEN instead of
VLAN_HLEN in packet_snd()




^ permalink raw reply

* Re: [PATCH] niu: Fix races between up/down and get_stats.
From: Flavio Leitner @ 2011-02-11 17:29 UTC (permalink / raw)
  To: David Miller; +Cc: netdev
In-Reply-To: <20110204162646.GC3710@redhat.com>

On Fri, Feb 04, 2011 at 02:26:46PM -0200, Flavio Leitner wrote:
> On Thu, Feb 03, 2011 at 04:25:29PM -0800, David Miller wrote:
> > 
> > As reported by Flavio Leitner, there is no synchronization to protect
> > NIU's get_stats method from seeing a NULL pointer in either
> > np->rx_rings or np->tx_rings.  In fact, as far as ->ndo_get_stats
> > is concerned, these values are set completely asynchronously.
> > 
> > Flavio attempted to fix this using a RW semaphore, which in fact
> > works most of the time.  However, dev_get_stats() can be invoked
> > from non-sleepable contexts in some cases, so this fix doesn't
> > work in all cases.
> > 
> > So instead, control the visibility of the np->{rx,tx}_ring pointers
> > when the device is being brough up, and use properties of the device
> > down sequence to our advantage.
> > 
> > In niu_get_stats(), return immediately if netif_running() is false.
> > The device shutdown sequence first marks the device as not running (by
> > clearing the __LINK_STATE_START bit), then it performans a
> > synchronize_rcu() (in dev_deactive_many()), and then finally it
> > invokes the driver ->ndo_stop() method.
> > 
> > This guarentees that all invocations of niu_get_stats() either see
> > netif_running() as false, or they see the channel pointers before
> > ->ndo_stop() clears them out.
> > 
> > If netif_running() is true, protect against startup races by loading
> > the np->{rx,tx}_rings pointer into a local variable, and punting if
> > it is NULL.  Use ACCESS_ONCE to prevent the compiler from reloading
> > the pointer on us.
> > 
> > Also, during open, control the order in which the pointers and the
> > ring counts become visible globally using SMP write memory barriers.
> > We make sure the np->num_{rx,tx}_rings value is stable and visible
> > before np->{rx,tx}_rings is.
> > 
> > Such visibility control is not necessary on the niu_free_channels()
> > side because of the RCU sequencing that happens during device down as
> > described above.  We are always guarenteed that all niu_get_stats
> > calls are finished, or will see netif_running() false, by the time
> > ->ndo_stop is invoked.
> > 
> > Reported-by: Flavio Leitner <fleitner@redhat.com>
> > Signed-off-by: David S. Miller <davem@davemloft.net>
> 
> nice patch, clever
> I got positive feedback on my patch. I'll ask for this patch as well.

Got a feedback that your patch works out too.
thanks,
-- 
Flavio

^ permalink raw reply

* Re: [patch net-next-2.6 1/4] net: extend netlink interface to handle generic slave management
From: Jiri Pirko @ 2011-02-11 17:40 UTC (permalink / raw)
  To: Patrick McHardy; +Cc: netdev, davem, shemminger, fubar
In-Reply-To: <4D555A43.5000005@trash.net>

Fri, Feb 11, 2011 at 04:48:19PM CET, kaber@trash.net wrote:
>On 11.02.2011 16:21, Jiri Pirko wrote:
>> Drivers like bridge and bonding uses their own way to manipulate with
>> underlink devices. This is an attempt to introduce common interface using
>> netlink.
>
>Thanks for working on this, this has been on my TODO list for a
>long time.
>
>> --- a/include/linux/if_link.h
>> +++ b/include/linux/if_link.h
>> @@ -136,6 +136,9 @@ enum {
>>  	IFLA_PORT_SELF,
>>  	IFLA_AF_SPEC,
>>  	IFLA_GROUP,		/* Group the device belongs to */
>> +	IFLA_SLAVE_LIST,
>> +	IFLA_SLAVE_ADD,
>> +	IFLA_SLAVE_DEL,
>
>I don't like this very much though, the attributes usually contain
>data, not commands. We already have NEWLINK, DELLINK etc. on the
>top level, the combinations of NEWLINK/NLM_F_CREAT and SLAVE_DEL
>or DELLINK and SLAVE_ADD and so on simply don't make sense.
>
>We usually also try to keep the interface symetrical in both
>directions (a NEWLINK message from the kernel is identical to a
>NEWLINK message from userspace, a DELLINK message as well besides
>containing additional information), so using different attributes
>for dumping slaves than for adding them seems wrong. If we can
>dump all slaves in one message, it should also be possible to
>enslave multiple devices using the same message.
>
>What I originally had planned to support enslaving devices is to
>make use of the IFLA_MASTER attribute. The IFLA_MASTER attribute
>would contain the bond or bridge ifindex and the IFLA_IFNAME
>attribute or ifindex would specify the slave device. All operations
>would be performed on the slave device as usual, if the IFLA_MASTER
>attribute is present we'd additionally call a master specific
>callback for enslaving or releasing slave devices. Besides allowing
>to keep messages symetrical, an additional benefit is that it would
>be possible to create and enslave a device in a single step.
>

Yes, that makes sense. I'm going to respin the patchset soon.

Jirka
>

^ permalink raw reply

* Re: [patch net-next-2.6 3/4] bond: implement slave management operations
From: Jiri Pirko @ 2011-02-11 17:51 UTC (permalink / raw)
  To: Jay Vosburgh; +Cc: netdev, davem, shemminger, kaber
In-Reply-To: <22104.1297444790@death>

Fri, Feb 11, 2011 at 06:19:50PM CET, fubar@us.ibm.com wrote:
>Jiri Pirko <jpirko@redhat.com> wrote:
>
>>Signed-off-by: Jiri Pirko <jpirko@redhat.com>
>>---
>> drivers/net/bonding/bond_main.c |   38 ++++++++++++++++++++++++++++++++++++++
>> 1 files changed, 38 insertions(+), 0 deletions(-)
>>
>>diff --git a/drivers/net/bonding/bond_main.c b/drivers/net/bonding/bond_main.c
>>index 1df9f0e..f8e59f9 100644
>>--- a/drivers/net/bonding/bond_main.c
>>+++ b/drivers/net/bonding/bond_main.c
>
>	I think this would be better served by a new bond_netlink.c
>file instead of cramming this into (the already huge) bond_main.c.  In
>the long run, there will be a lot more netlink related code in bonding,
>so I think it makes sense to give it a file of its own from the
>beginning.

Well technically is not netlink code so givin it into *netlink* file
would imho make no sense.

>
>>@@ -4285,6 +4285,40 @@ unwind:
>> 	return res;
>> }
>>
>>+static int bond_add_slave(struct net_device *bond_dev,
>>+			  struct net_device *slave_dev)
>>+{
>>+	return bond_enslave(bond_dev, slave_dev);
>>+}
>>+
>>+static int bond_del_slave(struct net_device *bond_dev,
>>+			  struct net_device *slave_dev)
>>+{
>>+	return bond_release(bond_dev, slave_dev);
>>+}
>>+
>>+static int bond_get_slave_count(const struct net_device *bond_dev)
>>+{
>>+	struct bonding *bond = netdev_priv(bond_dev);
>>+
>>+	return bond->slave_cnt;
>>+}
>>+
>>+static struct net_device *bond_get_slave(const struct net_device *bond_dev,
>>+					 int slave_index)
>>+{
>>+	struct bonding *bond = netdev_priv(bond_dev);
>>+	struct slave *slave;
>>+	int i;
>>+
>>+	/* no need to hold bond->lock here, protected against writers by rtnl */
>>+	bond_for_each_slave(bond, slave, i) {
>>+		if (slave_index == i)
>>+			return slave->dev;
>>+	}
>>+	return NULL;
>
>	I think using the name "slave_index" for this variable is
>confusing, since it isn't the ifindex of the slave.  This "index" is
>used to iterate through the list of slaves, so perhaps "slave_num" or
>"slave_position" is clearer.  The same comment applies to the equivalent
>code for bridge.
>
>	-J
>
>>+}
>>+
>> static int bond_xmit_roundrobin(struct sk_buff *skb, struct net_device *bond_dev)
>> {
>> 	struct bonding *bond = netdev_priv(bond_dev);
>>@@ -4657,6 +4691,10 @@ static const struct net_device_ops bond_netdev_ops = {
>> 	.ndo_netpoll_cleanup	= bond_netpoll_cleanup,
>> 	.ndo_poll_controller	= bond_poll_controller,
>> #endif
>>+	.ndo_add_slave		= bond_add_slave,
>>+	.ndo_del_slave		= bond_del_slave,
>>+	.ndo_get_slave_count	= bond_get_slave_count,
>>+	.ndo_get_slave		= bond_get_slave,
>> };
>>
>> static void bond_destructor(struct net_device *bond_dev)
>>-- 
>>1.7.3.4
>>
>
>---
>	-Jay Vosburgh, IBM Linux Technology Center, fubar@us.ibm.com

^ permalink raw reply

* Re: jme driver loses connection after resuming from suspend
From: Leonardo  L. P. da Mata @ 2011-02-11 18:48 UTC (permalink / raw)
  To: Guo-Fu Tseng; +Cc: linux-kernel, netdev
In-Reply-To: <20110210232658.M45636@cooldavid.org>

[-- Attachment #1: Type: text/plain, Size: 2916 bytes --]

Hello Guo-Fu Tseng, not good news, the patch is not working.

But i've noticed one interesting behavior.

I've done 2 tests, on the first i've suspended, resumed and after
resume done a tcpdump. Only after the tcpdump, the network starts to
work.
ethtool-before
ethtool-before-d
ethtool-after
ethtool-after-d
ethtool-after-tcpdump
ethtool-after-tcpdump-d
on the second test, i've done the tcpdump befor suspending, and after
the resume the connection works.
ethtool-before-2
ethtool-before-2-d
ethtool-before-2-tcpdump
ethtool-before-2-tcpdump-d
ethtool-after-2-tcpdump
ethtool-after-2-tcpdump-d

I've attached the ethtool logs, and they are listed in the order of the steps.

i hope we can solve this mistery.




On Thu, Feb 10, 2011 at 9:26 PM, Guo-Fu Tseng <cooldavid@cooldavid.org> wrote:
> Hi Leonardo  L. P. da Mata:
> The value of register which holds receive Unicast MAC Address somehow
> get messed-up after resume!
>
> Would you see if this source fix the issue:
> http://bbs.cooldavid.org/git/?p=jme.git;a=snapshot;h=refs/heads/resumefix;sf=tbz2
>
> The shortlog is here:
> http://bbs.cooldavid.org/git/?p=jme.git;a=shortlog;h=refs/heads/resumefix
>
>
> On Thu, 10 Feb 2011 19:07:31 -0200, Leonardo  L. P. da Mata wrote
>> Updated information on the bug, Guo-Fu Tseng says that might not be a
>> bug on the driver, but i've tested other network cards and they don't
>> share the same issue.
>>
>> Also, on interesting update that people may consider is that after
>> running tcpdump on the device, the network starts working again.
>> Information are updated in the bug.
>>
>> On Fri, Jan 28, 2011 at 10:33 PM, Andrew Morton
>> <akpm@linux-foundation.org> wrote:
>> > (cc's added)
>> >
>> > On Fri, 28 Jan 2011 16:03:11 -0200
>> > "Leonardo &#160;L. P. da Mata" <barroca@gmail.com> wrote:
>> >
>> >> Hello, i'm testing the kernel 2.6.37 on my hardware, Once connect on
>> >> wired network, i call the suspend with:
>> >> echo "mem" >/sys/power/state
>> >>
>> >> The system goes on suspend. After resuming from suspend, the network card
>> >> cannot be used anymore.
>> >>
>> >>
>> >> The bug is reported here:
>> >> &#160;https://bugzilla.kernel.org/show_bug.cgi?id=27692
>> >>
>> >> Can you please point me to similar problems on other network cards so
>> >> i can get possible solutions on this.
>> >
>> >
>>
>> --
>> Leonardo Luiz Padovani da Mata
>> barroca@gmail.com
>>
>> "May the force be with you, always"
>> "Nerd Pride... eu tenho. Voce tem?"
>> --
>> To unsubscribe from this list: send the line "unsubscribe netdev" in
>> the body of a message to majordomo@vger.kernel.org
>> More majordomo info at  http://vger.kernel.org/majordomo-info.html
>
>
> Guo-Fu Tseng
>
>



-- 
Leonardo Luiz Padovani da Mata
barroca@gmail.com

"May the force be with you, always"
"Nerd Pride... eu tenho. Voce tem?"

[-- Attachment #2: ethtool-before-d --]
[-- Type: application/octet-stream, Size: 4350 bytes --]

Offset	Values
--------	-----
000:	 35 00 00 00 00 00 dc 35 00 00 00 00 00 04 00 00
010:	 98 21 dc 35 23 03 00 60 00 00 00 00 00 00 00 00
020:	 05 08 00 3f 00 80 c9 35 00 00 00 00 00 02 00 00
030:	 64 95 c9 35 4f 07 00 00 00 26 9e d9 70 c9 00 00
040:	 00 00 00 28 02 00 00 04 00 00 00 00 37 00 00 00
050:	 40 28 e1 45 60 00 a0 00 00 00 00 00 00 00 00 00
060:	 01 00 02 00 00 00 00 00 fc 00 00 00 53 01 00 00
070:	 00 00 00 00 00 00 00 00 80 00 80 00 00 00 00 00
080:	 ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff
090:	 ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff
0a0:	 ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff
0b0:	 ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff
0c0:	 ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff
0d0:	 ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff
0e0:	 ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff
0f0:	 ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff
100:	 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
110:	 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
120:	 00 00 00 00 00 00 00 00 00 00 00 70 00 00 00 00
130:	 43 7e 00 00 00 00 00 00 00 00 00 00 00 00 00 00
140:	 d0 01 00 50 00 00 00 00 00 00 00 00 00 00 00 00
150:	 00 00 00 00 00 00 00 00 ff ff ff ff ff ff ff ff
160:	 ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff
170:	 ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff
180:	 ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff
190:	 ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff
1a0:	 ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff
1b0:	 ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff
1c0:	 ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff
1d0:	 ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff
1e0:	 ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff
1f0:	 ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff
200:	 27 0b ff 03 10 10 00 00 01 02 30 00 00 00 02 00
210:	 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
220:	 00 00 00 00 00 00 00 00 00 10 31 e2 00 10 31 e2
230:	 00 01 01 00 00 00 00 00 00 00 00 00 00 00 00 00
240:	 01 08 e8 03 00 22 00 00 00 00 00 00 00 00 00 00
250:	 00 00 00 00 00 00 00 00 00 00 00 00 e0 00 00 00
260:	 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
270:	 00 00 00 00 00 00 00 00 00 00 00 00 00 00 e0 00
280:	 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
290:	 00 00 fc 00 00 01 00 00 ff ff ff ff ff ff ff ff
2a0:	 ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff
2b0:	 ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff
2c0:	 ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff
2d0:	 ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff
2e0:	 ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff
2f0:	 ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff
300:	 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
310:	 00 00 00 00 00 00 00 02 00 00 00 00 00 00 00 00
320:	 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
330:	 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
340:	 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
350:	 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
360:	 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
370:	 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
380:	 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
390:	 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
3a0:	 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
3b0:	 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
3c0:	 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
3d0:	 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
3e0:	 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
3f0:	 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
400:	 00 31 6d 78 6e 00 21 32 e1 0d e1 45 03 00 00 00
410:	 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
420:	 00 00 40 6c 00 00 48 7c 81 00 00 00 00 00 00 00
430:	 00 2d 74 47 00 10 24 00 00 00 00 00 00 00 00 00
440:	 ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff
450:	 ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff
460:	 ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff
470:	 ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff
480:	 ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff
490:	 ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff
4a0:	 ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff
4b0:	 ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff
4c0:	 ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff
4d0:	 ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff
4e0:	 ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff
4f0:	 ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff


[-- Attachment #3: ethtool-after-tcpdump --]
[-- Type: application/octet-stream, Size: 518 bytes --]

Settings for eth0:
	Supported ports: [ TP MII ]
	Supported link modes:   10baseT/Half 10baseT/Full 
	                        100baseT/Half 100baseT/Full 
	Supports auto-negotiation: Yes
	Advertised link modes:  10baseT/Half 10baseT/Full 
	                        100baseT/Half 100baseT/Full 
	Advertised auto-negotiation: Yes
	Speed: 100Mb/s
	Duplex: Full
	Port: MII
	PHYAD: 1
	Transceiver: internal
	Auto-negotiation: on
	Supports Wake-on: pg
	Wake-on: g
	Current message level: 0x000020c6 (8390)
	Link detected: yes

[-- Attachment #4: ethtool-after-d --]
[-- Type: application/octet-stream, Size: 4350 bytes --]

Offset	Values
--------	-----
000:	 35 00 00 00 00 80 ce 35 00 00 00 00 00 04 00 00
010:	 08 81 ce 35 23 03 00 60 00 00 00 00 00 00 00 00
020:	 05 08 00 3f 00 00 d3 35 00 00 00 00 00 02 00 00
030:	 e4 00 d3 35 4f 07 00 00 7f fb df 6e fb ef 00 00
040:	 00 00 00 28 00 00 00 04 00 00 00 00 00 00 00 00
050:	 60 00 00 31 60 00 a0 00 00 00 00 00 00 00 00 00
060:	 01 00 06 00 00 00 00 00 08 00 00 00 0a 00 00 00
070:	 00 00 00 00 00 00 00 00 80 00 80 00 00 00 00 00
080:	 ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff
090:	 ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff
0a0:	 ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff
0b0:	 ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff
0c0:	 ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff
0d0:	 ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff
0e0:	 ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff
0f0:	 ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff
100:	 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
110:	 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
120:	 00 00 00 00 00 00 00 00 00 00 00 70 00 00 00 00
130:	 03 7e 00 00 00 00 00 00 00 00 00 00 00 00 00 00
140:	 d0 01 00 50 00 00 00 00 00 00 00 00 00 00 00 00
150:	 00 00 00 00 00 00 00 00 ff ff ff ff ff ff ff ff
160:	 ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff
170:	 ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff
180:	 ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff
190:	 ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff
1a0:	 ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff
1b0:	 ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff
1c0:	 ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff
1d0:	 ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff
1e0:	 ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff
1f0:	 ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff
200:	 04 74 ff 03 10 10 00 00 01 00 30 00 00 00 02 00
210:	 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
220:	 00 00 00 00 00 00 00 00 00 10 31 e2 00 10 31 e2
230:	 00 01 01 00 00 00 00 00 00 00 00 00 00 00 00 00
240:	 01 08 e8 03 00 22 00 00 00 00 00 00 00 00 00 00
250:	 00 00 00 00 00 00 00 00 00 00 00 00 e0 00 00 00
260:	 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
270:	 00 00 00 00 00 00 00 00 00 00 00 00 00 00 e0 00
280:	 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
290:	 00 00 18 01 00 01 00 00 ff ff ff ff ff ff ff ff
2a0:	 ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff
2b0:	 ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff
2c0:	 ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff
2d0:	 ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff
2e0:	 ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff
2f0:	 ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff
300:	 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
310:	 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
320:	 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
330:	 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
340:	 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
350:	 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
360:	 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
370:	 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
380:	 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
390:	 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
3a0:	 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
3b0:	 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
3c0:	 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
3d0:	 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
3e0:	 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
3f0:	 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
400:	 00 31 6d 78 6e 00 21 32 e1 0d e1 45 03 00 00 00
410:	 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
420:	 00 00 00 6c 00 00 08 7c 01 00 00 00 00 00 00 00
430:	 00 2d 74 47 00 10 24 00 00 00 00 00 00 00 00 00
440:	 ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff
450:	 ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff
460:	 ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff
470:	 ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff
480:	 ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff
490:	 ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff
4a0:	 ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff
4b0:	 ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff
4c0:	 ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff
4d0:	 ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff
4e0:	 ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff
4f0:	 ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff


[-- Attachment #5: ethtool-after-2-tcpdump-d --]
[-- Type: application/octet-stream, Size: 4350 bytes --]

Offset	Values
--------	-----
000:	 35 00 00 00 00 80 d1 35 00 00 00 00 00 04 00 00
010:	 58 84 d1 35 23 03 00 60 00 00 00 00 00 00 00 00
020:	 05 08 00 3f 00 80 cd 35 00 00 00 00 00 02 00 00
030:	 44 84 cd 35 4f 0f 00 00 ff fb df 6f fb ef 00 00
040:	 00 00 00 28 02 00 00 04 00 00 00 00 00 00 00 00
050:	 60 00 00 31 60 00 a0 00 00 00 00 00 00 00 00 00
060:	 01 00 06 00 00 00 00 00 22 00 00 00 40 00 00 00
070:	 00 00 00 00 00 00 00 00 80 00 80 00 00 00 00 00
080:	 ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff
090:	 ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff
0a0:	 ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff
0b0:	 ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff
0c0:	 ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff
0d0:	 ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff
0e0:	 ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff
0f0:	 ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff
100:	 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
110:	 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
120:	 00 00 00 00 00 00 00 00 00 00 00 70 00 00 00 00
130:	 03 7e 00 00 00 00 00 00 00 00 00 00 00 00 00 00
140:	 d0 01 00 50 00 00 00 00 00 00 00 00 00 00 00 00
150:	 00 00 00 00 00 00 00 00 ff ff ff ff ff ff ff ff
160:	 ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff
170:	 ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff
180:	 ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff
190:	 ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff
1a0:	 ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff
1b0:	 ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff
1c0:	 ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff
1d0:	 ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff
1e0:	 ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff
1f0:	 ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff
200:	 88 bd ff 03 10 10 00 00 01 00 30 00 00 00 02 00
210:	 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
220:	 00 00 00 00 00 00 00 00 00 10 31 e2 00 10 31 e2
230:	 00 01 01 00 00 00 00 00 00 00 00 00 00 00 00 00
240:	 01 08 e8 03 00 22 00 00 00 00 00 00 00 00 00 00
250:	 00 00 00 00 00 00 00 00 00 00 00 00 e0 00 00 00
260:	 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
270:	 00 00 00 00 00 00 00 00 00 00 00 00 00 00 e0 00
280:	 00 00 01 00 00 00 00 00 00 00 00 00 00 00 00 00
290:	 00 00 5c 03 00 01 00 00 ff ff ff ff ff ff ff ff
2a0:	 ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff
2b0:	 ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff
2c0:	 ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff
2d0:	 ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff
2e0:	 ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff
2f0:	 ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff
300:	 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
310:	 00 00 00 00 00 00 01 02 00 00 00 00 00 00 00 00
320:	 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
330:	 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
340:	 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
350:	 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
360:	 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
370:	 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
380:	 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
390:	 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
3a0:	 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
3b0:	 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
3c0:	 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
3d0:	 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
3e0:	 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
3f0:	 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
400:	 00 31 6d 78 6e 00 21 32 e1 0d e1 45 03 00 00 00
410:	 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
420:	 00 00 00 6c 00 00 08 7c 01 00 00 00 00 00 00 00
430:	 00 2d 74 47 00 10 24 00 00 00 00 00 00 00 00 00
440:	 ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff
450:	 ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff
460:	 ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff
470:	 ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff
480:	 ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff
490:	 ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff
4a0:	 ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff
4b0:	 ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff
4c0:	 ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff
4d0:	 ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff
4e0:	 ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff
4f0:	 ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff


[-- Attachment #6: ethtool-after-2-tcpdump --]
[-- Type: application/octet-stream, Size: 518 bytes --]

Settings for eth0:
	Supported ports: [ TP MII ]
	Supported link modes:   10baseT/Half 10baseT/Full 
	                        100baseT/Half 100baseT/Full 
	Supports auto-negotiation: Yes
	Advertised link modes:  10baseT/Half 10baseT/Full 
	                        100baseT/Half 100baseT/Full 
	Advertised auto-negotiation: Yes
	Speed: 100Mb/s
	Duplex: Full
	Port: MII
	PHYAD: 1
	Transceiver: internal
	Auto-negotiation: on
	Supports Wake-on: pg
	Wake-on: g
	Current message level: 0x000020c6 (8390)
	Link detected: yes

[-- Attachment #7: ethtool-after --]
[-- Type: application/octet-stream, Size: 518 bytes --]

Settings for eth0:
	Supported ports: [ TP MII ]
	Supported link modes:   10baseT/Half 10baseT/Full 
	                        100baseT/Half 100baseT/Full 
	Supports auto-negotiation: Yes
	Advertised link modes:  10baseT/Half 10baseT/Full 
	                        100baseT/Half 100baseT/Full 
	Advertised auto-negotiation: Yes
	Speed: 100Mb/s
	Duplex: Full
	Port: MII
	PHYAD: 1
	Transceiver: internal
	Auto-negotiation: on
	Supports Wake-on: pg
	Wake-on: g
	Current message level: 0x000020c6 (8390)
	Link detected: yes

[-- Attachment #8: ethtool-before-2-tcpdump-d --]
[-- Type: application/octet-stream, Size: 4350 bytes --]

Offset	Values
--------	-----
000:	 35 00 00 00 00 00 d8 35 00 00 00 00 00 04 00 00
010:	 68 1e d8 35 23 03 00 60 00 00 00 00 00 00 00 00
020:	 05 08 00 3f 00 c0 c6 35 00 00 00 00 00 02 00 00
030:	 24 d6 c6 35 4f 0f 00 00 00 26 9e d9 70 c9 00 00
040:	 00 00 00 28 02 00 00 04 00 00 00 00 37 00 00 00
050:	 40 28 e1 45 60 00 a0 00 00 00 00 00 00 00 00 00
060:	 01 00 02 00 00 00 00 00 e5 00 00 00 5e 01 00 00
070:	 00 00 00 00 00 00 00 00 80 00 80 00 00 00 00 00
080:	 ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff
090:	 ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff
0a0:	 ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff
0b0:	 ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff
0c0:	 ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff
0d0:	 ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff
0e0:	 ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff
0f0:	 ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff
100:	 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
110:	 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
120:	 00 00 00 00 00 00 00 00 00 00 00 70 00 00 00 00
130:	 03 6e 00 00 00 00 00 00 00 00 00 00 00 00 00 00
140:	 d0 01 00 50 00 00 00 00 00 00 00 00 00 00 00 00
150:	 00 00 00 00 00 00 00 00 ff ff ff ff ff ff ff ff
160:	 ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff
170:	 ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff
180:	 ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff
190:	 ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff
1a0:	 ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff
1b0:	 ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff
1c0:	 ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff
1d0:	 ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff
1e0:	 ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff
1f0:	 ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff
200:	 60 b1 ff 03 10 10 00 00 01 02 30 00 00 00 02 00
210:	 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
220:	 00 00 00 00 00 00 00 00 00 10 31 e2 00 10 31 e2
230:	 00 01 01 00 00 00 00 00 00 00 00 00 00 00 00 00
240:	 01 08 e8 03 00 22 00 00 00 00 00 00 00 00 00 00
250:	 00 00 00 00 00 00 00 00 00 00 00 00 e0 00 00 00
260:	 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
270:	 00 00 00 00 00 00 00 00 00 00 00 00 00 00 e0 00
280:	 00 00 01 00 00 00 00 00 00 00 00 00 00 00 00 00
290:	 00 00 85 03 00 01 00 00 ff ff ff ff ff ff ff ff
2a0:	 ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff
2b0:	 ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff
2c0:	 ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff
2d0:	 ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff
2e0:	 ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff
2f0:	 ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff
300:	 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
310:	 00 00 00 00 00 00 00 02 00 00 00 00 00 00 00 00
320:	 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
330:	 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
340:	 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
350:	 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
360:	 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
370:	 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
380:	 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
390:	 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
3a0:	 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
3b0:	 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
3c0:	 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
3d0:	 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
3e0:	 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
3f0:	 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
400:	 00 31 6d 78 6e 00 21 32 e1 0d e1 45 01 00 00 00
410:	 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
420:	 00 00 00 6c 00 00 00 00 01 00 00 00 00 00 00 00
430:	 00 2d 74 47 00 10 24 00 00 00 00 00 00 00 00 00
440:	 ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff
450:	 ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff
460:	 ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff
470:	 ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff
480:	 ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff
490:	 ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff
4a0:	 ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff
4b0:	 ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff
4c0:	 ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff
4d0:	 ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff
4e0:	 ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff
4f0:	 ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff


[-- Attachment #9: ethtool-after-tcpdump-d --]
[-- Type: application/octet-stream, Size: 4350 bytes --]

Offset	Values
--------	-----
000:	 35 00 00 00 00 80 ce 35 00 00 00 00 00 04 00 00
010:	 78 9d ce 35 23 03 00 60 00 00 00 00 00 00 00 00
020:	 05 08 00 3f 00 00 d3 35 00 00 00 00 00 02 00 00
030:	 64 1d d3 35 4f 0f 00 00 7f fb df 6e fb ef 00 00
040:	 00 00 00 28 02 00 00 04 00 00 00 00 00 00 00 00
050:	 40 28 e1 45 60 00 a0 00 00 00 00 00 00 00 00 00
060:	 01 00 06 00 00 00 00 00 e5 00 00 00 d2 01 00 00
070:	 00 00 00 00 00 00 00 00 80 00 80 00 00 00 00 00
080:	 ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff
090:	 ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff
0a0:	 ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff
0b0:	 ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff
0c0:	 ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff
0d0:	 ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff
0e0:	 ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff
0f0:	 ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff
100:	 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
110:	 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
120:	 00 00 00 00 00 00 00 00 00 00 00 70 00 00 00 00
130:	 03 6e 00 00 00 00 00 00 00 00 00 00 00 00 00 00
140:	 d0 01 00 50 00 00 00 00 00 00 00 00 00 00 00 00
150:	 00 00 00 00 00 00 00 00 ff ff ff ff ff ff ff ff
160:	 ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff
170:	 ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff
180:	 ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff
190:	 ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff
1a0:	 ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff
1b0:	 ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff
1c0:	 ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff
1d0:	 ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff
1e0:	 ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff
1f0:	 ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff
200:	 7e 81 ff 03 10 10 00 00 01 00 30 00 00 00 02 00
210:	 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
220:	 00 00 00 00 00 00 00 00 00 10 31 e2 00 10 31 e2
230:	 00 01 01 00 00 00 00 00 00 00 00 00 00 00 00 00
240:	 01 08 e8 03 00 22 00 00 00 00 00 00 00 00 00 00
250:	 00 00 00 00 00 00 00 00 00 00 00 00 e0 00 00 00
260:	 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
270:	 00 00 00 00 00 00 00 00 00 00 00 00 00 00 e0 00
280:	 00 00 01 00 00 00 00 00 00 00 00 00 00 00 00 00
290:	 00 00 09 01 00 01 00 00 ff ff ff ff ff ff ff ff
2a0:	 ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff
2b0:	 ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff
2c0:	 ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff
2d0:	 ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff
2e0:	 ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff
2f0:	 ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff
300:	 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
310:	 00 00 00 00 00 00 00 02 00 00 00 00 00 00 00 00
320:	 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
330:	 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
340:	 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
350:	 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
360:	 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
370:	 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
380:	 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
390:	 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
3a0:	 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
3b0:	 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
3c0:	 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
3d0:	 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
3e0:	 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
3f0:	 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
400:	 00 31 6d 78 6e 00 21 32 e1 0d e1 45 01 00 00 00
410:	 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
420:	 00 00 00 6c 00 00 00 00 01 00 00 00 00 00 00 00
430:	 00 2d 74 47 00 10 24 00 00 00 00 00 00 00 00 00
440:	 ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff
450:	 ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff
460:	 ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff
470:	 ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff
480:	 ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff
490:	 ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff
4a0:	 ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff
4b0:	 ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff
4c0:	 ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff
4d0:	 ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff
4e0:	 ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff
4f0:	 ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff


[-- Attachment #10: ethtool-before-2-tcpdump --]
[-- Type: application/octet-stream, Size: 518 bytes --]

Settings for eth0:
	Supported ports: [ TP MII ]
	Supported link modes:   10baseT/Half 10baseT/Full 
	                        100baseT/Half 100baseT/Full 
	Supports auto-negotiation: Yes
	Advertised link modes:  10baseT/Half 10baseT/Full 
	                        100baseT/Half 100baseT/Full 
	Advertised auto-negotiation: Yes
	Speed: 100Mb/s
	Duplex: Full
	Port: MII
	PHYAD: 1
	Transceiver: internal
	Auto-negotiation: on
	Supports Wake-on: pg
	Wake-on: g
	Current message level: 0x000020c6 (8390)
	Link detected: yes

[-- Attachment #11: ethtool-before-2-d --]
[-- Type: application/octet-stream, Size: 4350 bytes --]

Offset	Values
--------	-----
000:	 35 00 00 00 00 00 d8 35 00 00 00 00 00 04 00 00
010:	 c8 15 d8 35 23 03 00 60 00 00 00 00 00 00 00 00
020:	 05 08 00 3f 00 c0 c6 35 00 00 00 00 00 02 00 00
030:	 84 cc c6 35 4f 07 00 00 00 26 9e d9 70 c9 00 00
040:	 00 00 00 28 02 00 00 04 00 00 00 00 37 00 00 00
050:	 60 00 00 31 60 00 a0 00 00 00 00 00 00 00 00 00
060:	 01 00 02 00 00 00 00 00 a3 00 00 00 c4 00 00 00
070:	 00 00 00 00 00 00 00 00 80 00 80 00 00 00 00 00
080:	 ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff
090:	 ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff
0a0:	 ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff
0b0:	 ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff
0c0:	 ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff
0d0:	 ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff
0e0:	 ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff
0f0:	 ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff
100:	 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
110:	 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
120:	 00 00 00 00 00 00 00 00 00 00 00 70 00 00 00 00
130:	 03 7e 00 00 00 00 00 00 00 00 00 00 00 00 00 00
140:	 d0 01 00 50 00 00 00 00 00 00 00 00 00 00 00 00
150:	 00 00 00 00 00 00 00 00 ff ff ff ff ff ff ff ff
160:	 ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff
170:	 ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff
180:	 ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff
190:	 ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff
1a0:	 ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff
1b0:	 ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff
1c0:	 ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff
1d0:	 ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff
1e0:	 ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff
1f0:	 ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff
200:	 b9 7c ff 03 10 10 00 00 01 02 30 00 00 00 02 00
210:	 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
220:	 00 00 00 00 00 00 00 00 00 10 31 e2 00 10 31 e2
230:	 00 01 01 00 00 00 00 00 00 00 00 00 00 00 00 00
240:	 01 08 e8 03 00 22 00 00 00 00 00 00 00 00 00 00
250:	 00 00 00 00 00 00 00 00 00 00 00 00 e0 00 00 00
260:	 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
270:	 00 00 00 00 00 00 00 00 00 00 00 00 00 00 e0 00
280:	 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
290:	 00 00 1f 02 00 01 00 00 ff ff ff ff ff ff ff ff
2a0:	 ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff
2b0:	 ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff
2c0:	 ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff
2d0:	 ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff
2e0:	 ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff
2f0:	 ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff
300:	 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
310:	 00 00 00 00 00 00 00 02 00 00 00 00 00 00 00 00
320:	 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
330:	 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
340:	 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
350:	 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
360:	 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
370:	 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
380:	 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
390:	 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
3a0:	 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
3b0:	 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
3c0:	 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
3d0:	 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
3e0:	 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
3f0:	 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
400:	 00 31 6d 78 6e 00 21 32 e1 0d e1 45 03 00 00 00
410:	 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
420:	 00 00 00 6c 00 00 08 7c 01 00 00 00 00 00 00 00
430:	 00 2d 74 47 00 10 24 00 00 00 00 00 00 00 00 00
440:	 ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff
450:	 ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff
460:	 ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff
470:	 ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff
480:	 ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff
490:	 ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff
4a0:	 ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff
4b0:	 ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff
4c0:	 ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff
4d0:	 ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff
4e0:	 ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff
4f0:	 ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff


[-- Attachment #12: ethtool-before-2 --]
[-- Type: application/octet-stream, Size: 518 bytes --]

Settings for eth0:
	Supported ports: [ TP MII ]
	Supported link modes:   10baseT/Half 10baseT/Full 
	                        100baseT/Half 100baseT/Full 
	Supports auto-negotiation: Yes
	Advertised link modes:  10baseT/Half 10baseT/Full 
	                        100baseT/Half 100baseT/Full 
	Advertised auto-negotiation: Yes
	Speed: 100Mb/s
	Duplex: Full
	Port: MII
	PHYAD: 1
	Transceiver: internal
	Auto-negotiation: on
	Supports Wake-on: pg
	Wake-on: g
	Current message level: 0x000020c6 (8390)
	Link detected: yes

[-- Attachment #13: ethtool-before --]
[-- Type: application/octet-stream, Size: 518 bytes --]

Settings for eth0:
	Supported ports: [ TP MII ]
	Supported link modes:   10baseT/Half 10baseT/Full 
	                        100baseT/Half 100baseT/Full 
	Supports auto-negotiation: Yes
	Advertised link modes:  10baseT/Half 10baseT/Full 
	                        100baseT/Half 100baseT/Full 
	Advertised auto-negotiation: Yes
	Speed: 100Mb/s
	Duplex: Full
	Port: MII
	PHYAD: 1
	Transceiver: internal
	Auto-negotiation: on
	Supports Wake-on: pg
	Wake-on: g
	Current message level: 0x000020c6 (8390)
	Link detected: yes

^ permalink raw reply

* [PATCH net-2.6] tg3: Expand 5719 workaround
From: Matt Carlson @ 2011-02-11 18:54 UTC (permalink / raw)
  To: davem; +Cc: netdev, mcarlson

The previous patch applied cleanly for me, but here it is for net-2.6.

-----------

As a precautionary measure, expand the fix submitted in commit
4d163b75e979833979cc401ae433cb1d7743d57e entitled "tg3: Fix 5719 A0 tx
completion bug" to apply to all 5719 revisions.

Signed-off-by: Matt Carlson <mcarlson@broadcom.com>
---
 drivers/net/tg3.c |    4 ++--
 1 files changed, 2 insertions(+), 2 deletions(-)

diff --git a/drivers/net/tg3.c b/drivers/net/tg3.c
index cc06952..ecb3eb0 100644
--- a/drivers/net/tg3.c
+++ b/drivers/net/tg3.c
@@ -13318,7 +13318,7 @@ static int __devinit tg3_get_invariants(struct tg3 *tp)
 	}
 
 	/* Determine TSO capabilities */
-	if (tp->pci_chip_rev_id == CHIPREV_ID_5719_A0)
+	if (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5719)
 		; /* Do nothing. HW bug. */
 	else if (tp->tg3_flags3 & TG3_FLG3_5717_PLUS)
 		tp->tg3_flags2 |= TG3_FLG2_HW_TSO_3;
@@ -13372,7 +13372,7 @@ static int __devinit tg3_get_invariants(struct tg3 *tp)
 	}
 
 	if ((tp->tg3_flags3 & TG3_FLG3_5717_PLUS) &&
-	    tp->pci_chip_rev_id != CHIPREV_ID_5719_A0)
+	    GET_ASIC_REV(tp->pci_chip_rev_id) != ASIC_REV_5719)
 		tp->tg3_flags3 |= TG3_FLG3_USE_JUMBO_BDFLAG;
 
 	if (!(tp->tg3_flags2 & TG3_FLG2_5705_PLUS) ||
-- 
1.7.3.4



^ permalink raw reply related

* Re: [PATCH] ip_gre: Add IPPROTO_GRE to flowi in ipgre_tunnel_xmit
From: David Miller @ 2011-02-11 19:23 UTC (permalink / raw)
  To: steffen.klassert; +Cc: xiaosuo, netdev
In-Reply-To: <20110211093040.GB29583@secunet.com>

From: Steffen Klassert <steffen.klassert@secunet.com>
Date: Fri, 11 Feb 2011 10:30:40 +0100

> Commit 5811662b15db018c740c57d037523683fd3e6123 accidentally
> removed the setting of IPPROTO_GRE from the struct flowi
> in ipgre_tunnel_xmit. This patch restores it.
> 
> Signed-off-by: Steffen Klassert <steffen.klassert@secunet.com>

Applied and queued up for -stable, thanks!

^ permalink raw reply

* Re: [PATCH] niu: Fix races between up/down and get_stats.
From: David Miller @ 2011-02-11 19:33 UTC (permalink / raw)
  To: fleitner; +Cc: netdev
In-Reply-To: <20110211172952.GA3112@redhat.com>

From: Flavio Leitner <fleitner@redhat.com>
Date: Fri, 11 Feb 2011 15:29:52 -0200

> Got a feedback that your patch works out too.

Thanks a lot Flavio.

^ permalink raw reply

* Re: [PATCH net-2.6] tg3: Expand 5719 workaround
From: David Miller @ 2011-02-11 19:35 UTC (permalink / raw)
  To: mcarlson; +Cc: netdev
In-Reply-To: <1297450480-5998-1-git-send-email-mcarlson@broadcom.com>

From: "Matt Carlson" <mcarlson@broadcom.com>
Date: Fri, 11 Feb 2011 10:54:40 -0800

> The previous patch applied cleanly for me, but here it is for net-2.6.

I'm not making it up, this one fails too:

davem@sunset:~/src/GIT/net-2.6$ git apply --check --whitespace=error-all diff
error: patch failed: drivers/net/tg3.c:13318
error: drivers/net/tg3.c: patch does not apply

GIT wants the line numbers to match up exactly, no fuzz is allowed.

^ permalink raw reply

* [PATCH 2/2 v2] network: Allow af_packet to transmit +4 bytes for VLAN packets.
From: greearb @ 2011-02-11 19:35 UTC (permalink / raw)
  To: netdev; +Cc: Ben Greear

From: Ben Greear <greearb@candelatech.com>

This allows user-space to send a '1500' MTU VLAN packet on a
1500 MTU ethernet frame.  The extra 4 bytes of a VLAN header is
not usually charged against the MTU when other parts of the
network stack is transmitting vlans...

Signed-off-by: Ben Greear <greearb@candelatech.com>
---

v2:  Fix ETH_HLEN to be VLAN_HLEN

:100644 100644 91cb1d7... eb39d70... M	net/packet/af_packet.c
 net/packet/af_packet.c |   31 +++++++++++++++++++++++++++++--
 1 files changed, 29 insertions(+), 2 deletions(-)

diff --git a/net/packet/af_packet.c b/net/packet/af_packet.c
index 91cb1d7..eb39d70 100644
--- a/net/packet/af_packet.c
+++ b/net/packet/af_packet.c
@@ -466,7 +466,7 @@ retry:
 	 */
 
 	err = -EMSGSIZE;
-	if (len > dev->mtu + dev->hard_header_len)
+	if (len > dev->mtu + dev->hard_header_len + VLAN_HLEN)
 		goto out_unlock;
 
 	if (!skb) {
@@ -497,6 +497,19 @@ retry:
 		goto retry;
 	}
 
+	if (len > (dev->mtu + dev->hard_header_len)) {
+		/* Earlier code assumed this would be a VLAN pkt,
+		 * double-check this now that we have the actual
+		 * packet in hand.
+		 */
+		struct ethhdr *ehdr;
+		skb_reset_mac_header(skb);
+		ehdr = eth_hdr(skb);
+		if (ehdr->h_proto != htons(ETH_P_8021Q)) {
+			err = -EMSGSIZE;
+			goto out_unlock;
+		}
+	}
 
 	skb->protocol = proto;
 	skb->dev = dev;
@@ -1200,7 +1213,7 @@ static int packet_snd(struct socket *sock,
 	}
 
 	err = -EMSGSIZE;
-	if (!gso_type && (len > dev->mtu+reserve))
+	if (!gso_type && (len > dev->mtu + reserve + VLAN_HLEN))
 		goto out_unlock;
 
 	err = -ENOBUFS;
@@ -1225,6 +1238,20 @@ static int packet_snd(struct socket *sock,
 	if (err < 0)
 		goto out_free;
 
+	if (!gso_type && (len > dev->mtu + reserve)) {
+		/* Earlier code assumed this would be a VLAN pkt,
+		 * double-check this now that we have the actual
+		 * packet in hand.
+		 */
+		struct ethhdr *ehdr;
+		skb_reset_mac_header(skb);
+		ehdr = eth_hdr(skb);
+		if (ehdr->h_proto != htons(ETH_P_8021Q)) {
+			err = -EMSGSIZE;
+			goto out_free;
+		}
+	}
+
 	skb->protocol = proto;
 	skb->dev = dev;
 	skb->priority = sk->sk_priority;
-- 
1.7.2.3


^ permalink raw reply related

* Re: [PATCH 0/3] Net driver fixes related to power management
From: David Miller @ 2011-02-11 19:39 UTC (permalink / raw)
  To: rjw
  Cc: netdev, mcarlson, mchan, linux-pm, thomas, jcliburn, chris.snook,
	jie.yang
In-Reply-To: <201102101751.56508.rjw@sisk.pl>

From: "Rafael J. Wysocki" <rjw@sisk.pl>
Date: Thu, 10 Feb 2011 17:51:56 +0100

> The following series of patches fix minor issues related to power management
> in the tg3, alt1 and atl1c drivers.
> 
> [1/3] - tg3: Don't use device_init_wakeup() (PCI does that)
> [2/3] - atl1c: Don't use device_init_wakeup() (ditto)
> [3/3] - atl1: Don't use legacy PCI power management.
> 
> Please consider for applying.

All applied to net-next-2.6, thank you.

^ permalink raw reply

* Re: [PATCH v2 09/13] can: pruss CAN driver.
From: Wolfgang Grandegger @ 2011-02-11 20:33 UTC (permalink / raw)
  To: Subhasish Ghosh
  Cc: sachi-EvXpCiN+lbve9wHmmfpqLFaTQe2KTcn/,
	davinci-linux-open-source-VycZQUHpC/PFrsHnngEfi1aTQe2KTcn/,
	CAN NETWORK DRIVERS, nsekhar-l0cyMroinI0, open list,
	CAN NETWORK DRIVERS, m-watkins-l0cyMroinI0,
	linux-arm-kernel-IAPFreCvJWM7uuMidbF8XUB+6BGkLq7r
In-Reply-To: <1297435892-28278-10-git-send-email-subhasish-EvXpCiN+lbve9wHmmfpqLFaTQe2KTcn/@public.gmane.org>

Hello,

thanks for your contribution.

First some general comments:

- Please send a separate patch for the Socket-CAN driver.
  Or are there good reasons why we should look at the other 12 patches?

- Please run checkpatch.pl and fix the reported warnings. There are
  many.

- You are using casts extensively. Please get rid of them.

- Decoding the variable type into the name is *deprecated* in Linux.

- Also very long names are *deprecated* in Linux.

- Don't use typedef's.

Some more comments inline...

On 02/11/2011 03:51 PM, Subhasish Ghosh wrote:
> This patch adds support for the CAN device emulated on PRUSS.
> 
> Signed-off-by: Subhasish Ghosh <subhasish-EvXpCiN+lbve9wHmmfpqLFaTQe2KTcn/@public.gmane.org>
> ---
>  drivers/net/can/Kconfig                     |    1 +
>  drivers/net/can/Makefile                    |    1 +
>  drivers/net/can/da8xx_pruss/Kconfig         |   73 ++
>  drivers/net/can/da8xx_pruss/Makefile        |    7 +
>  drivers/net/can/da8xx_pruss/pruss_can.c     |  758 +++++++++++++++++
>  drivers/net/can/da8xx_pruss/pruss_can_api.c | 1227 +++++++++++++++++++++++++++
>  drivers/net/can/da8xx_pruss/pruss_can_api.h |  290 +++++++
>  7 files changed, 2357 insertions(+), 0 deletions(-)
>  create mode 100644 drivers/net/can/da8xx_pruss/Kconfig
>  create mode 100644 drivers/net/can/da8xx_pruss/Makefile
>  create mode 100644 drivers/net/can/da8xx_pruss/pruss_can.c
>  create mode 100644 drivers/net/can/da8xx_pruss/pruss_can_api.c
>  create mode 100644 drivers/net/can/da8xx_pruss/pruss_can_api.h

Why not s/da8xx_pruss/pruss_can/ ?

> diff --git a/drivers/net/can/Kconfig b/drivers/net/can/Kconfig
> index d5a9db6..ae8f0f9 100644
> --- a/drivers/net/can/Kconfig
> +++ b/drivers/net/can/Kconfig
> @@ -112,6 +112,7 @@ config PCH_CAN
>  	  This driver can access CAN bus.
>  
>  source "drivers/net/can/mscan/Kconfig"
> +source "drivers/net/can/da8xx_pruss/Kconfig"
>  
>  source "drivers/net/can/sja1000/Kconfig"
>  
> diff --git a/drivers/net/can/Makefile b/drivers/net/can/Makefile
> index 07ca159..849cdbf 100644
> --- a/drivers/net/can/Makefile
> +++ b/drivers/net/can/Makefile
> @@ -14,6 +14,7 @@ obj-$(CONFIG_CAN_SJA1000)	+= sja1000/
>  obj-$(CONFIG_CAN_MSCAN)		+= mscan/
>  obj-$(CONFIG_CAN_AT91)		+= at91_can.o
>  obj-$(CONFIG_CAN_TI_HECC)	+= ti_hecc.o
> +obj-$(CONFIG_CAN_TI_DA8XX_PRU)	+= da8xx_pruss/

Please use a common name/prefix, e.g. pruss_can.

>  obj-$(CONFIG_CAN_MCP251X)	+= mcp251x.o
>  obj-$(CONFIG_CAN_BFIN)		+= bfin_can.o
>  obj-$(CONFIG_CAN_JANZ_ICAN3)	+= janz-ican3.o
> diff --git a/drivers/net/can/da8xx_pruss/Kconfig b/drivers/net/can/da8xx_pruss/Kconfig
> new file mode 100644
> index 0000000..8b68f68
> --- /dev/null
> +++ b/drivers/net/can/da8xx_pruss/Kconfig
> @@ -0,0 +1,73 @@
> +#
> +# CAN Lite Kernel Configuration
> +#
> +config CAN_TI_DA8XX_PRU
> +	depends on CAN_DEV && ARCH_DAVINCI && ARCH_DAVINCI_DA850
> +	tristate "PRU based CAN emulation for DA8XX"
> +	---help---
> +	Enable this to emulate a CAN controller on the PRU of DA8XX.
> +	If not sure, mark N
> +
> +config DA8XX_PRU_CANID_MBX0
> +	hex "CANID for mailbox 0"
> +	depends on CAN_TI_DA8XX_PRU
> +	default "0x123"
> +	---help---
> +	Enter the CANID for mailbox 0
> +	Default value is set to 0x123, change this as required.
> +
> +config DA8XX_PRU_CANID_MBX1
> +	hex "CANID for mailbox 1"
> +	depends on CAN_TI_DA8XX_PRU
> +	default "0x123"
> +	 ---help---
> +	Enter the CANID for mailbox 1
> +	Default value is set to 0x123, change this as required.
> +
> +config DA8XX_PRU_CANID_MBX2
> +	hex "CANID for mailbox 2"
> +	depends on CAN_TI_DA8XX_PRU
> +	default "0x123"
> +	---help---
> +	Enter the CANID for mailbox 2
> +	Default value is set to 0x123, change this as required.
> +
> +config DA8XX_PRU_CANID_MBX3
> +	hex "CANID for mailbox 3"
> +	depends on CAN_TI_DA8XX_PRU
> +	default "0x123"
> +	---help---
> +	Enter the CANID for mailbox 3
> +	Default value is set to 0x123, change this as required.
> +
> +config DA8XX_PRU_CANID_MBX4
> +	hex "CANID for mailbox 4"
> +	depends on CAN_TI_DA8XX_PRU
> +	default "0x123"
> +	---help---
> +	Enter the CANID for mailbox 4
> +	Default value is set to 0x123, change this as required.
> +
> +config DA8XX_PRU_CANID_MBX5
> +	hex "CANID for mailbox 5"
> +	depends on CAN_TI_DA8XX_PRU
> +	default "0x123"
> +	---help---
> +	Enter the CANID for mailbox 5
> +	Default value is set to 0x123, change this as required.
> +
> +config DA8XX_PRU_CANID_MBX6
> +	hex "CANID for mailbox 6"
> +	depends on CAN_TI_DA8XX_PRU
> +	default "0x123"
> +	---help---
> +	Enter the CANID for mailbox 6
> +	Default value is set to 0x123, change this as required.
> +
> +config DA8XX_PRU_CANID_MBX7
> +	hex "CANID for mailbox 7"
> +	depends on CAN_TI_DA8XX_PRU
> +	default "0x123"
> +	---help---
> +	Enter the CANID for mailbox 7
> +	Default value is set to 0x123, change this as required.

Well, defining CAN identifiers via Kconfig entries is really wired.
Could you please explain why that's necessary and what's so special with
that CAN hardware. We need a better solution if the CAN controller
cannot handle and CAN id.

> diff --git a/drivers/net/can/da8xx_pruss/Makefile b/drivers/net/can/da8xx_pruss/Makefile
> new file mode 100644
> index 0000000..48f3055
> --- /dev/null
> +++ b/drivers/net/can/da8xx_pruss/Makefile
> @@ -0,0 +1,7 @@
> +#
> +# Makefile for CAN Lite emulation
> +#
> +can_emu-objs :=   pruss_can.o \
> +                  pruss_can_api.o
> +
> +obj-$(CONFIG_CAN_TI_DA8XX_PRU)    += can_emu.o

Again another name.

> diff --git a/drivers/net/can/da8xx_pruss/pruss_can.c b/drivers/net/can/da8xx_pruss/pruss_can.c
> new file mode 100644
> index 0000000..1b3afde
> --- /dev/null
> +++ b/drivers/net/can/da8xx_pruss/pruss_can.c
> @@ -0,0 +1,758 @@
> +/*
> + *  TI DA8XX PRU CAN Emulation device driver
> + *  Author: subhasish-EvXpCiN+lbve9wHmmfpqLFaTQe2KTcn/@public.gmane.org
> + *
> + *  This driver supports TI's PRU CAN Emulation and the
> + *  specs for the same is available at <http://www.ti.com>
> + *
> + *  Copyright (C) 2009 Texas Instruments Incorporated - http://www.ti.com/
> + *
> + *  This program is free software; you can redistribute it and/or
> + *  modify it under the terms of the GNU General Public License as
> + *  published by the Free Software Foundation version 2.
> + *
> + *  This program is distributed as is WITHOUT ANY WARRANTY of any
> + *  kind, whether express or implied; without even the implied warranty
> + *  of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
> + *  GNU General Public License for more details.
> + */
> +
> +#include <linux/module.h>
> +#include <linux/init.h>
> +#include <linux/kernel.h>
> +#include <linux/bitops.h>
> +#include <linux/interrupt.h>
> +#include <linux/errno.h>
> +#include <linux/netdevice.h>
> +#include <linux/skbuff.h>
> +#include <linux/platform_device.h>
> +#include <linux/firmware.h>
> +#include <linux/clk.h>
> +#include <linux/types.h>
> +
> +#include <linux/can.h>
> +#include <linux/can/dev.h>
> +#include <linux/can/error.h>
> +#include <mach/da8xx.h>
> +#include "pruss_can_api.h"
> +
> +#define DRV_NAME "da8xx_pruss_can"
> +#define DRV_DESC "TI PRU CAN Controller Driver v0.1"
> +#define PRU_CAN_START		1
> +#define PRU_CAN_STOP		0
> +#define MB_MIN			0
> +#define MB_MAX			7
> +
> +#define PRU_CANMID_IDE			BIT(29)	/* Extended frame format */
> +
> +#define PRU_CAN_ISR_BIT_CCI		BIT(15)
> +#define PRU_CAN_ISR_BIT_ESI		BIT(14)
> +#define PRU_CAN_ISR_BIT_SRDI		BIT(13)
> +#define PRU_CAN_ISR_BIT_RRI		BIT(8)
> +
> +#define PRU_CAN_MBXSR_BIT_STATE		BIT(7)
> +#define PRU_CAN_MBXSR_BIT_TC		BIT(6)
> +#define PRU_CAN_MBXSR_BIT_ERR		BIT(5)
> +#define PRU_CAN_MBXSR_BIT_OF		BIT(0)
> +
> +#define PRU_CAN_GSR_BIT_TXM		BIT(7)
> +#define PRU_CAN_GSR_BIT_RXM		BIT(6)
> +#define PRU_CAN_GSR_BIT_CM		BIT(5)
> +#define PRU_CAN_GSR_BIT_EPM		BIT(4)
> +#define PRU_CAN_GSR_BIT_BFM		BIT(3)
> +#define RTR_MBX_NO			8
> +#define MAX_INIT_RETRIES		20
> +#define L138_PRU_ARM_FREQ		312000
> +#define DFLT_PRU_FREQ			156000000
> +#define DFLT_PRU_BITRATE		125000
> +
> +#define CONFIG_DA8XX_PRU_CANID_MBX0	0x123
> +#define CONFIG_DA8XX_PRU_CANID_MBX1	0x123
> +#define CONFIG_DA8XX_PRU_CANID_MBX2	0x123
> +#define CONFIG_DA8XX_PRU_CANID_MBX3	0x123
> +#define CONFIG_DA8XX_PRU_CANID_MBX4	0x123
> +#define CONFIG_DA8XX_PRU_CANID_MBX5	0x123
> +#define CONFIG_DA8XX_PRU_CANID_MBX6	0x123
> +#define CONFIG_DA8XX_PRU_CANID_MBX7	0x123
> +
> +#ifdef __CAN_DEBUG
> +#define __can_debug(fmt, args...) printk(KERN_DEBUG "can_debug: " fmt, ## args)
> +#else
> +#define __can_debug(fmt, args...)
> +#endif
> +#define __can_err(fmt, args...) printk(KERN_ERR "can_err: " fmt, ## args)

Please use dev_dbg, dev_err, ... or netif_dbg, netdev_err, ... instead.

> +/*
> + * omapl_pru can private data
> + */
> +struct omapl_pru_can_priv {
> +	struct can_priv can;
> +	struct workqueue_struct *pru_can_wQ;
> +	struct work_struct rx_work;
> +	struct net_device *ndev;
> +	struct device *dev; /* pdev->dev */
> +	struct clk *clk_timer;
> +	u32 timer_freq;
> +	can_emu_app_hndl can_tx_hndl;
> +	can_emu_app_hndl can_rx_hndl;
> +	const struct firmware *fw_rx;
> +	const struct firmware *fw_tx;
> +	spinlock_t mbox_lock;
> +	u32 trx_irq;
> +	u32 tx_head;
> +	u32 tx_tail;
> +	u32 tx_next;
> +	u32 rx_next;
> +};
> +
> +static int omapl_pru_can_get_state(const struct net_device *ndev,
> +				   enum can_state *state)
> +{
> +	struct omapl_pru_can_priv *priv = netdev_priv(ndev);
> +	*state = priv->can.state;
> +	return 0;
> +}


There is no need for that function as you handle state changes in the
interrupt context.

> +static int omapl_pru_can_set_bittiming(struct net_device *ndev)
> +{
> +	struct omapl_pru_can_priv *priv = netdev_priv(ndev);
> +	struct can_bittiming *bt = &priv->can.bittiming;
> +	long bit_error = 0;
> +
> +	if (priv->can.ctrlmode & CAN_CTRLMODE_3_SAMPLES) {
> +		dev_warn(priv->dev, "WARN: Triple"
> +			 "sampling not set due to h/w limitations");
> +	}

No need for this test as you have not set the CAN_CTRLMODE_3_SAMPLES bit
in priv.ctrlmode_supported.

> +	if (pru_can_calc_timing(priv->dev, priv->can.clock.freq,
> +				bt->bitrate) != 0)
> +		return -EINVAL;
> +	bit_error =
> +	    (((priv->timer_freq / (priv->timer_freq / bt->bitrate)) -
> +	      bt->bitrate) * 1000) / bt->bitrate;
> +	if (bit_error) {
> +		bit_error =
> +		    (((priv->timer_freq / (priv->timer_freq / bt->bitrate)) -
> +		      bt->bitrate) * 1000000) / bt->bitrate;
> +		printk(KERN_INFO "\nBitrate error %ld.%ld%%\n",
> +			bit_error / 10000, bit_error % 1000);
> +	} else
> +		printk(KERN_INFO "\nBitrate error 0.0%%\n");
> +
> +	return 0;

Please use the pre-calculated bit-timing parameters. Have a look to the
SJA1000 driver for further information:

http://lxr.linux.no/#linux+v2.6.37/drivers/net/can/sja1000/sja1000.c#L202

In general, please use the bit-timing interface of Socket-CAN and drop
you own.

> +}
> +
> +static void omapl_pru_can_stop(struct net_device *ndev)
> +{
> +	struct omapl_pru_can_priv *priv = netdev_priv(ndev);
> +	u16 int_mask = 0;
> +
> +	pru_can_mask_ints(priv->dev, int_mask);	/* mask all ints */
> +	pru_can_start_abort_tx(priv->dev, PRU_CAN_STOP);
> +	priv->can.state = CAN_STATE_STOPPED;
> +}
> +
> +/*
> + * This is to just set the can state to ERROR_ACTIVE
> + *	ip link set canX up type can bitrate 125000
> + */
> +static void omapl_pru_can_start(struct net_device *ndev)
> +{
> +	struct omapl_pru_can_priv *priv = netdev_priv(ndev);
> +	u16 int_mask = 0xFFFF;
> +
> +	if (priv->can.state != CAN_STATE_STOPPED)
> +		omapl_pru_can_stop(ndev);
> +
> +	pru_can_mask_ints(priv->dev, int_mask);	/* unmask all ints */
> +
> +	pru_can_get_global_status(priv->dev, &priv->can_tx_hndl);
> +	pru_can_get_global_status(priv->dev, &priv->can_rx_hndl);
> +
> +	if (PRU_CAN_GSR_BIT_EPM & priv->can_tx_hndl.u32globalstatus)

Decoding the variable type into the name is deprecated in Linux.

> +		priv->can.state = CAN_STATE_ERROR_PASSIVE;
> +	else if (PRU_CAN_GSR_BIT_BFM & priv->can_tx_hndl.u32globalstatus)
> +		priv->can.state = CAN_STATE_BUS_OFF;
> +	else
> +		priv->can.state = CAN_STATE_ERROR_ACTIVE;
> +}
> +
> +static int omapl_pru_can_set_mode(struct net_device *ndev, enum can_mode mode)
> +{
> +	int ret = 0;
> +
> +	switch (mode) {
> +	case CAN_MODE_START:
> +		omapl_pru_can_start(ndev);
> +		if (netif_queue_stopped(ndev))
> +			netif_wake_queue(ndev);
> +		break;
> +	case CAN_MODE_STOP:
> +		omapl_pru_can_stop(ndev);
> +		if (!netif_queue_stopped(ndev))
> +			netif_stop_queue(ndev);
> +		break;

This case is not supported.

> +	default:
> +		ret = -EOPNOTSUPP;
> +		break;
> +	}
> +	return ret;
> +}
> +
> +static netdev_tx_t omapl_pru_can_start_xmit(struct sk_buff *skb,
> +					    struct net_device *ndev)
> +{
> +	struct omapl_pru_can_priv *priv = netdev_priv(ndev);
> +	struct can_frame *cf = (struct can_frame *)skb->data;
> +	int count;
> +	u8 *data = cf->data;
> +	u8 dlc = cf->can_dlc;
> +	u8 *ptr8data = NULL;
> +
> +	netif_stop_queue(ndev);
> +	if (cf->can_id & CAN_EFF_FLAG)	/* Extended frame format */
> +		*((u32 *) &priv->can_tx_hndl.strcanmailbox) =
> +		    (cf->can_id & CAN_EFF_MASK) | PRU_CANMID_IDE;



> +	else			/* Standard frame format */
> +		*((u32 *) &priv->can_tx_hndl.strcanmailbox) =
> +		    (cf->can_id & CAN_SFF_MASK) << 18;

You use many of such wired expressions. strcanmailbox is a struct

  typedef struct {
	u16 u16extendedidentifier;
	u16 u16baseidentifier;
        ...
  } can_mail_box_structure;

and you obviously set the fist two fields. In contrast, the member
u16extendedidentifier is never directly used. Puh, that's magic. Please
make your code more transparent and readable.

> +	if (cf->can_id & CAN_RTR_FLAG)	/* Remote transmission request */
> +		*((u32 *) &priv->can_tx_hndl.strcanmailbox) |= CAN_RTR_FLAG;
> +
> +	ptr8data = &priv->can_tx_hndl.strcanmailbox.u8data7 + (dlc - 1);
> +	for (count = 0; count < (u8) dlc; count++) {
> +		*ptr8data-- = *data++;
> +	}
> +	*((u32 *) &priv->can_tx_hndl.strcanmailbox.u16datalength) = (u32) dlc;

...

> +irqreturn_t omapl_rx_can_intr(int irq, void *dev_id)
> +{
> +
> +	struct net_device *ndev = dev_id;
> +	struct omapl_pru_can_priv *priv = netdev_priv(ndev);
> +	u32 intc_status = 0;
> +
> +	intc_status = pru_can_get_intc_status(priv->dev);
> +	if (intc_status & 4)
> +		return omapl_tx_can_intr(irq, dev_id);
> +	if (intc_status & 2) {
> +		if (!work_pending(&priv->rx_work))
> +			queue_work(priv->pru_can_wQ, &priv->rx_work);

You handle RX in a work queue!? Please use NAPI instead.

> +	}
> +
> +	return IRQ_HANDLED;
> +}
> +
> +static int omapl_pru_can_open(struct net_device *ndev)
> +{
> +	struct omapl_pru_can_priv *priv = netdev_priv(ndev);
> +	int err;
> +
> +	/* register interrupt handler */
> +	err = request_irq(priv->trx_irq, &omapl_rx_can_intr, IRQF_SHARED,
> +			  "pru_can_irq", ndev);
> +	if (err) {
> +		dev_err(priv->dev, "error requesting rx interrupt\n");
> +		goto exit_trx_irq;
> +	}
> +	/* common open */
> +	err = open_candev(ndev);
> +	if (err) {
> +		dev_err(priv->dev, "open_candev() failed %d\n", err);
> +		goto exit_open;
> +	}
> +
> +	pru_can_emu_init(priv->dev, priv->can.clock.freq);
> +	priv->tx_tail = MB_MIN;
> +	priv->tx_head = MB_MAX;
> +
> +	pru_can_rx_id_map(priv->dev, CONFIG_DA8XX_PRU_CANID_MBX0, 0);
> +	pru_can_rx_id_map(priv->dev, CONFIG_DA8XX_PRU_CANID_MBX1, 1);
> +	pru_can_rx_id_map(priv->dev, CONFIG_DA8XX_PRU_CANID_MBX2, 2);
> +	pru_can_rx_id_map(priv->dev, CONFIG_DA8XX_PRU_CANID_MBX3, 3);
> +	pru_can_rx_id_map(priv->dev, CONFIG_DA8XX_PRU_CANID_MBX4, 4);
> +	pru_can_rx_id_map(priv->dev, CONFIG_DA8XX_PRU_CANID_MBX5, 5);
> +	pru_can_rx_id_map(priv->dev, CONFIG_DA8XX_PRU_CANID_MBX6, 6);
> +	pru_can_rx_id_map(priv->dev, CONFIG_DA8XX_PRU_CANID_MBX7, 7);
> +
> +	omapl_pru_can_start(ndev);
> +	netif_start_queue(ndev);
> +	return 0;
> +
> +exit_open:
> +	free_irq(priv->trx_irq, ndev);
> +exit_trx_irq:
> +	return err;
> +}
> +
> +static int omapl_pru_can_close(struct net_device *ndev)
> +{
> +	struct omapl_pru_can_priv *priv = netdev_priv(ndev);
> +
> +	if (!netif_queue_stopped(ndev))
> +		netif_stop_queue(ndev);
> +
> +	close_candev(ndev);
> +
> +	free_irq(priv->trx_irq, ndev);
> +	return 0;
> +}
> +
> +static const struct net_device_ops omapl_pru_can_netdev_ops = {
> +	.ndo_open		= omapl_pru_can_open,
> +	.ndo_stop		= omapl_pru_can_close,
> +	.ndo_start_xmit		= omapl_pru_can_start_xmit,
> +};
> +
> +static int __devinit omapl_pru_can_probe(struct platform_device *pdev)
> +{
> +	struct net_device *ndev = NULL;
> +	const struct da8xx_pru_can_data *pdata;
> +	struct omapl_pru_can_priv *priv = NULL;
> +	struct device *dev = &pdev->dev;
> +	u32 err;
> +
> +	pdata = dev->platform_data;
> +	if (!pdata) {
> +		dev_err(&pdev->dev, "platform data not found\n");
> +		return -EINVAL;
> +	}
> +
> +	ndev = alloc_candev(sizeof(struct omapl_pru_can_priv), MB_MAX + 1);
> +	if (!ndev) {
> +		dev_err(&pdev->dev, "alloc_candev failed\n");
> +		err = -ENOMEM;
> +		goto probe_exit;
> +	}
> +	priv = netdev_priv(ndev);
> +
> +	priv->trx_irq = platform_get_irq(to_platform_device(dev->parent), 0);
> +	if (!priv->trx_irq) {
> +		dev_err(&pdev->dev, "unable to get pru interrupt resources!\n");
> +		err = -ENODEV;
> +		goto probe_exit;
> +	}
> +
> +	priv->ndev = ndev;
> +	priv->dev = dev; /* priv->dev = pdev->dev */
> +
> +	priv->can.bittiming_const = NULL;
> +	priv->can.do_set_bittiming = omapl_pru_can_set_bittiming;
> +	priv->can.do_set_mode = omapl_pru_can_set_mode;
> +	priv->can.do_get_state = omapl_pru_can_get_state;
> +	priv->can_tx_hndl.u8prunumber = CAN_TX_PRU_1;
> +	priv->can_rx_hndl.u8prunumber = CAN_RX_PRU_0;
> +
> +	/* we support local echo, no arp */
> +	ndev->flags |= (IFF_ECHO | IFF_NOARP);
> +
> +	/* pdev->dev->device_private->driver_data = ndev */
> +	platform_set_drvdata(pdev, ndev);
> +	SET_NETDEV_DEV(ndev, &pdev->dev);
> +	ndev->netdev_ops = &omapl_pru_can_netdev_ops;
> +
> +	priv->can.clock.freq = pruss_get_clk_freq(priv->dev);
> +
> +	priv->clk_timer = clk_get(&pdev->dev, "pll1_sysclk2");
> +	if (IS_ERR(priv->clk_timer)) {
> +		dev_err(&pdev->dev, "no timer clock available\n");
> +		err = PTR_ERR(priv->clk_timer);
> +		priv->clk_timer = NULL;
> +		goto probe_exit_candev;
> +	}
> +	priv->timer_freq = clk_get_rate(priv->clk_timer);
> +
> +	err = register_candev(ndev);
> +	if (err) {
> +		dev_err(&pdev->dev, "register_candev() failed\n");
> +		err = -ENODEV;
> +		goto probe_exit_clk;
> +	}
> +
> +	err = request_firmware(&priv->fw_tx, "PRU_CAN_Emulation_Tx.bin",
> +			&pdev->dev);
> +	if (err) {
> +		dev_err(&pdev->dev, "can't load firmware\n");
> +		err = -ENODEV;
> +		goto probe_exit_clk;
> +	}
> +
> +	dev_info(&pdev->dev, "fw_tx size %d. downloading...\n",
> +		 priv->fw_tx->size);
> +
> +	err = request_firmware(&priv->fw_rx, "PRU_CAN_Emulation_Rx.bin",
> +			&pdev->dev);
> +	if (err) {
> +		dev_err(&pdev->dev, "can't load firmware\n");
> +		err = -ENODEV;
> +		goto probe_release_fw;
> +	}
> +	dev_info(&pdev->dev, "fw_rx size %d. downloading...\n",
> +		 priv->fw_rx->size);
> +
> +	/* init the pru */
> +	pru_can_emu_init(priv->dev, priv->can.clock.freq);
> +	udelay(200);
> +
> +	pruss_enable(priv->dev, CAN_RX_PRU_0);
> +	pruss_enable(priv->dev, CAN_TX_PRU_1);
> +
> +	/* download firmware into pru */
> +	err = pruss_load(priv->dev, CAN_RX_PRU_0,
> +		(u32 *)priv->fw_rx->data, (priv->fw_rx->size / 4));
> +	if (err) {
> +		dev_err(&pdev->dev, "firmware download error\n");
> +		err = -ENODEV;
> +		goto probe_release_fw_1;
> +	}
> +	err = pruss_load(priv->dev, CAN_TX_PRU_1,
> +		(u32 *)priv->fw_tx->data, (priv->fw_tx->size / 4));
> +	if (err) {
> +		dev_err(&pdev->dev, "firmware download error\n");
> +		err = -ENODEV;
> +		goto probe_release_fw_1;
> +	}
> +
> +	if (pru_can_calc_timing(priv->dev, DFLT_PRU_FREQ,
> +				DFLT_PRU_BITRATE) != 0)
> +		return -EINVAL;

Please don't define a default bit-rate. It's error prune.

> +
> +	pruss_run(priv->dev, CAN_RX_PRU_0);
> +	pruss_run(priv->dev, CAN_TX_PRU_1);
> +
> +	/*Create The Work Queue */
> +	priv->pru_can_wQ = create_freezeable_workqueue("omapl_pru_wQ");
> +	if (priv->pru_can_wQ == NULL) {
> +		dev_err(&pdev->dev, "failed to create work queue\n");
> +		err = -ENODEV;
> +		goto probe_release_fw_1;
> +	}
> +
> +	INIT_WORK(&priv->rx_work, omapl_pru_can_rx_wQ);
> +	dev_info(&pdev->dev,
> +		 "%s device registered (trx_irq = %d,  clk = %d)\n",
> +		 DRV_NAME, priv->trx_irq, priv->can.clock.freq);
> +
> +	return 0;
> +
> +probe_release_fw_1:
> +	release_firmware(priv->fw_rx);
> +probe_release_fw:
> +	release_firmware(priv->fw_tx);
> +probe_exit_clk:
> +	clk_put(priv->clk_timer);
> +probe_exit_candev:
> +	if (NULL != ndev)
> +		free_candev(ndev);
> +probe_exit:
> +	return err;
> +}
> +
> +static int __devexit omapl_pru_can_remove(struct platform_device *pdev)
> +{
> +	struct net_device *ndev = platform_get_drvdata(pdev);
> +	struct omapl_pru_can_priv *priv = netdev_priv(ndev);
> +
> +	omapl_pru_can_stop(ndev);
> +
> +	pru_can_emu_exit(priv->dev);
> +	release_firmware(priv->fw_tx);
> +	release_firmware(priv->fw_rx);
> +	clk_put(priv->clk_timer);
> +	flush_workqueue(priv->pru_can_wQ);
> +	destroy_workqueue(priv->pru_can_wQ);
> +	unregister_candev(ndev);
> +	free_candev(ndev);
> +	platform_set_drvdata(pdev, NULL);
> +	return 0;
> +}
> +
> +#ifdef CONFIG_PM
> +static int omapl_pru_can_suspend(struct platform_device *pdev,
> +			pm_message_t mesg)
> +{
> +	dev_info(&pdev->dev, "%s not yet implemented\n", __func__);
> +	return 0;
> +}
> +
> +static int omapl_pru_can_resume(struct platform_device *pdev)
> +{
> +	dev_info(&pdev->dev, "%s not yet implemented\n", __func__);
> +	return 0;
> +}
> +#else
> +#define omapl_pru_can_suspend NULL
> +#define omapl_pru_can_resume NULL
> +#endif /* CONFIG_PM */
> +
> +static struct platform_driver omapl_pru_can_driver = {
> +	.probe		= omapl_pru_can_probe,
> +	.remove		= __devexit_p(omapl_pru_can_remove),
> +	.suspend	= omapl_pru_can_suspend,
> +	.resume		= omapl_pru_can_resume,
> +	.driver		= {
> +		.name	= DRV_NAME,
> +		.owner	= THIS_MODULE,
> +	},
> +};
> +
> +static int __init omapl_pru_can_init(void)
> +{
> +	__can_debug(KERN_INFO DRV_DESC "\n");
> +	return platform_driver_register(&omapl_pru_can_driver);
> +}
> +
> +module_init(omapl_pru_can_init);
> +
> +static void __exit omapl_pru_can_exit(void)
> +{
> +	__can_debug(KERN_INFO DRV_DESC " unloaded\n");
> +	platform_driver_unregister(&omapl_pru_can_driver);
> +}
> +
> +module_exit(omapl_pru_can_exit);
> +
> +MODULE_AUTHOR("Subhasish Ghosh <subhasish-EvXpCiN+lbve9wHmmfpqLFaTQe2KTcn/@public.gmane.org>");
> +MODULE_LICENSE("GPL");
> +MODULE_DESCRIPTION("omapl pru CAN netdevice driver");
> diff --git a/drivers/net/can/da8xx_pruss/pruss_can_api.c b/drivers/net/can/da8xx_pruss/pruss_can_api.c
> new file mode 100644
> index 0000000..2f7438a
> --- /dev/null
> +++ b/drivers/net/can/da8xx_pruss/pruss_can_api.c
> @@ -0,0 +1,1227 @@
> +/*
> + * Copyright (C) 2010 Texas Instruments Incorporated
> + * Author: Wilfred Felix
> + *
> + * This program is free software; you can redistribute it and/or modify it
> + * under the terms of the GNU General Public License as  published by the
> + * Free Software Foundation version 2.
> + *
> + * This program is distributed "as is" WITHOUT ANY WARRANTY of any kind,
> + * whether express or implied; without even the implied warranty of
> + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
> + * General Public License for more details.
> + */
> +
> +#include "pruss_can_api.h"
> +
> +static can_emu_drv_inst gstr_can_inst[ecanmaxinst];
> +
> +/*
> + * pru_can_set_brp()	Updates the  BRP register of PRU0
> + * and PRU1 of OMAP L138. This API will be called by the
> + * Application to updtae the BRP register of PRU0 and PRU1
> + *
> + * param	u16bitrateprescaler		The can bus bitrate
> + * prescaler value be set
> + *
> + * return   SUCCESS or FAILURE
> + */
> +s16 pru_can_set_brp(struct device *dev, u16 u16bitrateprescaler)
> +{
> +
> +	u32 u32offset;
> +
> +	if (u16bitrateprescaler > 255) {
> +		return -1;
> +	}
> +
> +	u32offset = (PRU_CAN_RX_CLOCK_BRP_REGISTER);
> +	pruss_writel(dev, u32offset, (u32 *) &u16bitrateprescaler, 1);
> +
> +	u32offset = (PRU_CAN_TX_CLOCK_BRP_REGISTER);
> +	pruss_writel(dev, u32offset, (u32 *) &u16bitrateprescaler, 1);
> +
> +	return 0;
> +
> +}
> +
> +/*
> + * pru_can_set_bit_timing()		Updates the timing register
> + * of PRU0 and PRU1 of OMAP L138. This API will be called by
> + * the Application to updtae the timing register of PRU0 and PRU1
> + *
> + * param	pstrbittiming		Pointer to structure holding
> + * the bit timing values for can bus.
> + *
> + * return   SUCCESS or FAILURE
> + */
> +s16 pru_can_set_bit_timing(struct device *dev,
> +		can_bit_timing_consts *pstrbittiming)
> +{
> +
> +	u32 u32offset;
> +	u32 u32serregister;
> +
> +	u32serregister = 0;
> +
> +	if (pstrbittiming == NULL) {
> +		return -1;
> +	}
> +
> +	if ((pstrbittiming->u8syncjumpwidth > PRU_CAN_MAX_SJW) ||
> +	    (pstrbittiming->u8phseg1 > PRU_CAN_MAX_PHSEG1) ||
> +	    (pstrbittiming->u8phseg2 > PRU_CAN_MAX_PHSEG2)) {
> +		return -1;
> +	}
> +
> +	u32serregister = u32serregister |
> +			((pstrbittiming->u8syncjumpwidth << 7) |
> +			(pstrbittiming->u8phseg1 << 3) |
> +			(pstrbittiming->u8phseg2));
> +
> +	u32offset = (PRU_CAN_TX_TIMING_REGISTER);
> +	pruss_writel(dev, u32offset, (u32 *) &u32serregister, 1);
> +
> +	u32offset = (PRU_CAN_RX_TIMING_REGISTER);
> +	pruss_writel(dev, u32offset, (u32 *) &u32serregister, 1);
> +
> +	return 0;
> +}
> +
> +
> +/*
> + * pru_can_calc_timing()
> + * Updates the  timing values of PRU0 and PRU1 of OMAP L138.
> + * This API will be called by the
> + * Application to updtae the timing values of PRU0 and PRU1
> + *
> + * return   SUCCESS or FAILURE
> + */
> +
> +s16 pru_can_calc_timing(struct device *dev, u32 pru_freq, u32 bit_rate)
> +{
> +	u16 u16phaseseg1;
> +	u16 u16phaseseg2;
> +	u32 u32offset;
> +	u32 u32timing_value;
> +	u32 u32setup_value;
> +	u32timing_value = TIMER_CLK_FREQ / bit_rate;
> +	u32offset = (PRU_CAN_TIMING_VAL_TX);
> +	pruss_writel(dev, u32offset, (u32 *) &u32timing_value, 4);
> +	pruss_readl(dev, u32offset, (u32 *) &u32timing_value, 4);
> +	u32setup_value =
> +	    (GPIO_SETUP_DELAY * (pru_freq / 1000000) / 1000) /
> +	    DELAY_LOOP_LENGTH;
> +	u32offset = (PRU_CAN_TIMING_VAL_TX_SJW);
> +	pruss_writel(dev, u32offset, (u32 *) &u32setup_value, 4);
> +	u16phaseseg1 = (u16) (u32timing_value / 2);
> +	u16phaseseg2 = u32timing_value - u16phaseseg1;
> +	u16phaseseg1 -= TIMER_SETUP_DELAY;
> +	u16phaseseg2 -= TIMER_SETUP_DELAY;
> +	u32setup_value = (u16phaseseg1 << 16) | u16phaseseg2;
> +	u32offset = (PRU_CAN_TIMING_VAL_RX);
> +	pruss_writel(dev, u32offset, (u32 *) &u32setup_value, 4);
> +	u32offset = (PRU_CAN_TIMING_VAL_RX + 4);
> +	pruss_writel(dev, u32offset, (u32 *) &u32timing_value, 4);
> +
> +	return 0;
> +}

Why can't you use the common Socket-CAN bit-timing infrastructure.

> +/*
> + * pru_can_write_data_to_mailbox()
> + * Updates the transmit mailboxes of PRU1 of OMAP L138.
> + * This API will be called by the Application to update
> + * the transmit mailboxes of PRU1
> + *
> + * param  pu16canframedata	Can mailbox data buffer
> + *
> + * param  u8mailboxnum		Mailbox to be updated
> + *
> + * return SUCCESS or FAILURE
> + */
> +s16 pru_can_write_data_to_mailbox(struct device *dev,
> +			can_emu_app_hndl *pstremuapphndl)
> +{
> +	s16 s16subrtnretval;
> +	u32 u32offset;
> +
> +	if (pstremuapphndl == NULL) {
> +		return -1;
> +	}
> +
> +	switch ((u8) pstremuapphndl->ecanmailboxnumber) {
> +	case 0:
> +		u32offset = (PRU_CAN_TX_MAILBOX0);
> +		break;
> +	case 1:
> +		u32offset = (PRU_CAN_TX_MAILBOX1);
> +		break;
> +	case 2:
> +		u32offset = (PRU_CAN_TX_MAILBOX2);
> +		break;
> +	case 3:
> +		u32offset = (PRU_CAN_TX_MAILBOX3);
> +		break;
> +	case 4:
> +		u32offset = (PRU_CAN_TX_MAILBOX4);
> +		break;
> +	case 5:
> +		u32offset = (PRU_CAN_TX_MAILBOX5);
> +		break;
> +	case 6:
> +		u32offset = (PRU_CAN_TX_MAILBOX6);
> +		break;
> +	case 7:
> +		u32offset = (PRU_CAN_TX_MAILBOX7);
> +		break;
> +	default:
> +		return -1;
> +	}

There are more efficient ways to implemet that, e.g. by using an array.


> +	s16subrtnretval = pruss_writel(dev, u32offset,
> +		(u32 *) &(pstremuapphndl->strcanmailbox), 4);
> +	if (s16subrtnretval == -1) {
> +		return -1;
> +	}
> +	return 0;
> +}
> +
> +/*
> + * pru_can_get_data_from_mailbox()
> + * Receive data from the receive mailboxes of PRU0  of OMAP L138.
> + * This API will be called by the Application to get data from
> + * the receive mailboxes of PRU0
> + *
> + * param  pu16canframedata	Can mailbox data buffer
> + *
> + * param  u8mailboxnum		Mailbox to be updated
> + *
> + * return SUCCESS or FAILURE
> + */
> +s16 pru_can_get_data_from_mailbox(struct device *dev,
> +		can_emu_app_hndl *pstremuapphndl)
> +{
> +	s16 s16subrtnretval;
> +	u32 u32offset;
> +
> +	if (pstremuapphndl == NULL) {
> +		return -1;
> +	}
> +
> +	switch ((u8) pstremuapphndl->ecanmailboxnumber) {
> +	case 0:
> +		u32offset = (PRU_CAN_RX_MAILBOX0);
> +		break;
> +	case 1:
> +		u32offset = (PRU_CAN_RX_MAILBOX1);
> +		break;
> +	case 2:
> +		u32offset = (PRU_CAN_RX_MAILBOX2);
> +		break;
> +	case 3:
> +		u32offset = (PRU_CAN_RX_MAILBOX3);
> +		break;
> +	case 4:
> +		u32offset = (PRU_CAN_RX_MAILBOX4);
> +		break;
> +	case 5:
> +		u32offset = (PRU_CAN_RX_MAILBOX5);
> +		break;
> +	case 6:
> +		u32offset = (PRU_CAN_RX_MAILBOX6);
> +		break;
> +	case 7:
> +		u32offset = (PRU_CAN_RX_MAILBOX7);
> +		break;
> +	case 8:
> +		u32offset = (PRU_CAN_RX_MAILBOX8);
> +		break;
> +	default:
> +		return -1;
> +	}

Ditto.

> +	s16subrtnretval =
> +	    pruss_readl(dev, u32offset,
> +		  (u32 *) &(pstremuapphndl->strcanmailbox),
> +				  4);
> +	if (s16subrtnretval == -1) {
> +		return -1;
> +	}
> +	return 0;
> +}
> +
> +/*
> + * pru_can_receive_id_map()
> + * Receive mailboxes ID Mapping of PRU0  of OMAP L138.
> + * This API will be called by the Application
> + * to map the IDs  to receive mailboxes of PRU0
> + *
> + * param  u32nodeid		Can node ID
> + *
> + * param  ecanmailboxno		Mailbox to be mapped
> + *
> + * return   SUCCESS or FAILURE
> + */
> +s16 pru_can_rx_id_map(struct device *dev, u32 u32nodeid,
> +		can_mailbox_number ecanmailboxno)
> +{
> +
> +	pruss_writel(dev, (PRU_CAN_ID_MAP +
> +		(((u8) ecanmailboxno) * 4)), (u32 *) &u32nodeid, 1);
> +
> +	return 0;
> +}
> +
> +/*
> + * pru_can_get_intr_status()
> + * Gets the interrupts status register value.
> + * This API will be called by the Application
> + * to get the interrupts status register value
> + *
> + * param  u8prunumber	PRU number for which IntStatusReg
> + * has to be read
> + *
> + * return   SUCCESS or FAILURE
> + */
> +s16 pru_can_get_intr_status(struct device *dev,
> +		can_emu_app_hndl *pstremuapphndl)
> +{
> +	u32 u32offset;
> +	s16 s16subrtnretval = -1;
> +
> +	if (pstremuapphndl == NULL) {
> +		return -1;
> +	}
> +
> +	if (pstremuapphndl->u8prunumber == DA8XX_PRUCORE_1) {
> +		u32offset = (PRU_CAN_TX_INTERRUPT_STATUS_REGISTER);
> +	} else if (pstremuapphndl->u8prunumber == DA8XX_PRUCORE_0) {
> +		u32offset = (PRU_CAN_RX_INTERRUPT_STATUS_REGISTER);
> +	} else {
> +		return -1;
> +	}
> +
> +	s16subrtnretval = pruss_readl(dev, u32offset,
> +		(u32 *) &pstremuapphndl->u32interruptstatus, 1);
> +	if (s16subrtnretval == -1) {
> +		return -1;
> +	}
> +
> +	return 0;
> +}
> +
> +/*
> + * pru_can_get_global_status()	Gets the globalstatus
> + * register value. This API will be called by the Application
> + * to  get the global status register value
> + *
> + * return   SUCCESS or FAILURE
> + */
> +s16 pru_can_get_global_status(struct device *dev,
> +		can_emu_app_hndl *pstremuapphndl)
> +{
> +	u32 u32offset;
> +	int s16subrtnretval = -1;
> +
> +	if (pstremuapphndl == NULL) {
> +		return -1;
> +	}
> +
> +	if (pstremuapphndl->u8prunumber == DA8XX_PRUCORE_1) {
> +		u32offset = (PRU_CAN_TX_GLOBAL_STATUS_REGISTER);
> +	} else if (pstremuapphndl->u8prunumber == DA8XX_PRUCORE_0) {
> +		u32offset = (PRU_CAN_RX_GLOBAL_STATUS_REGISTER);
> +	} else {
> +		return -1;
> +	}
> +
> +	s16subrtnretval = pruss_readl(dev, u32offset,
> +		(u32 *) &pstremuapphndl->u32globalstatus, 1);
> +	if (s16subrtnretval == -1) {
> +		return -1;
> +	}
> +
> +	return 0;
> +}
> +
> +/*
> + * pru_can_get_mailbox_status()		Gets the mailbox status
> + * register value. This API will be called by the Application
> + * to get the mailbox status register value
> + *
> + * return   SUCCESS or FAILURE
> + */
> +s16 pru_can_get_mailbox_status(struct device *dev,
> +		can_emu_app_hndl *pstremuapphndl)
> +{
> +	u32 u32offset;
> +	s16 s16subrtnretval = -1;
> +
> +	if (pstremuapphndl == NULL) {
> +		return -1;
> +	}
> +
> +	if (pstremuapphndl->u8prunumber == DA8XX_PRUCORE_1) {
> +		switch (pstremuapphndl->ecanmailboxnumber) {
> +		case 0:
> +			u32offset = (PRU_CAN_TX_MAILBOX0_STATUS_REGISTER);
> +			break;
> +		case 1:
> +			u32offset = (PRU_CAN_TX_MAILBOX1_STATUS_REGISTER);
> +			break;
> +		case 2:
> +			u32offset = (PRU_CAN_TX_MAILBOX2_STATUS_REGISTER);
> +			break;
> +		case 3:
> +			u32offset = (PRU_CAN_TX_MAILBOX3_STATUS_REGISTER);
> +			break;
> +		case 4:
> +			u32offset = (PRU_CAN_TX_MAILBOX4_STATUS_REGISTER);
> +			break;
> +		case 5:
> +			u32offset = (PRU_CAN_TX_MAILBOX5_STATUS_REGISTER);
> +			break;
> +		case 6:
> +			u32offset = (PRU_CAN_TX_MAILBOX6_STATUS_REGISTER);
> +			break;
> +		case 7:
> +			u32offset = (PRU_CAN_TX_MAILBOX7_STATUS_REGISTER);
> +			break;
> +		default:
> +			return -1;
> +		}
> +	}
> +
> +	else if (pstremuapphndl->u8prunumber == DA8XX_PRUCORE_0) {
> +		switch (pstremuapphndl->ecanmailboxnumber) {
> +		case 0:
> +			u32offset = (PRU_CAN_RX_MAILBOX0_STATUS_REGISTER);
> +			break;
> +		case 1:
> +			u32offset = (PRU_CAN_RX_MAILBOX1_STATUS_REGISTER);
> +			break;
> +		case 2:
> +			u32offset = (PRU_CAN_RX_MAILBOX2_STATUS_REGISTER);
> +			break;
> +		case 3:
> +			u32offset = (PRU_CAN_RX_MAILBOX3_STATUS_REGISTER);
> +			break;
> +		case 4:
> +			u32offset = (PRU_CAN_RX_MAILBOX4_STATUS_REGISTER);
> +			break;
> +		case 5:
> +			u32offset = (PRU_CAN_RX_MAILBOX5_STATUS_REGISTER);
> +			break;
> +		case 6:
> +			u32offset = (PRU_CAN_RX_MAILBOX6_STATUS_REGISTER);
> +			break;
> +		case 7:
> +			u32offset = (PRU_CAN_RX_MAILBOX7_STATUS_REGISTER);
> +			break;
> +		case 8:
> +			u32offset = (PRU_CAN_RX_MAILBOX8_STATUS_REGISTER);
> +			break;
> +		default:
> +			return -1;
> +		}
> +	}
> +
> +	else {
> +		return -1;
> +	}
> +
> +	s16subrtnretval = pruss_readl(dev, u32offset,
> +		(u32 *) &pstremuapphndl->u32mailboxstatus, 1);
> +	if (s16subrtnretval == -1) {
> +		return -1;
> +	}
> +
> +	return 0;
> +}
> +
> +s16 pru_can_tx_mode_set(struct device *dev, bool btransfer_flag,
> +				can_transfer_direction ecan_trx)
> +{
> +	u32 u32offset;
> +	u32 u32value;
> +
> +	if (ecan_trx == ecantransmit) {
> +		u32offset = (PRU_CAN_RX_GLOBAL_STATUS_REGISTER);
> +		pruss_readl(dev, u32offset, &u32value, 1);
> +		if (btransfer_flag == true) {
> +			u32value &= 0x1F;
> +			u32value |= 0x80;
> +		} else {
> +			u32value &= 0x7F;
> +		}
> +		pruss_writel(dev, u32offset, &u32value, 1);
> +		u32offset = (PRU_CAN_TX_GLOBAL_STATUS_REGISTER);
> +		pruss_writel(dev, u32offset, &u32value, 1);
> +	} else if (ecan_trx == ecanreceive) {
> +		u32offset = (PRU_CAN_RX_GLOBAL_STATUS_REGISTER);
> +		pruss_readl(dev, u32offset, &u32value, 1);
> +		if (btransfer_flag == true) {
> +			u32value &= 0x1F;
> +			u32value |= 0x40;
> +		} else {
> +			u32value &= 0xBF;
> +		}
> +		pruss_writel(dev, u32offset, &u32value, 1);
> +		u32offset = (PRU_CAN_TX_GLOBAL_STATUS_REGISTER);
> +		pruss_writel(dev, u32offset, &u32value, 1);
> +	} else
> +		return -1;
> +
> +	return 0;
> +}
> +
> +/*
> + * pru_can_config_mode_set()		Sets the timing value
> + * for data transfer. This API will be called by the Application
> + * to set timing valus for data transfer
> + *
> + * return   SUCCESS or FAILURE
> + */
> +s16 pru_can_config_mode_set(struct device *dev, bool bconfigmodeflag)
> +{
> +
> +	u32 u32bitrateprescaler;
> +	u32 u32canbittiming;
> +
> +	pruss_readl(dev, (PRU_CAN_TX_CLOCK_BRP_REGISTER),
> +			(u32 *) &u32bitrateprescaler, 1);
> +	pruss_readl(dev, (PRU_CAN_TX_TIMING_REGISTER),
> +			(u32 *) &u32canbittiming, 1);
> +
> +	if (bconfigmodeflag == 1) {
> +		pru_can_calc_timing(dev, u32canbittiming, u32bitrateprescaler);
> +	}
> +
> +	else {
> +		pru_can_calc_timing(dev, 0, 0);
> +	}
> +
> +	return 0;
> +}
> +
> +/*
> + * pru_can_emu_init()		Initializes the Can
> + * Emulation Parameters. This API will be called by the Application
> + * to Initialize the Can Emulation Parameters
> + *
> + * param    u32pruclock         PRU Clock value
> + *
> + * return   SUCCESS or FAILURE
> + */
> +s16 pru_can_emu_init(struct device *dev, u32 u32pruclock)
> +{
> +	u32 u32offset;
> +	u32 u32value;
> +	s16 s16subrtnretval = -1;
> +	u8 u8loop;
> +
> +	for (u8loop = 0; u8loop < (u8) ecanmaxinst; u8loop++) {
> +		gstr_can_inst[u8loop].bcaninststate = (bool) 0;
> +		gstr_can_inst[u8loop].ecantransferdirection =
> +		    (can_transfer_direction) 0;
> +		gstr_can_inst[u8loop].u32apphandlerptr = 0;
> +	}
> +
> +	u32offset = (PRU_CAN_TX_GLOBAL_CONTROL_REGISTER & 0xFFFF);
> +	u32value = 0x00000000;
> +	s16subrtnretval = pruss_writel(dev, u32offset, (u32 *) &u32value, 1);
> +	if (s16subrtnretval == -1) {
> +		return -1;
> +	}
> +
> +	u32offset = (PRU_CAN_TX_GLOBAL_STATUS_REGISTER & 0xFFFF);
> +	u32value = 0x00000040;
> +	s16subrtnretval = pruss_writel(dev, u32offset, (u32 *) &u32value, 1);
> +	if (s16subrtnretval == -1) {
> +		return -1;
> +	}
> +	u32offset = (PRU_CAN_RX_GLOBAL_STATUS_REGISTER & 0xFFFF);
> +	u32value = 0x00000040;
> +	s16subrtnretval = pruss_writel(dev, u32offset, (u32 *) &u32value, 1);
> +	if (s16subrtnretval == -1) {
> +		return -1;
> +	}
> +
> +	u32offset = (PRU_CAN_TX_INTERRUPT_MASK_REGISTER & 0xFFFF);
> +	u32value = 0x00004000;
> +	s16subrtnretval = pruss_writel(dev, u32offset, (u32 *) &u32value, 1);
> +	if (s16subrtnretval == -1) {
> +		return -1;
> +	}
> +
> +	u32offset = (PRU_CAN_TX_INTERRUPT_STATUS_REGISTER & 0xFFFF);
> +	u32value = 0x00000000;
> +	s16subrtnretval = pruss_writel(dev, u32offset, (u32 *) &u32value, 1);
> +	if (s16subrtnretval == -1) {
> +		return -1;
> +	}
> +
> +	u32offset = (PRU_CAN_TX_MAILBOX0_STATUS_REGISTER & 0xFFFF);
> +	u32value = 0x00000001;
> +	s16subrtnretval =
> +	    pruss_writel(dev, u32offset, (u32 *) &u32value, 1);
> +	if (s16subrtnretval == -1) {
> +		return -1;
> +	}
> +
> +	u32offset = (PRU_CAN_TX_MAILBOX1_STATUS_REGISTER & 0xFFFF);
> +	u32value = 0x00000001;
> +	s16subrtnretval = pruss_writel(dev, u32offset, (u32 *) &u32value, 1);
> +	if (s16subrtnretval == -1) {
> +		return -1;
> +	}
> +
> +	u32offset = (PRU_CAN_TX_MAILBOX2_STATUS_REGISTER & 0xFFFF);
> +	u32value = 0x00000001;
> +	s16subrtnretval = pruss_writel(dev, u32offset, (u32 *) &u32value, 1);
> +	if (s16subrtnretval == -1) {
> +		return -1;
> +	}
> +
> +	u32offset = (PRU_CAN_TX_MAILBOX3_STATUS_REGISTER & 0xFFFF);
> +	u32value = 0x00000001;
> +	s16subrtnretval = pruss_writel(dev, u32offset, (u32 *) &u32value, 1);
> +	if (s16subrtnretval == -1) {
> +		return -1;
> +	}
> +
> +	u32offset = (PRU_CAN_TX_MAILBOX4_STATUS_REGISTER & 0xFFFF);
> +	u32value = 0x00000001;
> +	s16subrtnretval = pruss_writel(dev, u32offset, (u32 *) &u32value, 1);
> +	if (s16subrtnretval == -1) {
> +		return -1;
> +	}
> +
> +	u32offset = (PRU_CAN_TX_MAILBOX5_STATUS_REGISTER & 0xFFFF);
> +	u32value = 0x00000001;
> +	s16subrtnretval = pruss_writel(dev, u32offset, (u32 *) &u32value, 1);
> +	if (s16subrtnretval == -1) {
> +		return -1;
> +	}
> +
> +	u32offset = (PRU_CAN_TX_MAILBOX6_STATUS_REGISTER & 0xFFFF);
> +	u32value = 0x00000001;
> +	s16subrtnretval = pruss_writel(dev, u32offset, (u32 *) &u32value, 1);
> +	if (s16subrtnretval == -1) {
> +		return -1;
> +	}
> +
> +	u32offset = (PRU_CAN_TX_MAILBOX7_STATUS_REGISTER & 0xFFFF);
> +	u32value = 0x00000001;
> +	s16subrtnretval = pruss_writel(dev, u32offset, (u32 *) &u32value, 1);
> +	if (s16subrtnretval == -1) {
> +		return -1;
> +	}
> +
> +	u32offset = (PRU_CAN_TX_ERROR_COUNTER_REGISTER & 0xFFFF);
> +	u32value = 0x00000000;
> +	s16subrtnretval = pruss_writel(dev, u32offset, (u32 *) &u32value, 1);
> +	if (s16subrtnretval == -1) {
> +		return -1;
> +	}
> +
> +	u32offset = (PRU_CAN_TX_TIMING_REGISTER & 0xFFFF);
> +	u32value = 0x00000000;
> +	s16subrtnretval = pruss_writel(dev, u32offset, (u32 *) &u32value, 1);
> +	if (s16subrtnretval == -1) {
> +		return -1;
> +	}
> +
> +	u32offset = (PRU_CAN_TX_CLOCK_BRP_REGISTER & 0xFFFF);
> +	u32value = 0x00000000;
> +	s16subrtnretval = pruss_writel(dev, u32offset, (u32 *) &u32value, 1);
> +	if (s16subrtnretval == -1) {
> +		return -1;
> +	}
> +
> +	u32offset = (PRU_CAN_TX_ERROR_COUNTER_REGISTER & 0xFFFF);
> +	u32value = 0x00000000;
> +	s16subrtnretval = pruss_writel(dev, u32offset, (u32 *) &u32value, 1);
> +	if (s16subrtnretval == -1) {
> +		return -1;
> +	}
> +
> +	u32offset = (PRUSS_INTC_POLARITY0 & 0xFFFF);
> +	u32value = 0xFFFFFFFF;
> +	s16subrtnretval = pruss_writel(dev, u32offset, (u32 *) &u32value, 1);
> +	if (s16subrtnretval == -1) {
> +		return -1;
> +	}
> +	u32offset = (PRUSS_INTC_POLARITY1 & 0xFFFF);
> +	u32value = 0xFFFFFFFF;
> +	s16subrtnretval = pruss_writel(dev, u32offset, (u32 *) &u32value, 1);
> +	if (s16subrtnretval == -1) {
> +		return -1;
> +	}
> +	u32offset = (PRUSS_INTC_TYPE0 & 0xFFFF);
> +	u32value = 0x1C000000;
> +	s16subrtnretval = pruss_writel(dev, u32offset, (u32 *) &u32value, 1);
> +	if (s16subrtnretval == -1) {
> +		return -1;
> +	}
> +	u32offset = (PRUSS_INTC_TYPE1 & 0xFFFF);
> +	u32value = 0x00000000;
> +	s16subrtnretval = pruss_writel(dev, u32offset, (u32 *) &u32value, 1);
> +	if (s16subrtnretval == -1) {
> +		return -1;
> +	}
> +
> +	u32offset = (PRUSS_INTC_HSTINTENIDXCLR & 0xFFFF);
> +	u32value = 0x0;
> +	s16subrtnretval = pruss_writel(dev, u32offset, (u32 *) &u32value, 1);
> +	if (s16subrtnretval == -1) {
> +		return -1;
> +	}
> +
> +	u32offset = (PRUSS_INTC_GLBLEN & 0xFFFF);
> +	u32value = 0x1;
> +	s16subrtnretval = pruss_writel(dev, u32offset, (u32 *) &u32value, 1);
> +	if (s16subrtnretval == -1) {
> +		return -1;
> +	}
> +	/* tx intr map arm->pru */
> +	u32offset = (PRUSS_INTC_HSTINTENIDXSET & 0xFFFF);
> +	u32value = 0x0;
> +	s16subrtnretval = pruss_writel(dev, u32offset, (u32 *) &u32value, 1);
> +	if (s16subrtnretval == -1) {
> +		return -1;
> +	}
> +
> +	u32offset = (PRUSS_INTC_HOSTMAP0 & 0xFFFF);
> +	u32value = 0x03020100;
> +	s16subrtnretval = pruss_writel(dev, u32offset, (u32 *) &u32value, 1);
> +	if (s16subrtnretval == -1) {
> +		return -1;
> +	}
> +
> +	u32offset = (PRUSS_INTC_HOSTMAP1 & 0xFFFF);
> +	u32value = 0x07060504;
> +	s16subrtnretval = pruss_writel(dev, u32offset, (u32 *) &u32value, 1);
> +	if (s16subrtnretval == -1) {
> +		return -1;
> +	}
> +
> +	u32offset = (PRUSS_INTC_HOSTMAP2 & 0xFFFF);
> +	u32value = 0x0000908;
> +	s16subrtnretval = pruss_writel(dev, u32offset, (u32 *) &u32value, 1);
> +	if (s16subrtnretval == -1) {
> +		return -1;
> +	}
> +
> +	u32offset = (PRUSS_INTC_CHANMAP0 & 0xFFFF);
> +	u32value = 0;
> +	s16subrtnretval = pruss_writel(dev, u32offset, (u32 *) &u32value, 1);
> +	if (s16subrtnretval == -1) {
> +		return -1;
> +	}
> +
> +	u32offset = (PRUSS_INTC_CHANMAP8 & 0xFFFF);
> +	u32value = 0x00020200;
> +	s16subrtnretval = pruss_writel(dev, u32offset, (u32 *) &u32value, 1);
> +	if (s16subrtnretval == -1) {
> +		return -1;
> +	}
> +
> +	u32offset = (PRUSS_INTC_STATIDXCLR & 0xFFFF);
> +	u32value = 32;
> +	s16subrtnretval = pruss_writel(dev, u32offset, (u32 *) &u32value, 1);
> +	if (s16subrtnretval == -1) {
> +		return -1;
> +	}
> +
> +	u32offset = (PRUSS_INTC_STATIDXCLR & 0xFFFF);
> +	u32value = 19;
> +	s16subrtnretval = pruss_writel(dev, u32offset, (u32 *) &u32value, 1);
> +	if (s16subrtnretval == -1) {
> +		return -1;
> +	}
> +
> +	u32offset = (PRUSS_INTC_ENIDXSET & 0xFFFF);
> +	u32value = 19;
> +	s16subrtnretval = pruss_writel(dev, u32offset, (u32 *) &u32value, 1);
> +	if (s16subrtnretval == -1) {
> +		return -1;
> +	}
> +	u32offset = (PRUSS_INTC_STATIDXCLR & 0xFFFF);
> +	u32value = 18;
> +	s16subrtnretval = pruss_writel(dev, u32offset, (u32 *) &u32value, 1);
> +	if (s16subrtnretval == -1) {
> +		return -1;
> +	}
> +
> +	u32offset = (PRUSS_INTC_ENIDXSET & 0xFFFF);
> +	u32value = 18;
> +	s16subrtnretval = pruss_writel(dev, u32offset, (u32 *) &u32value, 1);
> +	if (s16subrtnretval == -1) {
> +		return -1;
> +	}
> +
> +	u32offset = (PRUSS_INTC_STATIDXCLR & 0xFFFF);
> +	u32value = 34;
> +	s16subrtnretval = pruss_writel(dev, u32offset, (u32 *) &u32value, 1);
> +	if (s16subrtnretval == -1) {
> +		return -1;
> +	}
> +
> +	u32offset = (PRUSS_INTC_ENIDXSET & 0xFFFF);
> +	u32value = 34;
> +	s16subrtnretval = pruss_writel(dev, u32offset, (u32 *) &u32value, 1);
> +	if (s16subrtnretval == -1) {
> +		return -1;
> +	}
> +
> +	u32offset = (PRUSS_INTC_ENIDXSET & 0xFFFF);
> +	u32value = 32;
> +	s16subrtnretval = pruss_writel(dev, u32offset, (u32 *) &u32value, 1);
> +	if (s16subrtnretval == -1) {
> +		return -1;
> +	}
> +
> +	u32offset = (PRUSS_INTC_HOSTINTEN & 0xFFFF);
> +	u32value = 0x5;
> +	s16subrtnretval = pruss_writel(dev, u32offset, (u32 *) &u32value, 1);
> +	if (s16subrtnretval == -1) {
> +		return -1;
> +	}
> +
> +/* PRU0 - Rx Internal Registers Initializations */
> +
> +	u32offset = (PRU_CAN_RX_GLOBAL_CONTROL_REGISTER & 0xFFFF);
> +	u32value = 0x00000000;
> +	s16subrtnretval = pruss_writel(dev, u32offset, (u32 *) &u32value, 1);
> +	if (s16subrtnretval == -1) {
> +		return -1;
> +	}
> +
> +	u32offset = (PRU_CAN_RX_GLOBAL_STATUS_REGISTER & 0xFFFF);
> +	u32value = 0x00000040;
> +	s16subrtnretval = pruss_writel(dev, u32offset, (u32 *) &u32value, 1);
> +	if (s16subrtnretval == -1) {
> +		return -1;
> +	}
> +
> +	u32offset = (PRU_CAN_RX_INTERRUPT_MASK_REGISTER & 0xFFFF);
> +	u32value = 0x00004000;
> +	s16subrtnretval = pruss_writel(dev, u32offset, (u32 *) &u32value, 1);
> +	if (s16subrtnretval == -1) {
> +		return -1;
> +	}
> +
> +	u32offset = (PRU_CAN_RX_INTERRUPT_STATUS_REGISTER & 0xFFFF);
> +	u32value = 0x00000000;
> +	s16subrtnretval = pruss_writel(dev, u32offset, (u32 *) &u32value, 1);
> +	if (s16subrtnretval == -1) {
> +		return -1;
> +	}
> +
> +	u32offset = (PRU_CAN_RX_MAILBOX0_STATUS_REGISTER & 0xFFFF);
> +	u32value = 0x00000000;
> +	s16subrtnretval = pruss_writel(dev, u32offset, (u32 *) &u32value, 1);
> +	if (s16subrtnretval == -1) {
> +		return -1;
> +	}
> +
> +	u32offset = (PRU_CAN_RX_MAILBOX1_STATUS_REGISTER & 0xFFFF);
> +	u32value = 0x0000000;
> +	s16subrtnretval = pruss_writel(dev, u32offset, (u32 *) &u32value, 1);
> +	if (s16subrtnretval == -1) {
> +		return -1;
> +	}
> +
> +	u32offset = (PRU_CAN_RX_MAILBOX2_STATUS_REGISTER & 0xFFFF);
> +	u32value = 0x00000000;
> +	s16subrtnretval = pruss_writel(dev, u32offset, (u32 *) &u32value, 1);
> +	if (s16subrtnretval == -1) {
> +		return -1;
> +	}
> +
> +	u32offset = (PRU_CAN_RX_MAILBOX3_STATUS_REGISTER & 0xFFFF);
> +	u32value = 0x00000000;
> +	s16subrtnretval = pruss_writel(dev, u32offset, (u32 *) &u32value, 1);
> +	if (s16subrtnretval == -1) {
> +		return -1;
> +	}
> +
> +	u32offset = (PRU_CAN_RX_MAILBOX4_STATUS_REGISTER & 0xFFFF);
> +	u32value = 0x00000000;
> +	s16subrtnretval = pruss_writel(dev, u32offset, (u32 *) &u32value, 1);
> +	if (s16subrtnretval == -1) {
> +		return -1;
> +	}
> +
> +	u32offset = (PRU_CAN_RX_MAILBOX5_STATUS_REGISTER & 0xFFFF);
> +	u32value = 0x00000000;
> +	s16subrtnretval = pruss_writel(dev, u32offset, (u32 *) &u32value, 1);
> +	if (s16subrtnretval == -1) {
> +		return -1;
> +	}
> +
> +	u32offset = (PRU_CAN_RX_MAILBOX6_STATUS_REGISTER & 0xFFFF);
> +	u32value = 0x00000000;
> +	s16subrtnretval = pruss_writel(dev, u32offset, (u32 *) &u32value, 1);
> +	if (s16subrtnretval == -1) {
> +		return -1;
> +	}
> +
> +	u32offset = (PRU_CAN_RX_MAILBOX7_STATUS_REGISTER & 0xFFFF);
> +	u32value = 0x00000000;
> +	s16subrtnretval = pruss_writel(dev, u32offset, (u32 *) &u32value, 1);
> +	if (s16subrtnretval == -1) {
> +		return -1;
> +	}
> +
> +	u32offset = (PRU_CAN_RX_ERROR_COUNTER_REGISTER & 0xFFFF);
> +	u32value = 0x00000000;
> +	s16subrtnretval = pruss_writel(dev, u32offset, (u32 *) &u32value, 1);
> +	if (s16subrtnretval == -1) {
> +		return -1;
> +	}
> +
> +	u32offset = (PRU_CAN_RX_TIMING_REGISTER & 0xFFFF);
> +	u32value = 0x0000000;
> +	s16subrtnretval = pruss_writel(dev, u32offset, (u32 *) &u32value, 1);
> +	if (s16subrtnretval == -1) {
> +		return -1;
> +	}
> +
> +	u32offset = (PRU_CAN_RX_CLOCK_BRP_REGISTER & 0xFFFF);
> +	u32value = 0x00000000;
> +	s16subrtnretval = pruss_writel(dev, u32offset, (u32 *) &u32value, 1);
> +	if (s16subrtnretval == -1) {
> +		return -1;
> +	}

Above I realize a lot of duplicated code. Could be handled by an array
more efficiently, I believe.


> +	return 0;
> +}
> +
> +
> +/*
> + * pru_can_emu_open()		Opens the can emu for
> + * application to use. This API will be called by the Application
> + * to Open the can emu for application to use.
> + *
> + * param	pstremuapphndl	Pointer to application handler
> + * structure
> + *
> + * return   SUCCESS or FAILURE
> + */
> +s16 pru_can_emu_open(struct device *dev, can_emu_app_hndl *pstremuapphndl)
> +{
> +
> +	if (pstremuapphndl == NULL) {
> +		return -1;
> +	}
> +
> +	if (gstr_can_inst[pstremuapphndl->ecaninstance].bcaninststate == 1) {
> +		return -1;
> +	}
> +
> +	gstr_can_inst[(u8) pstremuapphndl->ecaninstance].
> +					bcaninststate = (bool)1;
> +	gstr_can_inst[(u8) pstremuapphndl->
> +		ecaninstance].ecantransferdirection =
> +		(can_transfer_direction)(u8)pstremuapphndl->ecantransferdirection;
> +	gstr_can_inst[(u8) pstremuapphndl->ecaninstance].
> +		u32apphandlerptr = (u32) pstremuapphndl;
> +
> +	return 0;
> +}
> +
> +
> +/*
> + * brief    pru_can_emu_close()	Closes the can emu for other
> + * applications to use. This API will be called by the Application to Close
> + * the can emu for other applications to use
> + *
> + * param	pstremuapphndl	Pointer to application handler structure
> + *
> + * return   SUCCESS or FAILURE
> + */
> +s16 pru_can_emu_close(struct device *dev, can_emu_app_hndl *pstremuapphndl)
> +{
> +
> +	if (pstremuapphndl == NULL) {
> +		return -1;
> +	}
> +	if (gstr_can_inst[pstremuapphndl->ecaninstance].bcaninststate == 0) {
> +		return -1;
> +	}
> +	if ((u32) pstremuapphndl != gstr_can_inst[(u8) pstremuapphndl->
> +			ecaninstance].u32apphandlerptr){
> +		return -1;
> +	}
> +	gstr_can_inst[(u8) pstremuapphndl->ecaninstance].bcaninststate
> +		= (bool) 0;
> +	gstr_can_inst[(u8) pstremuapphndl->
> +	ecaninstance].ecantransferdirection = (can_transfer_direction) 0;
> +	gstr_can_inst[(u8) pstremuapphndl->ecaninstance].u32apphandlerptr = 0;
> +
> +	return 0;
> +}
> +
> +/*
> + * brief    pru_can_emu_exit()	Diables all the PRUs
> + * This API will be called by the Application to disable all PRUs
> + * param	None
> + * return   SUCCESS or FAILURE
> + */
> +s16 pru_can_emu_exit(struct device *dev)
> +{
> +	s16 s16subrtnretval;
> +
> +	s16subrtnretval = pruss_disable(dev, CAN_RX_PRU_0);
> +	if (s16subrtnretval == -1)
> +		return -1;
> +	s16subrtnretval = pruss_disable(dev, CAN_TX_PRU_1);
> +	if (s16subrtnretval == -1)
> +		return -1;
> +
> +	return 0;
> +}
> +
> +s16 pru_can_emu_sreset(struct device *dev)
> +{
> +	return 0;
> +}
> +
> +s16 pru_can_tx(struct device *dev, u8 u8mailboxnumber, u8 u8prunumber)
> +{
> +	u32 u32offset = 0;
> +	u32 u32value = 0;
> +	s16 s16subrtnretval = -1;
> +
> +	if (DA8XX_PRUCORE_1 == u8prunumber) {
> +		switch (u8mailboxnumber) {
> +		case 0:
> +			u32offset = (PRU_CAN_TX_MAILBOX0_STATUS_REGISTER & 0xFFFF);
> +			u32value = 0x00000080;
> +			s16subrtnretval = pruss_writel(dev, u32offset,
> +					(u32 *) &u32value, 1);
> +			if (s16subrtnretval == -1) {
> +				return -1;
> +			}
> +			break;
> +		case 1:
> +			u32offset = (PRU_CAN_TX_MAILBOX1_STATUS_REGISTER & 0xFFFF);
> +			u32value = 0x00000080;
> +			s16subrtnretval = pruss_writel(dev, u32offset,
> +						(u32 *) &u32value, 1);
> +			if (s16subrtnretval == -1) {
> +				return -1;
> +			}
> +			break;
> +		case 2:
> +			u32offset = (PRU_CAN_TX_MAILBOX2_STATUS_REGISTER & 0xFFFF);
> +			u32value = 0x00000080;
> +			s16subrtnretval = pruss_writel(dev, u32offset,
> +						(u32 *) &u32value, 1);
> +			if (s16subrtnretval == -1) {
> +				return -1;
> +			}
> +			break;
> +		case 3:
> +			u32offset = (PRU_CAN_TX_MAILBOX3_STATUS_REGISTER & 0xFFFF);
> +			u32value = 0x00000080;
> +			s16subrtnretval = pruss_writel(dev, u32offset,
> +						(u32 *) &u32value, 1);
> +			if (s16subrtnretval == -1) {
> +				return -1;
> +			}
> +			break;
> +		case 4:
> +			u32offset = (PRU_CAN_TX_MAILBOX4_STATUS_REGISTER & 0xFFFF);
> +			u32value = 0x00000080;
> +			s16subrtnretval = pruss_writel(dev, u32offset,
> +						(u32 *) &u32value, 1);
> +			if (s16subrtnretval == -1) {
> +				return -1;
> +			}
> +			break;
> +		case 5:
> +			u32offset = (PRU_CAN_TX_MAILBOX5_STATUS_REGISTER & 0xFFFF);
> +			u32value = 0x00000080;
> +			s16subrtnretval = pruss_writel(dev, u32offset,
> +						(u32 *) &u32value, 1);
> +			if (s16subrtnretval == -1) {
> +				return -1;
> +			}
> +			break;
> +		case 6:
> +			u32offset = (PRU_CAN_TX_MAILBOX6_STATUS_REGISTER & 0xFFFF);
> +			u32value = 0x00000080;
> +			s16subrtnretval = pruss_writel(dev, u32offset,
> +						(u32 *) &u32value, 1);
> +			if (s16subrtnretval == -1) {
> +				return -1;
> +			}
> +			break;
> +		case 7:
> +			u32offset = (PRU_CAN_TX_MAILBOX7_STATUS_REGISTER & 0xFFFF);
> +			u32value = 0x00000080;
> +			s16subrtnretval = pruss_writel(dev, u32offset,
> +						(u32 *) &u32value, 1);
> +			if (s16subrtnretval == -1) {
> +				return -1;
> +			}
> +			break;
> +		default:
> +			return -1;
> +		}
> +	} else {
> +
> +		u32offset = (PRU_CAN_RX_INTERRUPT_STATUS_REGISTER & 0xFFFF);
> +		u32value = 0x00000000;
> +		s16subrtnretval = pruss_readl(dev, u32offset,
> +						(u32 *) &u32value, 1);
> +		if (s16subrtnretval == -1) {
> +			return -1;
> +		}
> +		u32value = u32value & ~(1 << u8mailboxnumber);
> +		s16subrtnretval = pruss_writel(dev, u32offset,
> +					(u32 *) &u32value, 1);
> +		if (s16subrtnretval == -1) {
> +			return -1;
> +		}
> +
> +		switch (u8mailboxnumber) {
> +		case 0:
> +			u32offset = (PRU_CAN_RX_MAILBOX0_STATUS_REGISTER & 0xFFFF);
> +			u32value = 0x00000000;
> +			s16subrtnretval = pruss_writel(dev, u32offset,
> +						(u32 *) &u32value, 1);
> +			if (s16subrtnretval == -1) {
> +				return -1;
> +			}
> +			break;
> +		case 1:
> +			u32offset = (PRU_CAN_RX_MAILBOX1_STATUS_REGISTER & 0xFFFF);
> +			u32value = 0x00000000;
> +			s16subrtnretval = pruss_writel(dev, u32offset,
> +						(u32 *) &u32value, 1);
> +			if (s16subrtnretval == -1) {
> +				return -1;
> +			}
> +			break;
> +		case 2:
> +			u32offset = (PRU_CAN_RX_MAILBOX2_STATUS_REGISTER & 0xFFFF);
> +			u32value = 0x00000000;
> +			s16subrtnretval = pruss_writel(dev, u32offset,
> +						(u32 *) &u32value, 1);
> +			if (s16subrtnretval == -1) {
> +				return -1;
> +			}
> +			break;
> +		case 3:
> +			u32offset = (PRU_CAN_RX_MAILBOX3_STATUS_REGISTER & 0xFFFF);
> +			u32value = 0x00000000;
> +			s16subrtnretval = pruss_writel(dev, u32offset,
> +						(u32 *) &u32value, 1);
> +			if (s16subrtnretval == -1) {
> +				return -1;
> +			}
> +			break;
> +		case 4:
> +			u32offset = (PRU_CAN_RX_MAILBOX4_STATUS_REGISTER & 0xFFFF);
> +			u32value = 0x00000000;
> +			s16subrtnretval = pruss_writel(dev, u32offset,
> +						(u32 *) &u32value, 1);
> +			if (s16subrtnretval == -1) {
> +				return -1;
> +			}
> +			break;
> +		case 5:
> +			u32offset = (PRU_CAN_RX_MAILBOX5_STATUS_REGISTER & 0xFFFF);
> +			u32value = 0x00000000;
> +			s16subrtnretval = pruss_writel(dev, u32offset,
> +						(u32 *) &u32value, 1);
> +			if (s16subrtnretval == -1) {
> +				return -1;
> +			}
> +			break;
> +		case 6:
> +			u32offset = (PRU_CAN_RX_MAILBOX6_STATUS_REGISTER & 0xFFFF);
> +			u32value = 0x00000000;
> +			s16subrtnretval = pruss_writel(dev, u32offset,
> +						(u32 *) &u32value, 1);
> +			if (s16subrtnretval == -1) {
> +				return -1;
> +			}
> +			break;
> +		case 7:
> +			u32offset = (PRU_CAN_RX_MAILBOX7_STATUS_REGISTER & 0xFFFF);
> +			u32value = 0x00000000;
> +			s16subrtnretval = pruss_writel(dev, u32offset,
> +						(u32 *) &u32value, 1);
> +			if (s16subrtnretval == -1) {
> +				return -1;
> +			}
> +			break;
> +		default:
> +			return -1;
> +		}

Ditto.

> +	}
> +	return 0;
> +}
> +
> +s16 pru_can_start_abort_tx(struct device *dev, bool bcantransmitabortflag)
> +{
> +	u32 u32offset;
> +	u32 u32value;
> +	s16 s16subrtnretval;
> +	u32offset = (PRUSS_INTC_STATIDXCLR & 0xFFFF);
> +	u32value = 32;
> +	s16subrtnretval = pruss_writel(dev, u32offset,
> +					(u32 *) &u32value, 1);
> +
> +	u32offset = (PRUSS_INTC_ENIDXSET & 0xFFFF);
> +	u32value = 32;
> +	s16subrtnretval = pruss_writel(dev, u32offset,
> +					(u32 *) &u32value, 1);
> +
> +	u32offset = (PRUSS_INTC_STATIDXSET & 0xFFFF);
> +	u32value = 32;
> +	s16subrtnretval = pruss_writel(dev, u32offset,
> +					(u32 *) &u32value, 1);
> +	if (s16subrtnretval == -1) {
> +		return -1;
> +	}
> +	return 0;
> +}
> +
> +s16 pru_can_mask_ints(struct device *dev, u32 int_mask)
> +{
> +	return 0;
> +}
> +
> +int pru_can_get_error_cnt(struct device *dev, u8 u8prunumber)
> +{
> +	return 0;
> +}
> +
> +int pru_can_get_intc_status(struct device *dev)
> +{
> +	u32 u32offset = 0;
> +	u32 u32getvalue = 0;
> +	u32 u32clrvalue = 0;
> +
> +	u32offset = (PRUSS_INTC_STATCLRINT1 & 0xFFFF);
> +	pruss_readl(dev, u32offset, (u32 *) &u32getvalue, 1);
> +
> +	if (u32getvalue & 4)
> +		u32clrvalue = 34;	/* CLR Event 34 */
> +
> +	if (u32getvalue & 2)
> +		u32clrvalue = 33;	/* CLR Event 33  */
> +
> +	if (u32clrvalue) {
> +		u32offset = (PRUSS_INTC_STATIDXCLR & 0xFFFF);
> +		pruss_writel(dev, u32offset, &u32clrvalue, 1);
> +	} else
> +		return -1;
> +
> +	return u32getvalue;
> +}
> diff --git a/drivers/net/can/da8xx_pruss/pruss_can_api.h b/drivers/net/can/da8xx_pruss/pruss_can_api.h
> new file mode 100644
> index 0000000..7550456
> --- /dev/null
> +++ b/drivers/net/can/da8xx_pruss/pruss_can_api.h
> @@ -0,0 +1,290 @@
> +/*
> + * Copyright (C) 2010 Texas Instruments Incorporated
> + * Author: Ganeshan N
> + *
> + * This program is free software; you can redistribute it and/or modify it
> + * under the terms of the GNU General Public License as  published by the
> + * Free Software Foundation version 2.
> + *
> + * This program is distributed "as is" WITHOUT ANY WARRANTY of any kind,
> + * whether express or implied; without even the implied warranty of
> + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
> + * General Public License for more details.
> + */
> +
> +#ifndef _PRU_CAN_API_H_
> +#define _PRU_CAN_API_H_
> +
> +#include <linux/types.h>
> +#include <linux/mfd/pruss/da8xx_pru.h>
> +
> +
> +#define CAN_BIT_TIMINGS			(0x273)
> +
> +/* Timer Clock is sourced from DDR freq (PLL1 SYS CLK 2) */
> +#define	TIMER_CLK_FREQ			132000000
> +
> +#define TIMER_SETUP_DELAY		14
> +#define GPIO_SETUP_DELAY		150
> +
> +#define CAN_RX_PRU_0			PRUSS_NUM0
> +#define CAN_TX_PRU_1			PRUSS_NUM1
> +
> +/* Number of Instruction in the Delay loop */
> +#define DELAY_LOOP_LENGTH		2
> +
> +#define PRU1_BASE_ADDR			0x2000
> +
> +#define PRU_CAN_TX_GLOBAL_CONTROL_REGISTER		(PRU1_BASE_ADDR)
> +#define PRU_CAN_TX_GLOBAL_STATUS_REGISTER		(PRU1_BASE_ADDR	+ 0x04)
> +#define PRU_CAN_TX_INTERRUPT_MASK_REGISTER		(PRU1_BASE_ADDR	+ 0x08)
> +#define PRU_CAN_TX_INTERRUPT_STATUS_REGISTER		(PRU1_BASE_ADDR	+ 0x0C)
> +#define PRU_CAN_TX_MAILBOX0_STATUS_REGISTER		(PRU1_BASE_ADDR	+ 0x10)
> +#define PRU_CAN_TX_MAILBOX1_STATUS_REGISTER		(PRU1_BASE_ADDR	+ 0x14)
> +#define PRU_CAN_TX_MAILBOX2_STATUS_REGISTER		(PRU1_BASE_ADDR	+ 0x18)
> +#define PRU_CAN_TX_MAILBOX3_STATUS_REGISTER		(PRU1_BASE_ADDR	+ 0x1C)
> +#define PRU_CAN_TX_MAILBOX4_STATUS_REGISTER		(PRU1_BASE_ADDR	+ 0x20)
> +#define PRU_CAN_TX_MAILBOX5_STATUS_REGISTER		(PRU1_BASE_ADDR	+ 0x24)
> +#define PRU_CAN_TX_MAILBOX6_STATUS_REGISTER		(PRU1_BASE_ADDR	+ 0x28)
> +#define PRU_CAN_TX_MAILBOX7_STATUS_REGISTER		(PRU1_BASE_ADDR	+ 0x2C)
> +#define PRU_CAN_TX_ERROR_COUNTER_REGISTER		(PRU1_BASE_ADDR	+ 0x30)
> +#define PRU_CAN_TX_TIMING_REGISTER			(PRU1_BASE_ADDR	+ 0x34)
> +#define PRU_CAN_TX_CLOCK_BRP_REGISTER			(PRU1_BASE_ADDR	+ 0x38)
> +
> +#define PRU_CAN_TX_MAILBOX0				(PRU1_BASE_ADDR	+ 0x40)
> +#define PRU_CAN_TX_MAILBOX1				(PRU1_BASE_ADDR	+ 0x50)
> +#define PRU_CAN_TX_MAILBOX2				(PRU1_BASE_ADDR	+ 0x60)
> +#define PRU_CAN_TX_MAILBOX3				(PRU1_BASE_ADDR	+ 0x70)
> +#define PRU_CAN_TX_MAILBOX4				(PRU1_BASE_ADDR	+ 0x80)
> +#define PRU_CAN_TX_MAILBOX5				(PRU1_BASE_ADDR	+ 0x90)
> +#define PRU_CAN_TX_MAILBOX6				(PRU1_BASE_ADDR	+ 0xA0)
> +#define PRU_CAN_TX_MAILBOX7				(PRU1_BASE_ADDR	+ 0xB0)
> +
> +#define PRU_CAN_TIMING_VAL_TX				(PRU1_BASE_ADDR	+ 0xC0)
> +#define PRU_CAN_TIMING_VAL_TX_SJW			(PRU1_BASE_ADDR	+ 0xC4)
> +#define PRU_CAN_TRANSMIT_FRAME				(PRU1_BASE_ADDR	+ 0xE0)
> +
> +#define PRU0_BASE_ADDR					0
> +
> +#define PRU_CAN_RX_GLOBAL_CONTROL_REGISTER		(PRU0_BASE_ADDR)
> +#define PRU_CAN_RX_GLOBAL_STATUS_REGISTER		(PRU0_BASE_ADDR	+ 0x04)
> +#define PRU_CAN_RX_INTERRUPT_MASK_REGISTER		(PRU0_BASE_ADDR	+ 0x08)
> +#define PRU_CAN_RX_INTERRUPT_STATUS_REGISTER		(PRU0_BASE_ADDR	+ 0x0C)
> +#define PRU_CAN_RX_MAILBOX0_STATUS_REGISTER		(PRU0_BASE_ADDR	+ 0x10)
> +#define PRU_CAN_RX_MAILBOX1_STATUS_REGISTER		(PRU0_BASE_ADDR	+ 0x14)
> +#define PRU_CAN_RX_MAILBOX2_STATUS_REGISTER		(PRU0_BASE_ADDR	+ 0x18)
> +#define PRU_CAN_RX_MAILBOX3_STATUS_REGISTER		(PRU0_BASE_ADDR	+ 0x1C)
> +#define PRU_CAN_RX_MAILBOX4_STATUS_REGISTER		(PRU0_BASE_ADDR	+ 0x20)
> +#define PRU_CAN_RX_MAILBOX5_STATUS_REGISTER		(PRU0_BASE_ADDR	+ 0x24)
> +#define PRU_CAN_RX_MAILBOX6_STATUS_REGISTER		(PRU0_BASE_ADDR	+ 0x28)
> +#define PRU_CAN_RX_MAILBOX7_STATUS_REGISTER		(PRU0_BASE_ADDR	+ 0x2C)
> +#define PRU_CAN_RX_MAILBOX8_STATUS_REGISTER		(PRU0_BASE_ADDR	+ 0x30)
> +#define PRU_CAN_RX_ERROR_COUNTER_REGISTER		(PRU0_BASE_ADDR	+ 0x34)
> +#define PRU_CAN_RX_TIMING_REGISTER			(PRU0_BASE_ADDR	+ 0x38)
> +#define PRU_CAN_RX_CLOCK_BRP_REGISTER			(PRU0_BASE_ADDR	+ 0x3C)
> +
> +#define PRU_CAN_RX_MAILBOX0				(PRU0_BASE_ADDR	+ 0x40)
> +#define PRU_CAN_RX_MAILBOX1				(PRU0_BASE_ADDR	+ 0x50)
> +#define PRU_CAN_RX_MAILBOX2				(PRU0_BASE_ADDR	+ 0x60)
> +#define PRU_CAN_RX_MAILBOX3				(PRU0_BASE_ADDR	+ 0x70)
> +#define PRU_CAN_RX_MAILBOX4				(PRU0_BASE_ADDR	+ 0x80)
> +#define PRU_CAN_RX_MAILBOX5				(PRU0_BASE_ADDR	+ 0x90)
> +#define PRU_CAN_RX_MAILBOX6				(PRU0_BASE_ADDR	+ 0xA0)
> +#define PRU_CAN_RX_MAILBOX7				(PRU0_BASE_ADDR	+ 0xB0)
> +#define PRU_CAN_RX_MAILBOX8				(PRU0_BASE_ADDR	+ 0xC0)
> +
> +#define PRU_CAN_TIMING_VAL_RX				(PRU0_BASE_ADDR	+ 0xD0)
> +#define PRU_CAN_RECEIVE_FRAME				(PRU0_BASE_ADDR	+ 0xD4)
> +#define PRU_CAN_ID_MAP					(PRU0_BASE_ADDR	+ 0xF0)

Please consider using a struct to define the register layout. This would
make you code much much more readable and compact:

	writel(&regs->brp_register, bitrateprescaler);

instead of:

	u32offset = (PRU_CAN_TX_CLOCK_BRP_REGISTER);
	pruss_writel(dev, u32offset, (u32 *) &u16bitrateprescaler, 1);


> +#define PRU_CAN_ERROR_ACTIVE				128
> +
> +#define CAN_ACK_FAILED					0xE
> +#define CAN_ARBTR_FAIL					0xD
> +#define CAN_BIT_ERROR					0xC
> +#define CAN_TRANSMISSION_SUCCESS			0xA
> +
> +#define STD_DATA_FRAME					0x1
> +#define EXTD_DATA_FRAME					0x2
> +#define STD_REMOTE_FRAME				0x3
> +#define EXTD_REMOTE_FRAME				0x4
> +
> +#define PRU_CAN_MAX_SJW					8
> +#define PRU_CAN_MAX_PHSEG1				25
> +#define PRU_CAN_MAX_PHSEG2				25
> +
> +#define DA8XX_PRUCANCORE_0_REGS				0x7000
> +#define DA8XX_PRUCANCORE_1_REGS				0x7800
> +#define PRU0_PROG_RAM_START_OFFSET			0x8000
> +#define PRU1_PROG_RAM_START_OFFSET			0xC000
> +#define PRU_CAN_INIT_MAX_TIMEOUT			0xFF
> +
> +typedef enum {
> +	ecaninst0 = 0,
> +	ecaninst1,
> +	ecanmaxinst
> +} can_instance_enum;
> +
> +typedef enum {
> +	ecanmailbox0 = 0,
> +	ecanmailbox1,
> +	ecanmailbox2,
> +	ecanmailbox3,
> +	ecanmailbox4,
> +	ecanmailbox5,
> +	ecanmailbox6,
> +	ecanmailbox7
> +} can_mailbox_number;
> +
> +typedef enum {
> +	ecandirectioninit = 0,
> +	ecantransmit,
> +	ecanreceive
> +} can_transfer_direction;
> +
> +typedef struct {
> +	u16 u16extendedidentifier;
> +	u16 u16baseidentifier;
> +	u8 u8data7;
> +	u8 u8data6;
> +	u8 u8data5;
> +	u8 u8data4;
> +	u8 u8data3;
> +	u8 u8data2;
> +	u8 u8data1;
> +	u8 u8data0;
> +	u16 u16datalength;
> +	u16 u16crc;
> +} can_mail_box_structure;
> +
> +typedef struct {
> +	can_transfer_direction ecantransferdirection;
> +} can_mailbox_config;
> +
> +typedef struct {
> +	can_instance_enum ecaninstance;
> +	can_transfer_direction ecantransferdirection;
> +	can_mail_box_structure strcanmailbox;
> +	can_mailbox_number ecanmailboxnumber;
> +	u8 u8prunumber;
> +	u32 u32globalstatus;
> +	u32 u32interruptstatus;
> +	u32 u32mailboxstatus;
> +} can_emu_app_hndl;
> +
> +typedef struct {
> +	bool bcaninststate;
> +	can_transfer_direction ecantransferdirection;
> +	u32 u32apphandlerptr;
> +} can_emu_drv_inst;
> +
> +typedef struct {
> +	u8 u8syncjumpwidth;
> +	u8 u8phseg1;
> +	u8 u8phseg2;
> +} can_bit_timing_consts;

Don't use typedef's!

Thanks.

Wolfgang.

^ permalink raw reply

* any way to reset all marked connections when using CONNMARK?
From: Chris Friesen @ 2011-02-11 21:24 UTC (permalink / raw)
  To: netdev, netfilter-devel, netfilter, coreteam


Hi,

We've got a scenario where we want to use CONNMARK to mark connections
that have passed a large number of rules in order to allow packets from
those connections to skip rules in the future (for performance reasons).

However, when we add new rules we want to ensure that all the
connections need to pass the new rules as well.

It has been proposed to add a custom patch to clear the mark for all
marked connections--is there a better way of doing this?

I thought maybe we could use the CONNMARK as a generation count and
bumping it up each time a rule is added.  This would require updating
the bypass rule each time we modify the other rules though.  If there
are better options I'd like to hear them.

Thanks,
Chris

-- 
Chris Friesen
Software Developer
GENBAND
chris.friesen@genband.com
www.genband.com

^ permalink raw reply

* Re: [PATCH v2 09/13] can: pruss CAN driver.
From: Marc Kleine-Budde @ 2011-02-11 21:33 UTC (permalink / raw)
  To: Subhasish Ghosh
  Cc: sachi-EvXpCiN+lbve9wHmmfpqLFaTQe2KTcn/,
	davinci-linux-open-source-VycZQUHpC/PFrsHnngEfi1aTQe2KTcn/,
	CAN NETWORK DRIVERS, nsekhar-l0cyMroinI0, open list,
	CAN NETWORK DRIVERS,
	linux-arm-kernel-IAPFreCvJWM7uuMidbF8XUB+6BGkLq7r,
	m-watkins-l0cyMroinI0,
	Wolfgang Grandegger (maintainer:CAN NETWORK DRIVERS)
In-Reply-To: <1297435892-28278-10-git-send-email-subhasish-EvXpCiN+lbve9wHmmfpqLFaTQe2KTcn/@public.gmane.org>


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

On 02/11/2011 03:51 PM, Subhasish Ghosh wrote:
> This patch adds support for the CAN device emulated on PRUSS.

Is this a software CAN device running on the omap dsp? Nice :)
My first impression is that this driver needs a lot of work, but we'll
help you.

Being new to the OMAP world here are soo many names for the same thing,
i.e. the CAN core and driver:

- da8cc
- pruss
- omap
- pru

These or combination of these are used all over the code. I'm preferring
one common prefix. I like the PRU_ prefix for the defines and the pru_
for functions.

Please don't encode the variable type into their names (a.k.a. polish
notation), e.g. it's "u8 data" not "u8 u8data", No typedefs, enums just
like defines in uppercase.

Get rid of the of the extra layer in pruss_can_api.c.

More comments inline:

> Signed-off-by: Subhasish Ghosh <subhasish-EvXpCiN+lbve9wHmmfpqLFaTQe2KTcn/@public.gmane.org>
> ---
>  drivers/net/can/Kconfig                     |    1 +
>  drivers/net/can/Makefile                    |    1 +
>  drivers/net/can/da8xx_pruss/Kconfig         |   73 ++
>  drivers/net/can/da8xx_pruss/Makefile        |    7 +
>  drivers/net/can/da8xx_pruss/pruss_can.c     |  758 +++++++++++++++++
>  drivers/net/can/da8xx_pruss/pruss_can_api.c | 1227 +++++++++++++++++++++++++++
>  drivers/net/can/da8xx_pruss/pruss_can_api.h |  290 +++++++
>  7 files changed, 2357 insertions(+), 0 deletions(-)
>  create mode 100644 drivers/net/can/da8xx_pruss/Kconfig
>  create mode 100644 drivers/net/can/da8xx_pruss/Makefile
>  create mode 100644 drivers/net/can/da8xx_pruss/pruss_can.c
>  create mode 100644 drivers/net/can/da8xx_pruss/pruss_can_api.c
>  create mode 100644 drivers/net/can/da8xx_pruss/pruss_can_api.h
> 
> diff --git a/drivers/net/can/Kconfig b/drivers/net/can/Kconfig
> index d5a9db6..ae8f0f9 100644
> --- a/drivers/net/can/Kconfig
> +++ b/drivers/net/can/Kconfig
> @@ -112,6 +112,7 @@ config PCH_CAN
>  	  This driver can access CAN bus.
>  
>  source "drivers/net/can/mscan/Kconfig"
> +source "drivers/net/can/da8xx_pruss/Kconfig"
>  
>  source "drivers/net/can/sja1000/Kconfig"
>  
> diff --git a/drivers/net/can/Makefile b/drivers/net/can/Makefile
> index 07ca159..849cdbf 100644
> --- a/drivers/net/can/Makefile
> +++ b/drivers/net/can/Makefile
> @@ -14,6 +14,7 @@ obj-$(CONFIG_CAN_SJA1000)	+= sja1000/
>  obj-$(CONFIG_CAN_MSCAN)		+= mscan/
>  obj-$(CONFIG_CAN_AT91)		+= at91_can.o
>  obj-$(CONFIG_CAN_TI_HECC)	+= ti_hecc.o
> +obj-$(CONFIG_CAN_TI_DA8XX_PRU)	+= da8xx_pruss/
>  obj-$(CONFIG_CAN_MCP251X)	+= mcp251x.o
>  obj-$(CONFIG_CAN_BFIN)		+= bfin_can.o
>  obj-$(CONFIG_CAN_JANZ_ICAN3)	+= janz-ican3.o
> diff --git a/drivers/net/can/da8xx_pruss/Kconfig b/drivers/net/can/da8xx_pruss/Kconfig
> new file mode 100644
> index 0000000..8b68f68
> --- /dev/null
> +++ b/drivers/net/can/da8xx_pruss/Kconfig
> @@ -0,0 +1,73 @@
> +#
> +# CAN Lite Kernel Configuration
     ^^^^^^^^^^^^^^^

what's can lite?

> +#
> +config CAN_TI_DA8XX_PRU
> +	depends on CAN_DEV && ARCH_DAVINCI && ARCH_DAVINCI_DA850
> +	tristate "PRU based CAN emulation for DA8XX"
> +	---help---
> +	Enable this to emulate a CAN controller on the PRU of DA8XX.
> +	If not sure, mark N
> +
> +config DA8XX_PRU_CANID_MBX0
> +	hex "CANID for mailbox 0"
> +	depends on CAN_TI_DA8XX_PRU
> +	default "0x123"
> +	---help---
> +	Enter the CANID for mailbox 0
> +	Default value is set to 0x123, change this as required.
> +
> +config DA8XX_PRU_CANID_MBX1
> +	hex "CANID for mailbox 1"
> +	depends on CAN_TI_DA8XX_PRU
> +	default "0x123"
> +	 ---help---
> +	Enter the CANID for mailbox 1
> +	Default value is set to 0x123, change this as required.
> +
> +config DA8XX_PRU_CANID_MBX2
> +	hex "CANID for mailbox 2"
> +	depends on CAN_TI_DA8XX_PRU
> +	default "0x123"
> +	---help---
> +	Enter the CANID for mailbox 2
> +	Default value is set to 0x123, change this as required.
> +
> +config DA8XX_PRU_CANID_MBX3
> +	hex "CANID for mailbox 3"
> +	depends on CAN_TI_DA8XX_PRU
> +	default "0x123"
> +	---help---
> +	Enter the CANID for mailbox 3
> +	Default value is set to 0x123, change this as required.
> +
> +config DA8XX_PRU_CANID_MBX4
> +	hex "CANID for mailbox 4"
> +	depends on CAN_TI_DA8XX_PRU
> +	default "0x123"
> +	---help---
> +	Enter the CANID for mailbox 4
> +	Default value is set to 0x123, change this as required.
> +
> +config DA8XX_PRU_CANID_MBX5
> +	hex "CANID for mailbox 5"
> +	depends on CAN_TI_DA8XX_PRU
> +	default "0x123"
> +	---help---
> +	Enter the CANID for mailbox 5
> +	Default value is set to 0x123, change this as required.
> +
> +config DA8XX_PRU_CANID_MBX6
> +	hex "CANID for mailbox 6"
> +	depends on CAN_TI_DA8XX_PRU
> +	default "0x123"
> +	---help---
> +	Enter the CANID for mailbox 6
> +	Default value is set to 0x123, change this as required.
> +
> +config DA8XX_PRU_CANID_MBX7
> +	hex "CANID for mailbox 7"
> +	depends on CAN_TI_DA8XX_PRU
> +	default "0x123"
> +	---help---
> +	Enter the CANID for mailbox 7
> +	Default value is set to 0x123, change this as required.

This doesn't fit to the Socketcan abstraction of a CAN card. Please
remove. After this "da8xx_pruss/Kconfig" just contains the
CAN_TI_DA8XX_PRU symbol, which can be added directly to
drivers/net/can/Kconfig. (With a perhaps a simpler kconfig symbol name.)

> diff --git a/drivers/net/can/da8xx_pruss/Makefile b/drivers/net/can/da8xx_pruss/Makefile
> new file mode 100644
> index 0000000..48f3055
> --- /dev/null
> +++ b/drivers/net/can/da8xx_pruss/Makefile
> @@ -0,0 +1,7 @@
> +#
> +# Makefile for CAN Lite emulation
> +#
> +can_emu-objs :=   pruss_can.o \
> +                  pruss_can_api.o

Do we need two c file? I haven't look at them, yet.

> +
> +obj-$(CONFIG_CAN_TI_DA8XX_PRU)    += can_emu.o
> diff --git a/drivers/net/can/da8xx_pruss/pruss_can.c b/drivers/net/can/da8xx_pruss/pruss_can.c
> new file mode 100644
> index 0000000..1b3afde
> --- /dev/null
> +++ b/drivers/net/can/da8xx_pruss/pruss_can.c
> @@ -0,0 +1,758 @@
> +/*
> + *  TI DA8XX PRU CAN Emulation device driver
> + *  Author: subhasish-EvXpCiN+lbve9wHmmfpqLFaTQe2KTcn/@public.gmane.org
> + *
> + *  This driver supports TI's PRU CAN Emulation and the
> + *  specs for the same is available at <http://www.ti.com>
> + *
> + *  Copyright (C) 2009 Texas Instruments Incorporated - http://www.ti.com/

You'll probably do some work on the driver, so add a 2011, here :)

> + *
> + *  This program is free software; you can redistribute it and/or
> + *  modify it under the terms of the GNU General Public License as
> + *  published by the Free Software Foundation version 2.
> + *
> + *  This program is distributed as is WITHOUT ANY WARRANTY of any
> + *  kind, whether express or implied; without even the implied warranty
> + *  of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
> + *  GNU General Public License for more details.
> + */
> +
> +#include <linux/module.h>
> +#include <linux/init.h>
> +#include <linux/kernel.h>
> +#include <linux/bitops.h>
> +#include <linux/interrupt.h>
> +#include <linux/errno.h>
> +#include <linux/netdevice.h>
> +#include <linux/skbuff.h>
> +#include <linux/platform_device.h>
> +#include <linux/firmware.h>
> +#include <linux/clk.h>
> +#include <linux/types.h>
> +
> +#include <linux/can.h>
> +#include <linux/can/dev.h>
> +#include <linux/can/error.h>
> +#include <mach/da8xx.h>
> +#include "pruss_can_api.h"

Do we need a separate header file?
> +
> +#define DRV_NAME "da8xx_pruss_can"
> +#define DRV_DESC "TI PRU CAN Controller Driver v0.1"
> +#define PRU_CAN_START		1
> +#define PRU_CAN_STOP		0
> +#define MB_MIN			0
> +#define MB_MAX			7

please add the common PRU_ prefis to the MB_*, too.

> +
> +#define PRU_CANMID_IDE			BIT(29)	/* Extended frame format */
> +
> +#define PRU_CAN_ISR_BIT_CCI		BIT(15)
> +#define PRU_CAN_ISR_BIT_ESI		BIT(14)
> +#define PRU_CAN_ISR_BIT_SRDI		BIT(13)
> +#define PRU_CAN_ISR_BIT_RRI		BIT(8)
> +
> +#define PRU_CAN_MBXSR_BIT_STATE		BIT(7)
> +#define PRU_CAN_MBXSR_BIT_TC		BIT(6)
> +#define PRU_CAN_MBXSR_BIT_ERR		BIT(5)
> +#define PRU_CAN_MBXSR_BIT_OF		BIT(0)
> +
> +#define PRU_CAN_GSR_BIT_TXM		BIT(7)
> +#define PRU_CAN_GSR_BIT_RXM		BIT(6)
> +#define PRU_CAN_GSR_BIT_CM		BIT(5)
> +#define PRU_CAN_GSR_BIT_EPM		BIT(4)
> +#define PRU_CAN_GSR_BIT_BFM		BIT(3)
> +#define RTR_MBX_NO			8

We don't have special mailboxes for RTR, pleae remove.

add the PRU_ prefix here, too.
> +#define MAX_INIT_RETRIES		20
> +#define L138_PRU_ARM_FREQ		312000
> +#define DFLT_PRU_FREQ			156000000

Any change that you get these values from the a clock device?
e.g.:
http://lxr.linux.no/linux+v2.6.37/drivers/net/can/flexcan.c#L909
http://lxr.linux.no/linux+v2.6.37/drivers/net/can/flexcan.c#L946

> +#define DFLT_PRU_BITRATE		125000

Please remove, we don't have a default bitrate.

> +
> +#define CONFIG_DA8XX_PRU_CANID_MBX0	0x123
> +#define CONFIG_DA8XX_PRU_CANID_MBX1	0x123
> +#define CONFIG_DA8XX_PRU_CANID_MBX2	0x123
> +#define CONFIG_DA8XX_PRU_CANID_MBX3	0x123
> +#define CONFIG_DA8XX_PRU_CANID_MBX4	0x123
> +#define CONFIG_DA8XX_PRU_CANID_MBX5	0x123
> +#define CONFIG_DA8XX_PRU_CANID_MBX6	0x123
> +#define CONFIG_DA8XX_PRU_CANID_MBX7	0x123

as alreadt said, we don't have default canids, please remove.

> +
> +#ifdef __CAN_DEBUG
> +#define __can_debug(fmt, args...) printk(KERN_DEBUG "can_debug: " fmt, ## args)
> +#else
> +#define __can_debug(fmt, args...)
> +#endif
> +#define __can_err(fmt, args...) printk(KERN_ERR "can_err: " fmt, ## args)

please use pr_<level> and and friends, use pr_fmt to set a common
prefix. Or even better use netdev_<level>.

> +
> +/*
> + * omapl_pru can private data
> + */
> +struct omapl_pru_can_priv {
> +	struct can_priv can;
> +	struct workqueue_struct *pru_can_wQ;
> +	struct work_struct rx_work;
> +	struct net_device *ndev;
> +	struct device *dev; /* pdev->dev */

nitpick: pointless comment :)

> +	struct clk *clk_timer;
> +	u32 timer_freq;
> +	can_emu_app_hndl can_tx_hndl;
> +	can_emu_app_hndl can_rx_hndl;

please no new typedefs.

> +	const struct firmware *fw_rx;
> +	const struct firmware *fw_tx;
> +	spinlock_t mbox_lock;
> +	u32 trx_irq;
> +	u32 tx_head;
> +	u32 tx_tail;
> +	u32 tx_next;
> +	u32 rx_next;

If these don't reflect register values, just use "unsigned int"s here.

> +};
> +
> +static int omapl_pru_can_get_state(const struct net_device *ndev,
> +				   enum can_state *state)

just for consistency most other can drivers use "struct net_device *dev".

> +{
> +	struct omapl_pru_can_priv *priv = netdev_priv(ndev);
> +	*state = priv->can.state;
> +	return 0;
> +}
> +
> +static int omapl_pru_can_set_bittiming(struct net_device *ndev)
> +{
> +	struct omapl_pru_can_priv *priv = netdev_priv(ndev);
> +	struct can_bittiming *bt = &priv->can.bittiming;
> +	long bit_error = 0;
> +
> +	if (priv->can.ctrlmode & CAN_CTRLMODE_3_SAMPLES) {
> +		dev_warn(priv->dev, "WARN: Triple"
> +			 "sampling not set due to h/w limitations");
> +	}

No need to check this, just set the modes you support in
"priv->can.ctrlmode_supported".

http://lxr.linux.no/linux+v2.6.37/drivers/net/can/at91_can.c#L1091

> +	if (pru_can_calc_timing(priv->dev, priv->can.clock.freq,
> +				bt->bitrate) != 0)

The above function does _set_ the bit timing into the hardware, calling
it "can_calc_timing" is a bit misleading.

Don't calculate the bit timing yoursef. Please define your
bittiming_const and set it, see:

http://lxr.linux.no/linux+v2.6.37/drivers/net/can/at91_can.c#L173
http://lxr.linux.no/linux+v2.6.37/drivers/net/can/at91_can.c#L1088

> +		return -EINVAL;
> +	bit_error =
> +	    (((priv->timer_freq / (priv->timer_freq / bt->bitrate)) -
> +	      bt->bitrate) * 1000) / bt->bitrate;
> +	if (bit_error) {
> +		bit_error =
> +		    (((priv->timer_freq / (priv->timer_freq / bt->bitrate)) -
> +		      bt->bitrate) * 1000000) / bt->bitrate;
> +		printk(KERN_INFO "\nBitrate error %ld.%ld%%\n",
> +			bit_error / 10000, bit_error % 1000);
> +	} else
> +		printk(KERN_INFO "\nBitrate error 0.0%%\n");
> +
> +	return 0;
> +}
> +
> +static void omapl_pru_can_stop(struct net_device *ndev)
> +{
> +	struct omapl_pru_can_priv *priv = netdev_priv(ndev);
> +	u16 int_mask = 0;
> +
> +	pru_can_mask_ints(priv->dev, int_mask);	/* mask all ints */
> +	pru_can_start_abort_tx(priv->dev, PRU_CAN_STOP);
> +	priv->can.state = CAN_STATE_STOPPED;
> +}
> +
> +/*
> + * This is to just set the can state to ERROR_ACTIVE
> + *	ip link set canX up type can bitrate 125000
> + */
> +static void omapl_pru_can_start(struct net_device *ndev)
> +{
> +	struct omapl_pru_can_priv *priv = netdev_priv(ndev);
> +	u16 int_mask = 0xFFFF;
> +
> +	if (priv->can.state != CAN_STATE_STOPPED)
> +		omapl_pru_can_stop(ndev);
> +
> +	pru_can_mask_ints(priv->dev, int_mask);	/* unmask all ints */
> +
> +	pru_can_get_global_status(priv->dev, &priv->can_tx_hndl);
> +	pru_can_get_global_status(priv->dev, &priv->can_rx_hndl);
> +
> +	if (PRU_CAN_GSR_BIT_EPM & priv->can_tx_hndl.u32globalstatus)
> +		priv->can.state = CAN_STATE_ERROR_PASSIVE;
> +	else if (PRU_CAN_GSR_BIT_BFM & priv->can_tx_hndl.u32globalstatus)
> +		priv->can.state = CAN_STATE_BUS_OFF;
> +	else
> +		priv->can.state = CAN_STATE_ERROR_ACTIVE;
> +}
> +
> +static int omapl_pru_can_set_mode(struct net_device *ndev, enum can_mode mode)
> +{
> +	int ret = 0;
> +
> +	switch (mode) {
> +	case CAN_MODE_START:
> +		omapl_pru_can_start(ndev);
> +		if (netif_queue_stopped(ndev))
> +			netif_wake_queue(ndev);
> +		break;
> +	case CAN_MODE_STOP:
> +		omapl_pru_can_stop(ndev);
> +		if (!netif_queue_stopped(ndev))
> +			netif_stop_queue(ndev);
> +		break;
> +	default:
> +		ret = -EOPNOTSUPP;
> +		break;
> +	}
> +	return ret;
> +}
> +
> +static netdev_tx_t omapl_pru_can_start_xmit(struct sk_buff *skb,
> +					    struct net_device *ndev)
> +{
> +	struct omapl_pru_can_priv *priv = netdev_priv(ndev);
> +	struct can_frame *cf = (struct can_frame *)skb->data;
> +	int count;
> +	u8 *data = cf->data;
> +	u8 dlc = cf->can_dlc;
> +	u8 *ptr8data = NULL;
> +
> +	netif_stop_queue(ndev);
> +	if (cf->can_id & CAN_EFF_FLAG)	/* Extended frame format */
> +		*((u32 *) &priv->can_tx_hndl.strcanmailbox) =
> +		    (cf->can_id & CAN_EFF_MASK) | PRU_CANMID_IDE;
> +	else			/* Standard frame format */
> +		*((u32 *) &priv->can_tx_hndl.strcanmailbox) =
> +		    (cf->can_id & CAN_SFF_MASK) << 18;
> +
> +	if (cf->can_id & CAN_RTR_FLAG)	/* Remote transmission request */
> +		*((u32 *) &priv->can_tx_hndl.strcanmailbox) |= CAN_RTR_FLAG;
> +
> +	ptr8data = &priv->can_tx_hndl.strcanmailbox.u8data7 + (dlc - 1);
> +	for (count = 0; count < (u8) dlc; count++) {
> +		*ptr8data-- = *data++;
> +	}
> +	*((u32 *) &priv->can_tx_hndl.strcanmailbox.u16datalength) = (u32) dlc;
> +/*
> + * search for the next available mbx
> + * if the next mbx is busy, then try the next + 1
> + * do this until the head is reached.
> + * if still unable to tx, stop accepting any packets
> + * if able to tx and the head is reached, then reset next to tail, i.e mbx0
> + * if head is not reached, then just point to the next mbx
> + */
> +	for (; priv->tx_next <= priv->tx_head; priv->tx_next++) {
> +		priv->can_tx_hndl.ecanmailboxnumber =
> +		    (can_mailbox_number) priv->tx_next;
> +		if (-1 == pru_can_write_data_to_mailbox(priv->dev,
> +					&priv->can_tx_hndl)) {
> +			if (priv->tx_next == priv->tx_head) {
> +				priv->tx_next = priv->tx_tail;
> +				if (!netif_queue_stopped(ndev))
> +					netif_stop_queue(ndev);	/* IF stalled */
> +				dev_err(priv->dev,
> +					"%s: no tx mbx available", __func__);
> +				return NETDEV_TX_BUSY;
> +			} else
> +				continue;
> +		} else {
> +			/* set transmit request */
> +			pru_can_tx(priv->dev, priv->tx_next, CAN_TX_PRU_1);
> +			pru_can_tx_mode_set(priv->dev, false, ecanreceive);
> +			pru_can_tx_mode_set(priv->dev, true, ecantransmit);
> +			pru_can_start_abort_tx(priv->dev, PRU_CAN_START);
> +			priv->tx_next++;
> +			can_put_echo_skb(skb, ndev, 0);
> +			break;
> +		}
> +	}
> +	if (priv->tx_next > priv->tx_head) {
> +		priv->tx_next = priv->tx_tail;
> +	}
> +	return NETDEV_TX_OK;
> +}
> +
> +static int omapl_pru_can_rx(struct net_device *ndev, u32 mbxno)
> +{
> +	struct omapl_pru_can_priv *priv = netdev_priv(ndev);
> +	struct net_device_stats *stats = &ndev->stats;
> +	struct can_frame *cf;
> +	struct sk_buff *skb;
> +	u32 pru_can_mbx_data;
> +	u8 *data = NULL;
> +	u8 *ptr8data = NULL;
> +	int count = 0;
> +
> +	skb = alloc_can_skb(ndev, &cf);
> +	if (!skb) {
> +		if (printk_ratelimit())
> +			dev_err(priv->dev,
> +				"alloc_can_skb() failed\n");
> +		return -ENOMEM;
> +	}
> +	data = cf->data;
> +	/*      get payload */
> +	priv->can_rx_hndl.ecanmailboxnumber = (can_mailbox_number) mbxno;
> +	if (pru_can_get_data_from_mailbox(priv->dev, &priv->can_rx_hndl)) {
> +		__can_err("failed to get data from mailbox\n");
> +		return -EAGAIN;
> +	}
> +	/* give ownweship to pru */
> +	pru_can_tx(priv->dev, mbxno, CAN_RX_PRU_0);
> +
> +	/* get data length code */
> +	cf->can_dlc =
> +	    get_can_dlc(*
> +			((u32 *) &priv->can_rx_hndl.strcanmailbox.
> +			 u16datalength) & 0xF);
> +	if (cf->can_dlc <= 4) {
> +		ptr8data =
> +		    &priv->can_rx_hndl.strcanmailbox.u8data3 + (4 -
> +								cf->can_dlc);
> +		for (count = 0; count < cf->can_dlc; count++) {
> +			*data++ = *ptr8data++;
> +		}
> +	} else {
> +		ptr8data = &priv->can_rx_hndl.strcanmailbox.u8data3;
> +		for (count = 0; count < 4; count++) {
> +			*data++ = *ptr8data++;
> +		}
> +		ptr8data =
> +		    &priv->can_rx_hndl.strcanmailbox.u8data4 - (cf->can_dlc -
> +								5);
> +		for (count = 0; count < cf->can_dlc - 4; count++) {
> +			*data++ = *ptr8data++;
> +		}
> +	}
> +
> +	pru_can_mbx_data = *((u32 *) &priv->can_rx_hndl.strcanmailbox);
> +	/* get id extended or std */
> +	if (pru_can_mbx_data & PRU_CANMID_IDE)
> +		cf->can_id = (pru_can_mbx_data & CAN_EFF_MASK) | CAN_EFF_FLAG;
> +	else
> +		cf->can_id = (pru_can_mbx_data >> 18) & CAN_SFF_MASK;
> +
> +	if (pru_can_mbx_data & CAN_RTR_FLAG)
> +		cf->can_id |= CAN_RTR_FLAG;
> +
> +	netif_rx_ni(skb);
> +	stats->rx_packets++;
> +	stats->rx_bytes += cf->can_dlc;
> +	return 0;
> +}
> +
> +static int omapl_pru_can_err(struct net_device *ndev, int int_status,
> +			     int err_status)
> +{
> +	struct omapl_pru_can_priv *priv = netdev_priv(ndev);
> +	struct net_device_stats *stats = &ndev->stats;
> +	struct can_frame *cf;
> +	struct sk_buff *skb;
> +	int tx_err_cnt, rx_err_cnt;
> +
> +	/* propogate the error condition to the can stack */
> +	skb = alloc_can_err_skb(ndev, &cf);
> +	if (!skb) {
> +		if (printk_ratelimit())
> +			dev_err(priv->dev,
> +				"alloc_can_err_skb() failed\n");
> +		return -ENOMEM;
> +	}
> +
> +	if (err_status & PRU_CAN_GSR_BIT_EPM) {	/* error passive int */
> +		priv->can.state = CAN_STATE_ERROR_PASSIVE;
> +		++priv->can.can_stats.error_passive;
> +		cf->can_id |= CAN_ERR_CRTL;
> +		tx_err_cnt = pru_can_get_error_cnt(priv->dev, CAN_TX_PRU_1);
> +		rx_err_cnt = pru_can_get_error_cnt(priv->dev, CAN_RX_PRU_0);
> +		if (tx_err_cnt > 127)
> +			cf->data[1] |= CAN_ERR_CRTL_TX_PASSIVE;
> +		if (rx_err_cnt > 127)
> +			cf->data[1] |= CAN_ERR_CRTL_RX_PASSIVE;
> +
> +		dev_dbg(priv->ndev->dev.parent, "Error passive interrupt\n");
> +	}
> +
> +	if (err_status & PRU_CAN_GSR_BIT_BFM) {
> +		priv->can.state = CAN_STATE_BUS_OFF;
> +		cf->can_id |= CAN_ERR_BUSOFF;
> +		/*
> +		 *      Disable all interrupts in bus-off to avoid int hog
> +		 *      this should be handled by the pru
> +		 */
> +		pru_can_mask_ints(priv->dev, 0xFFFF);
> +		can_bus_off(ndev);
> +		dev_dbg(priv->ndev->dev.parent, "Bus off mode\n");
> +	}
> +
> +	netif_rx(skb);
> +	stats->rx_packets++;
> +	stats->rx_bytes += cf->can_dlc;
> +	return 0;
> +}
> +
> +void omapl_pru_can_rx_wQ(struct work_struct *work)
> +{
> +	struct omapl_pru_can_priv *priv = container_of(work,
> +			struct omapl_pru_can_priv, rx_work);
> +	struct net_device *ndev = priv->ndev;
> +	u32 bit_set, mbxno = 0;
> +
> +	if (-1 == pru_can_get_intr_status(priv->dev, &priv->can_rx_hndl))
> +		return;
> +
> +	if (PRU_CAN_ISR_BIT_RRI & priv->can_rx_hndl.u32interruptstatus) {
> +		mbxno = RTR_MBX_NO;
> +		omapl_pru_can_rx(ndev, mbxno);
> +	} else {
> +		/* Extract the mboxno from the status */
> +		for (bit_set = 0; ((priv->can_rx_hndl.u32interruptstatus & 0xFF)
> +						>> bit_set != 0); bit_set++)
> +		;
> +		if (0 == bit_set) {
> +			dev_err(priv->dev,
> +				"%s: invalid mailbox number: %X\n", __func__,
> +				priv->can_rx_hndl.u32interruptstatus);
> +		} else {
> +			mbxno = bit_set - 1;
> +			if (PRU_CAN_ISR_BIT_ESI & priv->can_rx_hndl.
> +			    u32interruptstatus) {
> +				pru_can_get_global_status(priv->dev,
> +					&priv->can_rx_hndl);
> +				omapl_pru_can_err(ndev,
> +				priv->can_rx_hndl.u32interruptstatus,
> +				priv->can_rx_hndl.u32globalstatus);
> +			} else {
> +				omapl_pru_can_rx(ndev, mbxno);
> +			}
> +		}
> +	}
> +}
> +
> +irqreturn_t omapl_tx_can_intr(int irq, void *dev_id)
> +{
> +	struct net_device *ndev = dev_id;
> +	struct omapl_pru_can_priv *priv = netdev_priv(ndev);
> +	struct net_device_stats *stats = &ndev->stats;
> +	u32 bit_set, mbxno;
> +
> +	pru_can_get_intr_status(priv->dev, &priv->can_tx_hndl);
> +	if ((PRU_CAN_ISR_BIT_CCI & priv->can_tx_hndl.u32interruptstatus)
> +	    || (PRU_CAN_ISR_BIT_SRDI & priv->can_tx_hndl.u32interruptstatus)) {
> +		__can_debug("tx_int_status = 0x%X\n",
> +			    priv->can_tx_hndl.u32interruptstatus);
> +		can_free_echo_skb(ndev, 0);
> +	} else {
> +		for (bit_set = 0; ((priv->can_tx_hndl.u32interruptstatus & 0xFF)
> +						>> bit_set != 0); bit_set++)
> +		;
> +		if (0 == bit_set) {
> +			__can_err("%s: invalid mailbox number\n", __func__);
> +			can_free_echo_skb(ndev, 0);
> +		} else {
> +			mbxno = bit_set - 1;	/* mail box numbering starts from 0 */
> +			if (PRU_CAN_ISR_BIT_ESI & priv->can_tx_hndl.
> +			    u32interruptstatus) {
> +				/* read gsr and ack pru */
> +				pru_can_get_global_status(priv->dev, &priv->can_tx_hndl);
> +				omapl_pru_can_err(ndev,
> +						  priv->can_tx_hndl.
> +						  u32interruptstatus,
> +						  priv->can_tx_hndl.
> +						  u32globalstatus);
> +			} else {
> +				stats->tx_packets++;
> +				/* stats->tx_bytes += dlc; */
> +				/*can_get_echo_skb(ndev, 0);*/
> +			}
> +		}
> +	}
> +	if (netif_queue_stopped(ndev))
> +		netif_wake_queue(ndev);
> +
> +	can_get_echo_skb(ndev, 0);
> +	pru_can_tx_mode_set(priv->dev, true, ecanreceive);
> +	return IRQ_HANDLED;
> +}
> +
> +irqreturn_t omapl_rx_can_intr(int irq, void *dev_id)
> +{
> +
> +	struct net_device *ndev = dev_id;
> +	struct omapl_pru_can_priv *priv = netdev_priv(ndev);
> +	u32 intc_status = 0;
> +
> +	intc_status = pru_can_get_intc_status(priv->dev);
> +	if (intc_status & 4)
> +		return omapl_tx_can_intr(irq, dev_id);
> +	if (intc_status & 2) {
> +		if (!work_pending(&priv->rx_work))
> +			queue_work(priv->pru_can_wQ, &priv->rx_work);
> +	}
> +
> +	return IRQ_HANDLED;
> +}
> +
> +static int omapl_pru_can_open(struct net_device *ndev)
> +{
> +	struct omapl_pru_can_priv *priv = netdev_priv(ndev);
> +	int err;
> +
> +	/* register interrupt handler */
> +	err = request_irq(priv->trx_irq, &omapl_rx_can_intr, IRQF_SHARED,
> +			  "pru_can_irq", ndev);
> +	if (err) {
> +		dev_err(priv->dev, "error requesting rx interrupt\n");
> +		goto exit_trx_irq;
> +	}
> +	/* common open */
> +	err = open_candev(ndev);
> +	if (err) {
> +		dev_err(priv->dev, "open_candev() failed %d\n", err);
> +		goto exit_open;
> +	}
> +
> +	pru_can_emu_init(priv->dev, priv->can.clock.freq);
> +	priv->tx_tail = MB_MIN;
> +	priv->tx_head = MB_MAX;
> +
> +	pru_can_rx_id_map(priv->dev, CONFIG_DA8XX_PRU_CANID_MBX0, 0);
> +	pru_can_rx_id_map(priv->dev, CONFIG_DA8XX_PRU_CANID_MBX1, 1);
> +	pru_can_rx_id_map(priv->dev, CONFIG_DA8XX_PRU_CANID_MBX2, 2);
> +	pru_can_rx_id_map(priv->dev, CONFIG_DA8XX_PRU_CANID_MBX3, 3);
> +	pru_can_rx_id_map(priv->dev, CONFIG_DA8XX_PRU_CANID_MBX4, 4);
> +	pru_can_rx_id_map(priv->dev, CONFIG_DA8XX_PRU_CANID_MBX5, 5);
> +	pru_can_rx_id_map(priv->dev, CONFIG_DA8XX_PRU_CANID_MBX6, 6);
> +	pru_can_rx_id_map(priv->dev, CONFIG_DA8XX_PRU_CANID_MBX7, 7);
> +
> +	omapl_pru_can_start(ndev);
> +	netif_start_queue(ndev);
> +	return 0;
> +
> +exit_open:
> +	free_irq(priv->trx_irq, ndev);
> +exit_trx_irq:
> +	return err;
> +}
> +
> +static int omapl_pru_can_close(struct net_device *ndev)
> +{
> +	struct omapl_pru_can_priv *priv = netdev_priv(ndev);
> +
> +	if (!netif_queue_stopped(ndev))
> +		netif_stop_queue(ndev);
> +
> +	close_candev(ndev);
> +
> +	free_irq(priv->trx_irq, ndev);
> +	return 0;
> +}
> +
> +static const struct net_device_ops omapl_pru_can_netdev_ops = {
> +	.ndo_open		= omapl_pru_can_open,
> +	.ndo_stop		= omapl_pru_can_close,
> +	.ndo_start_xmit		= omapl_pru_can_start_xmit,
> +};
> +
> +static int __devinit omapl_pru_can_probe(struct platform_device *pdev)
> +{
> +	struct net_device *ndev = NULL;
> +	const struct da8xx_pru_can_data *pdata;
> +	struct omapl_pru_can_priv *priv = NULL;
> +	struct device *dev = &pdev->dev;
> +	u32 err;
> +
> +	pdata = dev->platform_data;
> +	if (!pdata) {
> +		dev_err(&pdev->dev, "platform data not found\n");
> +		return -EINVAL;
> +	}
> +
> +	ndev = alloc_candev(sizeof(struct omapl_pru_can_priv), MB_MAX + 1);
> +	if (!ndev) {
> +		dev_err(&pdev->dev, "alloc_candev failed\n");
> +		err = -ENOMEM;
> +		goto probe_exit;
> +	}
> +	priv = netdev_priv(ndev);
> +
> +	priv->trx_irq = platform_get_irq(to_platform_device(dev->parent), 0);
> +	if (!priv->trx_irq) {
> +		dev_err(&pdev->dev, "unable to get pru interrupt resources!\n");
> +		err = -ENODEV;
> +		goto probe_exit;
> +	}
> +
> +	priv->ndev = ndev;
> +	priv->dev = dev; /* priv->dev = pdev->dev */
> +
> +	priv->can.bittiming_const = NULL;
> +	priv->can.do_set_bittiming = omapl_pru_can_set_bittiming;
> +	priv->can.do_set_mode = omapl_pru_can_set_mode;
> +	priv->can.do_get_state = omapl_pru_can_get_state;
> +	priv->can_tx_hndl.u8prunumber = CAN_TX_PRU_1;
> +	priv->can_rx_hndl.u8prunumber = CAN_RX_PRU_0;
> +
> +	/* we support local echo, no arp */
> +	ndev->flags |= (IFF_ECHO | IFF_NOARP);
> +
> +	/* pdev->dev->device_private->driver_data = ndev */
> +	platform_set_drvdata(pdev, ndev);
> +	SET_NETDEV_DEV(ndev, &pdev->dev);
> +	ndev->netdev_ops = &omapl_pru_can_netdev_ops;
> +
> +	priv->can.clock.freq = pruss_get_clk_freq(priv->dev);
> +
> +	priv->clk_timer = clk_get(&pdev->dev, "pll1_sysclk2");
> +	if (IS_ERR(priv->clk_timer)) {
> +		dev_err(&pdev->dev, "no timer clock available\n");
> +		err = PTR_ERR(priv->clk_timer);
> +		priv->clk_timer = NULL;
> +		goto probe_exit_candev;
> +	}
> +	priv->timer_freq = clk_get_rate(priv->clk_timer);
> +
> +	err = register_candev(ndev);
> +	if (err) {
> +		dev_err(&pdev->dev, "register_candev() failed\n");
> +		err = -ENODEV;
> +		goto probe_exit_clk;
> +	}
> +
> +	err = request_firmware(&priv->fw_tx, "PRU_CAN_Emulation_Tx.bin",
> +			&pdev->dev);
> +	if (err) {
> +		dev_err(&pdev->dev, "can't load firmware\n");
> +		err = -ENODEV;
> +		goto probe_exit_clk;
> +	}
> +
> +	dev_info(&pdev->dev, "fw_tx size %d. downloading...\n",
> +		 priv->fw_tx->size);
> +
> +	err = request_firmware(&priv->fw_rx, "PRU_CAN_Emulation_Rx.bin",
> +			&pdev->dev);
> +	if (err) {
> +		dev_err(&pdev->dev, "can't load firmware\n");
> +		err = -ENODEV;
> +		goto probe_release_fw;
> +	}
> +	dev_info(&pdev->dev, "fw_rx size %d. downloading...\n",
> +		 priv->fw_rx->size);
> +
> +	/* init the pru */
> +	pru_can_emu_init(priv->dev, priv->can.clock.freq);
> +	udelay(200);
> +
> +	pruss_enable(priv->dev, CAN_RX_PRU_0);
> +	pruss_enable(priv->dev, CAN_TX_PRU_1);
> +
> +	/* download firmware into pru */
> +	err = pruss_load(priv->dev, CAN_RX_PRU_0,
> +		(u32 *)priv->fw_rx->data, (priv->fw_rx->size / 4));
> +	if (err) {
> +		dev_err(&pdev->dev, "firmware download error\n");
> +		err = -ENODEV;
> +		goto probe_release_fw_1;
> +	}
> +	err = pruss_load(priv->dev, CAN_TX_PRU_1,
> +		(u32 *)priv->fw_tx->data, (priv->fw_tx->size / 4));
> +	if (err) {
> +		dev_err(&pdev->dev, "firmware download error\n");
> +		err = -ENODEV;
> +		goto probe_release_fw_1;
> +	}
> +
> +	if (pru_can_calc_timing(priv->dev, DFLT_PRU_FREQ,
> +				DFLT_PRU_BITRATE) != 0)
> +		return -EINVAL;
> +
> +	pruss_run(priv->dev, CAN_RX_PRU_0);
> +	pruss_run(priv->dev, CAN_TX_PRU_1);
> +
> +	/*Create The Work Queue */
> +	priv->pru_can_wQ = create_freezeable_workqueue("omapl_pru_wQ");
> +	if (priv->pru_can_wQ == NULL) {
> +		dev_err(&pdev->dev, "failed to create work queue\n");
> +		err = -ENODEV;
> +		goto probe_release_fw_1;
> +	}
> +
> +	INIT_WORK(&priv->rx_work, omapl_pru_can_rx_wQ);
> +	dev_info(&pdev->dev,
> +		 "%s device registered (trx_irq = %d,  clk = %d)\n",
> +		 DRV_NAME, priv->trx_irq, priv->can.clock.freq);
> +
> +	return 0;
> +
> +probe_release_fw_1:
> +	release_firmware(priv->fw_rx);
> +probe_release_fw:
> +	release_firmware(priv->fw_tx);
> +probe_exit_clk:
> +	clk_put(priv->clk_timer);
> +probe_exit_candev:
> +	if (NULL != ndev)
> +		free_candev(ndev);
> +probe_exit:
> +	return err;
> +}
> +
> +static int __devexit omapl_pru_can_remove(struct platform_device *pdev)
> +{
> +	struct net_device *ndev = platform_get_drvdata(pdev);
> +	struct omapl_pru_can_priv *priv = netdev_priv(ndev);
> +
> +	omapl_pru_can_stop(ndev);
> +
> +	pru_can_emu_exit(priv->dev);
> +	release_firmware(priv->fw_tx);
> +	release_firmware(priv->fw_rx);
> +	clk_put(priv->clk_timer);
> +	flush_workqueue(priv->pru_can_wQ);
> +	destroy_workqueue(priv->pru_can_wQ);
> +	unregister_candev(ndev);
> +	free_candev(ndev);
> +	platform_set_drvdata(pdev, NULL);
> +	return 0;
> +}
> +
> +#ifdef CONFIG_PM
> +static int omapl_pru_can_suspend(struct platform_device *pdev,
> +			pm_message_t mesg)
> +{
> +	dev_info(&pdev->dev, "%s not yet implemented\n", __func__);
> +	return 0;
> +}
> +
> +static int omapl_pru_can_resume(struct platform_device *pdev)
> +{
> +	dev_info(&pdev->dev, "%s not yet implemented\n", __func__);
> +	return 0;
> +}
> +#else
> +#define omapl_pru_can_suspend NULL
> +#define omapl_pru_can_resume NULL
> +#endif /* CONFIG_PM */
> +
> +static struct platform_driver omapl_pru_can_driver = {
> +	.probe		= omapl_pru_can_probe,
> +	.remove		= __devexit_p(omapl_pru_can_remove),
> +	.suspend	= omapl_pru_can_suspend,
> +	.resume		= omapl_pru_can_resume,
> +	.driver		= {
> +		.name	= DRV_NAME,
> +		.owner	= THIS_MODULE,
> +	},
> +};
> +
> +static int __init omapl_pru_can_init(void)
> +{
> +	__can_debug(KERN_INFO DRV_DESC "\n");
> +	return platform_driver_register(&omapl_pru_can_driver);
> +}
> +
> +module_init(omapl_pru_can_init);
> +
> +static void __exit omapl_pru_can_exit(void)
> +{
> +	__can_debug(KERN_INFO DRV_DESC " unloaded\n");
> +	platform_driver_unregister(&omapl_pru_can_driver);
> +}
> +
> +module_exit(omapl_pru_can_exit);
> +
> +MODULE_AUTHOR("Subhasish Ghosh <subhasish-EvXpCiN+lbve9wHmmfpqLFaTQe2KTcn/@public.gmane.org>");
> +MODULE_LICENSE("GPL");
> +MODULE_DESCRIPTION("omapl pru CAN netdevice driver");
> diff --git a/drivers/net/can/da8xx_pruss/pruss_can_api.c b/drivers/net/can/da8xx_pruss/pruss_can_api.c
> new file mode 100644
> index 0000000..2f7438a
> --- /dev/null
> +++ b/drivers/net/can/da8xx_pruss/pruss_can_api.c
> @@ -0,0 +1,1227 @@
> +/*
> + * Copyright (C) 2010 Texas Instruments Incorporated
> + * Author: Wilfred Felix
> + *
> + * This program is free software; you can redistribute it and/or modify it
> + * under the terms of the GNU General Public License as  published by the
> + * Free Software Foundation version 2.
> + *
> + * This program is distributed "as is" WITHOUT ANY WARRANTY of any kind,
> + * whether express or implied; without even the implied warranty of
> + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
> + * General Public License for more details.
> + */
> +
> +#include "pruss_can_api.h"
> +
> +static can_emu_drv_inst gstr_can_inst[ecanmaxinst];
> +
> +/*
> + * pru_can_set_brp()	Updates the  BRP register of PRU0
> + * and PRU1 of OMAP L138. This API will be called by the
> + * Application to updtae the BRP register of PRU0 and PRU1
> + *
> + * param	u16bitrateprescaler		The can bus bitrate
> + * prescaler value be set
> + *
> + * return   SUCCESS or FAILURE
> + */
> +s16 pru_can_set_brp(struct device *dev, u16 u16bitrateprescaler)
> +{
> +
> +	u32 u32offset;
> +
> +	if (u16bitrateprescaler > 255) {
> +		return -1;
> +	}
> +
> +	u32offset = (PRU_CAN_RX_CLOCK_BRP_REGISTER);
> +	pruss_writel(dev, u32offset, (u32 *) &u16bitrateprescaler, 1);
> +
> +	u32offset = (PRU_CAN_TX_CLOCK_BRP_REGISTER);
> +	pruss_writel(dev, u32offset, (u32 *) &u16bitrateprescaler, 1);
> +
> +	return 0;
> +
> +}
> +
> +/*
> + * pru_can_set_bit_timing()		Updates the timing register
> + * of PRU0 and PRU1 of OMAP L138. This API will be called by
> + * the Application to updtae the timing register of PRU0 and PRU1
> + *
> + * param	pstrbittiming		Pointer to structure holding
> + * the bit timing values for can bus.
> + *
> + * return   SUCCESS or FAILURE
> + */
> +s16 pru_can_set_bit_timing(struct device *dev,
> +		can_bit_timing_consts *pstrbittiming)
> +{
> +
> +	u32 u32offset;
> +	u32 u32serregister;
> +
> +	u32serregister = 0;
> +
> +	if (pstrbittiming == NULL) {
> +		return -1;
> +	}
> +
> +	if ((pstrbittiming->u8syncjumpwidth > PRU_CAN_MAX_SJW) ||
> +	    (pstrbittiming->u8phseg1 > PRU_CAN_MAX_PHSEG1) ||
> +	    (pstrbittiming->u8phseg2 > PRU_CAN_MAX_PHSEG2)) {
> +		return -1;
> +	}
> +
> +	u32serregister = u32serregister |
> +			((pstrbittiming->u8syncjumpwidth << 7) |
> +			(pstrbittiming->u8phseg1 << 3) |
> +			(pstrbittiming->u8phseg2));
> +
> +	u32offset = (PRU_CAN_TX_TIMING_REGISTER);
> +	pruss_writel(dev, u32offset, (u32 *) &u32serregister, 1);
> +
> +	u32offset = (PRU_CAN_RX_TIMING_REGISTER);
> +	pruss_writel(dev, u32offset, (u32 *) &u32serregister, 1);
> +
> +	return 0;
> +}
> +
> +
> +/*
> + * pru_can_calc_timing()
> + * Updates the  timing values of PRU0 and PRU1 of OMAP L138.
> + * This API will be called by the
> + * Application to updtae the timing values of PRU0 and PRU1
> + *
> + * return   SUCCESS or FAILURE
> + */
> +
> +s16 pru_can_calc_timing(struct device *dev, u32 pru_freq, u32 bit_rate)
> +{
> +	u16 u16phaseseg1;
> +	u16 u16phaseseg2;
> +	u32 u32offset;
> +	u32 u32timing_value;
> +	u32 u32setup_value;
> +	u32timing_value = TIMER_CLK_FREQ / bit_rate;
> +	u32offset = (PRU_CAN_TIMING_VAL_TX);
> +	pruss_writel(dev, u32offset, (u32 *) &u32timing_value, 4);
> +	pruss_readl(dev, u32offset, (u32 *) &u32timing_value, 4);
> +	u32setup_value =
> +	    (GPIO_SETUP_DELAY * (pru_freq / 1000000) / 1000) /
> +	    DELAY_LOOP_LENGTH;
> +	u32offset = (PRU_CAN_TIMING_VAL_TX_SJW);
> +	pruss_writel(dev, u32offset, (u32 *) &u32setup_value, 4);
> +	u16phaseseg1 = (u16) (u32timing_value / 2);
> +	u16phaseseg2 = u32timing_value - u16phaseseg1;
> +	u16phaseseg1 -= TIMER_SETUP_DELAY;
> +	u16phaseseg2 -= TIMER_SETUP_DELAY;
> +	u32setup_value = (u16phaseseg1 << 16) | u16phaseseg2;
> +	u32offset = (PRU_CAN_TIMING_VAL_RX);
> +	pruss_writel(dev, u32offset, (u32 *) &u32setup_value, 4);
> +	u32offset = (PRU_CAN_TIMING_VAL_RX + 4);
> +	pruss_writel(dev, u32offset, (u32 *) &u32timing_value, 4);
> +
> +	return 0;
> +}
> +
> +/*
> + * pru_can_write_data_to_mailbox()
> + * Updates the transmit mailboxes of PRU1 of OMAP L138.
> + * This API will be called by the Application to update
> + * the transmit mailboxes of PRU1
> + *
> + * param  pu16canframedata	Can mailbox data buffer
> + *
> + * param  u8mailboxnum		Mailbox to be updated
> + *
> + * return SUCCESS or FAILURE
> + */
> +s16 pru_can_write_data_to_mailbox(struct device *dev,
> +			can_emu_app_hndl *pstremuapphndl)
> +{
> +	s16 s16subrtnretval;
> +	u32 u32offset;
> +
> +	if (pstremuapphndl == NULL) {
> +		return -1;
> +	}
> +
> +	switch ((u8) pstremuapphndl->ecanmailboxnumber) {
> +	case 0:
> +		u32offset = (PRU_CAN_TX_MAILBOX0);
> +		break;
> +	case 1:
> +		u32offset = (PRU_CAN_TX_MAILBOX1);
> +		break;
> +	case 2:
> +		u32offset = (PRU_CAN_TX_MAILBOX2);
> +		break;
> +	case 3:
> +		u32offset = (PRU_CAN_TX_MAILBOX3);
> +		break;
> +	case 4:
> +		u32offset = (PRU_CAN_TX_MAILBOX4);
> +		break;
> +	case 5:
> +		u32offset = (PRU_CAN_TX_MAILBOX5);
> +		break;
> +	case 6:
> +		u32offset = (PRU_CAN_TX_MAILBOX6);
> +		break;
> +	case 7:
> +		u32offset = (PRU_CAN_TX_MAILBOX7);
> +		break;
> +	default:
> +		return -1;
> +	}
> +
> +	s16subrtnretval = pruss_writel(dev, u32offset,
> +		(u32 *) &(pstremuapphndl->strcanmailbox), 4);
> +	if (s16subrtnretval == -1) {
> +		return -1;
> +	}
> +	return 0;
> +}
> +
> +/*
> + * pru_can_get_data_from_mailbox()
> + * Receive data from the receive mailboxes of PRU0  of OMAP L138.
> + * This API will be called by the Application to get data from
> + * the receive mailboxes of PRU0
> + *
> + * param  pu16canframedata	Can mailbox data buffer
> + *
> + * param  u8mailboxnum		Mailbox to be updated
> + *
> + * return SUCCESS or FAILURE
> + */
> +s16 pru_can_get_data_from_mailbox(struct device *dev,
> +		can_emu_app_hndl *pstremuapphndl)
> +{
> +	s16 s16subrtnretval;
> +	u32 u32offset;
> +
> +	if (pstremuapphndl == NULL) {
> +		return -1;
> +	}
> +
> +	switch ((u8) pstremuapphndl->ecanmailboxnumber) {
> +	case 0:
> +		u32offset = (PRU_CAN_RX_MAILBOX0);
> +		break;
> +	case 1:
> +		u32offset = (PRU_CAN_RX_MAILBOX1);
> +		break;
> +	case 2:
> +		u32offset = (PRU_CAN_RX_MAILBOX2);
> +		break;
> +	case 3:
> +		u32offset = (PRU_CAN_RX_MAILBOX3);
> +		break;
> +	case 4:
> +		u32offset = (PRU_CAN_RX_MAILBOX4);
> +		break;
> +	case 5:
> +		u32offset = (PRU_CAN_RX_MAILBOX5);
> +		break;
> +	case 6:
> +		u32offset = (PRU_CAN_RX_MAILBOX6);
> +		break;
> +	case 7:
> +		u32offset = (PRU_CAN_RX_MAILBOX7);
> +		break;
> +	case 8:
> +		u32offset = (PRU_CAN_RX_MAILBOX8);
> +		break;
> +	default:
> +		return -1;
> +	}
> +
> +	s16subrtnretval =
> +	    pruss_readl(dev, u32offset,
> +		  (u32 *) &(pstremuapphndl->strcanmailbox),
> +				  4);
> +	if (s16subrtnretval == -1) {
> +		return -1;
> +	}
> +	return 0;
> +}
> +
> +/*
> + * pru_can_receive_id_map()
> + * Receive mailboxes ID Mapping of PRU0  of OMAP L138.
> + * This API will be called by the Application
> + * to map the IDs  to receive mailboxes of PRU0
> + *
> + * param  u32nodeid		Can node ID
> + *
> + * param  ecanmailboxno		Mailbox to be mapped
> + *
> + * return   SUCCESS or FAILURE
> + */
> +s16 pru_can_rx_id_map(struct device *dev, u32 u32nodeid,
> +		can_mailbox_number ecanmailboxno)
> +{
> +
> +	pruss_writel(dev, (PRU_CAN_ID_MAP +
> +		(((u8) ecanmailboxno) * 4)), (u32 *) &u32nodeid, 1);
> +
> +	return 0;
> +}
> +
> +/*
> + * pru_can_get_intr_status()
> + * Gets the interrupts status register value.
> + * This API will be called by the Application
> + * to get the interrupts status register value
> + *
> + * param  u8prunumber	PRU number for which IntStatusReg
> + * has to be read
> + *
> + * return   SUCCESS or FAILURE
> + */
> +s16 pru_can_get_intr_status(struct device *dev,
> +		can_emu_app_hndl *pstremuapphndl)
> +{
> +	u32 u32offset;
> +	s16 s16subrtnretval = -1;
> +
> +	if (pstremuapphndl == NULL) {
> +		return -1;
> +	}
> +
> +	if (pstremuapphndl->u8prunumber == DA8XX_PRUCORE_1) {
> +		u32offset = (PRU_CAN_TX_INTERRUPT_STATUS_REGISTER);
> +	} else if (pstremuapphndl->u8prunumber == DA8XX_PRUCORE_0) {
> +		u32offset = (PRU_CAN_RX_INTERRUPT_STATUS_REGISTER);
> +	} else {
> +		return -1;
> +	}
> +
> +	s16subrtnretval = pruss_readl(dev, u32offset,
> +		(u32 *) &pstremuapphndl->u32interruptstatus, 1);
> +	if (s16subrtnretval == -1) {
> +		return -1;
> +	}
> +
> +	return 0;
> +}
> +
> +/*
> + * pru_can_get_global_status()	Gets the globalstatus
> + * register value. This API will be called by the Application
> + * to  get the global status register value
> + *
> + * return   SUCCESS or FAILURE
> + */
> +s16 pru_can_get_global_status(struct device *dev,
> +		can_emu_app_hndl *pstremuapphndl)
> +{
> +	u32 u32offset;
> +	int s16subrtnretval = -1;
> +
> +	if (pstremuapphndl == NULL) {
> +		return -1;
> +	}
> +
> +	if (pstremuapphndl->u8prunumber == DA8XX_PRUCORE_1) {
> +		u32offset = (PRU_CAN_TX_GLOBAL_STATUS_REGISTER);
> +	} else if (pstremuapphndl->u8prunumber == DA8XX_PRUCORE_0) {
> +		u32offset = (PRU_CAN_RX_GLOBAL_STATUS_REGISTER);
> +	} else {
> +		return -1;
> +	}
> +
> +	s16subrtnretval = pruss_readl(dev, u32offset,
> +		(u32 *) &pstremuapphndl->u32globalstatus, 1);
> +	if (s16subrtnretval == -1) {
> +		return -1;
> +	}
> +
> +	return 0;
> +}
> +
> +/*
> + * pru_can_get_mailbox_status()		Gets the mailbox status
> + * register value. This API will be called by the Application
> + * to get the mailbox status register value
> + *
> + * return   SUCCESS or FAILURE
> + */
> +s16 pru_can_get_mailbox_status(struct device *dev,
> +		can_emu_app_hndl *pstremuapphndl)
> +{
> +	u32 u32offset;
> +	s16 s16subrtnretval = -1;
> +
> +	if (pstremuapphndl == NULL) {
> +		return -1;
> +	}
> +
> +	if (pstremuapphndl->u8prunumber == DA8XX_PRUCORE_1) {
> +		switch (pstremuapphndl->ecanmailboxnumber) {
> +		case 0:
> +			u32offset = (PRU_CAN_TX_MAILBOX0_STATUS_REGISTER);
> +			break;
> +		case 1:
> +			u32offset = (PRU_CAN_TX_MAILBOX1_STATUS_REGISTER);
> +			break;
> +		case 2:
> +			u32offset = (PRU_CAN_TX_MAILBOX2_STATUS_REGISTER);
> +			break;
> +		case 3:
> +			u32offset = (PRU_CAN_TX_MAILBOX3_STATUS_REGISTER);
> +			break;
> +		case 4:
> +			u32offset = (PRU_CAN_TX_MAILBOX4_STATUS_REGISTER);
> +			break;
> +		case 5:
> +			u32offset = (PRU_CAN_TX_MAILBOX5_STATUS_REGISTER);
> +			break;
> +		case 6:
> +			u32offset = (PRU_CAN_TX_MAILBOX6_STATUS_REGISTER);
> +			break;
> +		case 7:
> +			u32offset = (PRU_CAN_TX_MAILBOX7_STATUS_REGISTER);
> +			break;
> +		default:
> +			return -1;
> +		}
> +	}
> +
> +	else if (pstremuapphndl->u8prunumber == DA8XX_PRUCORE_0) {
> +		switch (pstremuapphndl->ecanmailboxnumber) {
> +		case 0:
> +			u32offset = (PRU_CAN_RX_MAILBOX0_STATUS_REGISTER);
> +			break;
> +		case 1:
> +			u32offset = (PRU_CAN_RX_MAILBOX1_STATUS_REGISTER);
> +			break;
> +		case 2:
> +			u32offset = (PRU_CAN_RX_MAILBOX2_STATUS_REGISTER);
> +			break;
> +		case 3:
> +			u32offset = (PRU_CAN_RX_MAILBOX3_STATUS_REGISTER);
> +			break;
> +		case 4:
> +			u32offset = (PRU_CAN_RX_MAILBOX4_STATUS_REGISTER);
> +			break;
> +		case 5:
> +			u32offset = (PRU_CAN_RX_MAILBOX5_STATUS_REGISTER);
> +			break;
> +		case 6:
> +			u32offset = (PRU_CAN_RX_MAILBOX6_STATUS_REGISTER);
> +			break;
> +		case 7:
> +			u32offset = (PRU_CAN_RX_MAILBOX7_STATUS_REGISTER);
> +			break;
> +		case 8:
> +			u32offset = (PRU_CAN_RX_MAILBOX8_STATUS_REGISTER);
> +			break;
> +		default:
> +			return -1;
> +		}
> +	}
> +
> +	else {
> +		return -1;
> +	}
> +
> +	s16subrtnretval = pruss_readl(dev, u32offset,
> +		(u32 *) &pstremuapphndl->u32mailboxstatus, 1);
> +	if (s16subrtnretval == -1) {
> +		return -1;
> +	}
> +
> +	return 0;
> +}
> +
> +s16 pru_can_tx_mode_set(struct device *dev, bool btransfer_flag,
> +				can_transfer_direction ecan_trx)
> +{
> +	u32 u32offset;
> +	u32 u32value;
> +
> +	if (ecan_trx == ecantransmit) {
> +		u32offset = (PRU_CAN_RX_GLOBAL_STATUS_REGISTER);
> +		pruss_readl(dev, u32offset, &u32value, 1);
> +		if (btransfer_flag == true) {
> +			u32value &= 0x1F;
> +			u32value |= 0x80;
> +		} else {
> +			u32value &= 0x7F;
> +		}
> +		pruss_writel(dev, u32offset, &u32value, 1);
> +		u32offset = (PRU_CAN_TX_GLOBAL_STATUS_REGISTER);
> +		pruss_writel(dev, u32offset, &u32value, 1);
> +	} else if (ecan_trx == ecanreceive) {
> +		u32offset = (PRU_CAN_RX_GLOBAL_STATUS_REGISTER);
> +		pruss_readl(dev, u32offset, &u32value, 1);
> +		if (btransfer_flag == true) {
> +			u32value &= 0x1F;
> +			u32value |= 0x40;
> +		} else {
> +			u32value &= 0xBF;
> +		}
> +		pruss_writel(dev, u32offset, &u32value, 1);
> +		u32offset = (PRU_CAN_TX_GLOBAL_STATUS_REGISTER);
> +		pruss_writel(dev, u32offset, &u32value, 1);
> +	} else
> +		return -1;
> +
> +	return 0;
> +}
> +
> +/*
> + * pru_can_config_mode_set()		Sets the timing value
> + * for data transfer. This API will be called by the Application
> + * to set timing valus for data transfer
> + *
> + * return   SUCCESS or FAILURE
> + */
> +s16 pru_can_config_mode_set(struct device *dev, bool bconfigmodeflag)
> +{
> +
> +	u32 u32bitrateprescaler;
> +	u32 u32canbittiming;
> +
> +	pruss_readl(dev, (PRU_CAN_TX_CLOCK_BRP_REGISTER),
> +			(u32 *) &u32bitrateprescaler, 1);
> +	pruss_readl(dev, (PRU_CAN_TX_TIMING_REGISTER),
> +			(u32 *) &u32canbittiming, 1);
> +
> +	if (bconfigmodeflag == 1) {
> +		pru_can_calc_timing(dev, u32canbittiming, u32bitrateprescaler);
> +	}
> +
> +	else {
> +		pru_can_calc_timing(dev, 0, 0);
> +	}
> +
> +	return 0;
> +}
> +
> +/*
> + * pru_can_emu_init()		Initializes the Can
> + * Emulation Parameters. This API will be called by the Application
> + * to Initialize the Can Emulation Parameters
> + *
> + * param    u32pruclock         PRU Clock value
> + *
> + * return   SUCCESS or FAILURE
> + */
> +s16 pru_can_emu_init(struct device *dev, u32 u32pruclock)
> +{
> +	u32 u32offset;
> +	u32 u32value;
> +	s16 s16subrtnretval = -1;
> +	u8 u8loop;
> +
> +	for (u8loop = 0; u8loop < (u8) ecanmaxinst; u8loop++) {
> +		gstr_can_inst[u8loop].bcaninststate = (bool) 0;
> +		gstr_can_inst[u8loop].ecantransferdirection =
> +		    (can_transfer_direction) 0;
> +		gstr_can_inst[u8loop].u32apphandlerptr = 0;
> +	}
> +
> +	u32offset = (PRU_CAN_TX_GLOBAL_CONTROL_REGISTER & 0xFFFF);
> +	u32value = 0x00000000;
> +	s16subrtnretval = pruss_writel(dev, u32offset, (u32 *) &u32value, 1);
> +	if (s16subrtnretval == -1) {
> +		return -1;
> +	}
> +
> +	u32offset = (PRU_CAN_TX_GLOBAL_STATUS_REGISTER & 0xFFFF);
> +	u32value = 0x00000040;
> +	s16subrtnretval = pruss_writel(dev, u32offset, (u32 *) &u32value, 1);
> +	if (s16subrtnretval == -1) {
> +		return -1;
> +	}
> +	u32offset = (PRU_CAN_RX_GLOBAL_STATUS_REGISTER & 0xFFFF);
> +	u32value = 0x00000040;
> +	s16subrtnretval = pruss_writel(dev, u32offset, (u32 *) &u32value, 1);
> +	if (s16subrtnretval == -1) {
> +		return -1;
> +	}
> +
> +	u32offset = (PRU_CAN_TX_INTERRUPT_MASK_REGISTER & 0xFFFF);
> +	u32value = 0x00004000;
> +	s16subrtnretval = pruss_writel(dev, u32offset, (u32 *) &u32value, 1);
> +	if (s16subrtnretval == -1) {
> +		return -1;
> +	}
> +
> +	u32offset = (PRU_CAN_TX_INTERRUPT_STATUS_REGISTER & 0xFFFF);
> +	u32value = 0x00000000;
> +	s16subrtnretval = pruss_writel(dev, u32offset, (u32 *) &u32value, 1);
> +	if (s16subrtnretval == -1) {
> +		return -1;
> +	}
> +
> +	u32offset = (PRU_CAN_TX_MAILBOX0_STATUS_REGISTER & 0xFFFF);
> +	u32value = 0x00000001;
> +	s16subrtnretval =
> +	    pruss_writel(dev, u32offset, (u32 *) &u32value, 1);
> +	if (s16subrtnretval == -1) {
> +		return -1;
> +	}
> +
> +	u32offset = (PRU_CAN_TX_MAILBOX1_STATUS_REGISTER & 0xFFFF);
> +	u32value = 0x00000001;
> +	s16subrtnretval = pruss_writel(dev, u32offset, (u32 *) &u32value, 1);
> +	if (s16subrtnretval == -1) {
> +		return -1;
> +	}
> +
> +	u32offset = (PRU_CAN_TX_MAILBOX2_STATUS_REGISTER & 0xFFFF);
> +	u32value = 0x00000001;
> +	s16subrtnretval = pruss_writel(dev, u32offset, (u32 *) &u32value, 1);
> +	if (s16subrtnretval == -1) {
> +		return -1;
> +	}
> +
> +	u32offset = (PRU_CAN_TX_MAILBOX3_STATUS_REGISTER & 0xFFFF);
> +	u32value = 0x00000001;
> +	s16subrtnretval = pruss_writel(dev, u32offset, (u32 *) &u32value, 1);
> +	if (s16subrtnretval == -1) {
> +		return -1;
> +	}
> +
> +	u32offset = (PRU_CAN_TX_MAILBOX4_STATUS_REGISTER & 0xFFFF);
> +	u32value = 0x00000001;
> +	s16subrtnretval = pruss_writel(dev, u32offset, (u32 *) &u32value, 1);
> +	if (s16subrtnretval == -1) {
> +		return -1;
> +	}
> +
> +	u32offset = (PRU_CAN_TX_MAILBOX5_STATUS_REGISTER & 0xFFFF);
> +	u32value = 0x00000001;
> +	s16subrtnretval = pruss_writel(dev, u32offset, (u32 *) &u32value, 1);
> +	if (s16subrtnretval == -1) {
> +		return -1;
> +	}
> +
> +	u32offset = (PRU_CAN_TX_MAILBOX6_STATUS_REGISTER & 0xFFFF);
> +	u32value = 0x00000001;
> +	s16subrtnretval = pruss_writel(dev, u32offset, (u32 *) &u32value, 1);
> +	if (s16subrtnretval == -1) {
> +		return -1;
> +	}
> +
> +	u32offset = (PRU_CAN_TX_MAILBOX7_STATUS_REGISTER & 0xFFFF);
> +	u32value = 0x00000001;
> +	s16subrtnretval = pruss_writel(dev, u32offset, (u32 *) &u32value, 1);
> +	if (s16subrtnretval == -1) {
> +		return -1;
> +	}
> +
> +	u32offset = (PRU_CAN_TX_ERROR_COUNTER_REGISTER & 0xFFFF);
> +	u32value = 0x00000000;
> +	s16subrtnretval = pruss_writel(dev, u32offset, (u32 *) &u32value, 1);
> +	if (s16subrtnretval == -1) {
> +		return -1;
> +	}
> +
> +	u32offset = (PRU_CAN_TX_TIMING_REGISTER & 0xFFFF);
> +	u32value = 0x00000000;
> +	s16subrtnretval = pruss_writel(dev, u32offset, (u32 *) &u32value, 1);
> +	if (s16subrtnretval == -1) {
> +		return -1;
> +	}
> +
> +	u32offset = (PRU_CAN_TX_CLOCK_BRP_REGISTER & 0xFFFF);
> +	u32value = 0x00000000;
> +	s16subrtnretval = pruss_writel(dev, u32offset, (u32 *) &u32value, 1);
> +	if (s16subrtnretval == -1) {
> +		return -1;
> +	}
> +
> +	u32offset = (PRU_CAN_TX_ERROR_COUNTER_REGISTER & 0xFFFF);
> +	u32value = 0x00000000;
> +	s16subrtnretval = pruss_writel(dev, u32offset, (u32 *) &u32value, 1);
> +	if (s16subrtnretval == -1) {
> +		return -1;
> +	}
> +
> +	u32offset = (PRUSS_INTC_POLARITY0 & 0xFFFF);
> +	u32value = 0xFFFFFFFF;
> +	s16subrtnretval = pruss_writel(dev, u32offset, (u32 *) &u32value, 1);
> +	if (s16subrtnretval == -1) {
> +		return -1;
> +	}
> +	u32offset = (PRUSS_INTC_POLARITY1 & 0xFFFF);
> +	u32value = 0xFFFFFFFF;
> +	s16subrtnretval = pruss_writel(dev, u32offset, (u32 *) &u32value, 1);
> +	if (s16subrtnretval == -1) {
> +		return -1;
> +	}
> +	u32offset = (PRUSS_INTC_TYPE0 & 0xFFFF);
> +	u32value = 0x1C000000;
> +	s16subrtnretval = pruss_writel(dev, u32offset, (u32 *) &u32value, 1);
> +	if (s16subrtnretval == -1) {
> +		return -1;
> +	}
> +	u32offset = (PRUSS_INTC_TYPE1 & 0xFFFF);
> +	u32value = 0x00000000;
> +	s16subrtnretval = pruss_writel(dev, u32offset, (u32 *) &u32value, 1);
> +	if (s16subrtnretval == -1) {
> +		return -1;
> +	}
> +
> +	u32offset = (PRUSS_INTC_HSTINTENIDXCLR & 0xFFFF);
> +	u32value = 0x0;
> +	s16subrtnretval = pruss_writel(dev, u32offset, (u32 *) &u32value, 1);
> +	if (s16subrtnretval == -1) {
> +		return -1;
> +	}
> +
> +	u32offset = (PRUSS_INTC_GLBLEN & 0xFFFF);
> +	u32value = 0x1;
> +	s16subrtnretval = pruss_writel(dev, u32offset, (u32 *) &u32value, 1);
> +	if (s16subrtnretval == -1) {
> +		return -1;
> +	}
> +	/* tx intr map arm->pru */
> +	u32offset = (PRUSS_INTC_HSTINTENIDXSET & 0xFFFF);
> +	u32value = 0x0;
> +	s16subrtnretval = pruss_writel(dev, u32offset, (u32 *) &u32value, 1);
> +	if (s16subrtnretval == -1) {
> +		return -1;
> +	}
> +
> +	u32offset = (PRUSS_INTC_HOSTMAP0 & 0xFFFF);
> +	u32value = 0x03020100;
> +	s16subrtnretval = pruss_writel(dev, u32offset, (u32 *) &u32value, 1);
> +	if (s16subrtnretval == -1) {
> +		return -1;
> +	}
> +
> +	u32offset = (PRUSS_INTC_HOSTMAP1 & 0xFFFF);
> +	u32value = 0x07060504;
> +	s16subrtnretval = pruss_writel(dev, u32offset, (u32 *) &u32value, 1);
> +	if (s16subrtnretval == -1) {
> +		return -1;
> +	}
> +
> +	u32offset = (PRUSS_INTC_HOSTMAP2 & 0xFFFF);
> +	u32value = 0x0000908;
> +	s16subrtnretval = pruss_writel(dev, u32offset, (u32 *) &u32value, 1);
> +	if (s16subrtnretval == -1) {
> +		return -1;
> +	}
> +
> +	u32offset = (PRUSS_INTC_CHANMAP0 & 0xFFFF);
> +	u32value = 0;
> +	s16subrtnretval = pruss_writel(dev, u32offset, (u32 *) &u32value, 1);
> +	if (s16subrtnretval == -1) {
> +		return -1;
> +	}
> +
> +	u32offset = (PRUSS_INTC_CHANMAP8 & 0xFFFF);
> +	u32value = 0x00020200;
> +	s16subrtnretval = pruss_writel(dev, u32offset, (u32 *) &u32value, 1);
> +	if (s16subrtnretval == -1) {
> +		return -1;
> +	}
> +
> +	u32offset = (PRUSS_INTC_STATIDXCLR & 0xFFFF);
> +	u32value = 32;
> +	s16subrtnretval = pruss_writel(dev, u32offset, (u32 *) &u32value, 1);
> +	if (s16subrtnretval == -1) {
> +		return -1;
> +	}
> +
> +	u32offset = (PRUSS_INTC_STATIDXCLR & 0xFFFF);
> +	u32value = 19;
> +	s16subrtnretval = pruss_writel(dev, u32offset, (u32 *) &u32value, 1);
> +	if (s16subrtnretval == -1) {
> +		return -1;
> +	}
> +
> +	u32offset = (PRUSS_INTC_ENIDXSET & 0xFFFF);
> +	u32value = 19;
> +	s16subrtnretval = pruss_writel(dev, u32offset, (u32 *) &u32value, 1);
> +	if (s16subrtnretval == -1) {
> +		return -1;
> +	}
> +	u32offset = (PRUSS_INTC_STATIDXCLR & 0xFFFF);
> +	u32value = 18;
> +	s16subrtnretval = pruss_writel(dev, u32offset, (u32 *) &u32value, 1);
> +	if (s16subrtnretval == -1) {
> +		return -1;
> +	}
> +
> +	u32offset = (PRUSS_INTC_ENIDXSET & 0xFFFF);
> +	u32value = 18;
> +	s16subrtnretval = pruss_writel(dev, u32offset, (u32 *) &u32value, 1);
> +	if (s16subrtnretval == -1) {
> +		return -1;
> +	}
> +
> +	u32offset = (PRUSS_INTC_STATIDXCLR & 0xFFFF);
> +	u32value = 34;
> +	s16subrtnretval = pruss_writel(dev, u32offset, (u32 *) &u32value, 1);
> +	if (s16subrtnretval == -1) {
> +		return -1;
> +	}
> +
> +	u32offset = (PRUSS_INTC_ENIDXSET & 0xFFFF);
> +	u32value = 34;
> +	s16subrtnretval = pruss_writel(dev, u32offset, (u32 *) &u32value, 1);
> +	if (s16subrtnretval == -1) {
> +		return -1;
> +	}
> +
> +	u32offset = (PRUSS_INTC_ENIDXSET & 0xFFFF);
> +	u32value = 32;
> +	s16subrtnretval = pruss_writel(dev, u32offset, (u32 *) &u32value, 1);
> +	if (s16subrtnretval == -1) {
> +		return -1;
> +	}
> +
> +	u32offset = (PRUSS_INTC_HOSTINTEN & 0xFFFF);
> +	u32value = 0x5;
> +	s16subrtnretval = pruss_writel(dev, u32offset, (u32 *) &u32value, 1);
> +	if (s16subrtnretval == -1) {
> +		return -1;
> +	}
> +
> +/* PRU0 - Rx Internal Registers Initializations */
> +
> +	u32offset = (PRU_CAN_RX_GLOBAL_CONTROL_REGISTER & 0xFFFF);
> +	u32value = 0x00000000;
> +	s16subrtnretval = pruss_writel(dev, u32offset, (u32 *) &u32value, 1);
> +	if (s16subrtnretval == -1) {
> +		return -1;
> +	}
> +
> +	u32offset = (PRU_CAN_RX_GLOBAL_STATUS_REGISTER & 0xFFFF);
> +	u32value = 0x00000040;
> +	s16subrtnretval = pruss_writel(dev, u32offset, (u32 *) &u32value, 1);
> +	if (s16subrtnretval == -1) {
> +		return -1;
> +	}
> +
> +	u32offset = (PRU_CAN_RX_INTERRUPT_MASK_REGISTER & 0xFFFF);
> +	u32value = 0x00004000;
> +	s16subrtnretval = pruss_writel(dev, u32offset, (u32 *) &u32value, 1);
> +	if (s16subrtnretval == -1) {
> +		return -1;
> +	}
> +
> +	u32offset = (PRU_CAN_RX_INTERRUPT_STATUS_REGISTER & 0xFFFF);
> +	u32value = 0x00000000;
> +	s16subrtnretval = pruss_writel(dev, u32offset, (u32 *) &u32value, 1);
> +	if (s16subrtnretval == -1) {
> +		return -1;
> +	}
> +
> +	u32offset = (PRU_CAN_RX_MAILBOX0_STATUS_REGISTER & 0xFFFF);
> +	u32value = 0x00000000;
> +	s16subrtnretval = pruss_writel(dev, u32offset, (u32 *) &u32value, 1);
> +	if (s16subrtnretval == -1) {
> +		return -1;
> +	}
> +
> +	u32offset = (PRU_CAN_RX_MAILBOX1_STATUS_REGISTER & 0xFFFF);
> +	u32value = 0x0000000;
> +	s16subrtnretval = pruss_writel(dev, u32offset, (u32 *) &u32value, 1);
> +	if (s16subrtnretval == -1) {
> +		return -1;
> +	}
> +
> +	u32offset = (PRU_CAN_RX_MAILBOX2_STATUS_REGISTER & 0xFFFF);
> +	u32value = 0x00000000;
> +	s16subrtnretval = pruss_writel(dev, u32offset, (u32 *) &u32value, 1);
> +	if (s16subrtnretval == -1) {
> +		return -1;
> +	}
> +
> +	u32offset = (PRU_CAN_RX_MAILBOX3_STATUS_REGISTER & 0xFFFF);
> +	u32value = 0x00000000;
> +	s16subrtnretval = pruss_writel(dev, u32offset, (u32 *) &u32value, 1);
> +	if (s16subrtnretval == -1) {
> +		return -1;
> +	}
> +
> +	u32offset = (PRU_CAN_RX_MAILBOX4_STATUS_REGISTER & 0xFFFF);
> +	u32value = 0x00000000;
> +	s16subrtnretval = pruss_writel(dev, u32offset, (u32 *) &u32value, 1);
> +	if (s16subrtnretval == -1) {
> +		return -1;
> +	}
> +
> +	u32offset = (PRU_CAN_RX_MAILBOX5_STATUS_REGISTER & 0xFFFF);
> +	u32value = 0x00000000;
> +	s16subrtnretval = pruss_writel(dev, u32offset, (u32 *) &u32value, 1);
> +	if (s16subrtnretval == -1) {
> +		return -1;
> +	}
> +
> +	u32offset = (PRU_CAN_RX_MAILBOX6_STATUS_REGISTER & 0xFFFF);
> +	u32value = 0x00000000;
> +	s16subrtnretval = pruss_writel(dev, u32offset, (u32 *) &u32value, 1);
> +	if (s16subrtnretval == -1) {
> +		return -1;
> +	}
> +
> +	u32offset = (PRU_CAN_RX_MAILBOX7_STATUS_REGISTER & 0xFFFF);
> +	u32value = 0x00000000;
> +	s16subrtnretval = pruss_writel(dev, u32offset, (u32 *) &u32value, 1);
> +	if (s16subrtnretval == -1) {
> +		return -1;
> +	}
> +
> +	u32offset = (PRU_CAN_RX_ERROR_COUNTER_REGISTER & 0xFFFF);
> +	u32value = 0x00000000;
> +	s16subrtnretval = pruss_writel(dev, u32offset, (u32 *) &u32value, 1);
> +	if (s16subrtnretval == -1) {
> +		return -1;
> +	}
> +
> +	u32offset = (PRU_CAN_RX_TIMING_REGISTER & 0xFFFF);
> +	u32value = 0x0000000;
> +	s16subrtnretval = pruss_writel(dev, u32offset, (u32 *) &u32value, 1);
> +	if (s16subrtnretval == -1) {
> +		return -1;
> +	}
> +
> +	u32offset = (PRU_CAN_RX_CLOCK_BRP_REGISTER & 0xFFFF);
> +	u32value = 0x00000000;
> +	s16subrtnretval = pruss_writel(dev, u32offset, (u32 *) &u32value, 1);
> +	if (s16subrtnretval == -1) {
> +		return -1;
> +	}
> +	return 0;
> +}
> +
> +
> +/*
> + * pru_can_emu_open()		Opens the can emu for
> + * application to use. This API will be called by the Application
> + * to Open the can emu for application to use.
> + *
> + * param	pstremuapphndl	Pointer to application handler
> + * structure
> + *
> + * return   SUCCESS or FAILURE
> + */
> +s16 pru_can_emu_open(struct device *dev, can_emu_app_hndl *pstremuapphndl)
> +{
> +
> +	if (pstremuapphndl == NULL) {
> +		return -1;
> +	}
> +
> +	if (gstr_can_inst[pstremuapphndl->ecaninstance].bcaninststate == 1) {
> +		return -1;
> +	}
> +
> +	gstr_can_inst[(u8) pstremuapphndl->ecaninstance].
> +					bcaninststate = (bool)1;
> +	gstr_can_inst[(u8) pstremuapphndl->
> +		ecaninstance].ecantransferdirection =
> +		(can_transfer_direction)(u8)pstremuapphndl->ecantransferdirection;
> +	gstr_can_inst[(u8) pstremuapphndl->ecaninstance].
> +		u32apphandlerptr = (u32) pstremuapphndl;
> +
> +	return 0;
> +}
> +
> +
> +/*
> + * brief    pru_can_emu_close()	Closes the can emu for other
> + * applications to use. This API will be called by the Application to Close
> + * the can emu for other applications to use
> + *
> + * param	pstremuapphndl	Pointer to application handler structure
> + *
> + * return   SUCCESS or FAILURE
> + */
> +s16 pru_can_emu_close(struct device *dev, can_emu_app_hndl *pstremuapphndl)
> +{
> +
> +	if (pstremuapphndl == NULL) {
> +		return -1;
> +	}
> +	if (gstr_can_inst[pstremuapphndl->ecaninstance].bcaninststate == 0) {
> +		return -1;
> +	}
> +	if ((u32) pstremuapphndl != gstr_can_inst[(u8) pstremuapphndl->
> +			ecaninstance].u32apphandlerptr){
> +		return -1;
> +	}
> +	gstr_can_inst[(u8) pstremuapphndl->ecaninstance].bcaninststate
> +		= (bool) 0;
> +	gstr_can_inst[(u8) pstremuapphndl->
> +	ecaninstance].ecantransferdirection = (can_transfer_direction) 0;
> +	gstr_can_inst[(u8) pstremuapphndl->ecaninstance].u32apphandlerptr = 0;
> +
> +	return 0;
> +}
> +
> +/*
> + * brief    pru_can_emu_exit()	Diables all the PRUs
> + * This API will be called by the Application to disable all PRUs
> + * param	None
> + * return   SUCCESS or FAILURE
> + */
> +s16 pru_can_emu_exit(struct device *dev)
> +{
> +	s16 s16subrtnretval;
> +
> +	s16subrtnretval = pruss_disable(dev, CAN_RX_PRU_0);
> +	if (s16subrtnretval == -1)
> +		return -1;
> +	s16subrtnretval = pruss_disable(dev, CAN_TX_PRU_1);
> +	if (s16subrtnretval == -1)
> +		return -1;
> +
> +	return 0;
> +}
> +
> +s16 pru_can_emu_sreset(struct device *dev)
> +{
> +	return 0;
> +}
> +
> +s16 pru_can_tx(struct device *dev, u8 u8mailboxnumber, u8 u8prunumber)
> +{
> +	u32 u32offset = 0;
> +	u32 u32value = 0;
> +	s16 s16subrtnretval = -1;
> +
> +	if (DA8XX_PRUCORE_1 == u8prunumber) {
> +		switch (u8mailboxnumber) {
> +		case 0:
> +			u32offset = (PRU_CAN_TX_MAILBOX0_STATUS_REGISTER & 0xFFFF);
> +			u32value = 0x00000080;
> +			s16subrtnretval = pruss_writel(dev, u32offset,
> +					(u32 *) &u32value, 1);
> +			if (s16subrtnretval == -1) {
> +				return -1;
> +			}
> +			break;
> +		case 1:
> +			u32offset = (PRU_CAN_TX_MAILBOX1_STATUS_REGISTER & 0xFFFF);
> +			u32value = 0x00000080;
> +			s16subrtnretval = pruss_writel(dev, u32offset,
> +						(u32 *) &u32value, 1);
> +			if (s16subrtnretval == -1) {
> +				return -1;
> +			}
> +			break;
> +		case 2:
> +			u32offset = (PRU_CAN_TX_MAILBOX2_STATUS_REGISTER & 0xFFFF);
> +			u32value = 0x00000080;
> +			s16subrtnretval = pruss_writel(dev, u32offset,
> +						(u32 *) &u32value, 1);
> +			if (s16subrtnretval == -1) {
> +				return -1;
> +			}
> +			break;
> +		case 3:
> +			u32offset = (PRU_CAN_TX_MAILBOX3_STATUS_REGISTER & 0xFFFF);
> +			u32value = 0x00000080;
> +			s16subrtnretval = pruss_writel(dev, u32offset,
> +						(u32 *) &u32value, 1);
> +			if (s16subrtnretval == -1) {
> +				return -1;
> +			}
> +			break;
> +		case 4:
> +			u32offset = (PRU_CAN_TX_MAILBOX4_STATUS_REGISTER & 0xFFFF);
> +			u32value = 0x00000080;
> +			s16subrtnretval = pruss_writel(dev, u32offset,
> +						(u32 *) &u32value, 1);
> +			if (s16subrtnretval == -1) {
> +				return -1;
> +			}
> +			break;
> +		case 5:
> +			u32offset = (PRU_CAN_TX_MAILBOX5_STATUS_REGISTER & 0xFFFF);
> +			u32value = 0x00000080;
> +			s16subrtnretval = pruss_writel(dev, u32offset,
> +						(u32 *) &u32value, 1);
> +			if (s16subrtnretval == -1) {
> +				return -1;
> +			}
> +			break;
> +		case 6:
> +			u32offset = (PRU_CAN_TX_MAILBOX6_STATUS_REGISTER & 0xFFFF);
> +			u32value = 0x00000080;
> +			s16subrtnretval = pruss_writel(dev, u32offset,
> +						(u32 *) &u32value, 1);
> +			if (s16subrtnretval == -1) {
> +				return -1;
> +			}
> +			break;
> +		case 7:
> +			u32offset = (PRU_CAN_TX_MAILBOX7_STATUS_REGISTER & 0xFFFF);
> +			u32value = 0x00000080;
> +			s16subrtnretval = pruss_writel(dev, u32offset,
> +						(u32 *) &u32value, 1);
> +			if (s16subrtnretval == -1) {
> +				return -1;
> +			}
> +			break;
> +		default:
> +			return -1;
> +		}
> +	} else {
> +
> +		u32offset = (PRU_CAN_RX_INTERRUPT_STATUS_REGISTER & 0xFFFF);
> +		u32value = 0x00000000;
> +		s16subrtnretval = pruss_readl(dev, u32offset,
> +						(u32 *) &u32value, 1);
> +		if (s16subrtnretval == -1) {
> +			return -1;
> +		}
> +		u32value = u32value & ~(1 << u8mailboxnumber);
> +		s16subrtnretval = pruss_writel(dev, u32offset,
> +					(u32 *) &u32value, 1);
> +		if (s16subrtnretval == -1) {
> +			return -1;
> +		}
> +
> +		switch (u8mailboxnumber) {
> +		case 0:
> +			u32offset = (PRU_CAN_RX_MAILBOX0_STATUS_REGISTER & 0xFFFF);
> +			u32value = 0x00000000;
> +			s16subrtnretval = pruss_writel(dev, u32offset,
> +						(u32 *) &u32value, 1);
> +			if (s16subrtnretval == -1) {
> +				return -1;
> +			}
> +			break;
> +		case 1:
> +			u32offset = (PRU_CAN_RX_MAILBOX1_STATUS_REGISTER & 0xFFFF);
> +			u32value = 0x00000000;
> +			s16subrtnretval = pruss_writel(dev, u32offset,
> +						(u32 *) &u32value, 1);
> +			if (s16subrtnretval == -1) {
> +				return -1;
> +			}
> +			break;
> +		case 2:
> +			u32offset = (PRU_CAN_RX_MAILBOX2_STATUS_REGISTER & 0xFFFF);
> +			u32value = 0x00000000;
> +			s16subrtnretval = pruss_writel(dev, u32offset,
> +						(u32 *) &u32value, 1);
> +			if (s16subrtnretval == -1) {
> +				return -1;
> +			}
> +			break;
> +		case 3:
> +			u32offset = (PRU_CAN_RX_MAILBOX3_STATUS_REGISTER & 0xFFFF);
> +			u32value = 0x00000000;
> +			s16subrtnretval = pruss_writel(dev, u32offset,
> +						(u32 *) &u32value, 1);
> +			if (s16subrtnretval == -1) {
> +				return -1;
> +			}
> +			break;
> +		case 4:
> +			u32offset = (PRU_CAN_RX_MAILBOX4_STATUS_REGISTER & 0xFFFF);
> +			u32value = 0x00000000;
> +			s16subrtnretval = pruss_writel(dev, u32offset,
> +						(u32 *) &u32value, 1);
> +			if (s16subrtnretval == -1) {
> +				return -1;
> +			}
> +			break;
> +		case 5:
> +			u32offset = (PRU_CAN_RX_MAILBOX5_STATUS_REGISTER & 0xFFFF);
> +			u32value = 0x00000000;
> +			s16subrtnretval = pruss_writel(dev, u32offset,
> +						(u32 *) &u32value, 1);
> +			if (s16subrtnretval == -1) {
> +				return -1;
> +			}
> +			break;
> +		case 6:
> +			u32offset = (PRU_CAN_RX_MAILBOX6_STATUS_REGISTER & 0xFFFF);
> +			u32value = 0x00000000;
> +			s16subrtnretval = pruss_writel(dev, u32offset,
> +						(u32 *) &u32value, 1);
> +			if (s16subrtnretval == -1) {
> +				return -1;
> +			}
> +			break;
> +		case 7:
> +			u32offset = (PRU_CAN_RX_MAILBOX7_STATUS_REGISTER & 0xFFFF);
> +			u32value = 0x00000000;
> +			s16subrtnretval = pruss_writel(dev, u32offset,
> +						(u32 *) &u32value, 1);
> +			if (s16subrtnretval == -1) {
> +				return -1;
> +			}
> +			break;
> +		default:
> +			return -1;
> +		}
> +	}
> +	return 0;
> +}
> +
> +s16 pru_can_start_abort_tx(struct device *dev, bool bcantransmitabortflag)
> +{
> +	u32 u32offset;
> +	u32 u32value;
> +	s16 s16subrtnretval;
> +	u32offset = (PRUSS_INTC_STATIDXCLR & 0xFFFF);
> +	u32value = 32;
> +	s16subrtnretval = pruss_writel(dev, u32offset,
> +					(u32 *) &u32value, 1);
> +
> +	u32offset = (PRUSS_INTC_ENIDXSET & 0xFFFF);
> +	u32value = 32;
> +	s16subrtnretval = pruss_writel(dev, u32offset,
> +					(u32 *) &u32value, 1);
> +
> +	u32offset = (PRUSS_INTC_STATIDXSET & 0xFFFF);
> +	u32value = 32;
> +	s16subrtnretval = pruss_writel(dev, u32offset,
> +					(u32 *) &u32value, 1);
> +	if (s16subrtnretval == -1) {
> +		return -1;
> +	}
> +	return 0;
> +}
> +
> +s16 pru_can_mask_ints(struct device *dev, u32 int_mask)
> +{
> +	return 0;
> +}
> +
> +int pru_can_get_error_cnt(struct device *dev, u8 u8prunumber)
> +{
> +	return 0;
> +}
> +
> +int pru_can_get_intc_status(struct device *dev)
> +{
> +	u32 u32offset = 0;
> +	u32 u32getvalue = 0;
> +	u32 u32clrvalue = 0;
> +
> +	u32offset = (PRUSS_INTC_STATCLRINT1 & 0xFFFF);
> +	pruss_readl(dev, u32offset, (u32 *) &u32getvalue, 1);
> +
> +	if (u32getvalue & 4)
> +		u32clrvalue = 34;	/* CLR Event 34 */
> +
> +	if (u32getvalue & 2)
> +		u32clrvalue = 33;	/* CLR Event 33  */
> +
> +	if (u32clrvalue) {
> +		u32offset = (PRUSS_INTC_STATIDXCLR & 0xFFFF);
> +		pruss_writel(dev, u32offset, &u32clrvalue, 1);
> +	} else
> +		return -1;
> +
> +	return u32getvalue;
> +}
> diff --git a/drivers/net/can/da8xx_pruss/pruss_can_api.h b/drivers/net/can/da8xx_pruss/pruss_can_api.h
> new file mode 100644
> index 0000000..7550456
> --- /dev/null
> +++ b/drivers/net/can/da8xx_pruss/pruss_can_api.h
> @@ -0,0 +1,290 @@
> +/*
> + * Copyright (C) 2010 Texas Instruments Incorporated
> + * Author: Ganeshan N
> + *
> + * This program is free software; you can redistribute it and/or modify it
> + * under the terms of the GNU General Public License as  published by the
> + * Free Software Foundation version 2.
> + *
> + * This program is distributed "as is" WITHOUT ANY WARRANTY of any kind,
> + * whether express or implied; without even the implied warranty of
> + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
> + * General Public License for more details.
> + */
> +
> +#ifndef _PRU_CAN_API_H_
> +#define _PRU_CAN_API_H_
> +
> +#include <linux/types.h>
> +#include <linux/mfd/pruss/da8xx_pru.h>
> +
> +
> +#define CAN_BIT_TIMINGS			(0x273)
> +
> +/* Timer Clock is sourced from DDR freq (PLL1 SYS CLK 2) */
> +#define	TIMER_CLK_FREQ			132000000

any change to get this from a clk_dev?

> +
> +#define TIMER_SETUP_DELAY		14
> +#define GPIO_SETUP_DELAY		150
> +
> +#define CAN_RX_PRU_0			PRUSS_NUM0
> +#define CAN_TX_PRU_1			PRUSS_NUM1
> +
> +/* Number of Instruction in the Delay loop */
> +#define DELAY_LOOP_LENGTH		2

please create a struct describing your register layout.

> +
> +#define PRU1_BASE_ADDR			0x2000
> +
> +#define PRU_CAN_TX_GLOBAL_CONTROL_REGISTER		(PRU1_BASE_ADDR)
> +#define PRU_CAN_TX_GLOBAL_STATUS_REGISTER		(PRU1_BASE_ADDR	+ 0x04)
> +#define PRU_CAN_TX_INTERRUPT_MASK_REGISTER		(PRU1_BASE_ADDR	+ 0x08)
> +#define PRU_CAN_TX_INTERRUPT_STATUS_REGISTER		(PRU1_BASE_ADDR	+ 0x0C)
> +#define PRU_CAN_TX_MAILBOX0_STATUS_REGISTER		(PRU1_BASE_ADDR	+ 0x10)
> +#define PRU_CAN_TX_MAILBOX1_STATUS_REGISTER		(PRU1_BASE_ADDR	+ 0x14)
> +#define PRU_CAN_TX_MAILBOX2_STATUS_REGISTER		(PRU1_BASE_ADDR	+ 0x18)
> +#define PRU_CAN_TX_MAILBOX3_STATUS_REGISTER		(PRU1_BASE_ADDR	+ 0x1C)
> +#define PRU_CAN_TX_MAILBOX4_STATUS_REGISTER		(PRU1_BASE_ADDR	+ 0x20)
> +#define PRU_CAN_TX_MAILBOX5_STATUS_REGISTER		(PRU1_BASE_ADDR	+ 0x24)
> +#define PRU_CAN_TX_MAILBOX6_STATUS_REGISTER		(PRU1_BASE_ADDR	+ 0x28)
> +#define PRU_CAN_TX_MAILBOX7_STATUS_REGISTER		(PRU1_BASE_ADDR	+ 0x2C)

please use an array for the mailbox status register.

> +#define PRU_CAN_TX_ERROR_COUNTER_REGISTER		(PRU1_BASE_ADDR	+ 0x30)
> +#define PRU_CAN_TX_TIMING_REGISTER			(PRU1_BASE_ADDR	+ 0x34)
> +#define PRU_CAN_TX_CLOCK_BRP_REGISTER			(PRU1_BASE_ADDR	+ 0x38)
> +
> +#define PRU_CAN_TX_MAILBOX0				(PRU1_BASE_ADDR	+ 0x40)
> +#define PRU_CAN_TX_MAILBOX1				(PRU1_BASE_ADDR	+ 0x50)
> +#define PRU_CAN_TX_MAILBOX2				(PRU1_BASE_ADDR	+ 0x60)
> +#define PRU_CAN_TX_MAILBOX3				(PRU1_BASE_ADDR	+ 0x70)
> +#define PRU_CAN_TX_MAILBOX4				(PRU1_BASE_ADDR	+ 0x80)
> +#define PRU_CAN_TX_MAILBOX5				(PRU1_BASE_ADDR	+ 0x90)
> +#define PRU_CAN_TX_MAILBOX6				(PRU1_BASE_ADDR	+ 0xA0)
> +#define PRU_CAN_TX_MAILBOX7				(PRU1_BASE_ADDR	+ 0xB0)

also use an array here

> +
> +#define PRU_CAN_TIMING_VAL_TX				(PRU1_BASE_ADDR	+ 0xC0)
> +#define PRU_CAN_TIMING_VAL_TX_SJW			(PRU1_BASE_ADDR	+ 0xC4)
> +#define PRU_CAN_TRANSMIT_FRAME				(PRU1_BASE_ADDR	+ 0xE0)
> +
> +#define PRU0_BASE_ADDR					0
> +
> +#define PRU_CAN_RX_GLOBAL_CONTROL_REGISTER		(PRU0_BASE_ADDR)
> +#define PRU_CAN_RX_GLOBAL_STATUS_REGISTER		(PRU0_BASE_ADDR	+ 0x04)
> +#define PRU_CAN_RX_INTERRUPT_MASK_REGISTER		(PRU0_BASE_ADDR	+ 0x08)
> +#define PRU_CAN_RX_INTERRUPT_STATUS_REGISTER		(PRU0_BASE_ADDR	+ 0x0C)
> +#define PRU_CAN_RX_MAILBOX0_STATUS_REGISTER		(PRU0_BASE_ADDR	+ 0x10)
> +#define PRU_CAN_RX_MAILBOX1_STATUS_REGISTER		(PRU0_BASE_ADDR	+ 0x14)
> +#define PRU_CAN_RX_MAILBOX2_STATUS_REGISTER		(PRU0_BASE_ADDR	+ 0x18)
> +#define PRU_CAN_RX_MAILBOX3_STATUS_REGISTER		(PRU0_BASE_ADDR	+ 0x1C)
> +#define PRU_CAN_RX_MAILBOX4_STATUS_REGISTER		(PRU0_BASE_ADDR	+ 0x20)
> +#define PRU_CAN_RX_MAILBOX5_STATUS_REGISTER		(PRU0_BASE_ADDR	+ 0x24)
> +#define PRU_CAN_RX_MAILBOX6_STATUS_REGISTER		(PRU0_BASE_ADDR	+ 0x28)
> +#define PRU_CAN_RX_MAILBOX7_STATUS_REGISTER		(PRU0_BASE_ADDR	+ 0x2C)
> +#define PRU_CAN_RX_MAILBOX8_STATUS_REGISTER		(PRU0_BASE_ADDR	+ 0x30)

...array

> +#define PRU_CAN_RX_ERROR_COUNTER_REGISTER		(PRU0_BASE_ADDR	+ 0x34)
> +#define PRU_CAN_RX_TIMING_REGISTER			(PRU0_BASE_ADDR	+ 0x38)
> +#define PRU_CAN_RX_CLOCK_BRP_REGISTER			(PRU0_BASE_ADDR	+ 0x3C)
> +
> +#define PRU_CAN_RX_MAILBOX0				(PRU0_BASE_ADDR	+ 0x40)
> +#define PRU_CAN_RX_MAILBOX1				(PRU0_BASE_ADDR	+ 0x50)
> +#define PRU_CAN_RX_MAILBOX2				(PRU0_BASE_ADDR	+ 0x60)
> +#define PRU_CAN_RX_MAILBOX3				(PRU0_BASE_ADDR	+ 0x70)
> +#define PRU_CAN_RX_MAILBOX4				(PRU0_BASE_ADDR	+ 0x80)
> +#define PRU_CAN_RX_MAILBOX5				(PRU0_BASE_ADDR	+ 0x90)
> +#define PRU_CAN_RX_MAILBOX6				(PRU0_BASE_ADDR	+ 0xA0)
> +#define PRU_CAN_RX_MAILBOX7				(PRU0_BASE_ADDR	+ 0xB0)
> +#define PRU_CAN_RX_MAILBOX8				(PRU0_BASE_ADDR	+ 0xC0)

..array

The rx and tx register set look quite similar. Is it intended that you
have 8 tx but 9 rx mailboxes? Anyway....make a struct descriing the
register set and use it twice, one for rx and one for tx.

> +
> +#define PRU_CAN_TIMING_VAL_RX				(PRU0_BASE_ADDR	+ 0xD0)
> +#define PRU_CAN_RECEIVE_FRAME				(PRU0_BASE_ADDR	+ 0xD4)
> +#define PRU_CAN_ID_MAP					(PRU0_BASE_ADDR	+ 0xF0)
> +
> +#define PRU_CAN_ERROR_ACTIVE				128
> +
> +#define CAN_ACK_FAILED					0xE
> +#define CAN_ARBTR_FAIL					0xD
> +#define CAN_BIT_ERROR					0xC
> +#define CAN_TRANSMISSION_SUCCESS			0xA
> +
> +#define STD_DATA_FRAME					0x1
> +#define EXTD_DATA_FRAME					0x2
> +#define STD_REMOTE_FRAME				0x3
> +#define EXTD_REMOTE_FRAME				0x4
> +
> +#define PRU_CAN_MAX_SJW					8
> +#define PRU_CAN_MAX_PHSEG1				25
> +#define PRU_CAN_MAX_PHSEG2				25
> +
> +#define DA8XX_PRUCANCORE_0_REGS				0x7000
> +#define DA8XX_PRUCANCORE_1_REGS				0x7800
> +#define PRU0_PROG_RAM_START_OFFSET			0x8000
> +#define PRU1_PROG_RAM_START_OFFSET			0xC000
> +#define PRU_CAN_INIT_MAX_TIMEOUT			0xFF
> +
> +typedef enum {
> +	ecaninst0 = 0,
> +	ecaninst1,
> +	ecanmaxinst
> +} can_instance_enum;

seens unused
> +
> +typedef enum {
> +	ecanmailbox0 = 0,
> +	ecanmailbox1,
> +	ecanmailbox2,
> +	ecanmailbox3,
> +	ecanmailbox4,
> +	ecanmailbox5,
> +	ecanmailbox6,
> +	ecanmailbox7
> +} can_mailbox_number;

unused, too
> +
> +typedef enum {
> +	ecandirectioninit = 0,
> +	ecantransmit,
> +	ecanreceive
> +} can_transfer_direction;

please add a common prefix and please write them uppsercase.

> +
> +typedef struct {
> +	u16 u16extendedidentifier;
> +	u16 u16baseidentifier;
> +	u8 u8data7;
> +	u8 u8data6;
> +	u8 u8data5;
> +	u8 u8data4;
> +	u8 u8data3;
> +	u8 u8data2;
> +	u8 u8data1;
> +	u8 u8data0;

use an array for the data.

> +	u16 u16datalength;
> +	u16 u16crc;
> +} can_mail_box_structure;
> +
> +typedef struct {
> +	can_transfer_direction ecantransferdirection;
> +} can_mailbox_config;
> +
> +typedef struct {
> +	can_instance_enum ecaninstance;
> +	can_transfer_direction ecantransferdirection;
> +	can_mail_box_structure strcanmailbox;
> +	can_mailbox_number ecanmailboxnumber;
> +	u8 u8prunumber;
> +	u32 u32globalstatus;
> +	u32 u32interruptstatus;
> +	u32 u32mailboxstatus;
> +} can_emu_app_hndl;

You already have defines your priv. No need for further structs.

> +
> +typedef struct {
> +	bool bcaninststate;
> +	can_transfer_direction ecantransferdirection;
> +	u32 u32apphandlerptr;
> +} can_emu_drv_inst;

dito

> +
> +typedef struct {
> +	u8 u8syncjumpwidth;
> +	u8 u8phseg1;
> +	u8 u8phseg2;
> +} can_bit_timing_consts;
> +
> +/* Field Definition Macros  */
> +
> +/* CONTROL */
>

get rid of all the following functions, you don't need that extra layer
in the can driver.

> +/*
> + * pru_can_set_brp() Updates the  BRP register of PRU.
> + */
> +s16 pru_can_set_brp(struct device *dev, u16 u16prescaler);
> +
> +/*
> + * pru_can_set_bit_timing() Updates the  timing register of PRU
> + */
> +s16 pru_can_set_bit_timing(struct device *dev,
> +			can_bit_timing_consts *pstrbittiming);
> +
> +/*
> + * pru_can_calc_timing() Updates the timing values of PRU
> + */
> +s16 pru_can_calc_timing(struct device *dev,
> +			u32 u32bittiming, u32 u32bitrateprescaler);
> +
> +/*
> + * pru_can_write_data_to_mailbox() Updates the transmit mailboxes of PRU1
> + */
> +s16 pru_can_write_data_to_mailbox(struct device *dev,
> +			can_emu_app_hndl *pstremuapphndl);
> +
> +/*
> + * pru_can_get_data_from_mailbox() Receive data from receive mailboxes
> + */
> +s16 pru_can_get_data_from_mailbox(struct device *dev,
> +			can_emu_app_hndl *pstremuapphndl);
> +
> +/*
> + * pru_can_rx_id_map() Receive mailboxes ID Mapping of PRU0
> + */
> +s16 pru_can_rx_id_map(struct device *dev,
> +			u32 u32nodeid, can_mailbox_number ecanmailboxno);
> +
> +/*
> + *pru_can_get_intr_status() Get interrupts status register value
> + */
> +s16 pru_can_get_intr_status(struct device *dev,
> +			can_emu_app_hndl *pstremuapphndl);
> +
> +
> +/*
> + * pru_can_get_global_status() Get the globalstatus register value
> + */
> +s16 pru_can_get_global_status(struct device *dev,
> +			can_emu_app_hndl *pstremuapphndl);
> +
> +/*
> + * pru_can_get_mailbox_status() Get mailbox status reg value
> + */
> +s16 pru_can_get_mailbox_status(struct device *dev,
> +			can_emu_app_hndl *pstremuapphndl);
> +
> +/*
> + * pru_can_configuration_mode_set() Sets timing val for data transfer
> + */
> +s16 pru_can_config_mode_set(struct device *dev,
> +			bool bconfig_modeflag);
> +
> +/*
> + * pru_can_emu_init() Initializes Can Emulation Parameters
> + */
> +s16 pru_can_emu_init(struct device *dev,
> +			u32 u32pruclock);
> +
> +/*
> + * pru_can_emu_open() Opens can emu for application to use
> + */
> +s16 pru_can_emu_open(struct device *dev,
> +			can_emu_app_hndl *pstremuapphndl);
> +
> +/*
> + * pru_can_emu_close() Closes can emu for applications to use
> + */
> +s16 pru_can_emu_close(struct device *dev,
> +			can_emu_app_hndl *pstremuapphndl);
> +
> +/*
> + * pru_can_emu_exit() Diables all the PRUs
> + */
> +s16 pru_can_emu_exit(struct device *dev);
> +
> +s16 pru_can_tx_mode_set(struct device *dev, bool btransfer_flag,
> +			 can_transfer_direction ecan_trx);
> +
> +s16 pru_can_emu_sreset(struct device *dev);
> +
> +s16 pru_can_tx(struct device *dev,
> +			u8 u8mailboxnumber, u8 u8prunumber);
> +
> +s16 pru_can_start_abort_tx(struct device *dev,
> +			bool btxabort_flag);
> +
> +s16 pru_can_mask_ints(struct device *dev, u32 int_mask);
> +
> +s32 pru_can_get_error_cnt(struct device *dev, u8 u8prunumber);
> +
> +s32 pru_can_get_intc_status(struct device *dev);
> +#endif

regards, Marc

-- 
Pengutronix e.K.                  | Marc Kleine-Budde           |
Industrial Linux Solutions        | 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: 262 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

* [PATCH net-2.6] ixgbe: fix panic due to uninitialied pointer
From: Andy Gospodarek @ 2011-02-11 21:45 UTC (permalink / raw)
  To: netdev; +Cc: Don Skidmore, Alexander Duyck, Jeff Kirsher, Greg Rose

Systems containing an 82599EB and running a backported driver from
upstream were panicing on boot.  It turns out hw->mac.ops.setup_sfp is
only set for 82599, so one should check to be sure that pointer is set
before continuing in ixgbe_sfp_config_module_task.  I verified by
inspection that the upstream driver has the same issue and also added a
check before the call in ixgbe_sfp_link_config.

Signed-off-by: Andy Gospodarek <andy@greyhouse.net>
---
 drivers/net/ixgbe/ixgbe_main.c |    6 ++++--
 1 files changed, 4 insertions(+), 2 deletions(-)

diff --git a/drivers/net/ixgbe/ixgbe_main.c b/drivers/net/ixgbe/ixgbe_main.c
index fbae703..30f9ccf 100644
--- a/drivers/net/ixgbe/ixgbe_main.c
+++ b/drivers/net/ixgbe/ixgbe_main.c
@@ -3728,7 +3728,8 @@ static void ixgbe_sfp_link_config(struct ixgbe_adapter *adapter)
 			 * We need to try and force an autonegotiation
 			 * session, then bring up link.
 			 */
-			hw->mac.ops.setup_sfp(hw);
+			if (hw->mac.ops.setup_sfp)
+				hw->mac.ops.setup_sfp(hw);
 			if (!(adapter->flags & IXGBE_FLAG_IN_SFP_LINK_TASK))
 				schedule_work(&adapter->multispeed_fiber_task);
 		} else {
@@ -5968,7 +5969,8 @@ static void ixgbe_sfp_config_module_task(struct work_struct *work)
 		unregister_netdev(adapter->netdev);
 		return;
 	}
-	hw->mac.ops.setup_sfp(hw);
+	if (hw->mac.ops.setup_sfp)
+		hw->mac.ops.setup_sfp(hw);
 
 	if (!(adapter->flags & IXGBE_FLAG_IN_SFP_LINK_TASK))
 		/* This will also work for DA Twinax connections */
-- 
1.7.4


^ permalink raw reply related

* Re: [PATCH net-2.6] ixgbe: fix panic due to uninitialized pointer
From: Andy Gospodarek @ 2011-02-11 21:56 UTC (permalink / raw)
  To: netdev; +Cc: Don Skidmore, Alexander Duyck, Jeff Kirsher, Greg Rose
In-Reply-To: <1297460747-31896-1-git-send-email-andy@greyhouse.net>

On Fri, Feb 11, 2011 at 04:45:47PM -0500, Andy Gospodarek wrote:
> Systems containing an 82599EB and running a backported driver from
> upstream were panicing on boot.  It turns out hw->mac.ops.setup_sfp is
> only set for 82599, so one should check to be sure that pointer is set
> before continuing in ixgbe_sfp_config_module_task.  I verified by
> inspection that the upstream driver has the same issue and also added a
> check before the call in ixgbe_sfp_link_config.
> 
> Signed-off-by: Andy Gospodarek <andy@greyhouse.net>

Corrected spelling error in Subject.

^ permalink raw reply

* Re: any way to reset all marked connections when using CONNMARK?
From: Steven Kath @ 2011-02-11 22:11 UTC (permalink / raw)
  To: Chris Friesen; +Cc: netdev, netfilter-devel, netfilter, coreteam
In-Reply-To: <256863566.648.1297461959805.JavaMail.root@tahiti.vyatta.com>



----- "Chris Friesen" <chris.friesen@genband.com> wrote: -----
> We've got a scenario where we want to use CONNMARK to mark connections
> that have passed a large number of rules in order to allow packets
> from those connections to skip rules in the future (for performance
> reasons).
> 
> However, when we add new rules we want to ensure that all the
> connections need to pass the new rules as well.
> 
> It has been proposed to add a custom patch to clear the mark for all
> marked connections--is there a better way of doing this?
> 
> I thought maybe we could use the CONNMARK as a generation count and
> bumping it up each time a rule is added. This would require updating
> the bypass rule each time we modify the other rules though. If there
> are better options I'd like to hear them.

Using conntrack-tools might help:

conntrack --update --mark 0


^ permalink raw reply

* [PATCH] phy: Remove unneeded depends on PHYLIB
From: H Hartley Sweeten @ 2011-02-11 22:14 UTC (permalink / raw)
  To: Linux Kernel; +Cc: netdev, davem

Remove unneeded depends on PHYLIB.  The config selection is already in
an if PHYLIB / endif block.

Signed-off-by: H Hartley Sweeten <hsweeten@visionengravers.com>
Cc: "David S. Miller" <davem@davemloft.net>

---

diff --git a/drivers/net/phy/Kconfig b/drivers/net/phy/Kconfig
index 35fda5a..392a6c4 100644
--- a/drivers/net/phy/Kconfig
+++ b/drivers/net/phy/Kconfig
@@ -77,7 +77,6 @@ config NATIONAL_PHY
 	  Currently supports the DP83865 PHY.
 
 config STE10XP
-	depends on PHYLIB
 	tristate "Driver for STMicroelectronics STe10Xp PHYs"
 	---help---
 	  This is the driver for the STe100p and STe101p PHYs.

^ permalink raw reply related

* Re: [PATCH 2/2 v2] network: Allow af_packet to transmit +4 bytes for VLAN packets.
From: Eric Dumazet @ 2011-02-11 22:18 UTC (permalink / raw)
  To: greearb; +Cc: netdev
In-Reply-To: <1297452918-16993-1-git-send-email-greearb@candelatech.com>

Le vendredi 11 février 2011 à 11:35 -0800, greearb@candelatech.com a
écrit :
> From: Ben Greear <greearb@candelatech.com>
> 
> This allows user-space to send a '1500' MTU VLAN packet on a
> 1500 MTU ethernet frame.  The extra 4 bytes of a VLAN header is
> not usually charged against the MTU when other parts of the
> network stack is transmitting vlans...
> 
> Signed-off-by: Ben Greear <greearb@candelatech.com>
> ---

Reviewed-by: Eric Dumazet <eric.dumazet@gmail.com>



^ permalink raw reply


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