Netdev List
 help / color / mirror / Atom feed
* [RFC v2 0/2] Enable RX-FCS in e100
From: greearb @ 2011-06-24 19:06 UTC (permalink / raw)
  To: netdev; +Cc: Ben Greear

From: Ben Greear <greearb@candelatech.com>

This is on top of Miroslaw's patches.  No new patches
are required to ethtool.

This is for RFC only until his patches go in.

Ben Greear (2):
  net:  Support RXFCS feature flag.
  e100:  Support RXFCS feature flag.

 drivers/net/e100.c              |   15 ++++++++++++---
 include/linux/netdev_features.h |    2 ++
 net/core/ethtool.c              |    1 +
 3 files changed, 15 insertions(+), 3 deletions(-)

-- 
1.7.3.4


^ permalink raw reply

* pull request: wireless-2.6 2011-06-24
From: John W. Linville @ 2011-06-24 18:49 UTC (permalink / raw)
  To: davem; +Cc: linux-wireless, netdev, linux-kernel

Dave,

Here is another batch of fixes intended for 3.0.  Included are too
rtlwifi fixes from Larry:  a regression that broke firmware loading for
rtl8292cu; and a fix to arbitrate between two devices that share the
same PCI ID but are handled by different drivers...yeah.

The rest are Bluetooth fixes -- quoth Gustavo:

	Three regressions fix intended for 3.0. Two of them fix a
	change made in our HCI security process for 3.0. The third
	one fixes an issue with non-SSP devices.  All of them are
	critical fixes. They should be in 3.0. Please pull!  Thanks.

Please let me know if there are problems!

Thanks,

John

---

The following changes since commit 5c18e80be9ff362f6523b097d495bb2e2f939946:

  net/usb/kalmia: signedness bug in kalmia_bind() (2011-06-23 03:15:39 -0700)

are available in the git repository at:
  git://git.kernel.org/pub/scm/linux/kernel/git/linville/wireless-2.6.git for-davem

Ilia Kolomisnky (1):
      Bluetooth: Fix L2CAP connection establishment

Johan Hedberg (1):
      Bluetooth: Fix accepting connect requests for defer_setup

John W. Linville (2):
      Merge branch 'master' of master.kernel.org:/.../padovan/bluetooth-2.6
      Merge branch 'master' of git://git.kernel.org/.../linville/wireless-2.6 into for-davem

Larry Finger (2):
      rtlwifi: rtl8192se: Handle duplicate PCI ID 0x10ec:0x8192 conflict with r8192e_pci
      rtl8192cu: Fix missing firmware load

Luiz Augusto von Dentz (1):
      Bluetooth: Fix L2CAP security check

 drivers/net/wireless/rtlwifi/pci.c          |   13 ++++++++++++-
 drivers/net/wireless/rtlwifi/rtl8192cu/sw.c |   20 ++++++++++++++++++++
 net/bluetooth/hci_conn.c                    |    6 +++---
 net/bluetooth/l2cap_core.c                  |   21 +++++++++++++++------
 4 files changed, 50 insertions(+), 10 deletions(-)

diff --git a/drivers/net/wireless/rtlwifi/pci.c b/drivers/net/wireless/rtlwifi/pci.c
index 9f8ccae..254b64b 100644
--- a/drivers/net/wireless/rtlwifi/pci.c
+++ b/drivers/net/wireless/rtlwifi/pci.c
@@ -1624,6 +1624,16 @@ static bool _rtl_pci_find_adapter(struct pci_dev *pdev,
 	pci_read_config_byte(pdev, 0x8, &revisionid);
 	pci_read_config_word(pdev, 0x3C, &irqline);
 
+	/* PCI ID 0x10ec:0x8192 occurs for both RTL8192E, which uses
+	 * r8192e_pci, and RTL8192SE, which uses this driver. If the
+	 * revision ID is RTL_PCI_REVISION_ID_8192PCIE (0x01), then
+	 * the correct driver is r8192e_pci, thus this routine should
+	 * return false.
+	 */
+	if (deviceid == RTL_PCI_8192SE_DID &&
+	    revisionid == RTL_PCI_REVISION_ID_8192PCIE)
+		return false;
+
 	if (deviceid == RTL_PCI_8192_DID ||
 	    deviceid == RTL_PCI_0044_DID ||
 	    deviceid == RTL_PCI_0047_DID ||
@@ -1856,7 +1866,8 @@ int __devinit rtl_pci_probe(struct pci_dev *pdev,
 	pci_write_config_byte(pdev, 0x04, 0x07);
 
 	/* find adapter */
-	_rtl_pci_find_adapter(pdev, hw);
+	if (!_rtl_pci_find_adapter(pdev, hw))
+		goto fail3;
 
 	/* Init IO handler */
 	_rtl_pci_io_handler_init(&pdev->dev, hw);
diff --git a/drivers/net/wireless/rtlwifi/rtl8192cu/sw.c b/drivers/net/wireless/rtlwifi/rtl8192cu/sw.c
index bee7c14..092e342 100644
--- a/drivers/net/wireless/rtlwifi/rtl8192cu/sw.c
+++ b/drivers/net/wireless/rtlwifi/rtl8192cu/sw.c
@@ -53,6 +53,8 @@ MODULE_FIRMWARE("rtlwifi/rtl8192cufw.bin");
 static int rtl92cu_init_sw_vars(struct ieee80211_hw *hw)
 {
 	struct rtl_priv *rtlpriv = rtl_priv(hw);
+	const struct firmware *firmware;
+	int err;
 
 	rtlpriv->dm.dm_initialgain_enable = 1;
 	rtlpriv->dm.dm_flag = 0;
@@ -64,6 +66,24 @@ static int rtl92cu_init_sw_vars(struct ieee80211_hw *hw)
 			 ("Can't alloc buffer for fw.\n"));
 		return 1;
 	}
+	/* request fw */
+	err = request_firmware(&firmware, rtlpriv->cfg->fw_name,
+			rtlpriv->io.dev);
+	if (err) {
+		RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG,
+			 ("Failed to request firmware!\n"));
+		return 1;
+	}
+	if (firmware->size > 0x4000) {
+		RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG,
+			 ("Firmware is too big!\n"));
+		release_firmware(firmware);
+		return 1;
+	}
+	memcpy(rtlpriv->rtlhal.pfirmware, firmware->data, firmware->size);
+	rtlpriv->rtlhal.fwsize = firmware->size;
+	release_firmware(firmware);
+
 	return 0;
 }
 
diff --git a/net/bluetooth/hci_conn.c b/net/bluetooth/hci_conn.c
index 3163330..d3a05b9 100644
--- a/net/bluetooth/hci_conn.c
+++ b/net/bluetooth/hci_conn.c
@@ -608,11 +608,11 @@ int hci_conn_security(struct hci_conn *conn, __u8 sec_level, __u8 auth_type)
 		goto encrypt;
 
 auth:
-	if (test_and_set_bit(HCI_CONN_ENCRYPT_PEND, &conn->pend))
+	if (test_bit(HCI_CONN_ENCRYPT_PEND, &conn->pend))
 		return 0;
 
-	hci_conn_auth(conn, sec_level, auth_type);
-	return 0;
+	if (!hci_conn_auth(conn, sec_level, auth_type))
+		return 0;
 
 encrypt:
 	if (conn->link_mode & HCI_LM_ENCRYPT)
diff --git a/net/bluetooth/l2cap_core.c b/net/bluetooth/l2cap_core.c
index e64a1c2..56fdd91 100644
--- a/net/bluetooth/l2cap_core.c
+++ b/net/bluetooth/l2cap_core.c
@@ -4002,21 +4002,30 @@ static int l2cap_security_cfm(struct hci_conn *hcon, u8 status, u8 encrypt)
 			}
 		} else if (sk->sk_state == BT_CONNECT2) {
 			struct l2cap_conn_rsp rsp;
-			__u16 result;
+			__u16 res, stat;
 
 			if (!status) {
-				sk->sk_state = BT_CONFIG;
-				result = L2CAP_CR_SUCCESS;
+				if (bt_sk(sk)->defer_setup) {
+					struct sock *parent = bt_sk(sk)->parent;
+					res = L2CAP_CR_PEND;
+					stat = L2CAP_CS_AUTHOR_PEND;
+					parent->sk_data_ready(parent, 0);
+				} else {
+					sk->sk_state = BT_CONFIG;
+					res = L2CAP_CR_SUCCESS;
+					stat = L2CAP_CS_NO_INFO;
+				}
 			} else {
 				sk->sk_state = BT_DISCONN;
 				l2cap_sock_set_timer(sk, HZ / 10);
-				result = L2CAP_CR_SEC_BLOCK;
+				res = L2CAP_CR_SEC_BLOCK;
+				stat = L2CAP_CS_NO_INFO;
 			}
 
 			rsp.scid   = cpu_to_le16(chan->dcid);
 			rsp.dcid   = cpu_to_le16(chan->scid);
-			rsp.result = cpu_to_le16(result);
-			rsp.status = cpu_to_le16(L2CAP_CS_NO_INFO);
+			rsp.result = cpu_to_le16(res);
+			rsp.status = cpu_to_le16(stat);
 			l2cap_send_cmd(conn, chan->ident, L2CAP_CONN_RSP,
 							sizeof(rsp), &rsp);
 		}
-- 
John W. Linville		Someday the world will need a hero, and you
linville@tuxdriver.com			might be all we have.  Be ready.

^ permalink raw reply related

* winner
From: Microsoft @ 2011-06-23 19:42 UTC (permalink / raw)


You have won 500.000 GBP
send your phone number
and address

^ permalink raw reply

* Re: ethtool_set_features suggestion
From: Ben Hutchings @ 2011-06-24 18:40 UTC (permalink / raw)
  To: Ben Greear; +Cc: netdev
In-Reply-To: <4E04D576.8090902@candelatech.com>

On Fri, 2011-06-24 at 11:20 -0700, Ben Greear wrote:
> static int ethtool_set_features(struct net_device *dev, void __user *useraddr)
> {
> 	struct ethtool_sfeatures cmd;
> 	struct ethtool_set_features_block features[ETHTOOL_DEV_FEATURE_WORDS];
> 	netdev_features_t wanted = 0, valid = 0;
> 	int i, ret = 0;
> 
> 	if (copy_from_user(&cmd, useraddr, sizeof(cmd)))
> 		return -EFAULT;
> 	useraddr += sizeof(cmd);
> 
> 	if (cmd.size != ETHTOOL_DEV_FEATURE_WORDS)
> 		return -EINVAL;
> 
> (This is from net-next, with Miroslaw's patches applied)
> 
> I was thinking that we should deal with whatever size is passed in.
> That way, if we ever expand the kernel
> feature-words size, an old user-space ethtool app would
> still function OK.

Userland should find out the correct size from ETHTOOL_GFEATURES.

Ben.

-- 
Ben Hutchings, Senior Software Engineer, Solarflare
Not speaking for my employer; that's the marketing department's job.
They asked us to note that Solarflare product names are trademarked.


^ permalink raw reply

* Re: [PATCH] bridge: Forward EAPOL Kconfig option BRIDGE_PAE_FORWARD
From: Nick Carter @ 2011-06-24 18:29 UTC (permalink / raw)
  To: Stephen Hemminger; +Cc: netdev, davem
In-Reply-To: <20110623152929.3f94b3e7@nehalam.ftrdhcpuser.net>

New diffs below with the Kconfig option removed as requested.

Now all users and distro's will get the correct 802.1x bridge
behaviour by default.  That is EAPOL frames attempting to traverse the
bridge will be dropped (IEEE Std 802.1X-2001 C.3.3).

Users or distro's who want the non-standard behaviour of forwarding
EAPOL frames, can use a simple runtime configuration change to the
sysfs bridge/pae_forward attribute.

diff --git a/net/bridge/br_if.c b/net/bridge/br_if.c
index d9d1e2b..91c1b71 100644
--- a/net/bridge/br_if.c
+++ b/net/bridge/br_if.c
@@ -214,6 +214,7 @@ static struct net_device *new_bridge_dev(struct
net *net, const char *name)
 	br->topology_change = 0;
 	br->topology_change_detected = 0;
 	br->ageing_time = 300 * HZ;
+	br->pae_forward = BR_PAE_DEFAULT;

 	br_netfilter_rtable_init(br);

diff --git a/net/bridge/br_input.c b/net/bridge/br_input.c
index 90e985b..edeb92d 100644
--- a/net/bridge/br_input.c
+++ b/net/bridge/br_input.c
@@ -43,6 +43,16 @@ static int br_pass_frame_up(struct sk_buff *skb)
 		       netif_receive_skb);
 }

