Netdev List
 help / color / mirror / Atom feed
* Re: [PATCH 1/2] pcnet32: Introduce basic AT 2700/01 FTX support
From: Seewer Philippe @ 2006-02-17 20:12 UTC (permalink / raw)
  To: Don Fry; +Cc: tsbogend, linux-kernel, netdev
In-Reply-To: <20060217182104.GA19257@us.ibm.com>



Don Fry wrote:
> Philippe,
> 
> On a purely mechanical note, the patches do not apply cleanly because
> of whitespace changes.  Possibly your mailer changed tabs to spaces,
> which causes the patch not to apply, and also causes your patch to have
> different spacing than the rest of the file.  The driver does not
> conform to the 8-space indentation guideline/rule, but it is consistent
> in 4-space indentation.
uhhh.... did i forget to run Lindent..? Or was it that i just
selected-middle clicked them into thunderbird?
what's the recommended procedure oh how to append patches to
mails? (Documentation just says included not attached...)
> 
> I am looking over this change and the following one, to try and
> understand what and why you made your changes.
> 
> The change made by Thomas Bogendoerfer and modified by myself is much
> more flexible than your changes, in that they are not specific just to
> the Allied Telesyn boards with multiple Phys.
I'm not sure what you are talking about. I didn't see any PHY switching
code in the driver... And the specs specifically say that when more than
one PHY is connected control should revert to software.

> They also allow dynamic
> changing of cabling without requiring the driver to be removed/installed
> or the card power cycled.  I also see little value in the module
> parameters, when it can be determined dynamically. Also, maxphy might be
> thought to the the maximum number of phys, rather than the maximum phy
> number supported.  If static selection of the phy to use is passed in as
> a module parameter, why also include a maxphy?
maxphy is supposed to be how many PHYs are actually connected to the chip.
I didn't want to introduce a generic PHY scanner (which is possible)
because that would have haa impact on all cards not only cards that actually
have more than one phy.

I really tried to put this into pcnet32_open. But i just didn't work...

> 
> As I review your patches I will follow up to the mailing list.
> 
> On Fri, Feb 17, 2006 at 05:14:39PM +0100, Seewer Philippe wrote:
> 
>>This patch extends Don Fry's last patch for AT 2700/01 FX to set the
>>speed/fdx options for the FTX variants of these cards as well.
>>
>>Additionally the option override has been moved from pcnet32_open to
>>pcnet32_probe1 because it's only necessary to override the options once.
>>
>>Tested and works.
>>
>>Patch applies to 2.6.16-rc3
>>
> 
> Don Fry
> brazilnut@us.ibm.com

^ permalink raw reply

* [git patches] net driver fixes
From: Jeff Garzik @ 2006-02-17 21:24 UTC (permalink / raw)
  To: Andrew Morton, Linus Torvalds; +Cc: netdev, linux-kernel


Please pull from 'upstream-fixes' branch of
master.kernel.org:/pub/scm/linux/kernel/git/jgarzik/netdev-2.6.git

to receive the following updates:

 drivers/net/Kconfig               |    5 -
 drivers/net/bonding/bond_main.c   |    1 
 drivers/net/sis190.c              |    4 -
 drivers/net/skge.c                |   10 +++
 drivers/net/sky2.c                |   31 ++++++++++
 drivers/net/tokenring/smctr.h     |    2 
 drivers/net/wireless/atmel.c      |   98 ++++++++++++++++++++-------------
 drivers/net/wireless/wavelan_cs.c |   16 +----
 drivers/s390/net/lcs.c            |   31 +++++-----
 drivers/s390/net/lcs.h            |    2 
 drivers/s390/net/qeth.h           |  112 +++++++++++++++-----------------------
 drivers/s390/net/qeth_eddp.c      |   11 +++
 drivers/s390/net/qeth_main.c      |   17 ++---
 13 files changed, 189 insertions(+), 151 deletions(-)

Andrew Morton:
      smctr warning fix

Dan Williams:
      wireless/atmel: fix setting TX key only in ENCODEEXT
      wireless/atmel: fix Open System authentication process bugs

Francois Romieu:
      sis190: early setting of the pci driver private data

Frank Pavlic:
      s390: lcs performance enhancements
      s390: some qeth driver fixes

Jay Vosburgh:
      bonding: fix a locking bug in bond_release

Jean Tourrilhes:
      Wavelan_cs bitfield fixes

Stephen Hemminger:
      sk98lin: no d-link support (kconfig)
      skge: no longer experimental
      skge: speed setting
      sky2: speed setting fix

diff --git a/drivers/net/Kconfig b/drivers/net/Kconfig
index 47c72a6..e45a8f9 100644
--- a/drivers/net/Kconfig
+++ b/drivers/net/Kconfig
@@ -2020,8 +2020,8 @@ config SIS190
 	  will be called sis190.  This is recommended.
 
 config SKGE
-	tristate "New SysKonnect GigaEthernet support (EXPERIMENTAL)"
-	depends on PCI && EXPERIMENTAL
+	tristate "New SysKonnect GigaEthernet support"
+	depends on PCI
 	select CRC32
 	---help---
 	  This driver support the Marvell Yukon or SysKonnect SK-98xx/SK-95xx
@@ -2082,7 +2082,6 @@ config SK98LIN
 	    - Allied Telesyn AT-2971SX Gigabit Ethernet Adapter
 	    - Allied Telesyn AT-2971T Gigabit Ethernet Adapter
 	    - Belkin Gigabit Desktop Card 10/100/1000Base-T Adapter, Copper RJ-45
-	    - DGE-530T Gigabit Ethernet Adapter
 	    - EG1032 v2 Instant Gigabit Network Adapter
 	    - EG1064 v2 Instant Gigabit Network Adapter
 	    - Marvell 88E8001 Gigabit LOM Ethernet Adapter (Abit)
diff --git a/drivers/net/bonding/bond_main.c b/drivers/net/bonding/bond_main.c
index e0f51af..bcf9f17 100644
--- a/drivers/net/bonding/bond_main.c
+++ b/drivers/net/bonding/bond_main.c
@@ -1581,6 +1581,7 @@ int bond_release(struct net_device *bond
 		printk(KERN_INFO DRV_NAME
 		       ": %s: %s not enslaved\n",
 		       bond_dev->name, slave_dev->name);
+		write_unlock_bh(&bond->lock);
 		return -EINVAL;
 	}
 
diff --git a/drivers/net/sis190.c b/drivers/net/sis190.c
index b420182..ed4bc91 100644
--- a/drivers/net/sis190.c
+++ b/drivers/net/sis190.c
@@ -1791,6 +1791,8 @@ static int __devinit sis190_init_one(str
 		goto out;
 	}
 
+	pci_set_drvdata(pdev, dev);
+
 	tp = netdev_priv(dev);
 	ioaddr = tp->mmio_addr;
 
@@ -1827,8 +1829,6 @@ static int __devinit sis190_init_one(str
 	if (rc < 0)
 		goto err_remove_mii;
 
-	pci_set_drvdata(pdev, dev);
-
 	net_probe(tp, KERN_INFO "%s: %s at %p (IRQ: %d), "
 	       "%2.2x:%2.2x:%2.2x:%2.2x:%2.2x:%2.2x\n",
 	       pci_name(pdev), sis_chip_info[ent->driver_data].name,
diff --git a/drivers/net/skge.c b/drivers/net/skge.c
index bf55a4c..67fb19b 100644
--- a/drivers/net/skge.c
+++ b/drivers/net/skge.c
@@ -1697,6 +1697,7 @@ static void yukon_mac_init(struct skge_h
 	skge_write32(hw, SK_REG(port, GPHY_CTRL), reg | GPC_RST_SET);
 	skge_write32(hw, SK_REG(port, GPHY_CTRL), reg | GPC_RST_CLR);
 	skge_write32(hw, SK_REG(port, GMAC_CTRL), GMC_PAUSE_ON | GMC_RST_CLR);
+
 	if (skge->autoneg == AUTONEG_DISABLE) {
 		reg = GM_GPCR_AU_ALL_DIS;
 		gma_write16(hw, port, GM_GP_CTRL,
@@ -1704,16 +1705,23 @@ static void yukon_mac_init(struct skge_h
 
 		switch (skge->speed) {
 		case SPEED_1000:
+			reg &= ~GM_GPCR_SPEED_100;
 			reg |= GM_GPCR_SPEED_1000;
-			/* fallthru */
+			break;
 		case SPEED_100:
+			reg &= ~GM_GPCR_SPEED_1000;
 			reg |= GM_GPCR_SPEED_100;
+			break;
+		case SPEED_10:
+			reg &= ~(GM_GPCR_SPEED_1000 | GM_GPCR_SPEED_100);
+			break;
 		}
 
 		if (skge->duplex == DUPLEX_FULL)
 			reg |= GM_GPCR_DUP_FULL;
 	} else
 		reg = GM_GPCR_SPEED_1000 | GM_GPCR_SPEED_100 | GM_GPCR_DUP_FULL;
+
 	switch (skge->flow_control) {
 	case FLOW_MODE_NONE:
 		skge_write32(hw, SK_REG(port, GMAC_CTRL), GMC_PAUSE_OFF);
diff --git a/drivers/net/sky2.c b/drivers/net/sky2.c
index cae2edf..bfeba5b 100644
--- a/drivers/net/sky2.c
+++ b/drivers/net/sky2.c
@@ -520,10 +520,16 @@ static void sky2_mac_init(struct sky2_hw
 
 		switch (sky2->speed) {
 		case SPEED_1000:
+			reg &= ~GM_GPCR_SPEED_100;
 			reg |= GM_GPCR_SPEED_1000;
-			/* fallthru */
+			break;
 		case SPEED_100:
+			reg &= ~GM_GPCR_SPEED_1000;
 			reg |= GM_GPCR_SPEED_100;
+			break;
+		case SPEED_10:
+			reg &= ~(GM_GPCR_SPEED_1000 | GM_GPCR_SPEED_100);
+			break;
 		}
 
 		if (sky2->duplex == DUPLEX_FULL)
@@ -1446,6 +1452,29 @@ static void sky2_link_up(struct sky2_por
 	sky2_write8(hw, SK_REG(port, GMAC_IRQ_MSK), GMAC_DEF_MSK);
 
 	reg = gma_read16(hw, port, GM_GP_CTRL);
+	if (sky2->autoneg == AUTONEG_DISABLE) {
+		reg |= GM_GPCR_AU_ALL_DIS;
+
+		/* Is write/read necessary?  Copied from sky2_mac_init */
+		gma_write16(hw, port, GM_GP_CTRL, reg);
+		gma_read16(hw, port, GM_GP_CTRL);
+
+		switch (sky2->speed) {
+		case SPEED_1000:
+			reg &= ~GM_GPCR_SPEED_100;
+			reg |= GM_GPCR_SPEED_1000;
+			break;
+		case SPEED_100:
+			reg &= ~GM_GPCR_SPEED_1000;
+			reg |= GM_GPCR_SPEED_100;
+			break;
+		case SPEED_10:
+			reg &= ~(GM_GPCR_SPEED_1000 | GM_GPCR_SPEED_100);
+			break;
+		}
+	} else
+		reg &= ~GM_GPCR_AU_ALL_DIS;
+
 	if (sky2->duplex == DUPLEX_FULL || sky2->autoneg == AUTONEG_ENABLE)
 		reg |= GM_GPCR_DUP_FULL;
 
diff --git a/drivers/net/tokenring/smctr.h b/drivers/net/tokenring/smctr.h
index b306c7e..88dfa2e 100644
--- a/drivers/net/tokenring/smctr.h
+++ b/drivers/net/tokenring/smctr.h
@@ -1042,7 +1042,7 @@ typedef struct net_local {
         __u16            functional_address[2];
         __u16            bitwise_group_address[2];
 
-	__u8            *ptr_ucode;
+	const __u8       *ptr_ucode;
 
 	__u8		cleanup;
 
diff --git a/drivers/net/wireless/atmel.c b/drivers/net/wireless/atmel.c
index 98a76f1..dfc2401 100644
--- a/drivers/net/wireless/atmel.c
+++ b/drivers/net/wireless/atmel.c
@@ -1872,7 +1872,7 @@ static int atmel_set_encodeext(struct ne
 	struct atmel_private *priv = netdev_priv(dev);
 	struct iw_point *encoding = &wrqu->encoding;
 	struct iw_encode_ext *ext = (struct iw_encode_ext *)extra;
-	int idx, key_len;
+	int idx, key_len, alg = ext->alg, set_key = 1;
 
 	/* Determine and validate the key index */
 	idx = encoding->flags & IW_ENCODE_INDEX;
@@ -1883,39 +1883,42 @@ static int atmel_set_encodeext(struct ne
 	} else
 		idx = priv->default_key;
 
-	if ((encoding->flags & IW_ENCODE_DISABLED) ||
-	    ext->alg == IW_ENCODE_ALG_NONE) {
-		priv->wep_is_on = 0;
-		priv->encryption_level = 0;
-		priv->pairwise_cipher_suite = CIPHER_SUITE_NONE;
-	}
+	if (encoding->flags & IW_ENCODE_DISABLED)
+	    alg = IW_ENCODE_ALG_NONE;
 
-	if (ext->ext_flags & IW_ENCODE_EXT_SET_TX_KEY)
+	if (ext->ext_flags & IW_ENCODE_EXT_SET_TX_KEY) {
 		priv->default_key = idx;
+		set_key = ext->key_len > 0 ? 1 : 0;
+	}
 
-	/* Set the requested key */
-	switch (ext->alg) {
-	case IW_ENCODE_ALG_NONE:
-		break;
-	case IW_ENCODE_ALG_WEP:
-		if (ext->key_len > 5) {
-			priv->wep_key_len[idx] = 13;
-			priv->pairwise_cipher_suite = CIPHER_SUITE_WEP_128;
-			priv->encryption_level = 2;
-		} else if (ext->key_len > 0) {
-			priv->wep_key_len[idx] = 5;
-			priv->pairwise_cipher_suite = CIPHER_SUITE_WEP_64;
-			priv->encryption_level = 1;
-		} else {
+	if (set_key) {
+		/* Set the requested key first */
+		switch (alg) {
+		case IW_ENCODE_ALG_NONE:
+			priv->wep_is_on = 0;
+			priv->encryption_level = 0;
+			priv->pairwise_cipher_suite = CIPHER_SUITE_NONE;
+			break;
+		case IW_ENCODE_ALG_WEP:
+			if (ext->key_len > 5) {
+				priv->wep_key_len[idx] = 13;
+				priv->pairwise_cipher_suite = CIPHER_SUITE_WEP_128;
+				priv->encryption_level = 2;
+			} else if (ext->key_len > 0) {
+				priv->wep_key_len[idx] = 5;
+				priv->pairwise_cipher_suite = CIPHER_SUITE_WEP_64;
+				priv->encryption_level = 1;
+			} else {
+				return -EINVAL;
+			}
+			priv->wep_is_on = 1;
+			memset(priv->wep_keys[idx], 0, 13);
+			key_len = min ((int)ext->key_len, priv->wep_key_len[idx]);
+			memcpy(priv->wep_keys[idx], ext->key, key_len);
+			break;
+		default:
 			return -EINVAL;
 		}
-		priv->wep_is_on = 1;
-		memset(priv->wep_keys[idx], 0, 13);
-		key_len = min ((int)ext->key_len, priv->wep_key_len[idx]);
-		memcpy(priv->wep_keys[idx], ext->key, key_len);
-		break;
-	default:
-		return -EINVAL;
 	}
 
 	return -EINPROGRESS;
@@ -3061,17 +3064,26 @@ static void authenticate(struct atmel_pr
 	}
 
 	if (status == C80211_MGMT_SC_Success && priv->wep_is_on) {
+		int should_associate = 0;
 		/* WEP */
 		if (trans_seq_no != priv->ExpectedAuthentTransactionSeqNum)
 			return;
 
-		if (trans_seq_no == 0x0002 &&
-		    auth->el_id == C80211_MGMT_ElementID_ChallengeText) {
-			send_authentication_request(priv, system, auth->chall_text, auth->chall_text_len);
-			return;
+		if (system == C80211_MGMT_AAN_OPENSYSTEM) {
+			if (trans_seq_no == 0x0002) {
+				should_associate = 1;
+			}
+		} else if (system == C80211_MGMT_AAN_SHAREDKEY) {
+			if (trans_seq_no == 0x0002 &&
+			    auth->el_id == C80211_MGMT_ElementID_ChallengeText) {
+				send_authentication_request(priv, system, auth->chall_text, auth->chall_text_len);
+				return;
+			} else if (trans_seq_no == 0x0004) {
+				should_associate = 1;
+			}
 		}
 
-		if (trans_seq_no == 0x0004) {
+		if (should_associate) {
 			if(priv->station_was_associated) {
 				atmel_enter_state(priv, STATION_STATE_REASSOCIATING);
 				send_association_request(priv, 1);
@@ -3084,11 +3096,13 @@ static void authenticate(struct atmel_pr
 		}
 	}
 
-	if (status == C80211_MGMT_SC_AuthAlgNotSupported) {
+	if (status == WLAN_STATUS_NOT_SUPPORTED_AUTH_ALG) {
 		/* Do opensystem first, then try sharedkey */
-		if (system ==  C80211_MGMT_AAN_OPENSYSTEM) {
+		if (system == WLAN_AUTH_OPEN) {
 			priv->CurrentAuthentTransactionSeqNum = 0x001;
-			send_authentication_request(priv, C80211_MGMT_AAN_SHAREDKEY, NULL, 0);
+			priv->exclude_unencrypted = 1;
+			send_authentication_request(priv, WLAN_AUTH_SHARED_KEY, NULL, 0);
+			return;
 		} else if (priv->connect_to_any_BSS) {
 			int bss_index;
 
@@ -3439,10 +3453,13 @@ static void atmel_management_timer(u_lon
 			priv->AuthenticationRequestRetryCnt = 0;
 			restart_search(priv);
 		} else {
+			int auth = C80211_MGMT_AAN_OPENSYSTEM;
 			priv->AuthenticationRequestRetryCnt++;
 			priv->CurrentAuthentTransactionSeqNum = 0x0001;
 			mod_timer(&priv->management_timer, jiffies + MGMT_JIFFIES);
-			send_authentication_request(priv, C80211_MGMT_AAN_OPENSYSTEM, NULL, 0);
+			if (priv->wep_is_on && priv->exclude_unencrypted)
+				auth = C80211_MGMT_AAN_SHAREDKEY;
+			send_authentication_request(priv, auth, NULL, 0);
 	  }
 	  break;
 
@@ -3541,12 +3558,15 @@ static void atmel_command_irq(struct atm
 				priv->station_was_associated = priv->station_is_associated;
 				atmel_enter_state(priv, STATION_STATE_READY);
 			} else {
+				int auth = C80211_MGMT_AAN_OPENSYSTEM;
 				priv->AuthenticationRequestRetryCnt = 0;
 				atmel_enter_state(priv, STATION_STATE_AUTHENTICATING);
 
 				mod_timer(&priv->management_timer, jiffies + MGMT_JIFFIES);
 				priv->CurrentAuthentTransactionSeqNum = 0x0001;
-				send_authentication_request(priv, C80211_MGMT_AAN_SHAREDKEY, NULL, 0);
+				if (priv->wep_is_on && priv->exclude_unencrypted)
+					auth = C80211_MGMT_AAN_SHAREDKEY;
+				send_authentication_request(priv, auth, NULL, 0);
 			}
 			return;
 		}
diff --git a/drivers/net/wireless/wavelan_cs.c b/drivers/net/wireless/wavelan_cs.c
index cf37362..98122f3 100644
--- a/drivers/net/wireless/wavelan_cs.c
+++ b/drivers/net/wireless/wavelan_cs.c
@@ -950,16 +950,8 @@ wv_82593_cmd(struct net_device *	dev,
 static inline int
 wv_diag(struct net_device *	dev)
 {
-  int		ret = FALSE;
-
-  if(wv_82593_cmd(dev, "wv_diag(): diagnose",
-		  OP0_DIAGNOSE, SR0_DIAGNOSE_PASSED))
-    ret = TRUE;
-
-#ifdef DEBUG_CONFIG_ERRORS
-  printk(KERN_INFO "wavelan_cs: i82593 Self Test failed!\n");
-#endif
-  return(ret);
+  return(wv_82593_cmd(dev, "wv_diag(): diagnose",
+		      OP0_DIAGNOSE, SR0_DIAGNOSE_PASSED));
 } /* wv_diag */
 
 /*------------------------------------------------------------------*/
@@ -3604,8 +3596,8 @@ wv_82593_config(struct net_device *	dev)
   cfblk.lin_prio = 0;   	/* conform to 802.3 backoff algoritm */
   cfblk.exp_prio = 5;	        /* conform to 802.3 backoff algoritm */
   cfblk.bof_met = 1;	        /* conform to 802.3 backoff algoritm */
-  cfblk.ifrm_spc = 0x20;	/* 32 bit times interframe spacing */
-  cfblk.slottim_low = 0x20;	/* 32 bit times slot time */
+  cfblk.ifrm_spc = 0x20 >> 4;	/* 32 bit times interframe spacing */
+  cfblk.slottim_low = 0x20 >> 5;	/* 32 bit times slot time */
   cfblk.slottim_hi = 0x0;
   cfblk.max_retr = 15;
   cfblk.prmisc = ((lp->promiscuous) ? TRUE: FALSE);	/* Promiscuous mode */
diff --git a/drivers/s390/net/lcs.c b/drivers/s390/net/lcs.c
index 6229ba4..9cf88d7 100644
--- a/drivers/s390/net/lcs.c
+++ b/drivers/s390/net/lcs.c
@@ -98,9 +98,9 @@ lcs_register_debug_facility(void)
 		return -ENOMEM;
 	}
 	debug_register_view(lcs_dbf_setup, &debug_hex_ascii_view);
-	debug_set_level(lcs_dbf_setup, 4);
+	debug_set_level(lcs_dbf_setup, 2);
 	debug_register_view(lcs_dbf_trace, &debug_hex_ascii_view);
-	debug_set_level(lcs_dbf_trace, 4);
+	debug_set_level(lcs_dbf_trace, 2);
 	return 0;
 }
 
@@ -1292,9 +1292,8 @@ lcs_set_multicast_list(struct net_device
         LCS_DBF_TEXT(4, trace, "setmulti");
         card = (struct lcs_card *) dev->priv;
 
-        if (!lcs_set_thread_start_bit(card, LCS_SET_MC_THREAD)) {
+        if (!lcs_set_thread_start_bit(card, LCS_SET_MC_THREAD)) 
 		schedule_work(&card->kernel_thread_starter);
-	}
 }
 
 #endif /* CONFIG_IP_MULTICAST */
@@ -1459,6 +1458,8 @@ lcs_txbuffer_cb(struct lcs_channel *chan
 	lcs_release_buffer(channel, buffer);
 	card = (struct lcs_card *)
 		((char *) channel - offsetof(struct lcs_card, write));
+	if (netif_queue_stopped(card->dev))
+		netif_wake_queue(card->dev);
 	spin_lock(&card->lock);
 	card->tx_emitted--;
 	if (card->tx_emitted <= 0 && card->tx_buffer != NULL)
@@ -1478,6 +1479,7 @@ __lcs_start_xmit(struct lcs_card *card, 
 		 struct net_device *dev)
 {
 	struct lcs_header *header;
+	int rc = 0;
 
 	LCS_DBF_TEXT(5, trace, "hardxmit");
 	if (skb == NULL) {
@@ -1492,10 +1494,8 @@ __lcs_start_xmit(struct lcs_card *card, 
 		card->stats.tx_carrier_errors++;
 		return 0;
 	}
-	if (netif_queue_stopped(dev) ) {
-		card->stats.tx_dropped++;
-		return -EBUSY;
-	}
+	netif_stop_queue(card->dev);
+	spin_lock(&card->lock);
 	if (card->tx_buffer != NULL &&
 	    card->tx_buffer->count + sizeof(struct lcs_header) +
 	    skb->len + sizeof(u16) > LCS_IOBUFFERSIZE)
@@ -1506,7 +1506,8 @@ __lcs_start_xmit(struct lcs_card *card, 
 		card->tx_buffer = lcs_get_buffer(&card->write);
 		if (card->tx_buffer == NULL) {
 			card->stats.tx_dropped++;
-			return -EBUSY;
+			rc = -EBUSY;
+			goto out;
 		}
 		card->tx_buffer->callback = lcs_txbuffer_cb;
 		card->tx_buffer->count = 0;
@@ -1518,13 +1519,18 @@ __lcs_start_xmit(struct lcs_card *card, 
 	header->type = card->lan_type;
 	header->slot = card->portno;
 	memcpy(header + 1, skb->data, skb->len);
+	spin_unlock(&card->lock);
 	card->stats.tx_bytes += skb->len;
 	card->stats.tx_packets++;
 	dev_kfree_skb(skb);
-	if (card->tx_emitted <= 0)
+	netif_wake_queue(card->dev);
+	spin_lock(&card->lock);
+	if (card->tx_emitted <= 0 && card->tx_buffer != NULL)
 		/* If this is the first tx buffer emit it immediately. */
 		__lcs_emit_txbuffer(card);
-	return 0;
+out:
+	spin_unlock(&card->lock);
+	return rc;
 }
 
 static int
@@ -1535,9 +1541,7 @@ lcs_start_xmit(struct sk_buff *skb, stru
 
 	LCS_DBF_TEXT(5, trace, "pktxmit");
 	card = (struct lcs_card *) dev->priv;
-	spin_lock(&card->lock);
 	rc = __lcs_start_xmit(card, skb, dev);
-	spin_unlock(&card->lock);
 	return rc;
 }
 
@@ -2319,7 +2323,6 @@ __init lcs_init_module(void)
 		PRINT_ERR("Initialization failed\n");
 		return rc;
 	}
-
 	return 0;
 }
 
diff --git a/drivers/s390/net/lcs.h b/drivers/s390/net/lcs.h
index 08e60ad..2fad5e4 100644
--- a/drivers/s390/net/lcs.h
+++ b/drivers/s390/net/lcs.h
@@ -95,7 +95,7 @@ do {                                    
  */
 #define LCS_ILLEGAL_OFFSET		0xffff
 #define LCS_IOBUFFERSIZE		0x5000
-#define LCS_NUM_BUFFS			8	/* needs to be power of 2 */
+#define LCS_NUM_BUFFS			32	/* needs to be power of 2 */
 #define LCS_MAC_LENGTH			6
 #define LCS_INVALID_PORT_NO		-1
 #define LCS_LANCMD_TIMEOUT_DEFAULT      5
diff --git a/drivers/s390/net/qeth.h b/drivers/s390/net/qeth.h
index 9a064d4..4df0fcd 100644
--- a/drivers/s390/net/qeth.h
+++ b/drivers/s390/net/qeth.h
@@ -1076,16 +1076,6 @@ qeth_get_qdio_q_format(struct qeth_card 
 }
 
 static inline int
-qeth_isdigit(char * buf)
-{
-	while (*buf) {
-		if (!isdigit(*buf++))
-			return 0;
-	}
-	return 1;
-}
-
-static inline int
 qeth_isxdigit(char * buf)
 {
 	while (*buf) {
@@ -1104,33 +1094,17 @@ qeth_ipaddr4_to_string(const __u8 *addr,
 static inline int
 qeth_string_to_ipaddr4(const char *buf, __u8 *addr)
 {
-	const char *start, *end;
-	char abuf[4];
-	char *tmp;
-	int len;
-	int i;
-
-	start = buf;
-	for (i = 0; i < 4; i++) {
-		if (i == 3) {
-			end = strchr(start,0xa);
-			if (end)
-				len = end - start;
-			else		
-				len = strlen(start);
-		}
-		else {
-			end = strchr(start, '.');
-			len = end - start;
-		}
-		if ((len <= 0) || (len > 3))
-			return -EINVAL;
-		memset(abuf, 0, 4);
-		strncpy(abuf, start, len);
-		if (!qeth_isdigit(abuf))
+	int count = 0, rc = 0;
+	int in[4];
+
+	rc = sscanf(buf, "%d.%d.%d.%d%n", 
+		    &in[0], &in[1], &in[2], &in[3], &count);
+	if (rc != 4  || count) 
+		return -EINVAL;
+	for (count = 0; count < 4; count++) {
+		if (in[count] > 255)
 			return -EINVAL;
-		addr[i] = simple_strtoul(abuf, &tmp, 10);
-		start = end + 1;
+		addr[count] = in[count];
 	}
 	return 0;
 }
@@ -1149,36 +1123,44 @@ qeth_ipaddr6_to_string(const __u8 *addr,
 static inline int
 qeth_string_to_ipaddr6(const char *buf, __u8 *addr)
 {
-	const char *start, *end;
-	u16 *tmp_addr;
-	char abuf[5];
-	char *tmp;
-	int len;
-	int i;
-
-	tmp_addr = (u16 *)addr;
-	start = buf;
-	for (i = 0; i < 8; i++) {
-		if (i == 7) {
-			end = strchr(start,0xa);
-			if (end)
-				len = end - start;
-			else
-				len = strlen(start);
+	char *end, *start;
+	__u16 *in;
+        char num[5];
+        int num2, cnt, out, found, save_cnt;
+        unsigned short in_tmp[8] = {0, };
+
+	cnt = out = found = save_cnt = num2 = 0;
+        end = start = (char *) buf;
+	in = (__u16 *) addr;	
+	memset(in, 0, 16);
+        while (end) {
+                end = strchr(end,':');
+                if (end == NULL) {
+                        end = (char *)buf + (strlen(buf));
+                        out = 1;
+                }
+                if ((end - start)) { 
+                        memset(num, 0, 5);
+                        memcpy(num, start, end - start);
+			if (!qeth_isxdigit(num))
+				return -EINVAL;
+                        sscanf(start, "%x", &num2);
+                        if (found)
+                                in_tmp[save_cnt++] = num2;
+                        else
+                                in[cnt++] = num2;
+                        if (out)
+                                break;
+                } else {
+			if (found)
+				return -EINVAL;
+                        found = 1;
 		}
-		else {
-			end = strchr(start, ':');
-			len = end - start;
-		}
-		if ((len <= 0) || (len > 4))
-			return -EINVAL;
-		memset(abuf, 0, 5);
-		strncpy(abuf, start, len);
-		if (!qeth_isxdigit(abuf))
-			return -EINVAL;
-		tmp_addr[i] = simple_strtoul(abuf, &tmp, 16);
-		start = end + 1;
-	}
+		start = ++end;
+        }
+        cnt = 7;
+	while (save_cnt)
+                in[cnt--] = in_tmp[--save_cnt];
 	return 0;
 }
 
diff --git a/drivers/s390/net/qeth_eddp.c b/drivers/s390/net/qeth_eddp.c
index b023131..82cb4af 100644
--- a/drivers/s390/net/qeth_eddp.c
+++ b/drivers/s390/net/qeth_eddp.c
@@ -59,8 +59,7 @@ qeth_eddp_free_context(struct qeth_eddp_
 	for (i = 0; i < ctx->num_pages; ++i)
 		free_page((unsigned long)ctx->pages[i]);
 	kfree(ctx->pages);
-	if (ctx->elements != NULL)
-		kfree(ctx->elements);
+	kfree(ctx->elements);
 	kfree(ctx);
 }
 
@@ -413,6 +412,13 @@ __qeth_eddp_fill_context_tcp(struct qeth
 	
 	QETH_DBF_TEXT(trace, 5, "eddpftcp");
 	eddp->skb_offset = sizeof(struct qeth_hdr) + eddp->nhl + eddp->thl;
+       if (eddp->qh.hdr.l2.id == QETH_HEADER_TYPE_LAYER2) {
+               eddp->skb_offset += sizeof(struct ethhdr);
+#ifdef CONFIG_QETH_VLAN
+               if (eddp->mac.h_proto == __constant_htons(ETH_P_8021Q))
+                       eddp->skb_offset += VLAN_HLEN;
+#endif /* CONFIG_QETH_VLAN */
+       }
 	tcph = eddp->skb->h.th;
 	while (eddp->skb_offset < eddp->skb->len) {
 		data_len = min((int)skb_shinfo(eddp->skb)->tso_size,
@@ -483,6 +489,7 @@ qeth_eddp_fill_context_tcp(struct qeth_e
 		return -ENOMEM;
 	}
 	if (qhdr->hdr.l2.id == QETH_HEADER_TYPE_LAYER2) {
+		skb->mac.raw = (skb->data) + sizeof(struct qeth_hdr);
 		memcpy(&eddp->mac, eth_hdr(skb), ETH_HLEN);
 #ifdef CONFIG_QETH_VLAN
 		if (eddp->mac.h_proto == __constant_htons(ETH_P_8021Q)) {
diff --git a/drivers/s390/net/qeth_main.c b/drivers/s390/net/qeth_main.c
index 410abea..dba7f7f 100644
--- a/drivers/s390/net/qeth_main.c
+++ b/drivers/s390/net/qeth_main.c
@@ -516,7 +516,8 @@ __qeth_set_offline(struct ccwgroup_devic
 	QETH_DBF_TEXT(setup, 3, "setoffl");
 	QETH_DBF_HEX(setup, 3, &card, sizeof(void *));
 	
-	netif_carrier_off(card->dev);
+	if (card->dev && netif_carrier_ok(card->dev))
+		netif_carrier_off(card->dev);
 	recover_flag = card->state;
 	if (qeth_stop_card(card, recovery_mode) == -ERESTARTSYS){
 		PRINT_WARN("Stopping card %s interrupted by user!\n",
@@ -1679,6 +1680,7 @@ qeth_cmd_timeout(unsigned long data)
 	spin_unlock_irqrestore(&reply->card->lock, flags);
 }
 
+
 static struct qeth_ipa_cmd *
 qeth_check_ipa_data(struct qeth_card *card, struct qeth_cmd_buffer *iob)
 {
@@ -1699,7 +1701,8 @@ qeth_check_ipa_data(struct qeth_card *ca
 					   QETH_CARD_IFNAME(card),
 					   card->info.chpid);
 				card->lan_online = 0;
-				netif_carrier_off(card->dev);
+				if (card->dev && netif_carrier_ok(card->dev))
+					netif_carrier_off(card->dev);
 				return NULL;
 			case IPA_CMD_STARTLAN:
 				PRINT_INFO("Link reestablished on %s "
@@ -5562,7 +5565,7 @@ qeth_set_multicast_list(struct net_devic
 	if (card->info.type == QETH_CARD_TYPE_OSN)
 		return ;
 	 
-	QETH_DBF_TEXT(trace,3,"setmulti");
+	QETH_DBF_TEXT(trace, 3, "setmulti");
 	qeth_delete_mc_addresses(card);
 	if (card->options.layer2) {
 		qeth_layer2_add_multicast(card);
@@ -5579,7 +5582,6 @@ out:
 		return;
 	if (qeth_set_thread_start_bit(card, QETH_SET_PROMISC_MODE_THREAD)==0)
 		schedule_work(&card->kernel_thread_starter);
-
 }
 
 static int
@@ -7452,6 +7454,7 @@ qeth_softsetup_card(struct qeth_card *ca
 		card->lan_online = 1;
 	if (card->info.type==QETH_CARD_TYPE_OSN)
 		goto out;
+	qeth_set_large_send(card, card->options.large_send);
 	if (card->options.layer2) {
 		card->dev->features |=
 			NETIF_F_HW_VLAN_FILTER |
@@ -7468,12 +7471,6 @@ qeth_softsetup_card(struct qeth_card *ca
 #endif
 		goto out;
 	}
-	if ((card->options.large_send == QETH_LARGE_SEND_EDDP) ||
-	    (card->options.large_send == QETH_LARGE_SEND_TSO))
-		card->dev->features |= NETIF_F_TSO | NETIF_F_SG;
-	else
-		card->dev->features &= ~(NETIF_F_TSO | NETIF_F_SG);
-
 	if ((rc = qeth_setadapter_parms(card)))
 		QETH_DBF_TEXT_(setup, 2, "2err%d", rc);
 	if ((rc = qeth_start_ipassists(card)))

^ permalink raw reply related

* Please pull upstream branches of bu3sch.de
From: Michael Buesch @ 2006-02-18  1:19 UTC (permalink / raw)
  To: John W. Linville, Stefano Brivio
  Cc: netdev-u79uwXL29TY76Z2rM5mHXA, bcm43xx-dev-0fE9KPoRgkgATYTw5x5z8w,
	Jiri Benc

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

Hi John,

I rebased my repository at
git://bu3sch.de/wireless-2.6.git

Please pull the following changes from "softmac-upstream":
Michael Buesch:
      bcm43xx: fix txpower reporting in WE.
      bcm43xx: enable SPROM writing.
      bcm43xx: heavily increase mac_suspend timeout.
      bcm43xx: fix compiletime warning (phy_xmitpower)
      bcm43xx: remove WX debugging.
      bcm43xx: Partially fix PIO code. Add Kconfig option for PIO or DMA mode (or both).
      bcm43xx: add a note that not all devices support PIO.
      Apple Airport: Add Kconfig note that the bcm43xx driver has to be used for Airport Extreme cards.
      bcm43xx: update README
      bcm43xx: fix LED code.
      bcm43xx: rewrite and simplify the periodic task handling.
      bcm43xx: Code cleanups. This removes various "inline" statements and reduces codesize.

Please pull the following changes from "dscape-upstream":
Michael Buesch:
      bcm43xx-d80211: build magic add_sta binary in /tmp instead of $PWD
      bcm43xx-d80211: fix NULL pointer deref in bcm43xx_remove_one.
      bcm43xx-d80211: heavily increase mac_suspend timeout.
      bcm43xx-d80211: remove WX debugging.
      bcm43xx-d80211: Update docs to reflect changes in the driver.
      bcm43xx-d80211: fix LED code.
      bcm43xx-d80211: Code cleanups. This removes various "inline" statements and reduces codesize.

I don't append the diffs, as they are rather big.
If you want to review the changes, I suggest you look at the
webinterface of my repository:
http://bu3sch.de/git?p=wireless-2.6.git;a=summary

Stefano, please re-clone your copy now.

-- 
Greetings Michael.

[-- Attachment #2: Type: application/pgp-signature, Size: 189 bytes --]

^ permalink raw reply

* Re: [PATCH 2/2] fix file counting
From: Christoph Hellwig @ 2006-02-18 12:14 UTC (permalink / raw)
  To: Dipankar Sarma; +Cc: Andrew Morton, linux-kernel, paulmck, dada1, davem, netdev
In-Reply-To: <20060218092517.GP29846@in.ibm.com>

> > - Make the get_max_files export use _GPL - only unix.ko uses it.

The real question is, does af_unix really need to allow beeing built
modular?  It's quite different from other network protocol and deeply
tied to the kernel due to things like descriptor passing or using
the filesystem namespace.  I already had to export another symbol that
really should be internal just for it, and if one module acquires lots
of such hacks it's usually a bad sign..

^ permalink raw reply

* Re: [PATCH 2/2] fix file counting
From: Arjan van de Ven @ 2006-02-18 12:31 UTC (permalink / raw)
  To: Christoph Hellwig
  Cc: Dipankar Sarma, Andrew Morton, linux-kernel, paulmck, dada1,
	davem, netdev
In-Reply-To: <20060218121402.GB911@infradead.org>

On Sat, 2006-02-18 at 12:14 +0000, Christoph Hellwig wrote:
> > > - Make the get_max_files export use _GPL - only unix.ko uses it.
> 
> The real question is, does af_unix really need to allow beeing built
> modular?  It's quite different from other network protocol and deeply
> tied to the kernel due to things like descriptor passing or using
> the filesystem namespace.  I already had to export another symbol that
> really should be internal just for it, and if one module acquires lots
> of such hacks it's usually a bad sign..

in 2.4 the answer would have been simple; modutils back then used
AF_UNIX stuff before it could load modules, so modular was in practice
impossible. 

Anyway I'd agree with making this non-modular... NOBODY will use this as
a module, or if they do loading it somehow is the very first thing done.
You just can't live without this, so making it a module is non-sensical.

^ permalink raw reply

* [PATCH] pktgen: Ports the if_list to the in-kernel implementation.
From: Luiz Fernando Capitulino @ 2006-02-18 20:50 UTC (permalink / raw)
  To: davem, lkml, netdev, robert.olsson


 Hi!

 This patch ports the per-thread interface list to the in-kernel linked
list implementation. In general, the resulting code is a bit simpler.

 I've tested it with QEMU emulating a four CPU machine with four NICs.

 Note that this patch has been made in the top of my previous pktgen
patches.

Signed-off-by: Luiz Capitulino <lcapitulino@mandriva.com.br>

---

 net/core/pktgen.c |   79 +++++++++++++++++++++++++----------------------------
 1 files changed, 37 insertions(+), 42 deletions(-)

923450c2ba06160ba72fd17ccb2def142c1a5093
diff --git a/net/core/pktgen.c b/net/core/pktgen.c
index 3806068..f110214 100644
--- a/net/core/pktgen.c
+++ b/net/core/pktgen.c
@@ -209,7 +209,7 @@ struct pktgen_dev {
 	char result[512];
 
 	struct pktgen_thread *pg_thread;	/* the owner */
-	struct pktgen_dev *next;	/* Used for chaining in the thread's run-queue */
+	struct list_head list;		/* Used for chaining in the thread's run-queue */
 
 	int running;		/* if this changes to false, the test will stop */
 
@@ -327,7 +327,7 @@ struct pktgen_hdr {
 
 struct pktgen_thread {
 	spinlock_t if_lock;
-	struct pktgen_dev *if_list;	/* All device here */
+	struct list_head if_list;	/* All device here */
 	struct list_head th_list;
 	int removed;
 	char name[32];
@@ -1377,7 +1377,7 @@ static struct file_operations pktgen_if_
 static int pktgen_thread_show(struct seq_file *seq, void *v)
 {
 	struct pktgen_thread *t = seq->private;
-	struct pktgen_dev *pkt_dev = NULL;
+	struct pktgen_dev *pkt_dev;
 
 	BUG_ON(!t);
 
@@ -1387,13 +1387,13 @@ static int pktgen_thread_show(struct seq
 	seq_printf(seq, "Running: ");
 
 	if_lock(t);
-	for (pkt_dev = t->if_list; pkt_dev; pkt_dev = pkt_dev->next)
+	list_for_each_entry(pkt_dev, &t->if_list, list)
 		if (pkt_dev->running)
 			seq_printf(seq, "%s ", pkt_dev->ifname);
 
 	seq_printf(seq, "\nStopped: ");
 
-	for (pkt_dev = t->if_list; pkt_dev; pkt_dev = pkt_dev->next)
+	list_for_each_entry(pkt_dev, &t->if_list, list)
 		if (!pkt_dev->running)
 			seq_printf(seq, "%s ", pkt_dev->ifname);
 
@@ -2388,13 +2388,13 @@ static void pktgen_clear_counters(struct
 
 static void pktgen_run(struct pktgen_thread *t)
 {
-	struct pktgen_dev *pkt_dev = NULL;
+	struct pktgen_dev *pkt_dev;
 	int started = 0;
 
 	PG_DEBUG(printk("pktgen: entering pktgen_run. %p\n", t));
 
 	if_lock(t);
-	for (pkt_dev = t->if_list; pkt_dev; pkt_dev = pkt_dev->next) {
+	list_for_each_entry(pkt_dev, &t->if_list, list) {
 
 		/*
 		 * setup odev and create initial packet.
@@ -2435,15 +2435,14 @@ static void pktgen_stop_all_threads_ifs(
 
 static int thread_is_running(struct pktgen_thread *t)
 {
-	struct pktgen_dev *next;
+	struct pktgen_dev *pkt_dev;
 	int res = 0;
 
-	for (next = t->if_list; next; next = next->next) {
-		if (next->running) {
+	list_for_each_entry(pkt_dev, &t->if_list, list)
+		if (pkt_dev->running) {
 			res = 1;
 			break;
 		}
-	}
 	return res;
 }
 
@@ -2570,17 +2569,17 @@ static int pktgen_stop_device(struct pkt
 
 static struct pktgen_dev *next_to_run(struct pktgen_thread *t)
 {
-	struct pktgen_dev *next, *best = NULL;
+	struct pktgen_dev *pkt_dev, *best = NULL;
 
 	if_lock(t);
 
-	for (next = t->if_list; next; next = next->next) {
-		if (!next->running)
+	list_for_each_entry(pkt_dev, &t->if_list, list) {
+		if (!pkt_dev->running)
 			continue;
 		if (best == NULL)
-			best = next;
-		else if (next->next_tx_us < best->next_tx_us)
-			best = next;
+			best = pkt_dev;
+		else if (pkt_dev->next_tx_us < best->next_tx_us)
+			best = pkt_dev;
 	}
 	if_unlock(t);
 	return best;
@@ -2588,28 +2587,29 @@ static struct pktgen_dev *next_to_run(st
 
 static void pktgen_stop(struct pktgen_thread *t)
 {
-	struct pktgen_dev *next = NULL;
+	struct pktgen_dev *pkt_dev;
 
 	PG_DEBUG(printk("pktgen: entering pktgen_stop.\n"));
 
 	if_lock(t);
 
-	for (next = t->if_list; next; next = next->next)
-		pktgen_stop_device(next);
+	list_for_each_entry(pkt_dev, &t->if_list, list)
+		pktgen_stop_device(pkt_dev);
 
 	if_unlock(t);
 }
 
 static void pktgen_rem_all_ifs(struct pktgen_thread *t)
 {
-	struct pktgen_dev *cur, *next = NULL;
+	struct list_head *q, *n;
+	struct pktgen_dev *cur;
 
 	/* Remove all devices, free mem */
 
 	if_lock(t);
 
-	for (cur = t->if_list; cur; cur = next) {
-		next = cur->next;
+	list_for_each_safe(q, n, &t->if_list) {
+		cur = list_entry(q, struct pktgen_dev, list);
 		pktgen_remove_device(t, cur);
 	}
 
@@ -2880,14 +2880,14 @@ static void pktgen_thread_worker(struct 
 static struct pktgen_dev *pktgen_find_dev(struct pktgen_thread *t,
 					  const char *ifname)
 {
-	struct pktgen_dev *pkt_dev = NULL;
+	struct pktgen_dev *p, *pkt_dev = NULL;
 	if_lock(t);
 
-	for (pkt_dev = t->if_list; pkt_dev; pkt_dev = pkt_dev->next) {
-		if (strncmp(pkt_dev->ifname, ifname, IFNAMSIZ) == 0) {
+	list_for_each_entry(p, &t->if_list, list)
+		if (strncmp(p->ifname, ifname, IFNAMSIZ) == 0) {
+			pkt_dev = p;
 			break;
 		}
-	}
 
 	if_unlock(t);
 	PG_DEBUG(printk("pktgen: find_dev(%s) returning %p\n", ifname, pkt_dev));
@@ -2910,8 +2910,8 @@ static int add_dev_to_thread(struct pktg
 		rv = -EBUSY;
 		goto out;
 	}
-	pkt_dev->next = t->if_list;
-	t->if_list = pkt_dev;
+
+	list_add(&pkt_dev->list, &t->if_list);
 	pkt_dev->pg_thread = t;
 	pkt_dev->running = 0;
 
@@ -3037,6 +3037,8 @@ static int __init pktgen_create_thread(c
 	pe->proc_fops = &pktgen_thread_fops;
 	pe->data = t;
 
+	INIT_LIST_HEAD(&t->if_list);
+
 	list_add_tail(&t->th_list, &pktgen_threads);
 
 	t->removed = 0;
@@ -3060,20 +3062,13 @@ static int __init pktgen_create_thread(c
 static void _rem_dev_from_if_list(struct pktgen_thread *t,
 				  struct pktgen_dev *pkt_dev)
 {
-	struct pktgen_dev *i, *prev = NULL;
-
-	i = t->if_list;
+	struct list_head *q, *n;
+	struct pktgen_dev *p;
 
-	while (i) {
-		if (i == pkt_dev) {
-			if (prev)
-				prev->next = i->next;
-			else
-				t->if_list = NULL;
-			break;
-		}
-		prev = i;
-		i = i->next;
+	list_for_each_safe(q, n, &t->if_list) {
+		p = list_entry(q, struct pktgen_dev, list);
+		if (p == pkt_dev)
+			list_del(&p->list);
 	}
 }
 
-- 
1.2.1.g3397f9



-- 
Luiz Fernando N. Capitulino

^ permalink raw reply related

* From: Carlos Martín <carlos@cmartin.tk>
From: Carlos Martin @ 2006-02-18 22:35 UTC (permalink / raw)
  To: netdev; +Cc: acx100-devel, Carlos Martin

[PATCH] acxsm: Fix Kconfig option check

This check never actually worked because CONFIG_ACX_{ACX,USB} are
tristate. With Adrian Bunk's patch to the Kconfig, this works with the
_BOOL hidden Kconfig options.
Also update error message adding that this shouldn't happen anymore.

Signed-off-by: Carlos Martin <carlos@cmartin.tk>
---

 acx_struct.h |    3 ++-
 1 file changed, 2 insertions(+), 1 deletion(-)

diff --git a/acx_struct.h b/acx_struct.h
index 93495e0..3237974 100644
--- a/acx_struct.h
+++ b/acx_struct.h
@@ -105,8 +105,9 @@ enum { acx_debug = 0 };
 #define DEVTYPE_PCI		0
 #define DEVTYPE_USB		1
 
-#if !defined(CONFIG_ACX_PCI) && !defined(CONFIG_ACX_USB)
+#if !defined(CONFIG_ACX_PCI_BOOL) && !defined(CONFIG_ACX_USB_BOOL)
 #error Driver must include PCI and/or USB support. You selected neither.
+#error This really should not happen anymore. Please report.
 #endif
 
 #if defined(CONFIG_ACX_PCI)



-------------------------------------------------------
This SF.net email is sponsored by: Splunk Inc. Do you grep through log files
for problems?  Stop!  Download the new AJAX search engine that makes
searching your log files as easy as surfing the  web.  DOWNLOAD SPLUNK!
http://sel.as-us.falkag.net/sel?cmd=lnk&kid\x103432&bid#0486&dat\x121642

^ permalink raw reply related

* Re: From: Carlos   Martín <carlos@cmartin.tk>
From: Carlos Martín @ 2006-02-18 22:38 UTC (permalink / raw)
  To: netdev; +Cc: acx100-devel
In-Reply-To: <11403021213131-git-send-email-carlos@cmartin.tk>

Oops, sorry about that, I'll send a properly formed e-mail. I'm still managing 
to get stuff wrong with git-send-email.perl

   cmn
-- 
Carlos Martín Nieto    |   http://www.cmartin.tk
Hobbyist programmer    |


-------------------------------------------------------
This SF.net email is sponsored by: Splunk Inc. Do you grep through log files
for problems?  Stop!  Download the new AJAX search engine that makes
searching your log files as easy as surfing the  web.  DOWNLOAD SPLUNK!
http://sel.as-us.falkag.net/sel?cmd=lnk&kid\x103432&bid#0486&dat\x121642

^ permalink raw reply

* Re: From: Carlos   Martín <carlos@cmartin.tk>
From: Carlos Martín @ 2006-02-18 22:44 UTC (permalink / raw)
  To: netdev; +Cc: acx100-devel
In-Reply-To: <11403024891492-git-send-email-carlos@cmartin.tk>

I feel so fucking stupid right now.
This'll have to do for now. Denis isn't using any scripts to apply patches, so 
it shouldn't be much of a problem...

Sorry again.

   cmn
-- 
Carlos Martín Nieto    |   http://www.cmartin.tk
Hobbyist programmer    |


-------------------------------------------------------
This SF.net email is sponsored by: Splunk Inc. Do you grep through log files
for problems?  Stop!  Download the new AJAX search engine that makes
searching your log files as easy as surfing the  web.  DOWNLOAD SPLUNK!
http://sel.as-us.falkag.net/sel?cmd=lnk&kid\x103432&bid#0486&dat\x121642

^ permalink raw reply

* Re: [PATCH 1/5] IrDA: nsc-ircc: ISAPnP support
From: David S. Miller @ 2006-02-19  8:34 UTC (permalink / raw)
  To: samuel.ortiz-xNZwKgViW5gAvxtiuMwx3w
  Cc: netdev-u79uwXL29TY76Z2rM5mHXA, jt-sDzT885Ts8HQT0dZR+AlfA,
	irda-users-5NWGOfrQmneRv+LV9MX5uipxlwaOVQ5f
In-Reply-To: <20060213221443.GB31091@irie>

From: Samuel Ortiz <samuel.ortiz-xNZwKgViW5gAvxtiuMwx3w@public.gmane.org>
Date: Tue, 14 Feb 2006 00:14:43 +0200

> This enables PnP support for the nsc-ircc chipset.
> Since we can't fetch the chipset cfg_base from the PnP layer, we just use
> the PnP information as one more hint when probing the chip.
> 
> Signed-off-by: Jean Tourrilhes <jt-sDzT885Ts8HQT0dZR+AlfA@public.gmane.org> 
> Signed-off-by: Samuel Ortiz <samuel.ortiz-xNZwKgViW5gAvxtiuMwx3w@public.gmane.org> 

Applied, thanks.


-------------------------------------------------------
This SF.net email is sponsored by: Splunk Inc. Do you grep through log files
for problems?  Stop!  Download the new AJAX search engine that makes
searching your log files as easy as surfing the  web.  DOWNLOAD SPLUNK!
http://sel.as-us.falkag.net/sel?cmd=lnk&kid=103432&bid=230486&dat=121642

^ permalink raw reply

* Re: [PATCH 2/5] IrDA: nsc-ircc: PM update
From: David S. Miller @ 2006-02-19  8:35 UTC (permalink / raw)
  To: samuel.ortiz-xNZwKgViW5gAvxtiuMwx3w
  Cc: netdev-u79uwXL29TY76Z2rM5mHXA, jt-sDzT885Ts8HQT0dZR+AlfA,
	irda-users-5NWGOfrQmneRv+LV9MX5uipxlwaOVQ5f
In-Reply-To: <20060213221509.GC31091@irie>

From: Samuel Ortiz <samuel.ortiz-xNZwKgViW5gAvxtiuMwx3w@public.gmane.org>
Date: Tue, 14 Feb 2006 00:15:09 +0200

> This patch brings the nsc-ircc code to a more up to date power management
> scheme, following the current device model.
> 
> Signed-off-by: Dmitry Torokhov <dtor-JGs/UdohzUI@public.gmane.org>
> Signed-off-by: Rudolf Marek <r.marek-3zVPrsR01WjrBKCeMvbIDA@public.gmane.org>
> Signed-off-by: Samuel Ortiz <samuel.ortiz-xNZwKgViW5gAvxtiuMwx3w@public.gmane.org>

Applied.


-------------------------------------------------------
This SF.net email is sponsored by: Splunk Inc. Do you grep through log files
for problems?  Stop!  Download the new AJAX search engine that makes
searching your log files as easy as surfing the  web.  DOWNLOAD SPLUNK!
http://sel.as-us.falkag.net/sel?cmd=lnk&kid=103432&bid=230486&dat=121642

^ permalink raw reply

* Re: [PATCH 3/5] IrDA: nsc-ircc: support for yet another Thinkpad IrDA chipset
From: David S. Miller @ 2006-02-19  8:35 UTC (permalink / raw)
  To: samuel.ortiz-xNZwKgViW5gAvxtiuMwx3w
  Cc: netdev-u79uwXL29TY76Z2rM5mHXA, jt-sDzT885Ts8HQT0dZR+AlfA,
	irda-users-5NWGOfrQmneRv+LV9MX5uipxlwaOVQ5f
In-Reply-To: <20060213221521.GD31091@irie>

From: Samuel Ortiz <samuel.ortiz-xNZwKgViW5gAvxtiuMwx3w@public.gmane.org>
Date: Tue, 14 Feb 2006 00:15:21 +0200

> This patch simply adds support for a variation of the nsc-ircc PC8739x
> chipset, found in some IBM Thinkpad laptops.
> 
> Signed-off-by: Jean Tourrilhes <jt-sDzT885Ts8HQT0dZR+AlfA@public.gmane.org> 
> Signed-off-by: Samuel Ortiz <samuel.ortiz-xNZwKgViW5gAvxtiuMwx3w@public.gmane.org> 

Applied.


-------------------------------------------------------
This SF.net email is sponsored by: Splunk Inc. Do you grep through log files
for problems?  Stop!  Download the new AJAX search engine that makes
searching your log files as easy as surfing the  web.  DOWNLOAD SPLUNK!
http://sel.as-us.falkag.net/sel?cmd=lnk&kid=103432&bid=230486&dat=121642

^ permalink raw reply

* Re: [PATCH 4/5] IrDA: sti/cli removal from EP7211 IrDA driver
From: David S. Miller @ 2006-02-19  8:36 UTC (permalink / raw)
  To: samuel.ortiz-xNZwKgViW5gAvxtiuMwx3w
  Cc: netdev-u79uwXL29TY76Z2rM5mHXA, jt-sDzT885Ts8HQT0dZR+AlfA,
	irda-users-5NWGOfrQmneRv+LV9MX5uipxlwaOVQ5f
In-Reply-To: <20060213221538.GE31091@irie>

From: Samuel Ortiz <samuel.ortiz-xNZwKgViW5gAvxtiuMwx3w@public.gmane.org>
Date: Tue, 14 Feb 2006 00:15:38 +0200

> This patch replaces the deprecated sti/cli routines with the corresponding
> spin_lock ones.
> 
> Signed-off-by: David chosrova <david.chosrova-TDf4sKD1mxeHlu7OokbhRg@public.gmane.org>
> Signed-off-by: Samuel Ortiz <samuel.ortiz-xNZwKgViW5gAvxtiuMwx3w@public.gmane.org>

Applied.


-------------------------------------------------------
This SF.net email is sponsored by: Splunk Inc. Do you grep through log files
for problems?  Stop!  Download the new AJAX search engine that makes
searching your log files as easy as surfing the  web.  DOWNLOAD SPLUNK!
http://sel.as-us.falkag.net/sel?cmd=lnk&kid=103432&bid=230486&dat=121642

^ permalink raw reply

* Re: [PATCH 5/5] IrDA: pci_register_driver conversion
From: David S. Miller @ 2006-02-19  8:37 UTC (permalink / raw)
  To: samuel.ortiz-xNZwKgViW5gAvxtiuMwx3w
  Cc: netdev-u79uwXL29TY76Z2rM5mHXA, jt-sDzT885Ts8HQT0dZR+AlfA,
	irda-users-5NWGOfrQmneRv+LV9MX5uipxlwaOVQ5f
In-Reply-To: <20060213221548.GF31091@irie>

From: Samuel Ortiz <samuel.ortiz-xNZwKgViW5gAvxtiuMwx3w@public.gmane.org>
Date: Tue, 14 Feb 2006 00:15:48 +0200

> This patch converts 2 IrDA drivers pci_module_init() calls to
> pci_register_driver().
> 
> Signed-off-by: Christophe Lucas <clucas-6bugY6I12JBBDgjK7y7TUQ@public.gmane.org>
> Signed-off-by: Domen Puncer <domen-CvScVCPLwOZg9hUCZPvPmw@public.gmane.org>
> Signed-off-by: Samuel Ortiz <samuel-jcdQHdrhKHMdnm+yROfE0A@public.gmane.org>

Applied.


-------------------------------------------------------
This SF.net email is sponsored by: Splunk Inc. Do you grep through log files
for problems?  Stop!  Download the new AJAX search engine that makes
searching your log files as easy as surfing the  web.  DOWNLOAD SPLUNK!
http://sel.as-us.falkag.net/sel?cmd=lnk&kid=103432&bid=230486&dat=121642

^ permalink raw reply

* (usagi-users 03609) IPv6 setsockopt software MTU patch
From: hoerdt @ 2006-02-19 13:47 UTC (permalink / raw)
  To: usagi-users; +Cc: davem, netdev, olivier.matz, yoshfuji
In-Reply-To: <20060217.215101.09874309.yoshfuji@linux-ipv6.org>

Hi,

In my precedent mails, i pointed out that IPV6_MTU setsockopt
was ineffective because the field frag_size was not used further
in the ipv6 fragment code of the kernel. You can check out
that this is the case by this simple proof of concept code :

http://clarinet.u-strasbg.fr/~hoerdt/mtu.c

The fix is very simple, it only grab the value of frag_size and
use it in ip6_fragment file, could you please review the patch which
fix that problem at :

http://clarinet.u-strasbg.fr/~hoerdt/ip6_output.c.softfrag.patch

Thanks for the attention,

Hoerdt Mickaël

^ permalink raw reply

* (usagi-users 03610) Re: IPv6 setsockopt software MTU patch
From: YOSHIFUJI Hideaki / 吉藤英明 @ 2006-02-19 14:13 UTC (permalink / raw)
  To: hoerdt; +Cc: usagi-users, davem, netdev, olivier.matz, yoshfuji
In-Reply-To: <20060219134709.GC16304@clarinet.u-strasbg.fr>

In article <20060219134709.GC16304@clarinet.u-strasbg.fr> (at Sun, 19 Feb 2006 14:47:09 +0100), hoerdt@clarinet.u-strasbg.fr says:

> The fix is very simple, it only grab the value of frag_size and
> use it in ip6_fragment file, could you please review the patch which
> fix that problem at :
> 
> http://clarinet.u-strasbg.fr/~hoerdt/ip6_output.c.softfrag.patch

Thanks for the patch.
I think even we have np->frag_size, we should consider dst_mtu(&rt->u.dst)
as well. No?

--yoshfuji

^ permalink raw reply

* (usagi-users 03611) Re: IPv6 setsockopt software MTU patch
From: hoerdt @ 2006-02-19 14:54 UTC (permalink / raw)
  To: usagi-users; +Cc: davem, netdev, olivier.matz, yoshfuji
In-Reply-To: <20060219.231344.11160682.yoshfuji@linux-ipv6.org>

Yes, Hugo Santos suggested me to use the minimum of both, the new
patch is available there :

http://clarinet.u-strasbg.fr/~hoerdt/ip6_output.c.softfrag.patch2

Thanks,

Hoerdt Mickaël


On Sun, Feb 19, 2006 at 11:13:44PM +0900, YOSHIFUJI Hideaki / ?$B5HF#1QL@ wrote:
> In article <20060219134709.GC16304@clarinet.u-strasbg.fr> (at Sun, 19 Feb 2006 14:47:09 +0100), hoerdt@clarinet.u-strasbg.fr says:
> 
> > The fix is very simple, it only grab the value of frag_size and
> > use it in ip6_fragment file, could you please review the patch which
> > fix that problem at :
> > 
> > http://clarinet.u-strasbg.fr/~hoerdt/ip6_output.c.softfrag.patch
> 
> Thanks for the patch.
> I think even we have np->frag_size, we should consider dst_mtu(&rt->u.dst)
> as well. No?
> 
> --yoshfuji
> 
> 

^ permalink raw reply

* (usagi-users 03612) Re: IPv6 setsockopt software MTU patch
From: YOSHIFUJI Hideaki / 吉藤英明 @ 2006-02-19 16:08 UTC (permalink / raw)
  To: hoerdt; +Cc: usagi-users, netdev, olivier.matz, davem, yoshfuji
In-Reply-To: <20060219145413.GD16304@clarinet.u-strasbg.fr>

In article <20060219145413.GD16304@clarinet.u-strasbg.fr> (at Sun, 19 Feb 2006 15:54:13 +0100), hoerdt@clarinet.u-strasbg.fr says:

> Yes, Hugo Santos suggested me to use the minimum of both, the new
> patch is available there :
> 
> http://clarinet.u-strasbg.fr/~hoerdt/ip6_output.c.softfrag.patch2

Do you mean like this?

Signed-off-by: YOSHIFUJI Hideaki <yoshfuji@linux-ipv6.org>

diff --git a/net/ipv6/ip6_output.c b/net/ipv6/ip6_output.c
index efa3e72..3264740 100644
--- a/net/ipv6/ip6_output.c
+++ b/net/ipv6/ip6_output.c
@@ -494,6 +494,7 @@ static int ip6_fragment(struct sk_buff *
 	struct net_device *dev;
 	struct sk_buff *frag;
 	struct rt6_info *rt = (struct rt6_info*)skb->dst;
+	struct ipv6_pinfo *np = skb->sk ? inet6_sk(skb->sk) : NULL;
 	struct ipv6hdr *tmp_hdr;
 	struct frag_hdr *fh;
 	unsigned int mtu, hlen, left, len;
@@ -506,6 +507,8 @@ static int ip6_fragment(struct sk_buff *
 	nexthdr = *prevhdr;
 
 	mtu = dst_mtu(&rt->u.dst) - hlen - sizeof(struct frag_hdr);
+	if (np && np->frag_size && np->frag_size < dst_mtu(&rt->u.dst))
+		mtu = np->frag_size - hlen - sizeof(struct frag_hdr);
 
 	if (skb_shinfo(skb)->frag_list) {
 		int first_len = skb_pagelen(skb);


-- 
YOSHIFUJI Hideaki @ USAGI Project  <yoshfuji@linux-ipv6.org>
GPG-FP  : 9022 65EB 1ECF 3AD1 0BDF  80D8 4807 F894 E062 0EEA

^ permalink raw reply related

* Re: Merging Skylark's IOC3 patch
From: Martin Michlmayr @ 2006-02-19 21:56 UTC (permalink / raw)
  To: Ralf Baechle, netdev; +Cc: linux-mips, Stanislaw Skowronek
In-Reply-To: <20060219211527.GA12848@deprecation.cyrius.com>

* Martin Michlmayr <tbm@cyrius.com> [2006-02-19 21:15]:
> Can you please review and/or merge Skylark's IOC3 patch from
> ftp://ftp.linux-mips.org/pub/linux/mips/people/skylark/linux-mips-2.6.14-ioc3-r26.patch.bz2
> 
> From my basic understanding I believe that this patch needs to be split up
> and submitted to different sub-system maintainers.

(netdev@vger.kernel.org, this is only a RFC for now since the main
support patch for IOC3 has not been merged yet.)


From: Stanislaw Skowronek <skylark@linux-mips.org>

[PATCH 3/5] net: Convert the SGI IOC3 Ethernet driver to use IOC3 meta driver

Convert the SGI IOC3 Ethernet driver to use the IOC3 meta driver.

Signed-off-by: Stanislaw Skowronek <skylark@linux-mips.org>
Signed-off-by: Martin Michlmayr <tbm@cyrius.com>

---

 Kconfig    |    2 
 ioc3-eth.c |  458 +++++++------------------------------------------------------
 2 files changed, 55 insertions(+), 405 deletions(-)

diff --git a/drivers/net/Kconfig b/drivers/net/Kconfig
index 94ad74c..66c340d 100644
--- a/drivers/net/Kconfig
+++ b/drivers/net/Kconfig
@@ -462,7 +462,7 @@ config MIPS_AU1X00_ENET
 
 config SGI_IOC3_ETH
 	bool "SGI IOC3 Ethernet"
-	depends on NET_ETHERNET && PCI && SGI_IP27
+	depends on NET_ETHERNET && SGI_IOC3
 	select CRC32
 	select MII
 	help
diff --git a/drivers/net/ioc3-eth.c b/drivers/net/ioc3-eth.c
index 9b8295e..8fadae6 100644
--- a/drivers/net/ioc3-eth.c
+++ b/drivers/net/ioc3-eth.c
@@ -5,6 +5,7 @@
  *
  * Driver for SGI's IOC3 based Ethernet cards as found in the PCI card.
  *
+ * Copyright (C) 2005 Stanislaw Skowronek (port to meta-driver)
  * Copyright (C) 1999, 2000, 2001, 2003 Ralf Baechle
  * Copyright (C) 1995, 1999, 2000, 2001 by Silicon Graphics, Inc.
  *
@@ -20,15 +21,13 @@
  *  o Use prefetching for large packets.  What is a good lower limit for
  *    prefetching?
  *  o We're probably allocating a bit too much memory.
- *  o Use hardware checksums.
- *  o Convert to using a IOC3 meta driver.
  *  o Which PHYs might possibly be attached to the IOC3 in real live,
  *    which workarounds are required for them?  Do we ever have Lucent's?
  *  o For the 2.5 branch kill the mii-tool ioctls.
  */
 
 #define IOC3_NAME	"ioc3-eth"
-#define IOC3_VERSION	"2.6.3-3"
+#define IOC3_VERSION	"2.6.4-s2"
 
 #include <linux/config.h>
 #include <linux/init.h>
@@ -45,11 +44,6 @@
 #include <linux/tcp.h>
 #include <linux/udp.h>
 
-#ifdef CONFIG_SERIAL_8250
-#include <linux/serial_core.h>
-#include <linux/serial_8250.h>
-#endif
-
 #include <linux/netdevice.h>
 #include <linux/etherdevice.h>
 #include <linux/ethtool.h>
@@ -61,14 +55,19 @@
 #include <asm/io.h>
 #include <asm/pgtable.h>
 #include <asm/uaccess.h>
+
+#ifdef CONFIG_SGI_IP30
+#include <asm/mach-ip30/addrs.h>
+#else
 #include <asm/sn/types.h>
 #include <asm/sn/sn0/addrs.h>
 #include <asm/sn/sn0/hubni.h>
 #include <asm/sn/sn0/hubio.h>
 #include <asm/sn/klconfig.h>
-#include <asm/sn/ioc3.h>
 #include <asm/sn/sn0/ip27.h>
+#endif
 #include <asm/pci/bridge.h>
+#include <linux/ioc3.h>
 
 /*
  * 64 RX buffers.  This is tunable in the range of 16 <= x < 512.  The
@@ -81,6 +80,7 @@
 
 /* Private per NIC data of the driver.  */
 struct ioc3_private {
+	struct ioc3_driver_data *idd;
 	struct ioc3 *regs;
 	unsigned long *rxr;		/* pointer to receiver ring */
 	struct ioc3_etxd *txr;
@@ -149,8 +149,15 @@ static inline unsigned long ioc3_map(voi
 	return vdev | (0xaUL << PCI64_ATTR_TARG_SHFT) | PCI64_ATTR_PREF |
 	       ((unsigned long)ptr & TO_PHYS_MASK);
 #else
+#ifdef CONFIG_SGI_IP30
+	vdev <<= 58;   /* Shift to PCI64_ATTR_VIRTUAL */
+
+	return vdev | (0x8UL << PCI64_ATTR_TARG_SHFT) | PCI64_ATTR_PREF |
+	       ((unsigned long)ptr & TO_PHYS_MASK);
+#else
 	return virt_to_bus(ptr);
 #endif
+#endif
 }
 
 /* BEWARE: The IOC3 documentation documents the size of rx buffers as
@@ -226,219 +233,6 @@ static inline unsigned long ioc3_map(voi
 #define ioc3_r_midr_w()		be32_to_cpu(ioc3->midr_w)
 #define ioc3_w_midr_w(v)	do { ioc3->midr_w = cpu_to_be32(v); } while (0)
 
-static inline u32 mcr_pack(u32 pulse, u32 sample)
-{
-	return (pulse << 10) | (sample << 2);
-}
-
-static int nic_wait(struct ioc3 *ioc3)
-{
-	u32 mcr;
-
-        do {
-                mcr = ioc3_r_mcr();
-        } while (!(mcr & 2));
-
-        return mcr & 1;
-}
-
-static int nic_reset(struct ioc3 *ioc3)
-{
-        int presence;
-
-	ioc3_w_mcr(mcr_pack(500, 65));
-	presence = nic_wait(ioc3);
-
-	ioc3_w_mcr(mcr_pack(0, 500));
-	nic_wait(ioc3);
-
-        return presence;
-}
-
-static inline int nic_read_bit(struct ioc3 *ioc3)
-{
-	int result;
-
-	ioc3_w_mcr(mcr_pack(6, 13));
-	result = nic_wait(ioc3);
-	ioc3_w_mcr(mcr_pack(0, 100));
-	nic_wait(ioc3);
-
-	return result;
-}
-
-static inline void nic_write_bit(struct ioc3 *ioc3, int bit)
-{
-	if (bit)
-		ioc3_w_mcr(mcr_pack(6, 110));
-	else
-		ioc3_w_mcr(mcr_pack(80, 30));
-
-	nic_wait(ioc3);
-}
-
-/*
- * Read a byte from an iButton device
- */
-static u32 nic_read_byte(struct ioc3 *ioc3)
-{
-	u32 result = 0;
-	int i;
-
-	for (i = 0; i < 8; i++)
-		result = (result >> 1) | (nic_read_bit(ioc3) << 7);
-
-	return result;
-}
-
-/*
- * Write a byte to an iButton device
- */
-static void nic_write_byte(struct ioc3 *ioc3, int byte)
-{
-	int i, bit;
-
-	for (i = 8; i; i--) {
-		bit = byte & 1;
-		byte >>= 1;
-
-		nic_write_bit(ioc3, bit);
-	}
-}
-
-static u64 nic_find(struct ioc3 *ioc3, int *last)
-{
-	int a, b, index, disc;
-	u64 address = 0;
-
-	nic_reset(ioc3);
-	/* Search ROM.  */
-	nic_write_byte(ioc3, 0xf0);
-
-	/* Algorithm from ``Book of iButton Standards''.  */
-	for (index = 0, disc = 0; index < 64; index++) {
-		a = nic_read_bit(ioc3);
-		b = nic_read_bit(ioc3);
-
-		if (a && b) {
-			printk("NIC search failed (not fatal).\n");
-			*last = 0;
-			return 0;
-		}
-
-		if (!a && !b) {
-			if (index == *last) {
-				address |= 1UL << index;
-			} else if (index > *last) {
-				address &= ~(1UL << index);
-				disc = index;
-			} else if ((address & (1UL << index)) == 0)
-				disc = index;
-			nic_write_bit(ioc3, address & (1UL << index));
-			continue;
-		} else {
-			if (a)
-				address |= 1UL << index;
-			else
-				address &= ~(1UL << index);
-			nic_write_bit(ioc3, a);
-			continue;
-		}
-	}
-
-	*last = disc;
-
-	return address;
-}
-
-static int nic_init(struct ioc3 *ioc3)
-{
-	const char *type;
-	u8 crc;
-	u8 serial[6];
-	int save = 0, i;
-
-	type = "unknown";
-
-	while (1) {
-		u64 reg;
-		reg = nic_find(ioc3, &save);
-
-		switch (reg & 0xff) {
-		case 0x91:
-			type = "DS1981U";
-			break;
-		default:
-			if (save == 0) {
-				/* Let the caller try again.  */
-				return -1;
-			}
-			continue;
-		}
-
-		nic_reset(ioc3);
-
-		/* Match ROM.  */
-		nic_write_byte(ioc3, 0x55);
-		for (i = 0; i < 8; i++)
-			nic_write_byte(ioc3, (reg >> (i << 3)) & 0xff);
-
-		reg >>= 8; /* Shift out type.  */
-		for (i = 0; i < 6; i++) {
-			serial[i] = reg & 0xff;
-			reg >>= 8;
-		}
-		crc = reg & 0xff;
-		break;
-	}
-
-	printk("Found %s NIC", type);
-	if (type != "unknown") {
-		printk (" registration number %02x:%02x:%02x:%02x:%02x:%02x,"
-			" CRC %02x", serial[0], serial[1], serial[2],
-			serial[3], serial[4], serial[5], crc);
-	}
-	printk(".\n");
-
-	return 0;
-}
-
-/*
- * Read the NIC (Number-In-a-Can) device used to store the MAC address on
- * SN0 / SN00 nodeboards and PCI cards.
- */
-static void ioc3_get_eaddr_nic(struct ioc3_private *ip)
-{
-	struct ioc3 *ioc3 = ip->regs;
-	u8 nic[14];
-	int tries = 2; /* There may be some problem with the battery?  */
-	int i;
-
-	ioc3_w_gpcr_s(1 << 21);
-
-	while (tries--) {
-		if (!nic_init(ioc3))
-			break;
-		udelay(500);
-	}
-
-	if (tries < 0) {
-		printk("Failed to read MAC address\n");
-		return;
-	}
-
-	/* Read Memory.  */
-	nic_write_byte(ioc3, 0xf0);
-	nic_write_byte(ioc3, 0x00);
-	nic_write_byte(ioc3, 0x00);
-
-	for (i = 13; i >= 0; i--)
-		nic[i] = nic_read_byte(ioc3);
-
-	for (i = 2; i < 8; i++)
-		priv_netdev(ip)->dev_addr[i - 2] = nic[i];
-}
-
 /*
  * Ok, this is hosed by design.  It's necessary to know what machine the
  * NIC is in in order to know how to read the NIC address.  We also have
@@ -446,12 +240,16 @@ static void ioc3_get_eaddr_nic(struct io
  */
 static void ioc3_get_eaddr(struct ioc3_private *ip)
 {
-	int i;
+	int i,nz=0;
 
-
-	ioc3_get_eaddr_nic(ip);
+	for(i=0;i<6;i++)
+		nz |= (priv_netdev(ip)->dev_addr[i] = ip->idd->nic_mac[i]);
 
 	printk("Ethernet address is ");
+	if(!nz) {
+		printk("unreadable.\n");
+		return;
+	}
 	for (i = 0; i < 6; i++) {
 		printk("%02x", priv_netdev(ip)->dev_addr[i]);
 		if (i < 5)
@@ -750,9 +548,9 @@ static void ioc3_error(struct ioc3_priva
 
 /* The interrupt handler does all of the Rx thread work and cleans up
    after the Tx thread.  */
-static irqreturn_t ioc3_interrupt(int irq, void *_dev, struct pt_regs *regs)
+static int ioc3eth_intr(struct ioc3_submodule *is, struct ioc3_driver_data *idd, unsigned int irq, struct pt_regs *regs)
 {
-	struct net_device *dev = (struct net_device *)_dev;
+	struct net_device *dev = (struct net_device *)(idd->data[is->id]);
 	struct ioc3_private *ip = netdev_priv(dev);
 	struct ioc3 *ioc3 = ip->regs;
 	const u32 enabled = EISR_RXTIMERINT | EISR_RXOFLO | EISR_RXBUFOFLO |
@@ -773,7 +571,7 @@ static irqreturn_t ioc3_interrupt(int ir
 	if (eisr & EISR_TXEXPLICIT)
 		ioc3_tx(ip);
 
-	return IRQ_HANDLED;
+	return 0;
 }
 
 static inline void ioc3_setup_duplex(struct ioc3_private *ip)
@@ -840,6 +638,7 @@ static int ioc3_mii_init(struct ioc3_pri
 	ip->ioc3_timer.expires = jiffies + (12 * HZ)/10;  /* 1.2 sec. */
 	ip->ioc3_timer.data = (unsigned long) ip;
 	ip->ioc3_timer.function = &ioc3_timer;
+
 	add_timer(&ip->ioc3_timer);
 
 out:
@@ -1026,7 +825,7 @@ static void ioc3_init(struct net_device 
 	(void) ioc3_r_emcr();
 
 	/* Misc registers  */
-#ifdef CONFIG_SGI_IP27
+#if (defined CONFIG_SGI_IP27) || (defined CONFIG_SGI_IP30)
 	ioc3_w_erbar(PCI64_ATTR_BAR >> 32);	/* Barrier on last store */
 #else
 	ioc3_w_erbar(0);			/* Let PCI API get it right */
@@ -1063,12 +862,6 @@ static int ioc3_open(struct net_device *
 {
 	struct ioc3_private *ip = netdev_priv(dev);
 
-	if (request_irq(dev->irq, ioc3_interrupt, SA_SHIRQ, ioc3_str, dev)) {
-		printk(KERN_ERR "%s: Can't get irq %d\n", dev->name, dev->irq);
-
-		return -EAGAIN;
-	}
-
 	ip->ehar_h = 0;
 	ip->ehar_l = 0;
 	ioc3_init(dev);
@@ -1086,105 +879,12 @@ static int ioc3_close(struct net_device 
 	netif_stop_queue(dev);
 
 	ioc3_stop(ip);
-	free_irq(dev->irq, dev);
 
 	ioc3_free_rings(ip);
 	return 0;
 }
 
-/*
- * MENET cards have four IOC3 chips, which are attached to two sets of
- * PCI slot resources each: the primary connections are on slots
- * 0..3 and the secondaries are on 4..7
- *
- * All four ethernets are brought out to connectors; six serial ports
- * (a pair from each of the first three IOC3s) are brought out to
- * MiniDINs; all other subdevices are left swinging in the wind, leave
- * them disabled.
- */
-static inline int ioc3_is_menet(struct pci_dev *pdev)
-{
-	struct pci_dev *dev;
-
-	return pdev->bus->parent == NULL
-	       && (dev = pci_find_slot(pdev->bus->number, PCI_DEVFN(0, 0)))
-	       && dev->vendor == PCI_VENDOR_ID_SGI
-	       && dev->device == PCI_DEVICE_ID_SGI_IOC3
-	       && (dev = pci_find_slot(pdev->bus->number, PCI_DEVFN(1, 0)))
-	       && dev->vendor == PCI_VENDOR_ID_SGI
-	       && dev->device == PCI_DEVICE_ID_SGI_IOC3
-	       && (dev = pci_find_slot(pdev->bus->number, PCI_DEVFN(2, 0)))
-	       && dev->vendor == PCI_VENDOR_ID_SGI
-	       && dev->device == PCI_DEVICE_ID_SGI_IOC3;
-}
-
-#ifdef CONFIG_SERIAL_8250
-/*
- * Note about serial ports and consoles:
- * For console output, everyone uses the IOC3 UARTA (offset 0x178)
- * connected to the master node (look in ip27_setup_console() and
- * ip27prom_console_write()).
- *
- * For serial (/dev/ttyS0 etc), we can not have hardcoded serial port
- * addresses on a partitioned machine. Since we currently use the ioc3
- * serial ports, we use dynamic serial port discovery that the serial.c
- * driver uses for pci/pnp ports (there is an entry for the SGI ioc3
- * boards in pci_boards[]). Unfortunately, UARTA's pio address is greater
- * than UARTB's, although UARTA on o200s has traditionally been known as
- * port 0. So, we just use one serial port from each ioc3 (since the
- * serial driver adds addresses to get to higher ports).
- *
- * The first one to do a register_console becomes the preferred console
- * (if there is no kernel command line console= directive). /dev/console
- * (ie 5, 1) is then "aliased" into the device number returned by the
- * "device" routine referred to in this console structure
- * (ip27prom_console_dev).
- *
- * Also look in ip27-pci.c:pci_fixup_ioc3() for some comments on working
- * around ioc3 oddities in this respect.
- *
- * The IOC3 serials use a 22MHz clock rate with an additional divider by 3.
- */
-
-static void __devinit ioc3_serial_probe(struct pci_dev *pdev, struct ioc3 *ioc3)
-{
-	struct uart_port port;
-
-	/*
-	 * We need to recognice and treat the fourth MENET serial as it
-	 * does not have an SuperIO chip attached to it, therefore attempting
-	 * to access it will result in bus errors.  We call something an
-	 * MENET if PCI slot 0, 1, 2 and 3 of a master PCI bus all have an IOC3
-	 * in it.  This is paranoid but we want to avoid blowing up on a
-	 * showhorn PCI box that happens to have 4 IOC3 cards in it so it's
-	 * not paranoid enough ...
-	 */
-	if (ioc3_is_menet(pdev) && PCI_SLOT(pdev->devfn) == 3)
-		return;
-
-	/*
-	 * Register to interrupt zero because we share the interrupt with
-	 * the serial driver which we don't properly support yet.
-	 *
-	 * Can't use UPF_IOREMAP as the whole of IOC3 resources have already
-	 * been registered.
-	 */
-	memset(&port, 0, sizeof(port));
-	port.irq      = 0;
-	port.flags    = UPF_SKIP_TEST | UPF_BOOT_AUTOCONF;
-	port.iotype   = UPIO_MEM;
-	port.regshift = 0;
-	port.uartclk  = 22000000 / 3;
-
-	port.membase  = (unsigned char *) &ioc3->sregs.uarta;
-	serial8250_register_port(&port);
-
-	port.membase  = (unsigned char *) &ioc3->sregs.uartb;
-	serial8250_register_port(&port);
-}
-#endif
-
-static int ioc3_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
+static int ioc3eth_probe(struct ioc3_submodule *is, struct ioc3_driver_data *idd)
 {
 	unsigned int sw_physid1, sw_physid2;
 	struct net_device *dev = NULL;
@@ -1194,63 +894,29 @@ static int ioc3_probe(struct pci_dev *pd
 	u32 vendor, model, rev;
 	int err, pci_using_dac;
 
-	/* Configure DMA attributes. */
-	err = pci_set_dma_mask(pdev, 0xffffffffffffffffULL);
-	if (!err) {
-		pci_using_dac = 1;
-		err = pci_set_consistent_dma_mask(pdev, 0xffffffffffffffffULL);
-		if (err < 0) {
-			printk(KERN_ERR "%s: Unable to obtain 64 bit DMA "
-			       "for consistent allocations\n", pci_name(pdev));
-			goto out;
-		}
-	} else {
-		err = pci_set_dma_mask(pdev, 0xffffffffULL);
-		if (err) {
-			printk(KERN_ERR "%s: No usable DMA configuration, "
-			       "aborting.\n", pci_name(pdev));
-			goto out;
-		}
-		pci_using_dac = 0;
-	}
-
-	if (pci_enable_device(pdev))
-		return -ENODEV;
+	/* check for board type */
+	if(idd->class == IOC3_CLASS_SERIAL)
+		return 1;
 
 	dev = alloc_etherdev(sizeof(struct ioc3_private));
 	if (!dev) {
 		err = -ENOMEM;
 		goto out_disable;
 	}
+	idd->data[is->id] = dev;
 
-	if (pci_using_dac)
-		dev->features |= NETIF_F_HIGHDMA;
-
-	err = pci_request_regions(pdev, "ioc3");
-	if (err)
-		goto out_free;
+	/* assume we always have DAC */
+	dev->features |= NETIF_F_HIGHDMA;
 
 	SET_MODULE_OWNER(dev);
-	SET_NETDEV_DEV(dev, &pdev->dev);
+	SET_NETDEV_DEV(dev, &(idd->pdev->dev));
 
 	ip = netdev_priv(dev);
 
-	dev->irq = pdev->irq;
+	dev->irq = idd->pdev->irq;
 
-	ioc3_base = pci_resource_start(pdev, 0);
-	ioc3_size = pci_resource_len(pdev, 0);
-	ioc3 = (struct ioc3 *) ioremap(ioc3_base, ioc3_size);
-	if (!ioc3) {
-		printk(KERN_CRIT "ioc3eth(%s): ioremap failed, goodbye.\n",
-		       pci_name(pdev));
-		err = -ENOMEM;
-		goto out_res;
-	}
-	ip->regs = ioc3;
-
-#ifdef CONFIG_SERIAL_8250
-	ioc3_serial_probe(pdev, ioc3);
-#endif
+	ip->idd = idd;
+	ip->regs = ioc3 = idd->vma;
 
 	spin_lock_init(&ip->ioc3_lock);
 	init_timer(&ip->ioc3_timer);
@@ -1258,7 +924,7 @@ static int ioc3_probe(struct pci_dev *pd
 	ioc3_stop(ip);
 	ioc3_init(dev);
 
-	ip->pdev = pdev;
+	ip->pdev = idd->pdev;
 
 	ip->mii.phy_id_mask = 0x1f;
 	ip->mii.reg_num_mask = 0x1f;
@@ -1270,7 +936,7 @@ static int ioc3_probe(struct pci_dev *pd
 
 	if (ip->mii.phy_id == -1) {
 		printk(KERN_CRIT "ioc3-eth(%s): Didn't find a PHY, goodbye.\n",
-		       pci_name(pdev));
+		       pci_name(idd->pdev));
 		err = -ENODEV;
 		goto out_stop;
 	}
@@ -1316,56 +982,40 @@ static int ioc3_probe(struct pci_dev *pd
 out_stop:
 	ioc3_stop(ip);
 	ioc3_free_rings(ip);
-out_res:
-	pci_release_regions(pdev);
-out_free:
 	free_netdev(dev);
 out_disable:
-	/*
-	 * We should call pci_disable_device(pdev); here if the IOC3 wasn't
-	 * such a weird device ...
-	 */
 out:
 	return err;
 }
 
-static void __devexit ioc3_remove_one (struct pci_dev *pdev)
+static int ioc3eth_remove(struct ioc3_submodule *is, struct ioc3_driver_data *idd)
 {
-	struct net_device *dev = pci_get_drvdata(pdev);
+	struct net_device *dev = idd->data[is->id];
 	struct ioc3_private *ip = netdev_priv(dev);
-	struct ioc3 *ioc3 = ip->regs;
 
 	unregister_netdev(dev);
-	iounmap(ioc3);
-	pci_release_regions(pdev);
 	free_netdev(dev);
-	/*
-	 * We should call pci_disable_device(pdev); here if the IOC3 wasn't
-	 * such a weird device ...
-	 */
+	return 0;
 }
 
-static struct pci_device_id ioc3_pci_tbl[] = {
-	{ PCI_VENDOR_ID_SGI, PCI_DEVICE_ID_SGI_IOC3, PCI_ANY_ID, PCI_ANY_ID },
-	{ 0 }
-};
-MODULE_DEVICE_TABLE(pci, ioc3_pci_tbl);
-
-static struct pci_driver ioc3_driver = {
-	.name		= "ioc3-eth",
-	.id_table	= ioc3_pci_tbl,
-	.probe		= ioc3_probe,
-	.remove		= __devexit_p(ioc3_remove_one),
+static struct ioc3_submodule ioc3eth_submodule = {
+	.name = "ethernet",
+	.probe = ioc3eth_probe,
+	.remove = ioc3eth_remove,
+	.ethernet = 1,
+	.intr = ioc3eth_intr,
+	.owner = THIS_MODULE,
 };
 
 static int __init ioc3_init_module(void)
 {
-	return pci_register_driver(&ioc3_driver);
+	ioc3_register_submodule(&ioc3eth_submodule);
+	return 0;
 }
 
 static void __exit ioc3_cleanup_module(void)
 {
-	pci_unregister_driver(&ioc3_driver);
+	ioc3_unregister_submodule(&ioc3eth_submodule);
 }
 
 static int ioc3_start_xmit(struct sk_buff *skb, struct net_device *dev)

-- 
Martin Michlmayr
http://www.cyrius.com/

^ permalink raw reply related

* Re: Diff between Linus' and linux-mips git: declance
From: Martin Michlmayr @ 2006-02-20  0:17 UTC (permalink / raw)
  To: netdev, linux-mips
In-Reply-To: <20060220000141.GX10266@deprecation.cyrius.com>

Remove delta between Linus' and linux-mips git trees in declance

There are two changes between the Linus' and linux-mips git trees
regarding the declaner driver.  The first change is certainly correct
(as it is consistent with the rest of the file) and should be applied
to mainline; the other change seems correct too.

Signed-off-by: Martin Michlmayr <tbm@cyrius.com>


--- linux-2.6.16-rc4/drivers/net/declance.c	2006-02-19 20:09:07.000000000 +0000
+++ mips-2.6.16-rc4/drivers/net/declance.c	2006-02-19 20:15:22.000000000 +0000
@@ -704,8 +704,8 @@
 	return IRQ_HANDLED;
 }
 
-static irqreturn_t
-lance_interrupt(const int irq, void *dev_id, struct pt_regs *regs)
+static irqreturn_t lance_interrupt(const int irq, void *dev_id,
+				   struct pt_regs *regs)
 {
 	struct net_device *dev = (struct net_device *) dev_id;
 	struct lance_private *lp = netdev_priv(dev);
@@ -1255,7 +1255,7 @@
 	return 0;
 
 err_out_free_dev:
-	kfree(dev);
+	free_netdev(dev);
 
 err_out:
 	return ret;

-- 
Martin Michlmayr
http://www.cyrius.com/

^ permalink raw reply

* [RFC] [PATCH 1/2] Driver to remember ethernet MAC values: maclist
From: Martin Michlmayr @ 2006-02-20  1:01 UTC (permalink / raw)
  To: linux-kernel, netdev; +Cc: John Bowler

From: John Bowler <jbowler@acm.org>

Some Ethernet hardware implementations have no built-in storage for
allocated MAC values - an example is the Intel IXP420 chip which has
support for Ethernet but no defined way of storing allocated MAC values.
With such hardware different board level implementations store the
allocated MAC (or MACs) in different ways.  Rather than put board level
code into a specific Ethernet driver this driver provides a generally
accessible repository for the MACs which can be written by board level
code and read by the driver.

The implementation also allows user level programs to access the MAC
information in /proc/net/maclist.  This is useful as it allows user space
code to use the MAC if it is not used by a built-in driver.

This driver has been used for several months on various IXP420 based
platforms within the NSLU2-Linux project, including the Linksys NSLU2.
A sample implementation of the use of maclist is sent as patch 2.  This
one is for the Linksys NSLU2, but several more patches for other IXP420
based platforms are available.

Signed-off-by: John Bowler <jbowler@acm.org>
Signed-off-by: Martin Michlmayr <tbm@cyrius.com>
Signed-off-by: Alessandro Zummo <a.zummo@towertech.it>
Signed-off-by: Rod Whitby <rod@whitby.id.au>

---

 drivers/net/Kconfig   |   15 ++
 drivers/net/Makefile  |    1 
 drivers/net/maclist.c |  314 ++++++++++++++++++++++++++++++++++++++++++++++++++
 include/net/maclist.h |   23 +++
 4 files changed, 353 insertions(+)

--- /dev/null	1970-01-01 00:00:00.000000000 +0000
+++ linux-nslu2/include/net/maclist.h	2006-02-06 22:35:23.000000000 +0100
@@ -0,0 +1,23 @@
+#ifndef _MACLIST_H
+#define _MACLIST_H 1
+/*
+ * Interfaces to the MAC repository
+ */
+/*
+ * Add a single entry, returns 0 on success else an error
+ * code.  Must *not* be called from an interrupt handler.
+ */
+extern int maclist_add(const u8 id_to_add[6]);
+
+/*
+ * Return the current entry count (valid in any context).
+ */
+extern int maclist_count(void);
+
+/*
+ * Return the ID from the n'th entry (valid in any context),
+ * returns 0 on success, -EINVAL if 'n' is out of range.
+ */
+extern int maclist_read(u8 (*buffer_for_id)[6], int index_of_id_to_return);
+
+#endif /*_MACLIST_H*/
--- /dev/null	1970-01-01 00:00:00.000000000 +0000
+++ linux-nslu2/drivers/net/maclist.c	2006-02-06 22:35:23.000000000 +0100
@@ -0,0 +1,314 @@
+/*
+ * drivers/net/maclist.c
+ *
+ * a simple driver to remember ethernet MAC values
+ *
+ * Some Ethernet hardware implementations have no built-in
+ * storage for allocated MAC values - an example is the Intel
+ * IXP420 chip which has support for Ethernet but no defined
+ * way of storing allocated MAC values.  With such hardware
+ * different board level implementations store the allocated
+ * MAC (or MACs) in different ways.  Rather than put board
+ * level code into a specific Ethernet driver this driver
+ * provides a generally accessible repository for the MACs
+ * which can be written by board level code and read by the
+ * driver.
+ *
+ * The implementation also allows user level programs to
+ * access the MAC information in /proc/net/maclist.  This is
+ * useful as it allows user space code to use the MAC if it
+ * is not used by a built-in driver.
+ *
+ * Copyright (C) 2005 John Bowler
+ * Author: John Bowler <jbowler@acm.org>
+ * Maintainers: http://www.nslu2-linux.org/
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * version 2 as published by the Free Software Foundation.
+ *
+ * External interfaces:
+ *  Interfaces to linux kernel (and modules)
+ *   maclist_add:   add a single MAC
+ *   maclist_count: total number of MACs stored
+ *   maclist_read:  read a MAC 0..(maclist_count-1)
+ */
+#include <linux/module.h>
+#include <linux/moduleparam.h>
+#include <linux/etherdevice.h>
+#include <linux/proc_fs.h>
+#include <linux/errno.h>
+
+#include <net/maclist.h>
+
+#define MACLIST_NAME "maclist"
+
+MODULE_AUTHOR("John Bowler <jbowler@acm.org>");
+MODULE_DESCRIPTION("MAC list repository");
+MODULE_LICENSE("GPL");
+
+typedef struct maclist_entry {
+	struct maclist_entry *next;  /* Linked list, first first */
+	u8                    id[6]; /* 6 byte Ethernet MAC */
+} maclist_entry_t;
+
+/* Access to this list is possible at any time - entries in
+ * the list are never destroyed.  Modification of the list is
+ * safe only from the init code (i.e. modification must be
+ * single threaded), but read from an interrupt at the same
+ * time is possible and safe.
+ */
+static maclist_entry_t *maclist_list = 0;
+
+/*
+ * External interfaces.
+ *
+ * Add a single entry, returns 0 on success else an error
+ * code.  Must be single threaded.
+ */
+int maclist_add(const u8 new_id[6]) {
+	maclist_entry_t *new_entry, **tail;
+
+	if (new_id == 0 || !is_valid_ether_addr(new_id)) {
+		printk(KERN_ERR MACLIST_NAME ": invalid ethernet address\n");
+		return -EINVAL;
+	}
+	new_entry = kmalloc(sizeof *new_entry, GFP_KERNEL);
+	if (new_entry == 0)
+		return -ENOMEM;
+	new_entry->next = 0;
+	memcpy(new_entry->id, new_id, sizeof new_entry->id);
+
+	tail = &maclist_list;
+	while (*tail != 0)
+		tail = &(*tail)->next;
+	*tail = new_entry;
+	return 0;
+}
+EXPORT_SYMBOL(maclist_add);
+
+/*
+ * Return the current entry count (valid in any context).
+ */
+int maclist_count(void) {
+	maclist_entry_t *tail = maclist_list;
+	int count = 0;
+
+	while (tail != 0) {
+		tail = tail->next;
+		++count;
+	}
+
+	return count;
+}
+EXPORT_SYMBOL(maclist_count);
+
+/*
+ * Return the ID from the n'th entry (valid in any context),
+ * returns 0 on success, -EINVAL if 'n' is out of range.
+ */
+int maclist_read(u8 (*id)[6], int n) {
+	maclist_entry_t *entry = maclist_list;
+
+	while (n > 0 && entry != 0) {
+		--n;
+		entry = entry->next;
+	}
+
+	if (n == 0 && entry != 0) {
+		memcpy(id, entry->id, sizeof *id);
+		return 0;
+	}
+
+	printk(KERN_ERR MACLIST_NAME ": id does not exist\n");
+	return -EINVAL;
+}
+EXPORT_SYMBOL(maclist_read);
+
+/*
+ * Parameter parsing.  The option string is a list of MAC
+ * addresses, comma separated.  (The parsing really should
+ * be somewhere central...)
+ */
+static int __init maclist_setup(char *param) {
+	int bytes = 0, seen_a_digit = 0;
+	u8 id[6];
+
+	memset(id, 0, sizeof id);
+
+	if (param) do {
+		int digit = -1;
+		switch (*param) {
+		case '0': digit = 0; break;
+		case '1': digit = 1; break;
+		case '2': digit = 2; break;
+		case '3': digit = 3; break;
+		case '4': digit = 4; break;
+		case '5': digit = 5; break;
+		case '6': digit = 6; break;
+		case '7': digit = 7; break;
+		case '8': digit = 8; break;
+		case '9': digit = 9; break;
+		case 'a': case 'A': digit = 10; break;
+		case 'b': case 'B': digit = 11; break;
+		case 'c': case 'C': digit = 12; break;
+		case 'd': case 'D': digit = 13; break;
+		case 'e': case 'E': digit = 14; break;
+		case 'f': case 'F': digit = 15; break;
+		case ':':
+			if (seen_a_digit)
+				bytes = (bytes+1) & ~1;
+			else
+				bytes += 2; /* i.e. ff::ff is ff:00:ff */
+			seen_a_digit = 0;
+			break;
+		case 0:
+			if (bytes == 0) /* nothing new seen so far */
+				return 0;
+			/*fall through*/
+		case ',': case ';':
+			if (bytes > 0)
+				bytes = 12; /* i.e. all trailing bytes 0 */
+			break;
+		default:
+			printk(KERN_ERR MACLIST_NAME ": invalid character <%c[%d]>\n",
+					*param, *param);
+			return -EINVAL;
+		}
+
+		if (digit >= 0) {
+			id[bytes>>1] = (id[bytes>>1] << 4) + digit; break;
+			++bytes;
+			seen_a_digit = 1;
+		}
+
+		if (bytes >= 12) {
+			int rc = maclist_add(id);
+			if (rc)
+				return rc;
+			bytes = 0;
+			seen_a_digit = 0;
+			memset(id, 0, sizeof id);
+			if (*param == 0)
+				return 0;
+		}
+		++param;
+	} while (1);
+
+	return 0;
+}
+
+/*
+ * procfs support, if compiled in.
+ */
+#ifdef CONFIG_PROC_FS
+/*
+ * Character device read
+ */
+static int maclist_getchar(off_t n) {
+	static char xdigit[16] = "0123456789abcdef";
+	maclist_entry_t *head = maclist_list;
+	int b;
+
+	do {
+		if (head == 0)
+			return -1;
+		if (n < 18)
+			break;
+		head = head->next;
+		n -= 18;
+	} while (1);
+
+	if (n == 17)
+		return '\n';
+
+	b = n/3;
+	switch (n - b*3) {
+	case 0: return xdigit[head->id[b] >> 4];
+	case 1: return xdigit[head->id[b] & 0xf];
+	default: return ':';
+	}
+}
+
+/*
+ * The extensively undocumented proc_read_t callback is implemented here.
+ * Go look in fs/proc/generic.c:
+ *
+ * Prototype:
+ *    int f(char *buffer, char **start, off_t offset,
+ *          int count, int *peof, void *dat)
+ *
+ * Assume that the buffer is "count" bytes in size.
+ *
+ * 2) Set *start = an address within the buffer.
+ *    Put the data of the requested offset at *start.
+ *    Return the number of bytes of data placed there.
+ *    If this number is greater than zero and you
+ *    didn't signal eof and the reader is prepared to
+ *    take more data you will be called again with the
+ *    requested offset advanced by the number of bytes
+ *    absorbed.
+ */
+static int maclist_proc_read(char *buffer, char **start, off_t offset,
+		int count, int *peof, void *dat) {
+	int total;
+
+	*start = buffer;
+	total = 0;
+
+	while (total < count) {
+		int ch = maclist_getchar(offset++);
+		if (ch == -1) {
+			*peof = 1;
+			break;
+		}
+		*buffer++ = ch;
+		++total;
+	}
+
+	return total;
+}
+#endif
+
+/*
+ * Finally, the init/exit functions.
+ */
+static void __exit maclist_exit(void)
+{
+	maclist_entry_t *list;
+
+	remove_proc_entry(MACLIST_NAME, proc_net);
+
+	list = maclist_list;
+	maclist_list = 0;
+
+	while (list != 0) {
+		maclist_entry_t *head = list;
+		list = head->next;
+		kfree(head);
+	}
+}
+
+#ifdef MODULE
+static char ids[256];
+module_param_string(ids, ids, sizeof ids, 0);
+MODULE_PARM_DESC(ids, "comma separated list of MAC ids\n");
+#else
+__setup("maclist_ids=", maclist_setup);
+#endif
+
+static int __init maclist_init(void)
+{
+#	ifdef MODULE
+		if (ids[0])
+			maclist_setup(ids);
+#	endif
+
+	/* Ignore failure, the module will still work. */
+	(void)create_proc_read_entry(MACLIST_NAME, S_IRUGO, proc_net, maclist_proc_read, NULL);
+
+	return 0;
+}
+
+module_init(maclist_init);
+module_exit(maclist_exit);
--- linux-nslu2.orig/drivers/net/Makefile	2006-02-06 22:35:18.000000000 +0100
+++ linux-nslu2/drivers/net/Makefile	2006-02-06 22:35:23.000000000 +0100
@@ -74,6 +74,7 @@ obj-$(CONFIG_RIONET) += rionet.o
 # end link order section
 #
 
+obj-$(CONFIG_MACLIST) += maclist.o
 obj-$(CONFIG_MII) += mii.o
 obj-$(CONFIG_PHYLIB) += phy/
 
--- linux-nslu2.orig/drivers/net/Kconfig	2006-02-06 22:35:18.000000000 +0100
+++ linux-nslu2/drivers/net/Kconfig	2006-02-06 22:35:23.000000000 +0100
@@ -180,6 +180,21 @@ config NET_ETHERNET
 	  kernel: saying N will just cause the configurator to skip all
 	  the questions about Ethernet network cards. If unsure, say N.
 
+config MACLIST
+	tristate "Ethernet MAC repository"
+	depends on NET_ETHERNET
+	help
+	  Some ethernet controllers have no built-in way of obtaining an
+	  appropriate Ethernet MAC address.  Such controllers have to be
+	  initialised in a board-specific way, depending on how the allocated
+	  MAC is stored.  The MAC repository provides a set of APIs and a
+	  proc entry (/proc/net/maclist) to store MAC values from the board
+	  so that such drivers can obtain a MAC address without board-specific
+	  code.  You do not need to enable this device - it will be selected
+	  automatically by any device which requires it.  It is only useful
+	  to enable it manually when building a device driver independently
+	  of the kernel build.
+
 config MII
 	tristate "Generic Media Independent Interface device support"
 	depends on NET_ETHERNET

-- 
Martin Michlmayr
http://www.cyrius.com/

^ permalink raw reply

* [RFC] [PATCH 2/2] Driver to remember ethernet MAC values: NSLU2 support
From: Martin Michlmayr @ 2006-02-20  1:01 UTC (permalink / raw)
  To: linux-kernel, netdev; +Cc: John Bowler

From: John Bowler <jbowler@acm.org>

Implement maclist support for the Linksys NSLU2.  The MAC address is read
from the RedBoot partition in flash.

Signed-off-by: John Bowler <jbowler@acm.org>
Signed-off-by: Martin Michlmayr <tbm@cyrius.com>
Signed-off-by: Alessandro Zummo <a.zummo@towertech.it>
Signed-off-by: Rod Whitby <rod@whitby.id.au>

--

 arch/arm/mach-ixp4xx/Kconfig       |    4 +--
 arch/arm/mach-ixp4xx/nslu2-setup.c |   39 +++++++++++++++++++++++++++++++++++++
 2 files changed, 41 insertions(+), 2 deletions(-)

--- linux-nslu2.orig/arch/arm/mach-ixp4xx/nslu2-setup.c	2006-02-06 22:34:55.000000000 +0100
+++ linux-nslu2/arch/arm/mach-ixp4xx/nslu2-setup.c	2006-02-06 22:35:31.000000000 +0100
@@ -16,11 +16,14 @@
 #include <linux/kernel.h>
 #include <linux/serial.h>
 #include <linux/serial_8250.h>
+#include <linux/mtd/mtd.h>
 
 #include <asm/mach-types.h>
 #include <asm/mach/arch.h>
 #include <asm/mach/flash.h>
 
+#include <net/maclist.h>
+
 static struct flash_platform_data nslu2_flash_data = {
 	.map_name		= "cfi_probe",
 	.width			= 2,
@@ -117,6 +120,37 @@ static void nslu2_power_off(void)
 	gpio_line_set(NSLU2_PO_GPIO, IXP4XX_GPIO_HIGH);
 }
 
+/*
+ * When the RedBoot partition is added the MAC address is read from
+ * it.
+ */
+static void nslu2_flash_add(struct mtd_info *mtd) {
+	if (strcmp(mtd->name, "RedBoot") == 0) {
+		size_t retlen;
+		u_char mac[6];
+
+		/* The MAC is at a known offset... */
+		if (mtd->read(mtd, 0x3FFB0, 6, &retlen, mac) == 0 && retlen == 6) {
+			printk(KERN_INFO "NSLU2 MAC: %.2x:%.2x:%.2x:%.2x:%.2x:%.2x\n",
+				mac[0], mac[1], mac[2], mac[3], mac[4], mac[5]);
+			maclist_add(mac);
+		} else {
+			printk(KERN_ERR "NSLU2 MAC: read failed\n");
+		}
+	}
+}
+
+/*
+ * Nothing to do on remove at present.
+ */
+static void nslu2_flash_remove(struct mtd_info *mtd) {
+}
+
+static struct mtd_notifier nslu2_flash_notifier = {
+	.add = nslu2_flash_add,
+	.remove = nslu2_flash_remove,
+};
+
 static void __init nslu2_init(void)
 {
 	/* The NSLU2 has a 33MHz crystal on board - 1.01% different
@@ -124,6 +158,11 @@ static void __init nslu2_init(void)
 	 */
 	ixp4xx_set_board_tick_rate(66000000);
 
+	/* The flash has an ethernet MAC embedded in it which we need,
+	 * that is all this notifier does.
+	 */
+	register_mtd_user(&nslu2_flash_notifier);
+
 	ixp4xx_sys_init();
 
 	pm_power_off = nslu2_power_off;

-- 
Martin Michlmayr
http://www.cyrius.com/

^ permalink raw reply

* Re: [RFC] [PATCH 1/2] Driver to remember ethernet MAC values: maclist
From: Adrian Bunk @ 2006-02-20  1:47 UTC (permalink / raw)
  To: Martin Michlmayr; +Cc: linux-kernel, netdev, John Bowler
In-Reply-To: <20060220010113.GA19309@deprecation.cyrius.com>

On Mon, Feb 20, 2006 at 01:01:13AM +0000, Martin Michlmayr wrote:

> From: John Bowler <jbowler@acm.org>
> 
> Some Ethernet hardware implementations have no built-in storage for
> allocated MAC values - an example is the Intel IXP420 chip which has
> support for Ethernet but no defined way of storing allocated MAC values.
> With such hardware different board level implementations store the
> allocated MAC (or MACs) in different ways.  Rather than put board level
> code into a specific Ethernet driver this driver provides a generally
> accessible repository for the MACs which can be written by board level
> code and read by the driver.
> 
> The implementation also allows user level programs to access the MAC
> information in /proc/net/maclist.  This is useful as it allows user space
> code to use the MAC if it is not used by a built-in driver.
> 
> This driver has been used for several months on various IXP420 based
> platforms within the NSLU2-Linux project, including the Linksys NSLU2.
> A sample implementation of the use of maclist is sent as patch 2.  This
> one is for the Linksys NSLU2, but several more patches for other IXP420
> based platforms are available.
>...

Silly question:

Why can't this be implemented in user space using the SIOCSIFHWADDR 
ioctl?

> Martin Michlmayr

cu
Adrian

-- 

       "Is there not promise of rain?" Ling Tan asked suddenly out
        of the darkness. There had been need of rain for many days.
       "Only a promise," Lao Er said.
                                       Pearl S. Buck - Dragon Seed

^ permalink raw reply

* Re: [RFC] [PATCH 1/2] Driver to remember ethernet MAC values: maclist
From: Alessandro Zummo @ 2006-02-20  2:01 UTC (permalink / raw)
  To: Adrian Bunk; +Cc: Martin Michlmayr, linux-kernel, netdev, John Bowler
In-Reply-To: <20060220014735.GD4971@stusta.de>

On Mon, 20 Feb 2006 02:47:35 +0100
Adrian Bunk <bunk@stusta.de> wrote:

> > Some Ethernet hardware implementations have no built-in storage for
> > allocated MAC values - an example is the Intel IXP420 chip which has
> > support for Ethernet but no defined way of storing allocated MAC values.
> > With such hardware different board level implementations store the
> > allocated MAC (or MACs) in different ways.  Rather than put board level
> > c
> Silly question:
> 
> Why can't this be implemented in user space using the SIOCSIFHWADDR 
> ioctl?

 Because sometimes you need to have networking available
 well before userspace.

 (netconsole, root over nfs, ...)

-- 

 Best regards,

 Alessandro Zummo,
  Tower Technologies - Turin, Italy

  http://www.towertech.it

^ permalink raw reply

* Re: [RFC] [PATCH 1/2] Driver to remember ethernet MAC values: maclist
From: Adrian Bunk @ 2006-02-20  2:39 UTC (permalink / raw)
  To: Alessandro Zummo; +Cc: Martin Michlmayr, linux-kernel, netdev, John Bowler
In-Reply-To: <20060220030146.11f418dc@inspiron>

On Mon, Feb 20, 2006 at 03:01:46AM +0100, Alessandro Zummo wrote:
> On Mon, 20 Feb 2006 02:47:35 +0100
> Adrian Bunk <bunk@stusta.de> wrote:
> 
> > > Some Ethernet hardware implementations have no built-in storage for
> > > allocated MAC values - an example is the Intel IXP420 chip which has
> > > support for Ethernet but no defined way of storing allocated MAC values.
> > > With such hardware different board level implementations store the
> > > allocated MAC (or MACs) in different ways.  Rather than put board level
> > > c
> > Silly question:
> > 
> > Why can't this be implemented in user space using the SIOCSIFHWADDR 
> > ioctl?
> 
>  Because sometimes you need to have networking available
>  well before userspace.
> 
>  (netconsole, root over nfs, ...)

Why can't setting MAC addresses be done from initramfs?

>  Best regards,
>  Alessandro Zummo,

cu
Adrian

-- 

       "Is there not promise of rain?" Ling Tan asked suddenly out
        of the darkness. There had been need of rain for many days.
       "Only a promise," Lao Er said.
                                       Pearl S. Buck - Dragon Seed

^ 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