+static inline bool br_pae_forward(struct net_bridge *br, __be16 proto)
+{
+	return br->pae_forward == BR_PAE_FORWARD && proto == htons(ETH_P_PAE);
+}
+
+static inline bool br_pae_drop(struct net_bridge *br, __be16 proto)
+{
+	return br->pae_forward == BR_PAE_DEFAULT && proto == htons(ETH_P_PAE);
+}
+
 /* note: already called with rcu_read_lock */
 int br_handle_frame_finish(struct sk_buff *skb)
 {
@@ -98,6 +108,10 @@ int br_handle_frame_finish(struct sk_buff *skb)
 	}

 	if (skb) {
+		/* Prevent Crosstalk (IEEE Std 802.1X-2001 C.3.3) */
+		if (unlikely(br_pae_drop(br, skb->protocol)))
+			goto drop;
+
 		if (dst)
 			br_forward(dst->dst, skb, skb2);
 		else
@@ -166,6 +180,10 @@ struct sk_buff *br_handle_frame(struct sk_buff *skb)
 		if (p->br->stp_enabled == BR_NO_STP && dest[5] == 0)
 			goto forward;

+		/* Check if PAE frame should be forwarded */
+		if (br_pae_forward(p->br, skb->protocol))
+			goto forward;
+
 		if (NF_HOOK(NFPROTO_BRIDGE, NF_BR_LOCAL_IN, skb, skb->dev,
 			    NULL, br_handle_local_finish))
 			return NULL;	/* frame consumed by filter */
diff --git a/net/bridge/br_private.h b/net/bridge/br_private.h
index 4e1b620..683c057 100644
--- a/net/bridge/br_private.h
+++ b/net/bridge/br_private.h
@@ -244,6 +244,11 @@ struct net_bridge
 	struct timer_list		multicast_query_timer;
 #endif

+	enum {
+		BR_PAE_DEFAULT,		/* 802.1x frames consumed by bridge */
+		BR_PAE_FORWARD,		/* 802.1x frames forwarded by bridge */
+	} pae_forward;
+
 	struct timer_list		hello_timer;
 	struct timer_list		tcn_timer;
 	struct timer_list		topology_change_timer;
diff --git a/net/bridge/br_sysfs_br.c b/net/bridge/br_sysfs_br.c
index 5c1e555..9bdbc84 100644
--- a/net/bridge/br_sysfs_br.c
+++ b/net/bridge/br_sysfs_br.c
@@ -679,6 +679,31 @@ static DEVICE_ATTR(nf_call_arptables, S_IRUGO | S_IWUSR,
 		   show_nf_call_arptables, store_nf_call_arptables);
 #endif

+static ssize_t show_pae_forward(struct device *d, struct
device_attribute *attr,
+				char *buf)
+{
+	struct net_bridge *br = to_bridge(d);
+	return sprintf(buf, "%d\n", br->pae_forward);
+}
+
+static int set_pae_forward(struct net_bridge *br, unsigned long val)
+{
+	if (val > BR_PAE_FORWARD)
+		return -EINVAL;
+
+	br->pae_forward = val;
+	return 0;
+}
+
+static ssize_t store_pae_forward(struct device *d,
+				 struct device_attribute *attr, const char *buf,
+				 size_t len)
+{
+	return store_bridge_parm(d, buf, len, set_pae_forward);
+}
+static DEVICE_ATTR(pae_forward, S_IRUGO | S_IWUSR, show_pae_forward,
+		   store_pae_forward);
+
 static struct attribute *bridge_attrs[] = {
 	&dev_attr_forward_delay.attr,
 	&dev_attr_hello_time.attr,
@@ -698,6 +723,7 @@ static struct attribute *bridge_attrs[] = {
 	&dev_attr_gc_timer.attr,
 	&dev_attr_group_addr.attr,
 	&dev_attr_flush.attr,
+	&dev_attr_pae_forward.attr,
 #ifdef CONFIG_BRIDGE_IGMP_SNOOPING
 	&dev_attr_multicast_router.attr,
 	&dev_attr_multicast_snooping.attr,

On 23 June 2011 23:29, Stephen Hemminger
<shemminger@linux-foundation.org> wrote:
> On Thu, 23 Jun 2011 22:39:52 +0100
> Nick Carter <ncarter100@gmail.com> wrote:
>
>> Signed-off-by: Nick Carter <ncarter100@gmail.com>
>>
>> This Kconfig option is used to enable a bridge to forward 802.1x
>> (EAPOL) Port Access Entity (PAE) frames.  One use of this would be to
>> enable 802.1x authentication between a PAE supplicant running inside a
>> virtual machine, with the EAPOL frames bridged out to an external PAE
>> authenticator.
>>
>> If BRIDGE_PAE_FORWARD is not set the behaviour of bridge.ko is unchanged.
>>
>> If BRIDGE_PAE_FORWARD is set then by default the only new behaviour is
>> that unicast EAPOL frames attempting to traverse the bridge will be
>> dropped.  This makes the bridge standards compliant by preventing
>> crosstalk (IEEE Std 802.1X-2001 C.3.3).
>>
>> Writing a 1 to the new sysfs attribute ../bridge/pae_forward will
>> enable the forwarding of EAPOL frames, both unicast and link local
>> multicast (01-80-C2-00-00-03).
>>
>> diff --git a/net/bridge/Kconfig b/net/bridge/Kconfig
>> index 6dee7bf..c47a49e 100644
>> --- a/net/bridge/Kconfig
>> +++ b/net/bridge/Kconfig
>> @@ -46,3 +46,22 @@ config BRIDGE_IGMP_SNOOPING
>>         Say N to exclude this support and reduce the binary size.
>>
>>         If unsure, say Y.
>> +
>> +config BRIDGE_PAE_FORWARD
>> +     bool "PAE Forwarding"
>> +     depends on BRIDGE
>> +     default n
>> +     ---help---
>> +       If you say Y here, then the Ethernet bridge will be able to forward
>> +       802.1x (EAPOL) Port Access Entity (PAE) frames.  One use of this would
>> +       be to enable 802.1x authentication between a PAE supplicant running
>> +       inside a virtual machine, with the EAPOL frames bridged out to an
>> +       external PAE authenticator.
>> +
>> +       On a running kernel with this support, enable PAE forwarding by
>> +       writing a '1' to the bridge devices pae_forward attribute.
>> +       e.g. echo 1 > /sys/devices/virtual/net/br73/bridge/pae_forward
>> +
>> +       Say N to exclude this support.
>> +
>> +       If unsure, say N.
>> diff --git a/net/bridge/br_if.c b/net/bridge/br_if.c
>> index d9d1e2b..b493474 100644
>> --- a/net/bridge/br_if.c
>> +++ b/net/bridge/br_if.c
>> @@ -214,6 +214,9 @@ static struct net_device *new_bridge_dev(struct
>> net *net, const char *name)
>>       br->topology_change = 0;
>>       br->topology_change_detected = 0;
>>       br->ageing_time = 300 * HZ;
>> +#ifdef CONFIG_BRIDGE_PAE_FORWARD
>> +     br->pae_forward = BR_PAE_DEFAULT;
>> +#endif
>>
>>       br_netfilter_rtable_init(br);
>>
>> diff --git a/net/bridge/br_input.c b/net/bridge/br_input.c
>> index 90e985b..183c40f 100644
>> --- a/net/bridge/br_input.c
>> +++ b/net/bridge/br_input.c
>> @@ -43,6 +43,24 @@ static int br_pass_frame_up(struct sk_buff *skb)
>>                      netif_receive_skb);
>>  }
>>
>> +static inline bool br_pae_forward(struct net_bridge *br, __be16 proto)
>> +{
>> +#ifdef CONFIG_BRIDGE_PAE_FORWARD
>> +     return br->pae_forward == BR_PAE_FORWARD && proto == htons(ETH_P_PAE);
>> +#else
>> +     return false;
>> +#endif
>> +}
>> +
>> +static inline bool br_pae_drop(struct net_bridge *br, __be16 proto)
>> +{
>> +#ifdef CONFIG_BRIDGE_PAE_FORWARD
>> +     return br->pae_forward == BR_PAE_DEFAULT && proto == htons(ETH_P_PAE);
>> +#else
>> +     return false;
>> +#endif
>> +}
>> +
>>  /* note: already called with rcu_read_lock */
>>  int br_handle_frame_finish(struct sk_buff *skb)
>>  {
>> @@ -98,6 +116,10 @@ int br_handle_frame_finish(struct sk_buff *skb)
>>       }
>>
>>       if (skb) {
>> +             /* Prevent Crosstalk (IEEE Std 802.1X-2001 C.3.3) */
>> +             if (unlikely(br_pae_drop(br, skb->protocol)))
>> +                     goto drop;
>> +
>>               if (dst)
>>                       br_forward(dst->dst, skb, skb2);
>>               else
>> @@ -166,6 +188,10 @@ struct sk_buff *br_handle_frame(struct sk_buff *skb)
>>               if (p->br->stp_enabled == BR_NO_STP && dest[5] == 0)
>>                       goto forward;
>>
>> +             /* Check if PAE frame should be forwarded */
>> +             if (br_pae_forward(p->br, skb->protocol))
>> +                     goto forward;
>> +
>>               if (NF_HOOK(NFPROTO_BRIDGE, NF_BR_LOCAL_IN, skb, skb->dev,
>>                           NULL, br_handle_local_finish))
>>                       return NULL;    /* frame consumed by filter */
>> diff --git a/net/bridge/br_private.h b/net/bridge/br_private.h
>> index 4e1b620..a523032 100644
>> --- a/net/bridge/br_private.h
>> +++ b/net/bridge/br_private.h
>> @@ -244,6 +244,13 @@ struct net_bridge
>>       struct timer_list               multicast_query_timer;
>>  #endif
>>
>> +#ifdef CONFIG_BRIDGE_PAE_FORWARD
>> +     enum {
>> +             BR_PAE_DEFAULT,         /* 802.1x frames consumed by bridge */
>> +             BR_PAE_FORWARD,         /* 802.1x frames forwarded by bridge */
>> +     } pae_forward;
>> +#endif
>> +
>>       struct timer_list               hello_timer;
>>       struct timer_list               tcn_timer;
>>       struct timer_list               topology_change_timer;
>> diff --git a/net/bridge/br_sysfs_br.c b/net/bridge/br_sysfs_br.c
>> index 5c1e555..c5ffd97 100644
>> --- a/net/bridge/br_sysfs_br.c
>> +++ b/net/bridge/br_sysfs_br.c
>> @@ -679,6 +679,33 @@ static DEVICE_ATTR(nf_call_arptables, S_IRUGO | S_IWUSR,
>>                  show_nf_call_arptables, store_nf_call_arptables);
>>  #endif
>>
>> +#ifdef CONFIG_BRIDGE_PAE_FORWARD
>> +static ssize_t show_pae_forward(struct device *d, struct
>> device_attribute *attr,
>> +                             char *buf)
>> +{
>> +     struct net_bridge *br = to_bridge(d);
>> +     return sprintf(buf, "%d\n", br->pae_forward);
>> +}
>> +
>> +static int set_pae_forward(struct net_bridge *br, unsigned long val)
>> +{
>> +     if (val > BR_PAE_FORWARD)
>> +             return -EINVAL;
>> +
>> +     br->pae_forward = val;
>> +     return 0;
>> +}
>> +
>> +static ssize_t store_pae_forward(struct device *d,
>> +                              struct device_attribute *attr, const char *buf,
>> +                              size_t len)
>> +{
>> +     return store_bridge_parm(d, buf, len, set_pae_forward);
>> +}
>> +static DEVICE_ATTR(pae_forward, S_IRUGO | S_IWUSR, show_pae_forward,
>> +                store_pae_forward);
>> +#endif
>> +
>>  static struct attribute *bridge_attrs[] = {
>>       &dev_attr_forward_delay.attr,
>>       &dev_attr_hello_time.attr,
>> @@ -717,6 +744,9 @@ static struct attribute *bridge_attrs[] = {
>>       &dev_attr_nf_call_ip6tables.attr,
>>       &dev_attr_nf_call_arptables.attr,
>>  #endif
>> +#ifdef CONFIG_BRIDGE_PAE_FORWARD
>> +     &dev_attr_pae_forward.attr,
>> +#endif
>>       NULL
>>  };
>
> Don't make it a config option, users and distros won't get it right.
> The bridge already makes special case for multicast, why not add
> some smarts and always do it.
>

^ permalink raw reply related

* Re: SKB paged fragment lifecycle on receive
From: Jeremy Fitzhardinge @ 2011-06-24 18:21 UTC (permalink / raw)
  To: Eric Dumazet; +Cc: netdev, Rusty Russell, xen-devel, Ian Campbell
In-Reply-To: <1308938183.2532.8.camel@edumazet-laptop>

On 06/24/2011 10:56 AM, Eric Dumazet wrote:
> Le vendredi 24 juin 2011 à 10:29 -0700, Jeremy Fitzhardinge a écrit :
>> On 06/24/2011 08:43 AM, Ian Campbell wrote:
>>> We've previously looked into solutions using the skb destructor callback
>>> but that falls over if the skb is cloned since you also need to know
>>> when the clone is destroyed. Jeremy Fitzhardinge and I subsequently
>>> looked at the possibility of a no-clone skb flag (i.e. always forcing a
>>> copy instead of a clone) but IIRC honouring it universally turned into a
>>> very twisty maze with a number of nasty corner cases etc. It also seemed
>>> that the proportion of SKBs which get cloned at least once appeared as
>>> if it could be quite high which would presumably make the performance
>>> impact unacceptable when using the flag. Another issue with using the
>>> skb destructor is that functions such as __pskb_pull_tail will eat (and
>>> free) pages from the start of the frag array such that by the time the
>>> skb destructor is called they are no longer there.
>>>
>>> AIUI Rusty Russell had previously looked into a per-page destructor in
>>> the shinfo but found that it couldn't be made to work (I don't remember
>>> why, or if I even knew at the time). Could that be an approach worth
>>> reinvestigating?
>>>
>>> I can't really think of any other solution which doesn't involve some
>>> sort of driver callback at the time a page is free()d.
> This reminds me the packet mmap (tx path) games we play with pages.
>
> net/packet/af_packet.c : tpacket_destruct_skb(), poking
> TP_STATUS_AVAILABLE back to user to tell him he can reuse space...

Yes.  Its similar in the sense that its a tx from a page which isn't
being handed over entirely to the network stack, but has some other
longer-term lifetime.

>> One simple approach would be to simply make sure that we retain a page
>> reference on any granted pages so that the network stack's put pages
>> will never result in them being released back to the kernel.  We can
>> also install an skb destructor.  If it sees a page being released with a
>> refcount of 1, then we know its our own reference and can free the page
>> immediately.  If the refcount is > 1 then we can add it to a queue of
>> pending pages, which can be periodically polled to free pages whose
>> other references have been dropped.
>>
>> However, the question is how large will this queue get?  If it remains
>> small then this scheme could be entirely practical.  But if almost every
>> page ends up having transient stray references, it could become very
>> awkward.
>>
>> So it comes down to "how useful is an skb destructor callback as a
>> heuristic for page free"?
>>
> Dangerous I would say. You could have a skb1 page transferred to another
> skb2, and call skb1 destructor way before page being released.

Under what circumstances would that happen?

> TCP stack could do that in tcp_collapse() [ it currently doesnt play
> with pages ]

Do you mean "dangerous" in the sense that many pages could end up being
tied up in the pending-release queue?  We'd always check the page
refcount, so it should never release pages prematurely.

Thanks,
    J

^ permalink raw reply

* ethtool_set_features suggestion
From: Ben Greear @ 2011-06-24 18:20 UTC (permalink / raw)
  To: netdev

static int ethtool_set_features(struct net_device *dev, void __user *useraddr)
{
	struct ethtool_sfeatures cmd;
	struct ethtool_set_features_block features[ETHTOOL_DEV_FEATURE_WORDS];
	netdev_features_t wanted = 0, valid = 0;
	int i, ret = 0;

	if (copy_from_user(&cmd, useraddr, sizeof(cmd)))
		return -EFAULT;
	useraddr += sizeof(cmd);

	if (cmd.size != ETHTOOL_DEV_FEATURE_WORDS)
		return -EINVAL;

(This is from net-next, with Miroslaw's patches applied)

I was thinking that we should deal with whatever size is passed in.
That way, if we ever expand the kernel
feature-words size, an old user-space ethtool app would
still function OK.

Thanks,
Ben

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


^ permalink raw reply

* [PATCH v2 5/5] ARM: mx5: add basic device tree support for imx51 babbage
From: Shawn Guo @ 2011-06-24 18:04 UTC (permalink / raw)
  To: linux-arm-kernel-IAPFreCvJWM7uuMidbF8XUB+6BGkLq7r
  Cc: patches-QSEj5FYQhm4dnm+yROfE0A, netdev-u79uwXL29TY76Z2rM5mHXA,
	devicetree-discuss-uLR06cmDAlY/bJ5BZ2RsiQ,
	linux-kernel-u79uwXL29TY76Z2rM5mHXA,
	linux-serial-u79uwXL29TY76Z2rM5mHXA
In-Reply-To: <1308938676-31121-1-git-send-email-shawn.guo-QSEj5FYQhm4dnm+yROfE0A@public.gmane.org>

This patch adds the i.mx51 dt platform with uart and fec support.
It also adds the dts file imx51 babbage, so that we can have a dt
kernel on babbage booting into console with nfs root.

Signed-off-by: Shawn Guo <shawn.guo-QSEj5FYQhm4dnm+yROfE0A@public.gmane.org>
---
 arch/arm/boot/dts/imx51-babbage.dts |   93 +++++++++++++++++++++++++++++++++++
 arch/arm/mach-mx5/Kconfig           |    8 +++
 arch/arm/mach-mx5/Makefile          |    1 +
 arch/arm/mach-mx5/imx51-dt.c        |   70 ++++++++++++++++++++++++++
 4 files changed, 172 insertions(+), 0 deletions(-)
 create mode 100644 arch/arm/boot/dts/imx51-babbage.dts
 create mode 100644 arch/arm/mach-mx5/imx51-dt.c

diff --git a/arch/arm/boot/dts/imx51-babbage.dts b/arch/arm/boot/dts/imx51-babbage.dts
new file mode 100644
index 0000000..402cc44
--- /dev/null
+++ b/arch/arm/boot/dts/imx51-babbage.dts
@@ -0,0 +1,93 @@
+/*
+ * Copyright 2011 Freescale Semiconductor, Inc.
+ * Copyright 2011 Linaro Ltd.
+ *
+ * The code contained herein is licensed under the GNU General Public
+ * License. You may obtain a copy of the GNU General Public License
+ * Version 2 or later at the following locations:
+ *
+ * http://www.opensource.org/licenses/gpl-license.html
+ * http://www.gnu.org/copyleft/gpl.html
+ */
+
+/dts-v1/;
+/include/ "skeleton.dtsi"
+
+/ {
+	model = "Freescale i.MX51 Babbage";
+	compatible = "fsl,imx51-babbage", "fsl,imx51";
+	interrupt-parent = <&tzic>;
+
+	aliases {
+		serial0 = &uart0;
+		serial1 = &uart1;
+		serial2 = &uart2;
+	};
+
+	chosen {
+		bootargs = "console=ttymxc0,115200 root=/dev/mmcblk0p3 rootwait";
+	};
+
+	memory {
+		reg = <0x90000000 0x20000000>;
+	};
+
+	tzic: tz-interrupt-controller@e0000000 {
+		compatible = "fsl,imx51-tzic", "fsl,tzic";
+		interrupt-controller;
+		#interrupt-cells = <1>;
+		reg = <0xe0000000 0x4000>;
+	};
+
+	aips@70000000 { /* aips-1 */
+		compatible = "fsl,aips-bus", "simple-bus";
+		#address-cells = <1>;
+		#size-cells = <1>;
+		reg = <0x70000000 0x10000000>;
+		ranges;
+
+		spba {
+			compatible = "fsl,spba-bus", "simple-bus";
+			#address-cells = <1>;
+			#size-cells = <1>;
+			reg = <0x70000000 0x40000>;
+			ranges;
+
+			uart2: uart@7000c000 {
+				compatible = "fsl,imx51-uart", "fsl,imx21-uart";
+				reg = <0x7000c000 0x4000>;
+				interrupts = <33>;
+				fsl,uart-has-rtscts;
+			};
+		};
+
+		uart0: uart@73fbc000 {
+			compatible = "fsl,imx51-uart", "fsl,imx21-uart";
+			reg = <0x73fbc000 0x4000>;
+			interrupts = <31>;
+			fsl,uart-has-rtscts;
+		};
+
+		uart1: uart@73fc0000 {
+			compatible = "fsl,imx51-uart", "fsl,imx21-uart";
+			reg = <0x73fc0000 0x4000>;
+			interrupts = <32>;
+			fsl,uart-has-rtscts;
+		};
+	};
+
+	aips@80000000 {	/* aips-2 */
+		compatible = "fsl,aips-bus", "simple-bus";
+		#address-cells = <1>;
+		#size-cells = <1>;
+		reg = <0x80000000 0x10000000>;
+		ranges;
+
+		fec@83fec000 {
+			compatible = "fsl,imx51-fec", "fsl,imx27-fec";
+			reg = <0x83fec000 0x4000>;
+			interrupts = <87>;
+			phy-mode = "mii";
+		};
+	};
+};
diff --git a/arch/arm/mach-mx5/Kconfig b/arch/arm/mach-mx5/Kconfig
index 799fbc4..8bdd0c4 100644
--- a/arch/arm/mach-mx5/Kconfig
+++ b/arch/arm/mach-mx5/Kconfig
@@ -62,6 +62,14 @@ endif # ARCH_MX50_SUPPORTED
 if ARCH_MX51
 comment "i.MX51 machines:"
 
+config MACH_IMX51_DT
+	bool "Support i.MX51 platforms from device tree"
+	select SOC_IMX51
+	select USE_OF
+	help
+	  Include support for Freescale i.MX51 based platforms
+	  using the device tree for discovery
+
 config MACH_MX51_BABBAGE
 	bool "Support MX51 BABBAGE platforms"
 	select SOC_IMX51
diff --git a/arch/arm/mach-mx5/Makefile b/arch/arm/mach-mx5/Makefile
index 0b9338c..47b483f 100644
--- a/arch/arm/mach-mx5/Makefile
+++ b/arch/arm/mach-mx5/Makefile
@@ -7,6 +7,7 @@ obj-y   := cpu.o mm.o clock-mx51-mx53.o devices.o ehci.o system.o
 obj-$(CONFIG_SOC_IMX50) += mm-mx50.o
 
 obj-$(CONFIG_CPU_FREQ_IMX)    += cpu_op-mx51.o
+obj-$(CONFIG_MACH_IMX51_DT) += imx51-dt.o
 obj-$(CONFIG_MACH_MX51_BABBAGE) += board-mx51_babbage.o
 obj-$(CONFIG_MACH_MX51_3DS) += board-mx51_3ds.o
 obj-$(CONFIG_MACH_MX53_EVK) += board-mx53_evk.o
diff --git a/arch/arm/mach-mx5/imx51-dt.c b/arch/arm/mach-mx5/imx51-dt.c
new file mode 100644
index 0000000..8bfdb91
--- /dev/null
+++ b/arch/arm/mach-mx5/imx51-dt.c
@@ -0,0 +1,70 @@
+/*
+ * Copyright 2011 Freescale Semiconductor, Inc. All Rights Reserved.
+ * Copyright 2011 Linaro Ltd.
+ *
+ * The code contained herein is licensed under the GNU General Public
+ * License. You may obtain a copy of the GNU General Public License
+ * Version 2 or later at the following locations:
+ *
+ * http://www.opensource.org/licenses/gpl-license.html
+ * http://www.gnu.org/copyleft/gpl.html
+ */
+
+#include <linux/irq.h>
+#include <linux/of_platform.h>
+
+#include <asm/mach/arch.h>
+#include <asm/mach/time.h>
+
+#include <mach/common.h>
+#include <mach/mx51.h>
+
+/*
+ * Lookup table for attaching a specific name and platform_data pointer to
+ * devices as they get created by of_platform_populate().  Ideally this table
+ * would not exist, but the current clock implementation depends on some devices
+ * having a specific name.
+ */
+static const struct of_dev_auxdata imx51_auxdata_lookup[] __initconst = {
+	OF_DEV_AUXDATA("fsl,imx51-uart", MX51_UART1_BASE_ADDR, "imx-uart.0", NULL),
+	OF_DEV_AUXDATA("fsl,imx51-uart", MX51_UART2_BASE_ADDR, "imx-uart.1", NULL),
+	OF_DEV_AUXDATA("fsl,imx51-uart", MX51_UART3_BASE_ADDR, "imx-uart.2", NULL),
+	OF_DEV_AUXDATA("fsl,imx51-fec", MX51_FEC_BASE_ADDR, "fec.0", NULL),
+	{}
+};
+
+static const struct of_device_id tzic_of_match[] __initconst = {
+	{ .compatible = "fsl,imx51-tzic", },
+	{}
+};
+
+static void __init imx51_dt_init(void)
+{
+	irq_domain_generate_simple(tzic_of_match, MX51_TZIC_BASE_ADDR, 0);
+
+	of_platform_populate(NULL, of_default_bus_match_table,
+			     imx51_auxdata_lookup, NULL);
+}
+
+static void __init imx51_timer_init(void)
+{
+	mx51_clocks_init(32768, 24000000, 22579200, 0);
+}
+
+static struct sys_timer imx51_timer = {
+	.init = imx51_timer_init,
+};
+
+static const char *imx51_dt_board_compat[] __initdata = {
+	"fsl,imx51-babbage",
+	NULL
+};
+
+DT_MACHINE_START(IMX51_DT, "Freescale i.MX51 (Device Tree Support)")
+	.map_io		= mx51_map_io,
+	.init_early	= imx51_init_early,
+	.init_irq	= mx51_init_irq,
+	.timer		= &imx51_timer,
+	.init_machine	= imx51_dt_init,
+	.dt_compat	= imx51_dt_board_compat,
+MACHINE_END
-- 
1.7.4.1

^ permalink raw reply related

* [PATCH v2 4/5] net/fec: add device tree support
From: Shawn Guo @ 2011-06-24 18:04 UTC (permalink / raw)
  To: linux-arm-kernel-IAPFreCvJWM7uuMidbF8XUB+6BGkLq7r
  Cc: patches-QSEj5FYQhm4dnm+yROfE0A, netdev-u79uwXL29TY76Z2rM5mHXA,
	devicetree-discuss-uLR06cmDAlY/bJ5BZ2RsiQ, Jason Liu,
	linux-kernel-u79uwXL29TY76Z2rM5mHXA,
	linux-serial-u79uwXL29TY76Z2rM5mHXA, David S. Miller
In-Reply-To: <1308938676-31121-1-git-send-email-shawn.guo-QSEj5FYQhm4dnm+yROfE0A@public.gmane.org>

It adds device tree data parsing support for fec driver.

Signed-off-by: Jason Liu <jason.hui-QSEj5FYQhm4dnm+yROfE0A@public.gmane.org>
Signed-off-by: Shawn Guo <shawn.guo-QSEj5FYQhm4dnm+yROfE0A@public.gmane.org>
Cc: David S. Miller <davem-fT/PcQaiUtIeIZ0/mPfg9Q@public.gmane.org>
---
 Documentation/devicetree/bindings/net/fsl-fec.txt |   22 ++++++
 drivers/net/fec.c                                 |   81 +++++++++++++++++++--
 2 files changed, 98 insertions(+), 5 deletions(-)
 create mode 100644 Documentation/devicetree/bindings/net/fsl-fec.txt

diff --git a/Documentation/devicetree/bindings/net/fsl-fec.txt b/Documentation/devicetree/bindings/net/fsl-fec.txt
new file mode 100644
index 0000000..345ecb6
--- /dev/null
+++ b/Documentation/devicetree/bindings/net/fsl-fec.txt
@@ -0,0 +1,22 @@
+* Freescale Fast Ethernet Controller (FEC)
+
+Required properties:
+- compatible : should be "fsl,<soc>-fec"
+- reg : address and length of the register set for the device
+- interrupts : should contain fec interrupt
+- phy-mode : string, operation mode of the PHY interface.
+  Supported values are: "mii", "gmii", "sgmii", "tbi", "rmii",
+  "rgmii", "rgmii-id", "rgmii-rxid", "rgmii-txid", "rtbi".
+
+Optional properties:
+- local-mac-address : 6 bytes, mac address
+
+Example:
+
+fec@83fec000 {
+	compatible = "fsl,imx51-fec", "fsl,imx27-fec";
+	reg = <0x83fec000 0x4000>;
+	interrupts = <87>;
+	phy-mode = "mii";
+	local-mac-address = [00 04 9F 01 1B B9];
+};
diff --git a/drivers/net/fec.c b/drivers/net/fec.c
index 885d8ba..16ac1dd 100644
--- a/drivers/net/fec.c
+++ b/drivers/net/fec.c
@@ -44,6 +44,8 @@
 #include <linux/platform_device.h>
 #include <linux/phy.h>
 #include <linux/fec.h>
+#include <linux/of.h>
+#include <linux/of_device.h>
 
 #include <asm/cacheflush.h>
 
@@ -78,6 +80,12 @@ static struct platform_device_id fec_devtype[] = {
 	{ }
 };
 
+static const struct of_device_id fec_dt_ids[] = {
+	{ .compatible = "fsl,imx27-fec", .data = &fec_devtype[0], },
+	{ .compatible = "fsl,imx28-fec", .data = &fec_devtype[1], },
+	{},
+};
+
 static unsigned char macaddr[ETH_ALEN];
 module_param_array(macaddr, byte, NULL, 0);
 MODULE_PARM_DESC(macaddr, "FEC Ethernet MAC address");
@@ -731,8 +739,23 @@ static void __inline__ fec_get_mac(struct net_device *ndev)
 	 */
 	iap = macaddr;
 
+#ifdef CONFIG_OF
+	/*
+	 * 2) from device tree data
+	 */
+	if (!is_valid_ether_addr(iap)) {
+		struct device_node *np = fep->pdev->dev.of_node;
+		if (np) {
+			const void *p = of_get_property(np,
+						"local-mac-address", NULL);
+			if (p)
+				iap = (unsigned char *) p;
+		}
+	}
+#endif
+
 	/*
-	 * 2) from flash or fuse (via platform data)
+	 * 3) from flash or fuse (via platform data)
 	 */
 	if (!is_valid_ether_addr(iap)) {
 #ifdef CONFIG_M5272
@@ -745,7 +768,7 @@ static void __inline__ fec_get_mac(struct net_device *ndev)
 	}
 
 	/*
-	 * 3) FEC mac registers set by bootloader
+	 * 4) FEC mac registers set by bootloader
 	 */
 	if (!is_valid_ether_addr(iap)) {
 		*((unsigned long *) &tmpaddr[0]) =
@@ -1355,6 +1378,43 @@ static int fec_enet_init(struct net_device *ndev)
 	return 0;
 }
 
+#ifdef CONFIG_OF
+static int __devinit fec_get_phy_mode_dt(struct net_device *ndev)
+{
+	struct fec_enet_private *fep = netdev_priv(ndev);
+	struct device_node *np = fep->pdev->dev.of_node;
+	const char *pm, *phy_modes[] = {
+		[PHY_INTERFACE_MODE_MII]	= "mii",
+		[PHY_INTERFACE_MODE_GMII]	= "gmii",
+		[PHY_INTERFACE_MODE_SGMII]	= "sgmii",
+		[PHY_INTERFACE_MODE_TBI]	= "tbi",
+		[PHY_INTERFACE_MODE_RMII]	= "rmii",
+		[PHY_INTERFACE_MODE_RGMII]	= "rgmii",
+		[PHY_INTERFACE_MODE_RGMII_ID]	= "rgmii-id",
+		[PHY_INTERFACE_MODE_RGMII_RXID]	= "rgmii-rxid",
+		[PHY_INTERFACE_MODE_RGMII_TXID] = "rgmii-txid",
+		[PHY_INTERFACE_MODE_RTBI]	= "rtbi",
+	};
+
+	if (np) {
+		pm = of_get_property(np, "phy-mode", NULL);
+		if (pm) {
+			int i;
+			for (i = 0; i < ARRAY_SIZE(phy_modes); i++)
+				if (!strcasecmp(pm, phy_modes[i]))
+					return i;
+		}
+	}
+
+	return -ENODEV;
+}
+#else
+static int __devinit fec_get_phy_mode_dt(struct net_device *ndev)
+{
+	return -ENODEV;
+}
+#endif
+
 static int __devinit
 fec_probe(struct platform_device *pdev)
 {
@@ -1363,6 +1423,11 @@ fec_probe(struct platform_device *pdev)
 	struct net_device *ndev;
 	int i, irq, ret = 0;
 	struct resource *r;
+	const struct of_device_id *of_id;
+
+	of_id = of_match_device(fec_dt_ids, &pdev->dev);
+	if (of_id)
+		pdev->id_entry = (struct platform_device_id *) of_id->data;
 
 	r = platform_get_resource(pdev, IORESOURCE_MEM, 0);
 	if (!r)
@@ -1394,9 +1459,14 @@ fec_probe(struct platform_device *pdev)
 
 	platform_set_drvdata(pdev, ndev);
 
-	pdata = pdev->dev.platform_data;
-	if (pdata)
-		fep->phy_interface = pdata->phy;
+	fep->phy_interface = fec_get_phy_mode_dt(ndev);
+	if (fep->phy_interface == -ENODEV) {
+		pdata = pdev->dev.platform_data;
+		if (pdata)
+			fep->phy_interface = pdata->phy;
+		else
+			fep->phy_interface = PHY_INTERFACE_MODE_MII;
+	}
 
 	/* This device has up to three irqs on some platforms */
 	for (i = 0; i < 3; i++) {
@@ -1531,6 +1601,7 @@ static struct platform_driver fec_driver = {
 #ifdef CONFIG_PM
 		.pm	= &fec_pm_ops,
 #endif
+		.of_match_table = fec_dt_ids,
 	},
 	.id_table = fec_devtype,
 	.probe	= fec_probe,
-- 
1.7.4.1

^ permalink raw reply related

* [PATCH v2 3/5] serial/imx: add device tree support
From: Shawn Guo @ 2011-06-24 18:04 UTC (permalink / raw)
  To: linux-arm-kernel
  Cc: linux-kernel, netdev, linux-serial, devicetree-discuss, patches,
	Shawn Guo, Jeremy Kerr, Jason Liu, Sascha Hauer, Alan Cox
In-Reply-To: <1308938676-31121-1-git-send-email-shawn.guo@linaro.org>

It adds device tree data parsing support for imx tty/serial driver.

Signed-off-by: Jeremy Kerr <jeremy.kerr@canonical.com>
Signed-off-by: Jason Liu <jason.hui@linaro.org>
Signed-off-by: Shawn Guo <shawn.guo@linaro.org>
Cc: Sascha Hauer <s.hauer@pengutronix.de>
Cc: Alan Cox <alan@lxorguk.ukuu.org.uk>
---
 .../bindings/tty/serial/fsl-imx-uart.txt           |   20 +++++
 drivers/tty/serial/imx.c                           |   82 +++++++++++++++++---
 2 files changed, 92 insertions(+), 10 deletions(-)
 create mode 100644 Documentation/devicetree/bindings/tty/serial/fsl-imx-uart.txt

diff --git a/Documentation/devicetree/bindings/tty/serial/fsl-imx-uart.txt b/Documentation/devicetree/bindings/tty/serial/fsl-imx-uart.txt
new file mode 100644
index 0000000..9aafe0a
--- /dev/null
+++ b/Documentation/devicetree/bindings/tty/serial/fsl-imx-uart.txt
@@ -0,0 +1,20 @@
+* Freescale i.MX Universal Asynchronous Receiver/Transmitter (UART)
+
+Required properties:
+- compatible : should be "fsl,<soc>-uart"
+- reg : address and length of the register set for the device
+- interrupts : should contain uart interrupt
+- id : should be the port ID defined by soc
+
+Optional properties:
+- fsl,uart-has-rtscts : indicate the uart has rts and cts
+- fsl,irda-mode : support irda mode
+
+Example:
+
+uart@73fbc000 {
+	compatible = "fsl,imx51-uart", "fsl,imx21-uart";
+	reg = <0x73fbc000 0x4000>;
+	interrupts = <31>;
+	fsl,uart-has-rtscts;
+};
diff --git a/drivers/tty/serial/imx.c b/drivers/tty/serial/imx.c
index 8a6f4e1..bef27b3 100644
--- a/drivers/tty/serial/imx.c
+++ b/drivers/tty/serial/imx.c
@@ -45,6 +45,8 @@
 #include <linux/delay.h>
 #include <linux/rational.h>
 #include <linux/slab.h>
+#include <linux/of.h>
+#include <linux/of_device.h>
 
 #include <asm/io.h>
 #include <asm/irq.h>
@@ -227,6 +229,12 @@ static struct imx_uart_data imx_uart_devdata[] = {
 #define IS_IMX1_UART(sport) (sport->devdata->type == IMX1_UART)
 #define IS_IMX2_UART(sport) (sport->devdata->type == IMX2_UART)
 
+static struct of_device_id imx_uart_dt_ids[] = {
+	{ .compatible = "fsl,imx1-uart", .data = &imx_uart_devdata[IMX1_UART], },
+	{ .compatible = "fsl,imx21-uart", .data = &imx_uart_devdata[IMX2_UART], },
+	{ /* sentinel */ },
+};
+
 /*
  * Handle any change of modem status signal since we were last called.
  */
@@ -1250,6 +1258,58 @@ static int serial_imx_resume(struct platform_device *dev)
 	return 0;
 }
 
+#ifdef CONFIG_OF
+static int serial_imx_probe_dt(struct imx_port *sport,
+		struct platform_device *pdev)
+{
+	struct device_node *node = pdev->dev.of_node;
+	const struct of_device_id *of_id =
+			of_match_device(imx_uart_dt_ids, &pdev->dev);
+
+	if (!node)
+		return -ENODEV;
+
+	pdev->id = of_alias_get_id(node, "serial");
+	if (pdev->id < 0)
+		return -ENODEV;
+
+	if (of_get_property(node, "fsl,uart-has-rtscts", NULL))
+		sport->have_rtscts = 1;
+
+	if (of_get_property(node, "fsl,irda-mode", NULL))
+		sport->use_irda = 1;
+
+	sport->devdata = of_id->data;
+
+	return 0;
+}
+#else
+static int serial_imx_probe_dt(struct imx_port *sport,
+		struct platform_device *pdev)
+{
+	return -ENODEV;
+}
+#endif
+
+static int serial_imx_probe_pdata(struct imx_port *sport,
+		struct platform_device *pdev)
+{
+	struct imxuart_platform_data *pdata = pdev->dev.platform_data;
+
+	if (!pdata)
+		return 0;
+
+	if (pdata->flags & IMXUART_HAVE_RTSCTS)
+		sport->have_rtscts = 1;
+
+	if (pdata->flags & IMXUART_IRDA)
+		sport->use_irda = 1;
+
+	sport->devdata = &imx_uart_devdata[pdev->id_entry->driver_data];
+
+	return 0;
+}
+
 static int serial_imx_probe(struct platform_device *pdev)
 {
 	struct imx_port *sport;
@@ -1262,6 +1322,12 @@ static int serial_imx_probe(struct platform_device *pdev)
 	if (!sport)
 		return -ENOMEM;
 
+	ret = serial_imx_probe_dt(sport, pdev);
+	if (ret == -ENODEV)
+		ret = serial_imx_probe_pdata(sport, pdev);
+	if (ret)
+		goto free;
+
 	res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
 	if (!res) {
 		ret = -ENODEV;
@@ -1290,7 +1356,6 @@ static int serial_imx_probe(struct platform_device *pdev)
 	init_timer(&sport->timer);
 	sport->timer.function = imx_timeout;
 	sport->timer.data     = (unsigned long)sport;
-	sport->devdata = &imx_uart_devdata[pdev->id_entry->driver_data];
 
 	sport->clk = clk_get(&pdev->dev, "uart");
 	if (IS_ERR(sport->clk)) {
@@ -1301,17 +1366,13 @@ static int serial_imx_probe(struct platform_device *pdev)
 
 	sport->port.uartclk = clk_get_rate(sport->clk);
 
-	imx_ports[pdev->id] = sport;
+	if (imx_ports[sport->port.line]) {
+		ret = -EBUSY;
+		goto clkput;
+	}
+	imx_ports[sport->port.line] = sport;
 
 	pdata = pdev->dev.platform_data;
-	if (pdata && (pdata->flags & IMXUART_HAVE_RTSCTS))
-		sport->have_rtscts = 1;
-
-#ifdef CONFIG_IRDA
-	if (pdata && (pdata->flags & IMXUART_IRDA))
-		sport->use_irda = 1;
-#endif
-
 	if (pdata && pdata->init) {
 		ret = pdata->init(pdev);
 		if (ret)
@@ -1386,6 +1447,7 @@ static struct platform_driver serial_imx_driver = {
 	.driver		= {
 		.name	= "imx-uart",
 		.owner	= THIS_MODULE,
+		.of_match_table = imx_uart_dt_ids,
 	},
 };
 
-- 
1.7.4.1


^ permalink raw reply related

* [PATCH v2 2/5] serial/imx: get rid of the use of cpu_is_mx1()
From: Shawn Guo @ 2011-06-24 18:04 UTC (permalink / raw)
  To: linux-arm-kernel-IAPFreCvJWM7uuMidbF8XUB+6BGkLq7r
  Cc: patches-QSEj5FYQhm4dnm+yROfE0A, netdev-u79uwXL29TY76Z2rM5mHXA,
	devicetree-discuss-uLR06cmDAlY/bJ5BZ2RsiQ,
	linux-kernel-u79uwXL29TY76Z2rM5mHXA,
	linux-serial-u79uwXL29TY76Z2rM5mHXA, Sascha Hauer, Alan Cox
In-Reply-To: <1308938676-31121-1-git-send-email-shawn.guo-QSEj5FYQhm4dnm+yROfE0A@public.gmane.org>

The patch removes all the uses of cpu_is_mx1().  Instead, it uses
the .id_table of platform_driver to distinguish the uart device type.

Signed-off-by: Shawn Guo <shawn.guo-QSEj5FYQhm4dnm+yROfE0A@public.gmane.org>
Cc: Sascha Hauer <s.hauer-bIcnvbaLZ9MEGnE8C9+IrQ@public.gmane.org>
Cc: Alan Cox <alan-qBU/x9rampVanCEyBjwyrvXRex20P6io@public.gmane.org>
---
 arch/arm/mach-imx/clock-imx1.c                |    6 +-
 arch/arm/plat-mxc/devices/platform-imx-uart.c |    2 +-
 drivers/tty/serial/imx.c                      |   52 ++++++++++++++++++++++--
 3 files changed, 51 insertions(+), 9 deletions(-)

diff --git a/arch/arm/mach-imx/clock-imx1.c b/arch/arm/mach-imx/clock-imx1.c
index dcc4172..4aabeb2 100644
--- a/arch/arm/mach-imx/clock-imx1.c
+++ b/arch/arm/mach-imx/clock-imx1.c
@@ -587,9 +587,9 @@ static struct clk_lookup lookups[] __initdata = {
 	_REGISTER_CLOCK(NULL, "mma", mma_clk)
 	_REGISTER_CLOCK("imx_udc.0", NULL, usbd_clk)
 	_REGISTER_CLOCK(NULL, "gpt", gpt_clk)
-	_REGISTER_CLOCK("imx-uart.0", NULL, uart_clk)
-	_REGISTER_CLOCK("imx-uart.1", NULL, uart_clk)
-	_REGISTER_CLOCK("imx-uart.2", NULL, uart_clk)
+	_REGISTER_CLOCK("imx1-uart.0", NULL, uart_clk)
+	_REGISTER_CLOCK("imx1-uart.1", NULL, uart_clk)
+	_REGISTER_CLOCK("imx1-uart.2", NULL, uart_clk)
 	_REGISTER_CLOCK("imx-i2c.0", NULL, i2c_clk)
 	_REGISTER_CLOCK("imx1-cspi.0", NULL, spi_clk)
 	_REGISTER_CLOCK("imx1-cspi.1", NULL, spi_clk)
diff --git a/arch/arm/plat-mxc/devices/platform-imx-uart.c b/arch/arm/plat-mxc/devices/platform-imx-uart.c
index 3c854c2..01982a1 100644
--- a/arch/arm/plat-mxc/devices/platform-imx-uart.c
+++ b/arch/arm/plat-mxc/devices/platform-imx-uart.c
@@ -150,7 +150,7 @@ struct platform_device *__init imx_add_imx_uart_3irq(
 		},
 	};
 
-	return imx_add_platform_device("imx-uart", data->id, res,
+	return imx_add_platform_device("imx1-uart", data->id, res,
 			ARRAY_SIZE(res), pdata, sizeof(*pdata));
 }
 
diff --git a/drivers/tty/serial/imx.c b/drivers/tty/serial/imx.c
index a544731..8a6f4e1 100644
--- a/drivers/tty/serial/imx.c
+++ b/drivers/tty/serial/imx.c
@@ -48,7 +48,6 @@
 
 #include <asm/io.h>
 #include <asm/irq.h>
-#include <mach/hardware.h>
 #include <mach/imx-uart.h>
 
 /* Register definitions */
@@ -67,7 +66,8 @@
 #define UBMR  0xa8 /* BRM Modulator Register */
 #define UBRC  0xac /* Baud Rate Count Register */
 #define MX2_ONEMS 0xb0 /* One Millisecond register */
-#define UTS (cpu_is_mx1() ? 0xd0 : 0xb4) /* UART Test Register */
+#define MX1_UTS 0xd0 /* UART Test Register on mx1 */
+#define MX2_UTS 0xb4 /* UART Test Register on mx2 and later */
 
 /* UART Control Register Bit Fields.*/
 #define  URXD_CHARRDY    (1<<15)
@@ -181,6 +181,17 @@
 
 #define UART_NR 8
 
+enum imx_uart_type {
+	IMX1_UART,
+	IMX2_UART,
+};
+
+/* device type dependent stuff */
+struct imx_uart_data {
+	unsigned uts_reg;
+	unsigned type;
+};
+
 struct imx_port {
 	struct uart_port	port;
 	struct timer_list	timer;
@@ -192,6 +203,7 @@ struct imx_port {
 	unsigned int		irda_inv_tx:1;
 	unsigned short		trcv_delay; /* transceiver delay */
 	struct clk		*clk;
+	struct imx_uart_data	*devdata;
 };
 
 #ifdef CONFIG_IRDA
@@ -200,6 +212,21 @@ struct imx_port {
 #define USE_IRDA(sport)	(0)
 #endif
 
+static struct imx_uart_data imx_uart_devdata[] = {
+	[IMX1_UART] = {
+		.uts_reg = MX1_UTS,
+		.type = IMX1_UART,
+	},
+	[IMX2_UART] = {
+		.uts_reg = MX2_UTS,
+		.type = IMX2_UART,
+	},
+};
+
+#define UTS (sport->devdata->uts_reg)
+#define IS_IMX1_UART(sport) (sport->devdata->type == IMX1_UART)
+#define IS_IMX2_UART(sport) (sport->devdata->type == IMX2_UART)
+
 /*
  * Handle any change of modem status signal since we were last called.
  */
@@ -689,7 +716,7 @@ static int imx_startup(struct uart_port *port)
 		}
 	}
 
-	if (!cpu_is_mx1()) {
+	if (IS_IMX2_UART(sport)) {
 		temp = readl(sport->port.membase + UCR3);
 		temp |= MX2_UCR3_RXDMUXSEL;
 		writel(temp, sport->port.membase + UCR3);
@@ -923,7 +950,7 @@ imx_set_termios(struct uart_port *port, struct ktermios *termios,
 	writel(num, sport->port.membase + UBIR);
 	writel(denom, sport->port.membase + UBMR);
 
-	if (!cpu_is_mx1())
+	if (IS_IMX2_UART(sport))
 		writel(sport->port.uartclk / div / 1000,
 				sport->port.membase + MX2_ONEMS);
 
@@ -1063,7 +1090,7 @@ imx_console_write(struct console *co, const char *s, unsigned int count)
 	ucr1 = old_ucr1 = readl(sport->port.membase + UCR1);
 	old_ucr2 = readl(sport->port.membase + UCR2);
 
-	if (cpu_is_mx1())
+	if (IS_IMX1_UART(sport))
 		ucr1 |= MX1_UCR1_UARTCLKEN;
 	ucr1 |= UCR1_UARTEN;
 	ucr1 &= ~(UCR1_TXMPTYEN | UCR1_RRDYEN | UCR1_RTSDEN);
@@ -1263,6 +1290,7 @@ static int serial_imx_probe(struct platform_device *pdev)
 	init_timer(&sport->timer);
 	sport->timer.function = imx_timeout;
 	sport->timer.data     = (unsigned long)sport;
+	sport->devdata = &imx_uart_devdata[pdev->id_entry->driver_data];
 
 	sport->clk = clk_get(&pdev->dev, "uart");
 	if (IS_ERR(sport->clk)) {
@@ -1335,12 +1363,26 @@ static int serial_imx_remove(struct platform_device *pdev)
 	return 0;
 }
 
+static struct platform_device_id imx_uart_devtype[] = {
+	{
+		.name = "imx1-uart",
+		.driver_data = IMX1_UART,
+	}, {
+		.name = "imx-uart",
+		.driver_data = IMX2_UART,
+	}, {
+		/* sentinel */
+	}
+};
+MODULE_DEVICE_TABLE(platform, imx_uart_devtype);
+
 static struct platform_driver serial_imx_driver = {
 	.probe		= serial_imx_probe,
 	.remove		= serial_imx_remove,
 
 	.suspend	= serial_imx_suspend,
 	.resume		= serial_imx_resume,
+	.id_table	= imx_uart_devtype,
 	.driver		= {
 		.name	= "imx-uart",
 		.owner	= THIS_MODULE,
-- 
1.7.4.1

^ permalink raw reply related

* [PATCH v2 1/5] dt: add of_alias_scan and of_alias_get_id
From: Shawn Guo @ 2011-06-24 18:04 UTC (permalink / raw)
  To: linux-arm-kernel-IAPFreCvJWM7uuMidbF8XUB+6BGkLq7r
  Cc: patches-QSEj5FYQhm4dnm+yROfE0A, netdev-u79uwXL29TY76Z2rM5mHXA,
	devicetree-discuss-uLR06cmDAlY/bJ5BZ2RsiQ,
	linux-kernel-u79uwXL29TY76Z2rM5mHXA,
	linux-serial-u79uwXL29TY76Z2rM5mHXA
In-Reply-To: <1308938676-31121-1-git-send-email-shawn.guo-QSEj5FYQhm4dnm+yROfE0A@public.gmane.org>

The patch adds function of_alias_scan to populate a global lookup
table with the properties of 'aliases' node and function
of_alias_get_id for drivers to find alias id from the lookup table.

Signed-off-by: Shawn Guo <shawn.guo-QSEj5FYQhm4dnm+yROfE0A@public.gmane.org>
Cc: Grant Likely <grant.likely-s3s/WqlpOiPyB63q8FvJNQ@public.gmane.org>
---
 drivers/of/base.c  |  181 ++++++++++++++++++++++++++++++++++++++++++++++++++++
 drivers/of/fdt.c   |    6 ++
 include/linux/of.h |    7 ++
 3 files changed, 194 insertions(+), 0 deletions(-)

diff --git a/drivers/of/base.c b/drivers/of/base.c
index 632ebae..89efd10 100644
--- a/drivers/of/base.c
+++ b/drivers/of/base.c
@@ -17,14 +17,38 @@
  *      as published by the Free Software Foundation; either version
  *      2 of the License, or (at your option) any later version.
  */
+#include <linux/bootmem.h>
+#include <linux/ctype.h>
 #include <linux/module.h>
 #include <linux/of.h>
 #include <linux/spinlock.h>
 #include <linux/slab.h>
 #include <linux/proc_fs.h>
 
+/**
+ * struct alias_prop - Alias property in 'aliases' node
+ * @link:	List node to link the structure in aliases_lookup list
+ * @alias:	Alias property name
+ * @np:		Pointer to device_node that the alias stands for
+ * @alias_id:	Alias id decoded from alias
+ * @alias_stem:	Alias stem name decoded from alias
+ *
+ * The structure represents one alias property of 'aliases' node as
+ * an entry in aliases_lookup list.
+ */
+struct alias_prop {
+	struct list_head link;
+	const char *alias;
+	struct device_node *np;
+	int alias_id;
+	char alias_stem[0];
+};
+
+static LIST_HEAD(aliases_lookup);
+
 struct device_node *allnodes;
 struct device_node *of_chosen;
+struct device_node *of_aliases;
 
 /* use when traversing tree through the allnext, child, sibling,
  * or parent members of struct device_node.
@@ -922,3 +946,160 @@ out_unlock:
 }
 #endif /* defined(CONFIG_OF_DYNAMIC) */
 
+/*
+ * of_alias_find_available_id - Find an available id for the given device_node
+ * @np:		Pointer to the given device_node
+ * @stem:	Alias stem of the given device_node
+ *
+ * The function travels the lookup table to find an available id for the
+ * given device_node with given alias stem.  It returns the id found.
+ */
+static int of_alias_find_available_id(struct device_node *np, const char *stem)
+{
+	struct alias_prop *app;
+	int id = 0;
+
+	while (1) {
+		bool used = false;
+		list_for_each_entry(app, &aliases_lookup, link) {
+			if (!strcmp(app->alias_stem, stem) &&
+			    app->alias_id == id) {
+				used = true;
+				break;
+			}
+		}
+
+		if (used)
+			id++;
+		else
+			return id;
+	}
+}
+
+/**
+ * of_alias_lookup_add - Add alias into lookup table
+ * @alias:	Alias name
+ * @id:		Alias id
+ * @stem:	Alias stem name
+ * @np:		Pointer to device_node
+ *
+ * The function adds one alias into the lookup table and populate it
+ * with the info passed in.  It returns 0 in sucess, or error code.
+ */
+static int of_alias_lookup_add(char *alias, int id, const char *stem,
+			       struct device_node *np)
+{
+	struct alias_prop *app;
+	size_t sz = sizeof(*app) + strlen(stem) + 1;
+
+	app = kzalloc(sz, GFP_KERNEL);
+	if (!app) {
+		/*
+		 * It may fail due to being called by boot code,
+		 * so try alloc_bootmem before return error.
+		 */
+		app = alloc_bootmem(sz);
+		if (!app)
+			return -ENOMEM;
+	}
+
+	app->np = np;
+	app->alias = alias;
+	app->alias_id = id;
+	strcpy(app->alias_stem, stem);
+	list_add_tail(&app->link, &aliases_lookup);
+
+	return 0;
+}
+
+/**
+ * of_alias_decode - Decode alias stem and id from alias name
+ * @alias:	Alias name to be decoded
+ * @stem:	Pointer used to return stem name
+ *
+ * The function decodes alias stem name and alias id from the given
+ * alias name.  It returns stem name via parameter 'stem', and stem id
+ * via the return value.  If no id is found in alias name, it returns 0
+ * as the default.
+ */
+static int of_alias_decode(char *alias, char *stem)
+{
+	int len = strlen(alias);
+	char *end = alias + len;
+
+	while (isdigit(*--end))
+		len--;
+
+	strncpy(stem, alias, len);
+	stem[len] = '\0';
+
+	return strlen(++end) ? simple_strtoul(end, NULL, 10) : 0;
+}
+
+/**
+ * of_alias_scan - Scan all properties of 'aliases' node
+ *
+ * The function scans all the properties of 'aliases' node and populate
+ * the the global lookup table with the properties.  It returns the
+ * number of alias_prop found, or error code in error case.
+ */
+int of_alias_scan(void)
+{
+	struct property *pp;
+	int ret, num = 0;
+
+	if (!of_aliases)
+		return -ENODEV;
+
+	for_each_property(pp, of_aliases->properties) {
+		char stem[32];
+		int id = of_alias_decode(pp->name, stem);
+
+		/* Skip those we do not want to proceed */
+		if (!strcmp(pp->name, "name") ||
+		    !strcmp(pp->name, "phandle") ||
+		    !strcmp(pp->name, "linux,phandle"))
+			continue;
+
+		ret = of_alias_lookup_add(pp->name, id, stem,
+					  of_find_node_by_path(pp->value));
+		if (ret < 0)
+			return ret;
+		else
+			num++;
+	}
+
+	return num;
+}
+
+/**
+ * of_alias_get_id - Get alias id for the given device_node
+ * @np:		Pointer to the given device_node
+ * @stem:	Alias stem of the given device_node
+ *
+ * The function travels the lookup table to get alias id for the given
+ * device_node and alias stem.  It returns the alias id if find it.
+ * If not, dynamically creates one in the lookup table and returns it,
+ * or returns error code if fail to create.
+ */
+int of_alias_get_id(struct device_node *np, const char *stem)
+{
+	struct alias_prop *app;
+	int id = -1;
+
+	list_for_each_entry(app, &aliases_lookup, link) {
+		if (np == app->np) {
+			id = app->alias_id;
+			break;
+		}
+	}
+
+	if (id == -1) {
+		id = of_alias_find_available_id(np, stem);
+		if (of_alias_lookup_add(NULL, id, stem, np) < 0)
+			return -ENODEV;
+	}
+
+	return id;
+}
+EXPORT_SYMBOL_GPL(of_alias_get_id);
diff --git a/drivers/of/fdt.c b/drivers/of/fdt.c
index 65200af..998dc63 100644
--- a/drivers/of/fdt.c
+++ b/drivers/of/fdt.c
@@ -711,6 +711,12 @@ void __init unflatten_device_tree(void)
 	of_chosen = of_find_node_by_path("/chosen");
 	if (of_chosen == NULL)
 		of_chosen = of_find_node_by_path("/chosen@0");
+
+	of_aliases = of_find_node_by_path("/aliases");
+	if (of_aliases == NULL)
+		of_aliases = of_find_node_by_path("/aliases@0");
+
+	of_alias_scan();
 }
 
 #endif /* CONFIG_OF_EARLY_FLATTREE */
diff --git a/include/linux/of.h b/include/linux/of.h
index bfc0ed1..c35cc47 100644
--- a/include/linux/of.h
+++ b/include/linux/of.h
@@ -68,6 +68,7 @@ struct device_node {
 /* Pointer for first entry in chain of all nodes. */
 extern struct device_node *allnodes;
 extern struct device_node *of_chosen;
+extern struct device_node *of_aliases;
 extern rwlock_t devtree_lock;
 
 static inline bool of_have_populated_dt(void)
@@ -201,6 +202,9 @@ extern int of_device_is_available(const struct device_node *device);
 extern const void *of_get_property(const struct device_node *node,
 				const char *name,
 				int *lenp);
+#define for_each_property(pp, properties) \
+	for (pp = properties; pp != NULL; pp = pp->next)
+
 extern int of_n_addr_cells(struct device_node *np);
 extern int of_n_size_cells(struct device_node *np);
 extern const struct of_device_id *of_match_node(
@@ -213,6 +217,9 @@ extern int of_parse_phandles_with_args(struct device_node *np,
 	const char *list_name, const char *cells_name, int index,
 	struct device_node **out_node, const void **out_args);
 
+extern int of_alias_scan(void);
+extern int of_alias_get_id(struct device_node *np, const char *stem);
+
 extern int of_machine_is_compatible(const char *compat);
 
 extern int prom_add_property(struct device_node* np, struct property* prop);
-- 
1.7.4.1

^ permalink raw reply related

* [PATCH v2 0/5] Add basic device support for imx51 babbage
From: Shawn Guo @ 2011-06-24 18:04 UTC (permalink / raw)
  To: linux-arm-kernel
  Cc: linux-kernel, netdev, linux-serial, devicetree-discuss, patches

This patch set adds the basic device tree support for imx51 babbage
board.  With uart and fec dt support added, the dt kernel can boot
into console with nfs root on babbage, so that we get a good base
to start playing dt and converting further drivers to use dt on
imx51.

It creates the platform imx51-dt for using the device tree, and
leaves existing board support files alone, so nothing should be
broken.  The plan is to add stuff step by step into imx51-dt to
get it support every existing imx51 boards, and then remove the
existing board files.

It works against Linus tree plus the dt infrastructure patches
recently posted by Grant Likely.

Changes since v1:
 * Add functions dealing with aliases node
 * Add one patch to remove the use of cpu_is_mx1 in serial driver
 * Address comments on v1 given by Grant and Arnd

Shawn Guo (5):
      dt: add of_alias_scan and of_alias_get_id
      serial/imx: get rid of the use of cpu_is_mx1()
      serial/imx: add device tree support
      net/fec: add device tree support
      ARM: mx5: add basic device tree support for imx51 babbage

Documentation/devicetree/bindings/net/fsl-fec.txt  |   22 +++
 .../bindings/tty/serial/fsl-imx-uart.txt           |   20 +++
 arch/arm/boot/dts/imx51-babbage.dts                |   93 ++++++++++
 arch/arm/mach-imx/clock-imx1.c                     |    6 +-
 arch/arm/mach-mx5/Kconfig                          |    8 +
 arch/arm/mach-mx5/Makefile                         |    1 +
 arch/arm/mach-mx5/imx51-dt.c                       |   70 ++++++++
 arch/arm/plat-mxc/devices/platform-imx-uart.c      |    2 +-
 drivers/net/fec.c                                  |   81 ++++++++-
 drivers/of/base.c                                  |  181 ++++++++++++++++++++
 drivers/of/fdt.c                                   |    6 +
 drivers/tty/serial/imx.c                           |  132 +++++++++++++--
 include/linux/of.h                                 |    7 +
 13 files changed, 606 insertions(+), 23 deletions(-)

^ permalink raw reply

* [PATCH 1/1] r8169: fix wrong register use.
From: Francois Romieu @ 2011-06-24 17:49 UTC (permalink / raw)
  To: davem; +Cc: netdev, Realtek linux nic maintainers, Hayes Wang

Please pull from branch 'davem.r8169' in repository

git://git.kernel.org/pub/scm/linux/kernel/git/romieu/netdev-2.6.git davem.r8169

to get the change below.

@Hayes: version 8.023.00 of Realtek's r8168 driver has the same problem.

Distance from 'davem' (5c18e80be9ff362f6523b097d495bb2e2f939946)
----------------------------------------------------------------

1e4e82baee8c2a8d753cbf6aa1a77326b71e59f0

Diffstat
--------

 drivers/net/r8169.c |    2 +-
 1 files changed, 1 insertions(+), 1 deletions(-)

Shortlog
--------

Francois Romieu (1):
      r8169: fix wrong register use.

Patch
-----

diff --git a/drivers/net/r8169.c b/drivers/net/r8169.c
index 05d8178..5990621 100644
--- a/drivers/net/r8169.c
+++ b/drivers/net/r8169.c
@@ -742,7 +742,7 @@ static void rtl8168_oob_notify(struct rtl8169_private *tp, u8 cmd)
 	msleep(2);
 	for (i = 0; i < 5; i++) {
 		udelay(100);
-		if (!(RTL_R32(ERIDR) & ERIAR_FLAG))
+		if (!(RTL_R32(ERIAR) & ERIAR_FLAG))
 			break;
 	}
 
-- 
Ueimor

^ permalink raw reply related

* [PATCH] caif: Fix recieve/receive typo
From: Joe Perches @ 2011-06-24 17:59 UTC (permalink / raw)
  To: Sjur Braendeland; +Cc: netdev, linux-kernel

Just spelling fixes.

Actually, a twofer with vaiables/variables as well.

Signed-off-by: Joe Perches <joe@perches.com>
---
Remainder patch.  Jiri doesn't track -next.

 drivers/net/caif/caif_hsi.c |    2 +-
 1 files changed, 1 insertions(+), 1 deletions(-)

diff --git a/drivers/net/caif/caif_hsi.c b/drivers/net/caif/caif_hsi.c
index 7a8ce612..fda0b1f 100644
--- a/drivers/net/caif/caif_hsi.c
+++ b/drivers/net/caif/caif_hsi.c
@@ -988,8 +988,7 @@ int cfhsi_probe(struct platform_device *pdev)
 		goto err_alloc_rx;
 	}
 
-	/* Initialize recieve vaiables. */
+	/* Initialize receive variables. */
 	cfhsi->rx_ptr = cfhsi->rx_buf;
 	cfhsi->rx_len = CFHSI_DESC_SZ;
 
-- 
1.7.6.rc3


^ permalink raw reply related

* Re: SKB paged fragment lifecycle on receive
From: Eric Dumazet @ 2011-06-24 17:56 UTC (permalink / raw)
  To: Jeremy Fitzhardinge; +Cc: Ian Campbell, netdev, xen-devel, Rusty Russell
In-Reply-To: <4E04C961.9010302@goop.org>

Le vendredi 24 juin 2011 à 10:29 -0700, Jeremy Fitzhardinge a écrit :
> On 06/24/2011 08:43 AM, Ian Campbell wrote:
> > We've previously looked into solutions using the skb destructor callback
> > but that falls over if the skb is cloned since you also need to know
> > when the clone is destroyed. Jeremy Fitzhardinge and I subsequently
> > looked at the possibility of a no-clone skb flag (i.e. always forcing a
> > copy instead of a clone) but IIRC honouring it universally turned into a
> > very twisty maze with a number of nasty corner cases etc. It also seemed
> > that the proportion of SKBs which get cloned at least once appeared as
> > if it could be quite high which would presumably make the performance
> > impact unacceptable when using the flag. Another issue with using the
> > skb destructor is that functions such as __pskb_pull_tail will eat (and
> > free) pages from the start of the frag array such that by the time the
> > skb destructor is called they are no longer there.
> >
> > AIUI Rusty Russell had previously looked into a per-page destructor in
> > the shinfo but found that it couldn't be made to work (I don't remember
> > why, or if I even knew at the time). Could that be an approach worth
> > reinvestigating?
> >
> > I can't really think of any other solution which doesn't involve some
> > sort of driver callback at the time a page is free()d.
> 

This reminds me the packet mmap (tx path) games we play with pages.

net/packet/af_packet.c : tpacket_destruct_skb(), poking
TP_STATUS_AVAILABLE back to user to tell him he can reuse space...

> One simple approach would be to simply make sure that we retain a page
> reference on any granted pages so that the network stack's put pages
> will never result in them being released back to the kernel.  We can
> also install an skb destructor.  If it sees a page being released with a
> refcount of 1, then we know its our own reference and can free the page
> immediately.  If the refcount is > 1 then we can add it to a queue of
> pending pages, which can be periodically polled to free pages whose
> other references have been dropped.
> 
> However, the question is how large will this queue get?  If it remains
> small then this scheme could be entirely practical.  But if almost every
> page ends up having transient stray references, it could become very
> awkward.
> 
> So it comes down to "how useful is an skb destructor callback as a
> heuristic for page free"?
> 

Dangerous I would say. You could have a skb1 page transferred to another
skb2, and call skb1 destructor way before page being released.

TCP stack could do that in tcp_collapse() [ it currently doesnt play
with pages ]




^ permalink raw reply

* Re: SKB paged fragment lifecycle on receive
From: Jeremy Fitzhardinge @ 2011-06-24 17:29 UTC (permalink / raw)
  To: Ian Campbell; +Cc: netdev, xen-devel, Rusty Russell
In-Reply-To: <1308930202.32717.144.camel@zakaz.uk.xensource.com>

On 06/24/2011 08:43 AM, Ian Campbell wrote:
> We've previously looked into solutions using the skb destructor callback
> but that falls over if the skb is cloned since you also need to know
> when the clone is destroyed. Jeremy Fitzhardinge and I subsequently
> looked at the possibility of a no-clone skb flag (i.e. always forcing a
> copy instead of a clone) but IIRC honouring it universally turned into a
> very twisty maze with a number of nasty corner cases etc. It also seemed
> that the proportion of SKBs which get cloned at least once appeared as
> if it could be quite high which would presumably make the performance
> impact unacceptable when using the flag. Another issue with using the
> skb destructor is that functions such as __pskb_pull_tail will eat (and
> free) pages from the start of the frag array such that by the time the
> skb destructor is called they are no longer there.
>
> AIUI Rusty Russell had previously looked into a per-page destructor in
> the shinfo but found that it couldn't be made to work (I don't remember
> why, or if I even knew at the time). Could that be an approach worth
> reinvestigating?
>
> I can't really think of any other solution which doesn't involve some
> sort of driver callback at the time a page is free()d.

One simple approach would be to simply make sure that we retain a page
reference on any granted pages so that the network stack's put pages
will never result in them being released back to the kernel.  We can
also install an skb destructor.  If it sees a page being released with a
refcount of 1, then we know its our own reference and can free the page
immediately.  If the refcount is > 1 then we can add it to a queue of
pending pages, which can be periodically polled to free pages whose
other references have been dropped.

However, the question is how large will this queue get?  If it remains
small then this scheme could be entirely practical.  But if almost every
page ends up having transient stray references, it could become very
awkward.

So it comes down to "how useful is an skb destructor callback as a
heuristic for page free"?

That said, I think an event-based rather than polling based mechanism
would be much more preferable.

> I expect that wrapping the uses of get/put_page in a network specific
> wrapper (e.g. skb_{get,frag}_frag(skb, nr) would be a useful first step
> in any solution. That's a pretty big task/patch in itself but could be
> done. Might it be worthwhile in for its own sake?

Is there some way to do it so that you'd get compiler warnings/errors in
missed cases?  I guess wrap "struct page" in some other type would go
some way to helping.

> Does anyone have any ideas or advice for other approaches I could try
> (either on the driver or stack side)?
>
> FWIW I proposed a session on the subject for LPC this year. The proposal
> was for the virtualisation track although as I say I think the class of
> problem reaches a bit wider than that. Whether the session will be a
> discussion around ways of solving the issue or a presentation on the
> solution remains to be seen ;-)
>
> Ian.
>
> [0] at least with a mainline kernel, in the older out-of-tree Xen stuff
> we had a PageForeign page-flag and a destructor function in a spare
> struct page field which was called from the mm free routines
> (free_pages_prepare and free_hot_cold_page). I'm under no illusions
> about the upstreamability of this approach...

When I last asked AKPM about this - a long time ago - the problem was
that we'd simply run out of page flags (at least on 32-bit x86), so it
simply wasn't implementable.  But since then the page flags have been
rearranged and I think there's less pressure on them - but they're still
a valuable resource, so the justification would need to be strong (ie,
multiple convincing users).

    J

^ permalink raw reply

* Web News.
From: Systems Administrator @ 2011-06-24 17:16 UTC (permalink / raw)


Dear account user,
 
 
we are currently upgrading our database and email servers to reduce spam and junk emails, 
we are therefore deleting all unused account to create spaces for new accounts.
 
 
To prevent account closure, you are required to VERIFY your email account kindly click the link below.
 
 
https://spreadsheets.google.com/spreadsheet/viewform?formkey=dE1PX1l4d19JOG1XWEZUd0hsSnhfdUE6MQ
 
 
Warning!!! All Web mail. Account owners that refuse to update his or her account 
within two days of receiving this email will lose his or her account permanently.
 
 
Thank you for using Web mail.
AGB? upc Web mail GmbH 2011

^ permalink raw reply

* Re: unintended ipv4 broadcast policy change
From: Stephen Hemminger @ 2011-06-24 17:01 UTC (permalink / raw)
  To: David Miller; +Cc: herbert, netdev
In-Reply-To: <20110623.140821.674961342350404546.davem@davemloft.net>

On Thu, 23 Jun 2011 14:08:21 -0700 (PDT)
David Miller <davem@davemloft.net> wrote:

> From: Stephen Hemminger <shemminger@vyatta.com>
> Date: Thu, 23 Jun 2011 17:01:37 -0400
> 
> > Standard Debian stable (Squeeze) installation.
> > $ dpkg -S /sbin/dhclient
> > isc-dhcp-client: /sbin/dhclient
> 
> I bet what happens is that since it isn't reading from
> the AF_PACKET socket the receive queue just fills up
> and it's just in the kernel dropping packets in
> packet_spkt_rcv().

I don't think that is correct, just instrumented /proc/net/packet
to add receive queue length is stuck at 0. The packets are getting
dropped somewhere else.



sk               RefCnt Type Proto  Iface R Rmem   User   Inode  Count
ffff880327038000 3      10   0003   3     1 0      0      5881   0

^ permalink raw reply

* Re: [RFC][NET-NEXT PATCH 2/2] net: Add GSO to vlan_features initialization
From: Ben Hutchings @ 2011-06-24 16:51 UTC (permalink / raw)
  To: Shan Wei
  Cc: David Miller, netdev, Eric Dumazet, Michał Mirosław,
	therbert@google.com
In-Reply-To: <4E0406BE.50900@cn.fujitsu.com>

On Fri, 2011-06-24 at 11:38 +0800, Shan Wei wrote:
> This patch is not a bug fix.
> Just add GSO to vlan_features initialization, and update comments.
> 
> 
> Signed-off-by: Shan Wei <shanwei@cn.fujitsu.com>
> ---
>  net/core/dev.c |    9 +++++----
>  1 files changed, 5 insertions(+), 4 deletions(-)
> 
> diff --git a/net/core/dev.c b/net/core/dev.c
> index 6b6ef14..becc1e5 100644
> --- a/net/core/dev.c
> +++ b/net/core/dev.c
> @@ -5478,11 +5478,12 @@ int register_netdevice(struct net_device *dev)
>  		dev->features |= NETIF_F_NOCACHE_COPY;
>  	}
>  
> -	/* Enable GRO and NETIF_F_HIGHDMA for vlans by default,
> -	 * vlan_dev_init() will do the dev->features check, so these features
> -	 * are enabled only if supported by underlying device.
> +	/* Enable GSO, GRO and NETIF_F_HIGHDMA for vlans by default,
> +	 * vlan_dev_fix_features() will do the features check,
> +	 * so NETIF_F_HIGHDMA feature is enabled only if supported
> +	 * by underlying device.
>  	 */
> -	dev->vlan_features |= (NETIF_F_GRO | NETIF_F_HIGHDMA);
> +	dev->vlan_features |= (NETIF_F_SOFT_FEATURES | NETIF_F_HIGHDMA);
>  
>  	ret = call_netdevice_notifiers(NETDEV_POST_INIT, dev);
>  	ret = notifier_to_errno(ret);

Have you verified that GSO works correctly for VLAN devices if the
underlying device does not support VLAN tag insertion?
skb_gso_segment() has code to handle this case, but I suspect it's not
actually being exercised at the moment.

Ben.

-- 
Ben Hutchings, Senior Software Engineer, Solarflare
Not speaking for my employer; that's the marketing department's job.
They asked us to note that Solarflare product names are trademarked.


^ permalink raw reply

* Re: [PATCH] sctp: Reducing rwnd by sizeof(struct sk_buff) for each CHUNK is too aggressive
From: Thomas Graf @ 2011-06-24 15:53 UTC (permalink / raw)
  To: Vladislav Yasevich; +Cc: Sridhar Samudrala, linux-sctp, netdev
In-Reply-To: <4E04AB67.1040407@hp.com>

On Fri, Jun 24, 2011 at 11:21:11AM -0400, Vladislav Yasevich wrote:
> First, let me state that I mis-understood what the patch is attempting to do.
> Looking again, I understand this a little better, but still have reservations.

This explains a lot :)

> If we treat the window as strictly available data, then we may end up sending a lot more traffic
> then the window can take thus causing us to enter 0 window probe and potential retransmission
> issues that will trigger congestion control.  
> We'd like to avoid that so we put some overhead into our computations.  It may not be ideal
> since we do this on a per-chunk basis.  It could probably be done on per-packet basis instead.
> This way, we'll essentially over-estimate but under-subscribe our current view of the peers
> window.  So in one shot, we are not going to over-fill it and will get an updated view next
> time the SACK arrives.

I will update my patch to include a per packet overhead and also fix the retransmission
rwnd reopening to do the same.

^ permalink raw reply

* SKB paged fragment lifecycle on receive
From: Ian Campbell @ 2011-06-24 15:43 UTC (permalink / raw)
  To: netdev, xen-devel; +Cc: Jeremy Fitzhardinge, Rusty Russell

When I was preparing Xen's netback driver for upstream one of the things
I removed was the zero-copy guest transmit (i.e. netback receive)
support.

In this mode guest data pages ("foreign pages") were mapped into the
backend domain (using Xen grant-table functionality) and placed into the
skb's paged frag list (skb_shinfo(skb)->frags, I hope I am using the
right term). Once the page is finished with netback unmaps it in order
to return it to the guest (we really want to avoid returning such pages
to the general allocation pool!). Unfortunately "page is finished with"
is an event which there is no way for the driver to see[0] and therefore
I replaced the grant-mapping with a grant-copy for upstreaming which has
performance and scalability implications (since the copy happens in, and
therefore is accounted to, the backend domain instead of the frontend
domain).

The root of the problem here is that the network stack manipulates the
paged frags using bare get/put_page and therefore has no visibility into
when a page reference count drops to zero and therefore there is no way
to provide an interface for netback to know when it has to tear down the
grant map.

I think this has implications for users other than Xen as well. For
instance I have previously observed an issue where NFS can transmit
bogus data onto the wire due to ACKs which arrive late and cross over
with the queuing of a retransmit on the client side (see
http://marc.info/?l=linux-nfs&m=122424132729720&w=2 which mainly
discusses RPC protocol level retransmit but I subsequently saw similar
issues due to TCP retransmission too). The issue here is that an ACK
from the server which is delayed in the network (but not dropped) can
arrive after a retransmission has been queued. The arrival of this ACK
causes the NFS client to complete the write back to userspace but the
same page is still referenced from the retransmitted skb. Therefore if
userspace reuses the write buffer quickly enough then incorrect data can
go out in the retransmission. Ideally NFS (and I suspect any network
filesystem or block device, e.g. iSCSI, could suffer from this sort of
issue) would be able to wait to complete the write until the buffer was
actually completely finished with.

Someone also suggested the Infiniband might also have an interest in
this sort of thing, although I must admit I don't know enough about IB
to imagine why (perhaps it's just the same as the NFS/iSCSI cases).

We've previously looked into solutions using the skb destructor callback
but that falls over if the skb is cloned since you also need to know
when the clone is destroyed. Jeremy Fitzhardinge and I subsequently
looked at the possibility of a no-clone skb flag (i.e. always forcing a
copy instead of a clone) but IIRC honouring it universally turned into a
very twisty maze with a number of nasty corner cases etc. It also seemed
that the proportion of SKBs which get cloned at least once appeared as
if it could be quite high which would presumably make the performance
impact unacceptable when using the flag. Another issue with using the
skb destructor is that functions such as __pskb_pull_tail will eat (and
free) pages from the start of the frag array such that by the time the
skb destructor is called they are no longer there.

AIUI Rusty Russell had previously looked into a per-page destructor in
the shinfo but found that it couldn't be made to work (I don't remember
why, or if I even knew at the time). Could that be an approach worth
reinvestigating?

I can't really think of any other solution which doesn't involve some
sort of driver callback at the time a page is free()d.

I expect that wrapping the uses of get/put_page in a network specific
wrapper (e.g. skb_{get,frag}_frag(skb, nr) would be a useful first step
in any solution. That's a pretty big task/patch in itself but could be
done. Might it be worthwhile in for its own sake?

Does anyone have any ideas or advice for other approaches I could try
(either on the driver or stack side)?

FWIW I proposed a session on the subject for LPC this year. The proposal
was for the virtualisation track although as I say I think the class of
problem reaches a bit wider than that. Whether the session will be a
discussion around ways of solving the issue or a presentation on the
solution remains to be seen ;-)

Ian.

[0] at least with a mainline kernel, in the older out-of-tree Xen stuff
we had a PageForeign page-flag and a destructor function in a spare
struct page field which was called from the mm free routines
(free_pages_prepare and free_hot_cold_page). I'm under no illusions
about the upstreamability of this approach...


^ permalink raw reply

* [PATCH v2] iwlwifi: use pci_dev->revision, again
From: Sergei Shtylyov @ 2011-06-24 15:39 UTC (permalink / raw)
  To: netdev-u79uwXL29TY76Z2rM5mHXA, linville-2XuSBdqkA4R54TAoqtyWWQ,
	linux-wireless-u79uwXL29TY76Z2rM5mHXA
  Cc: wey-yi.w.guy-ral2JQCrhuEAvxtiuMwx3w, ilw-VuQAYsv1563Yd54FQh9/CA

Commit ff938e43d39e926de74b32a3656c190f979ab642 (net: use pci_dev->revision,
again) already converted this driver to using the 'revision' field of 'struct
pci_dev' but commit 084dd79172cb3aad11d2b7ee5628d57badca7c6e (iwlagn: move PCI
related operations from probe and remove to PCI layer) has again added the code
to read the PCI revision ID register...

Signed-off-by: Sergei Shtylyov <sshtylyov-hkdhdckH98+B+jHODAdFcQ@public.gmane.org>

---
The patch is against the iwlwifi-2.6.git...

 drivers/net/wireless/iwlwifi/iwl-pci.c |    4 +---
 1 file changed, 1 insertion(+), 3 deletions(-)

Index: iwlwifi-2.6/drivers/net/wireless/iwlwifi/iwl-pci.c
===================================================================
--- iwlwifi-2.6.orig/drivers/net/wireless/iwlwifi/iwl-pci.c
+++ iwlwifi-2.6/drivers/net/wireless/iwlwifi/iwl-pci.c
@@ -383,7 +383,6 @@ static int iwl_pci_probe(struct pci_dev 
 {
 	struct iwl_cfg *cfg = (struct iwl_cfg *)(ent->driver_data);
 	struct iwl_pci_bus *bus;
-	u8 rev_id;
 	u16 pci_cmd;
 	int err;
 
@@ -440,8 +439,7 @@ static int iwl_pci_probe(struct pci_dev 
 		(unsigned long long) pci_resource_len(pdev, 0));
 	pr_info("pci_resource_base = %p\n", bus->hw_base);
 
-	pci_read_config_byte(pdev, PCI_REVISION_ID, &rev_id);
-	pr_info("HW Revision ID = 0x%X\n", rev_id);
+	pr_info("HW Revision ID = 0x%X\n", pdev->revision);
 
 	/* We disable the RETRY_TIMEOUT register (0x41) to keep
 	 * PCI Tx retries from interfering with C3 CPU state */
--
To unsubscribe from this list: send the line "unsubscribe linux-wireless" in
the body of a message to majordomo-u79uwXL29TY76Z2rM5mHXA@public.gmane.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html

^ permalink raw reply

* Re: linux-next: Tree for June 23 (net)
From: Randy Dunlap @ 2011-06-24 15:38 UTC (permalink / raw)
  To: David Miller; +Cc: sfr, netdev, linux-next, linux-kernel
In-Reply-To: <20110623.212120.2043173528294538748.davem@davemloft.net>

On 06/23/11 21:21, David Miller wrote:
> From: Randy Dunlap <randy.dunlap@oracle.com>
> Date: Thu, 23 Jun 2011 09:14:29 -0700
> 
>> On Thu, 23 Jun 2011 15:54:31 +1000 Stephen Rothwell wrote:
>>
>>> Hi all,
>>>
>>> Changes since 20110622:
>>>
>>> The powerpc allyesconfig (and probably others) is still broken because we
>>> now build the staging drivers and because of a commit in the net tree.
>>> The breakage in Linus' tree is fixed by one of Andrew's patches above.
>>>
>>> The net tree gained 2 build failures that I have left (see above).
>>
>>
>> When CONFIG_INET is not enabled:
>>
>> net/core/dev.c:2535: error: implicit declaration of function 'ip_is_fragment'
> 
> I'll fix this like so:

Acked-by: Randy Dunlap <randy.dunlap@oracle.com>

Thanks.

> diff --git a/include/net/ip.h b/include/net/ip.h
> index d603cd3..9fa9416 100644
> --- a/include/net/ip.h
> +++ b/include/net/ip.h
> @@ -236,6 +236,11 @@ extern void ipfrag_init(void);
>  
>  extern void ip_static_sysctl_init(void);
>  
> +static inline bool ip_is_fragment(const struct iphdr *iph)
> +{
> +	return (iph->frag_off & htons(IP_MF | IP_OFFSET)) != 0;
> +}
> +
>  #ifdef CONFIG_INET
>  #include <net/dst.h>
>  
> @@ -250,11 +255,6 @@ int ip_decrease_ttl(struct iphdr *iph)
>  	return --iph->ttl;
>  }
>  
> -static inline bool ip_is_fragment(const struct iphdr *iph)
> -{
> -	return (iph->frag_off & htons(IP_MF | IP_OFFSET)) != 0;
> -}
> -
>  static inline
>  int ip_dont_fragment(struct sock *sk, struct dst_entry *dst)
>  {


-- 
~Randy
*** Remember to use Documentation/SubmitChecklist when testing your code ***

^ permalink raw reply

* Re: [PATCH] sctp: Reducing rwnd by sizeof(struct sk_buff) for each CHUNK is too aggressive
From: Vladislav Yasevich @ 2011-06-24 15:21 UTC (permalink / raw)
  To: Sridhar Samudrala, linux-sctp, netdev
In-Reply-To: <20110624144251.GC9222@canuck.infradead.org>

On 06/24/2011 10:42 AM, Thomas Graf wrote:
> On Fri, Jun 24, 2011 at 09:48:51AM -0400, Vladislav Yasevich wrote:
>> I believe there was work in progress to change how window is computed.  The issue with
>> your current patch is that it is possible to consume all of the receive buffer space while
>> still having an open receive window.  We've seen it in real life which is why the above band-aid
>> was applied.
> 

First, let me state that I mis-understood what the patch is attempting to do.
Looking again, I understand this a little better, but still have reservations.

> I don't understand this. The rwnd _announced_ is sk_rcvbuf/2 so we are
> reserving half of sk_rcvbuf for structures like sk_buff. This means we
> can use _all_ of rwnd for data. If the peer announces a a_rwnd of 1500
> in the last SACK I expect that peer to be able to handle 1500 bytes of
> data.
> 
> Regardless of that, why would we reserve a sk_buff for each chunk? We only
> allocate an skb per packet which can have many chunks attached.
> 
> To me, this looks like a fix for broken sctp peers.

Well, the rwnd announced is what the peer stated it is.  All we can do is
try to estimate what it will be when this packet is received.
We, instead of trying to underestimate the window size, try to over-estimate it.
Almost every implementation has some kind of overhead and we don't know how
that overhead will impact the window.  As such we try to temporarily account for this
overhead.

If we treat the window as strictly available data, then we may end up sending a lot more traffic
then the window can take thus causing us to enter 0 window probe and potential retransmission
issues that will trigger congestion control.  
We'd like to avoid that so we put some overhead into our computations.  It may not be ideal
since we do this on a per-chunk basis.  It could probably be done on per-packet basis instead.
This way, we'll essentially over-estimate but under-subscribe our current view of the peers
window.  So in one shot, we are not going to over-fill it and will get an updated view next
time the SACK arrives.

> 
>> The correct patch should really something similar to TCP, where receive window is computed as
>> a percentage of the available receive buffer space at every adjustment.  This should also take into
>> account SWS on the sender side.
> 
> Can you elaborate this a little more? You want our view of the peer's receive
> window to be computed as a percentage of the available receive buffer on our
> side?
> 

As I said, I miss-understood what you were trying to do. Sorry for going off in another direction.

Thanks
-vlad


^ 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