Netdev List
 help / color / mirror / Atom feed
* Re: [PATCH net-next] bnx2x: MTU for FCoE L2 ring
From: David Miller @ 2011-02-06 19:21 UTC (permalink / raw)
  To: vladz; +Cc: netdev, eilong
In-Reply-To: <1296996562.16759.9.camel@lb-tlvb-vladz>

From: "Vladislav Zolotarov" <vladz@broadcom.com>
Date: Sun, 6 Feb 2011 14:49:22 +0200

> Always configure an FCoE L2 ring with a mini-jumbo MTU size (2500).
> To do that we had to move the rx_buf_size parameter from per
> function level to a per ring level.
> 
> Signed-off-by: Vladislav Zolotarov <vladz@broadcom.com>
> Signed-off-by: Eilon Greenstein <eilong@broadcom.com>

Applied.

^ permalink raw reply

* Re: [net-next-2.6 PATCH 0/5] enic: updates to version 2.1.1.6
From: David Miller @ 2011-02-06 19:18 UTC (permalink / raw)
  To: vkolluri; +Cc: netdev
In-Reply-To: <20110205021618.8510.34816.stgit@savbu-pc100.cisco.com>

From: Vasanthy Kolluri <vkolluri@cisco.com>
Date: Fri, 04 Feb 2011 18:17:00 -0800

> The following series implements enic driver updates:
> 
> 1/5 - Clean up: Organize devcmd wrapper routines
> 2/5 - Bug Fix: Fix return values of enic_add/del_station_addr routines
> 3/5 - Bug Fix: Reorder firmware devcmds - CMD_INIT and CMD_IG_VLAN_REWRITE_MODE
> 4/5 - Clean up: Remove support for an older version of hardware
> 5/5 - Update MAINTAINERS
> 
> Signed-off-by: Christian Benvenuti <benve@cisco.com>
> Signed-off-by: Vasanthy Kolluri <vkolluri@cisco.com>
> Signed-off-by: Roopa Prabhu <roprabhu@cisco.com>
> Signed-off-by: David Wang <dwang2@cisco.com>

These patches do not apply cleanly to current net-next-2.6, please
respin them.

Thanks.

^ permalink raw reply

* Re: [PATCH 4/4] m68k/atari: ARAnyM - Add support for network access
From: David Miller @ 2011-02-06 19:17 UTC (permalink / raw)
  To: geert
  Cc: linux-m68k, linux-kernel, cz-bobek-lists-aranym, schmitz,
	pstehlik, M.Jurik, netdev
In-Reply-To: <1296989469-7844-5-git-send-email-geert@linux-m68k.org>

From: Geert Uytterhoeven <geert@linux-m68k.org>
Date: Sun,  6 Feb 2011 11:51:09 +0100

> +	dev->trans_start = jiffies;

Device drivers no longer make this operation, the generic code
does it (see net/core/dev.c:dev_hard_start_xmit() and how it
invokes txq_trans_update() on ->ndo_start_xmit() success).

Therefore, please remove this line.

> +	pr_debug(DRV_NAME ": send %d bytes\n", len);

For consistency with other network drivers, add an appropriate CPP
define for "pr_fmt" and use netdev_info(), netdev_debug(), etc.

In situations where a netdev pointer is not available
(ie. pre-register_netdev()), use "dev_*()" instead.

Thanks.

^ permalink raw reply

* Re: 2.6.37 regression: adding main interface to a bridge breaks vlan interface RX
From: Jesse Gross @ 2011-02-06 18:09 UTC (permalink / raw)
  To: chriss; +Cc: netdev
In-Reply-To: <loom.20110205T163216-459@post.gmane.org>

On Sat, Feb 5, 2011 at 7:34 AM, chriss <mail_to_chriss@gmx.net> wrote:
> Maciej Rutecki <maciej.rutecki <at> gmail.com> writes:
>
>>
>> On niedziela, 23 stycznia 2011 o 22:29:02 Jesse Gross wrote:
>> > On Sun, Jan 23, 2011 at 9:45 AM, Maciej Rutecki
>> >
>> > <maciej.rutecki <at> gmail.com> wrote:
>> > > I created a Bugzilla entry at
>> > > https://bugzilla.kernel.org/show_bug.cgi?id=27432
>> > > for your bug report, please add your address to the CC list in there,
>> > > thanks!
>> >
>> > This isn't a bug - the change resolved behavior that varied depending
>> > on what NIC was in use.
>>
>> Thanks for the update. Closing.
>>
>> Regards
>
>
> Hi
>
> How am i supposed to put my eth to a bridge and have a seprate vlan besides that
> bridge?

You should either attached a bridge to a vlan device or stack a vlan
device on the bridge port depending on what you are trying to achieve.

The bridge handler takes all packets of the device that it is attached
to, so having a vlan also attached to the same device will not work.
You may get different results on older kernels depending on what NIC
you were using but that was a bug.

^ permalink raw reply

* [PATCH net-next] bnx2x: Proper netdev->ndo_set_rx_mode() implementation.
From: Vlad Zolotarov @ 2011-02-06 16:50 UTC (permalink / raw)
  To: Dave Miller; +Cc: netdev@vger.kernel.org, Eilon Greenstein

Completed the bnx2x_set_rx_mode() to a proper netdev->ndo_set_rx_mode 
implementation: 
 - Added a missing configuration of a unicast MAC addresses list.
 - Changed bp->dma_lock from being a mutex to a spinlock as long as it's taken
under netdev->addr_list_lock now.

Signed-off-by: Vladislav Zolotarov <vladz@broadcom.com>
Signed-off-by: Eilon Greenstein <eilong@broadcom.com>
---
 drivers/net/bnx2x/bnx2x.h      |   13 +-
 drivers/net/bnx2x/bnx2x_cmn.c  |   17 +-
 drivers/net/bnx2x/bnx2x_main.c |  444 +++++++++++++++++++++++++++++++---------
 3 files changed, 369 insertions(+), 105 deletions(-)

diff --git a/drivers/net/bnx2x/bnx2x.h b/drivers/net/bnx2x/bnx2x.h
index 8e41837..9821bd9 100644
--- a/drivers/net/bnx2x/bnx2x.h
+++ b/drivers/net/bnx2x/bnx2x.h
@@ -129,6 +129,7 @@ void bnx2x_panic_dump(struct bnx2x *bp);
 #endif
 
 #define bnx2x_mc_addr(ha)      ((ha)->addr)
+#define bnx2x_uc_addr(ha)      ((ha)->addr)
 
 #define U64_LO(x)			(u32)(((u64)(x)) & 0xffffffff)
 #define U64_HI(x)			(u32)(((u64)(x)) >> 32)
@@ -810,6 +811,7 @@ struct bnx2x_slowpath {
 	struct eth_stats_query		fw_stats;
 	struct mac_configuration_cmd	mac_config;
 	struct mac_configuration_cmd	mcast_config;
+	struct mac_configuration_cmd	uc_mac_config;
 	struct client_init_ramrod_data	client_init_data;
 
 	/* used by dmae command executer */
@@ -939,7 +941,7 @@ struct bnx2x {
 	struct eth_spe		*spq_prod_bd;
 	struct eth_spe		*spq_last_bd;
 	__le16			*dsb_sp_prod;
-	atomic_t		spq_left; /* serialize spq */
+	atomic_t		cq_spq_left; /* ETH_XXX ramrods credit */
 	/* used to synchronize spq accesses */
 	spinlock_t		spq_lock;
 
@@ -949,6 +951,7 @@ struct bnx2x {
 	u16			eq_prod;
 	u16			eq_cons;
 	__le16			*eq_cons_sb;
+	atomic_t		eq_spq_left; /* COMMON_XXX ramrods credit */
 
 	/* Flags for marking that there is a STAT_QUERY or
 	   SET_MAC ramrod pending */
@@ -1131,7 +1134,7 @@ struct bnx2x {
 
 	int			dmae_ready;
 	/* used to synchronize dmae accesses */
-	struct mutex		dmae_mutex;
+	spinlock_t		dmae_lock;
 
 	/* used to protect the FW mail box */
 	struct mutex		fw_mb_mutex;
@@ -1447,6 +1450,12 @@ u32 bnx2x_fw_command(struct bnx2x *bp, u32 command, u32 param);
 void bnx2x_calc_fc_adv(struct bnx2x *bp);
 int bnx2x_sp_post(struct bnx2x *bp, int command, int cid,
 		  u32 data_hi, u32 data_lo, int common);
+
+/* Clears multicast and unicast list configuration in the chip. */
+void bnx2x_invalidate_e1_mc_list(struct bnx2x *bp);
+void bnx2x_invalidate_e1h_mc_list(struct bnx2x *bp);
+void bnx2x_invalidate_uc_list(struct bnx2x *bp);
+
 void bnx2x_update_coalesce(struct bnx2x *bp);
 int bnx2x_get_link_cfg_idx(struct bnx2x *bp);
 
diff --git a/drivers/net/bnx2x/bnx2x_cmn.c b/drivers/net/bnx2x/bnx2x_cmn.c
index 710ce5d..ae98f7d 100644
--- a/drivers/net/bnx2x/bnx2x_cmn.c
+++ b/drivers/net/bnx2x/bnx2x_cmn.c
@@ -1427,28 +1427,35 @@ int bnx2x_nic_load(struct bnx2x *bp, int load_mode)
 
 	bnx2x_set_eth_mac(bp, 1);
 
+	/* Clear MC configuration */
+	if (CHIP_IS_E1(bp))
+		bnx2x_invalidate_e1_mc_list(bp);
+	else
+		bnx2x_invalidate_e1h_mc_list(bp);
+
+	/* Clear UC lists configuration */
+	bnx2x_invalidate_uc_list(bp);
+
 	if (bp->port.pmf)
 		bnx2x_initial_phy_init(bp, load_mode);
 
+	/* Initialize Rx filtering */
+	bnx2x_set_rx_mode(bp->dev);
+
 	/* Start fast path */
 	switch (load_mode) {
 	case LOAD_NORMAL:
 		/* Tx queue should be only reenabled */
 		netif_tx_wake_all_queues(bp->dev);
 		/* Initialize the receive filter. */
-		bnx2x_set_rx_mode(bp->dev);
 		break;
 
 	case LOAD_OPEN:
 		netif_tx_start_all_queues(bp->dev);
 		smp_mb__after_clear_bit();
-		/* Initialize the receive filter. */
-		bnx2x_set_rx_mode(bp->dev);
 		break;
 
 	case LOAD_DIAG:
-		/* Initialize the receive filter. */
-		bnx2x_set_rx_mode(bp->dev);
 		bp->state = BNX2X_STATE_DIAG;
 		break;
 
diff --git a/drivers/net/bnx2x/bnx2x_main.c b/drivers/net/bnx2x/bnx2x_main.c
index 8cdcf5b..ea10b26 100644
--- a/drivers/net/bnx2x/bnx2x_main.c
+++ b/drivers/net/bnx2x/bnx2x_main.c
@@ -586,7 +586,7 @@ static int bnx2x_issue_dmae_with_comp(struct bnx2x *bp,
 	   bp->slowpath->wb_data[2], bp->slowpath->wb_data[3]);
 
 	/* lock the dmae channel */
-	mutex_lock(&bp->dmae_mutex);
+	spin_lock_bh(&bp->dmae_lock);
 
 	/* reset completion */
 	*wb_comp = 0;
@@ -617,7 +617,7 @@ static int bnx2x_issue_dmae_with_comp(struct bnx2x *bp,
 	   bp->slowpath->wb_data[2], bp->slowpath->wb_data[3]);
 
 unlock:
-	mutex_unlock(&bp->dmae_mutex);
+	spin_unlock_bh(&bp->dmae_lock);
 	return rc;
 }
 
@@ -1397,7 +1397,7 @@ void bnx2x_sp_event(struct bnx2x_fastpath *fp,
 	}
 
 	smp_mb__before_atomic_inc();
-	atomic_inc(&bp->spq_left);
+	atomic_inc(&bp->cq_spq_left);
 	/* push the change in fp->state and towards the memory */
 	smp_wmb();
 
@@ -2731,11 +2731,18 @@ int bnx2x_sp_post(struct bnx2x *bp, int command, int cid,
 
 	spin_lock_bh(&bp->spq_lock);
 
-	if (!atomic_read(&bp->spq_left)) {
-		BNX2X_ERR("BUG! SPQ ring full!\n");
-		spin_unlock_bh(&bp->spq_lock);
-		bnx2x_panic();
-		return -EBUSY;
+	if (common) {
+		if (!atomic_read(&bp->eq_spq_left)) {
+			BNX2X_ERR("BUG! EQ ring full!\n");
+			spin_unlock_bh(&bp->spq_lock);
+			bnx2x_panic();
+			return -EBUSY;
+		}
+	} else if (!atomic_read(&bp->cq_spq_left)) {
+			BNX2X_ERR("BUG! SPQ ring full!\n");
+			spin_unlock_bh(&bp->spq_lock);
+			bnx2x_panic();
+			return -EBUSY;
 	}
 
 	spe = bnx2x_sp_get_next(bp);
@@ -2766,20 +2773,26 @@ int bnx2x_sp_post(struct bnx2x *bp, int command, int cid,
 	spe->data.update_data_addr.lo = cpu_to_le32(data_lo);
 
 	/* stats ramrod has it's own slot on the spq */
-	if (command != RAMROD_CMD_ID_COMMON_STAT_QUERY)
+	if (command != RAMROD_CMD_ID_COMMON_STAT_QUERY) {
 		/* It's ok if the actual decrement is issued towards the memory
 		 * somewhere between the spin_lock and spin_unlock. Thus no
 		 * more explict memory barrier is needed.
 		 */
-		atomic_dec(&bp->spq_left);
+		if (common)
+			atomic_dec(&bp->eq_spq_left);
+		else
+			atomic_dec(&bp->cq_spq_left);
+	}
+
 
 	DP(BNX2X_MSG_SP/*NETIF_MSG_TIMER*/,
 	   "SPQE[%x] (%x:%x)  command %d  hw_cid %x  data (%x:%x) "
-	   "type(0x%x) left %x\n",
+	   "type(0x%x) left (ETH, COMMON) (%x,%x)\n",
 	   bp->spq_prod_idx, (u32)U64_HI(bp->spq_mapping),
 	   (u32)(U64_LO(bp->spq_mapping) +
 	   (void *)bp->spq_prod_bd - (void *)bp->spq), command,
-	   HW_CID(bp, cid), data_hi, data_lo, type, atomic_read(&bp->spq_left));
+	   HW_CID(bp, cid), data_hi, data_lo, type,
+	   atomic_read(&bp->cq_spq_left), atomic_read(&bp->eq_spq_left));
 
 	bnx2x_sp_prod_update(bp);
 	spin_unlock_bh(&bp->spq_lock);
@@ -3691,8 +3704,8 @@ static void bnx2x_eq_int(struct bnx2x *bp)
 	sw_cons = bp->eq_cons;
 	sw_prod = bp->eq_prod;
 
-	DP(BNX2X_MSG_SP, "EQ:  hw_cons %u  sw_cons %u bp->spq_left %u\n",
-			hw_cons, sw_cons, atomic_read(&bp->spq_left));
+	DP(BNX2X_MSG_SP, "EQ:  hw_cons %u  sw_cons %u bp->cq_spq_left %u\n",
+			hw_cons, sw_cons, atomic_read(&bp->eq_spq_left));
 
 	for (; sw_cons != hw_cons;
 	      sw_prod = NEXT_EQ_IDX(sw_prod), sw_cons = NEXT_EQ_IDX(sw_cons)) {
@@ -3757,13 +3770,15 @@ static void bnx2x_eq_int(struct bnx2x *bp)
 		case (EVENT_RING_OPCODE_SET_MAC | BNX2X_STATE_OPEN):
 		case (EVENT_RING_OPCODE_SET_MAC | BNX2X_STATE_DIAG):
 			DP(NETIF_MSG_IFUP, "got set mac ramrod\n");
-			bp->set_mac_pending = 0;
+			if (elem->message.data.set_mac_event.echo)
+				bp->set_mac_pending = 0;
 			break;
 
 		case (EVENT_RING_OPCODE_SET_MAC |
 		      BNX2X_STATE_CLOSING_WAIT4_HALT):
 			DP(NETIF_MSG_IFDOWN, "got (un)set mac ramrod\n");
-			bp->set_mac_pending = 0;
+			if (elem->message.data.set_mac_event.echo)
+				bp->set_mac_pending = 0;
 			break;
 		default:
 			/* unknown event log error and continue */
@@ -3775,7 +3790,7 @@ next_spqe:
 	} /* for */
 
 	smp_mb__before_atomic_inc();
-	atomic_add(spqe_cnt, &bp->spq_left);
+	atomic_add(spqe_cnt, &bp->eq_spq_left);
 
 	bp->eq_cons = sw_cons;
 	bp->eq_prod = sw_prod;
@@ -4208,7 +4223,7 @@ void bnx2x_update_coalesce(struct bnx2x *bp)
 static void bnx2x_init_sp_ring(struct bnx2x *bp)
 {
 	spin_lock_init(&bp->spq_lock);
-	atomic_set(&bp->spq_left, MAX_SPQ_PENDING);
+	atomic_set(&bp->cq_spq_left, MAX_SPQ_PENDING);
 
 	bp->spq_prod_idx = 0;
 	bp->dsb_sp_prod = BNX2X_SP_DSB_INDEX;
@@ -4233,6 +4248,9 @@ static void bnx2x_init_eq_ring(struct bnx2x *bp)
 	bp->eq_cons = 0;
 	bp->eq_prod = NUM_EQ_DESC;
 	bp->eq_cons_sb = BNX2X_EQ_INDEX;
+	/* we want a warning message before it gets rought... */
+	atomic_set(&bp->eq_spq_left,
+		min_t(int, MAX_SP_DESC_CNT - MAX_SPQ_PENDING, NUM_EQ_DESC) - 1);
 }
 
 static void bnx2x_init_ind_table(struct bnx2x *bp)
@@ -5838,7 +5856,7 @@ int bnx2x_init_hw(struct bnx2x *bp, u32 load_code)
 	   BP_ABS_FUNC(bp), load_code);
 
 	bp->dmae_ready = 0;
-	mutex_init(&bp->dmae_mutex);
+	spin_lock_init(&bp->dmae_lock);
 	rc = bnx2x_gunzip_init(bp);
 	if (rc)
 		return rc;
@@ -6173,12 +6191,14 @@ static void bnx2x_set_mac_addr_gen(struct bnx2x *bp, int set, const u8 *mac,
 	int ramrod_flags = WAIT_RAMROD_COMMON;
 
 	bp->set_mac_pending = 1;
-	smp_wmb();
 
 	config->hdr.length = 1;
 	config->hdr.offset = cam_offset;
 	config->hdr.client_id = 0xff;
-	config->hdr.reserved1 = 0;
+	/* Mark the single MAC configuration ramrod as opposed to a
+	 * UC/MC list configuration).
+	 */
+	config->hdr.echo = 1;
 
 	/* primary MAC */
 	config->config_table[0].msb_mac_addr =
@@ -6210,6 +6230,8 @@ static void bnx2x_set_mac_addr_gen(struct bnx2x *bp, int set, const u8 *mac,
 	   config->config_table[0].middle_mac_addr,
 	   config->config_table[0].lsb_mac_addr, BP_FUNC(bp), cl_bit_vec);
 
+	mb();
+
 	bnx2x_sp_post(bp, RAMROD_CMD_ID_COMMON_SET_MAC, 0,
 		      U64_HI(bnx2x_sp_mapping(bp, mac_config)),
 		      U64_LO(bnx2x_sp_mapping(bp, mac_config)), 1);
@@ -6274,20 +6296,15 @@ static u8 bnx2x_e1h_cam_offset(struct bnx2x *bp, u8 rel_offset)
 	if (CHIP_IS_E1H(bp))
 		return E1H_FUNC_MAX * rel_offset + BP_FUNC(bp);
 	else if (CHIP_MODE_IS_4_PORT(bp))
-		return BP_FUNC(bp) * 32  + rel_offset;
+		return E2_FUNC_MAX * rel_offset + BP_FUNC(bp);
 	else
-		return BP_VN(bp) * 32  + rel_offset;
+		return E2_FUNC_MAX * rel_offset + BP_VN(bp);
 }
 
 /**
  *  LLH CAM line allocations: currently only iSCSI and ETH macs are
  *  relevant. In addition, current implementation is tuned for a
  *  single ETH MAC.
- *
- *  When multiple unicast ETH MACs PF configuration in switch
- *  independent mode is required (NetQ, multiple netdev MACs,
- *  etc.), consider better utilisation of 16 per function MAC
- *  entries in the LLH memory.
  */
 enum {
 	LLH_CAM_ISCSI_ETH_LINE = 0,
@@ -6362,14 +6379,37 @@ void bnx2x_set_eth_mac(struct bnx2x *bp, int set)
 		bnx2x_set_mac_addr_gen(bp, set, bcast, 0, cam_offset + 1, 1);
 	}
 }
-static void bnx2x_set_e1_mc_list(struct bnx2x *bp, u8 offset)
+
+static inline u8 bnx2x_e1_cam_mc_offset(struct bnx2x *bp)
+{
+	return CHIP_REV_IS_SLOW(bp) ?
+		(BNX2X_MAX_EMUL_MULTI * (1 + BP_PORT(bp))) :
+		(BNX2X_MAX_MULTICAST * (1 + BP_PORT(bp)));
+}
+
+/* set mc list, do not wait as wait implies sleep and
+ * set_rx_mode can be invoked from non-sleepable context.
+ *
+ * Instead we use the same ramrod data buffer each time we need
+ * to configure a list of addresses, and use the fact that the
+ * list of MACs is changed in an incremental way and that the
+ * function is called under the netif_addr_lock. A temporary
+ * inconsistent CAM configuration (possible in case of a very fast
+ * sequence of add/del/add on the host side) will shortly be
+ * restored by the handler of the last ramrod.
+ */
+static int bnx2x_set_e1_mc_list(struct bnx2x *bp)
 {
 	int i = 0, old;
 	struct net_device *dev = bp->dev;
+	u8 offset = bnx2x_e1_cam_mc_offset(bp);
 	struct netdev_hw_addr *ha;
 	struct mac_configuration_cmd *config_cmd = bnx2x_sp(bp, mcast_config);
 	dma_addr_t config_cmd_map = bnx2x_sp_mapping(bp, mcast_config);
 
+	if (netdev_mc_count(dev) > BNX2X_MAX_MULTICAST)
+		return -EINVAL;
+
 	netdev_for_each_mc_addr(ha, dev) {
 		/* copy mac */
 		config_cmd->config_table[i].msb_mac_addr =
@@ -6410,32 +6450,47 @@ static void bnx2x_set_e1_mc_list(struct bnx2x *bp, u8 offset)
 		}
 	}
 
+	wmb();
+
 	config_cmd->hdr.length = i;
 	config_cmd->hdr.offset = offset;
 	config_cmd->hdr.client_id = 0xff;
-	config_cmd->hdr.reserved1 = 0;
+	/* Mark that this ramrod doesn't use bp->set_mac_pending for
+	 * synchronization.
+	 */
+	config_cmd->hdr.echo = 0;
 
-	bp->set_mac_pending = 1;
-	smp_wmb();
+	mb();
 
-	bnx2x_sp_post(bp, RAMROD_CMD_ID_COMMON_SET_MAC, 0,
+	return bnx2x_sp_post(bp, RAMROD_CMD_ID_COMMON_SET_MAC, 0,
 		   U64_HI(config_cmd_map), U64_LO(config_cmd_map), 1);
 }
-static void bnx2x_invlidate_e1_mc_list(struct bnx2x *bp)
+
+void bnx2x_invalidate_e1_mc_list(struct bnx2x *bp)
 {
 	int i;
 	struct mac_configuration_cmd *config_cmd = bnx2x_sp(bp, mcast_config);
 	dma_addr_t config_cmd_map = bnx2x_sp_mapping(bp, mcast_config);
 	int ramrod_flags = WAIT_RAMROD_COMMON;
+	u8 offset = bnx2x_e1_cam_mc_offset(bp);
 
-	bp->set_mac_pending = 1;
-	smp_wmb();
-
-	for (i = 0; i < config_cmd->hdr.length; i++)
+	for (i = 0; i < BNX2X_MAX_MULTICAST; i++)
 		SET_FLAG(config_cmd->config_table[i].flags,
 			MAC_CONFIGURATION_ENTRY_ACTION_TYPE,
 			T_ETH_MAC_COMMAND_INVALIDATE);
 
+	wmb();
+
+	config_cmd->hdr.length = BNX2X_MAX_MULTICAST;
+	config_cmd->hdr.offset = offset;
+	config_cmd->hdr.client_id = 0xff;
+	/* We'll wait for a completion this time... */
+	config_cmd->hdr.echo = 1;
+
+	bp->set_mac_pending = 1;
+
+	mb();
+
 	bnx2x_sp_post(bp, RAMROD_CMD_ID_COMMON_SET_MAC, 0,
 		      U64_HI(config_cmd_map), U64_LO(config_cmd_map), 1);
 
@@ -6445,6 +6500,44 @@ static void bnx2x_invlidate_e1_mc_list(struct bnx2x *bp)
 
 }
 
+/* Accept one or more multicasts */
+static int bnx2x_set_e1h_mc_list(struct bnx2x *bp)
+{
+	struct net_device *dev = bp->dev;
+	struct netdev_hw_addr *ha;
+	u32 mc_filter[MC_HASH_SIZE];
+	u32 crc, bit, regidx;
+	int i;
+
+	memset(mc_filter, 0, 4 * MC_HASH_SIZE);
+
+	netdev_for_each_mc_addr(ha, dev) {
+		DP(NETIF_MSG_IFUP, "Adding mcast MAC: %pM\n",
+		   bnx2x_mc_addr(ha));
+
+		crc = crc32c_le(0, bnx2x_mc_addr(ha),
+				ETH_ALEN);
+		bit = (crc >> 24) & 0xff;
+		regidx = bit >> 5;
+		bit &= 0x1f;
+		mc_filter[regidx] |= (1 << bit);
+	}
+
+	for (i = 0; i < MC_HASH_SIZE; i++)
+		REG_WR(bp, MC_HASH_OFFSET(bp, i),
+		       mc_filter[i]);
+
+	return 0;
+}
+
+void bnx2x_invalidate_e1h_mc_list(struct bnx2x *bp)
+{
+	int i;
+
+	for (i = 0; i < MC_HASH_SIZE; i++)
+		REG_WR(bp, MC_HASH_OFFSET(bp, i), 0);
+}
+
 #ifdef BCM_CNIC
 /**
  * Set iSCSI MAC(s) at the next enties in the CAM after the ETH
@@ -7110,20 +7203,15 @@ void bnx2x_chip_cleanup(struct bnx2x *bp, int unload_mode)
 	/* Give HW time to discard old tx messages */
 	msleep(1);
 
-	if (CHIP_IS_E1(bp)) {
-		/* invalidate mc list,
-		 * wait and poll (interrupts are off)
-		 */
-		bnx2x_invlidate_e1_mc_list(bp);
-		bnx2x_set_eth_mac(bp, 0);
-
-	} else {
-		REG_WR(bp, NIG_REG_LLH0_FUNC_EN + port*8, 0);
+	bnx2x_set_eth_mac(bp, 0);
 
-		bnx2x_set_eth_mac(bp, 0);
+	bnx2x_invalidate_uc_list(bp);
 
-		for (i = 0; i < MC_HASH_SIZE; i++)
-			REG_WR(bp, MC_HASH_OFFSET(bp, i), 0);
+	if (CHIP_IS_E1(bp))
+		bnx2x_invalidate_e1_mc_list(bp);
+	else {
+		bnx2x_invalidate_e1h_mc_list(bp);
+		REG_WR(bp, NIG_REG_LLH0_FUNC_EN + port*8, 0);
 	}
 
 #ifdef BCM_CNIC
@@ -8813,12 +8901,197 @@ static int bnx2x_close(struct net_device *dev)
 	return 0;
 }
 
+#define E1_MAX_UC_LIST	29
+#define E1H_MAX_UC_LIST	30
+#define E2_MAX_UC_LIST	14
+static inline u8 bnx2x_max_uc_list(struct bnx2x *bp)
+{
+	if (CHIP_IS_E1(bp))
+		return E1_MAX_UC_LIST;
+	else if (CHIP_IS_E1H(bp))
+		return E1H_MAX_UC_LIST;
+	else
+		return E2_MAX_UC_LIST;
+}
+
+
+static inline u8 bnx2x_uc_list_cam_offset(struct bnx2x *bp)
+{
+	if (CHIP_IS_E1(bp))
+		/* CAM Entries for Port0:
+		 *      0 - prim ETH MAC
+		 *      1 - BCAST MAC
+		 *      2 - iSCSI L2 ring ETH MAC
+		 *      3-31 - UC MACs
+		 *
+		 * Port1 entries are allocated the same way starting from
+		 * entry 32.
+		 */
+		return 3 + 32 * BP_PORT(bp);
+	else if (CHIP_IS_E1H(bp)) {
+		/* CAM Entries:
+		 *      0-7  - prim ETH MAC for each function
+		 *      8-15 - iSCSI L2 ring ETH MAC for each function
+		 *      16 till 255 UC MAC lists for each function
+		 *
+		 * Remark: There is no FCoE support for E1H, thus FCoE related
+		 *         MACs are not considered.
+		 */
+		return E1H_FUNC_MAX * (CAM_ISCSI_ETH_LINE + 1) +
+			bnx2x_max_uc_list(bp) * BP_FUNC(bp);
+	} else {
+		/* CAM Entries (there is a separate CAM per engine):
+		 *      0-4  - prim ETH MAC for each function
+		 *      4-7 - iSCSI L2 ring ETH MAC for each function
+		 *      8-11 - FIP ucast L2 MAC for each function
+		 *      12-15 - ALL_ENODE_MACS mcast MAC for each function
+		 *      16 till 71 UC MAC lists for each function
+		 */
+		u8 func_idx =
+			(CHIP_MODE_IS_4_PORT(bp) ? BP_FUNC(bp) : BP_VN(bp));
+
+		return E2_FUNC_MAX * (CAM_MAX_PF_LINE + 1) +
+			bnx2x_max_uc_list(bp) * func_idx;
+	}
+}
+
+/* set uc list, do not wait as wait implies sleep and
+ * set_rx_mode can be invoked from non-sleepable context.
+ *
+ * Instead we use the same ramrod data buffer each time we need
+ * to configure a list of addresses, and use the fact that the
+ * list of MACs is changed in an incremental way and that the
+ * function is called under the netif_addr_lock. A temporary
+ * inconsistent CAM configuration (possible in case of very fast
+ * sequence of add/del/add on the host side) will shortly be
+ * restored by the handler of the last ramrod.
+ */
+static int bnx2x_set_uc_list(struct bnx2x *bp)
+{
+	int i = 0, old;
+	struct net_device *dev = bp->dev;
+	u8 offset = bnx2x_uc_list_cam_offset(bp);
+	struct netdev_hw_addr *ha;
+	struct mac_configuration_cmd *config_cmd = bnx2x_sp(bp, uc_mac_config);
+	dma_addr_t config_cmd_map = bnx2x_sp_mapping(bp, uc_mac_config);
+
+	if (netdev_uc_count(dev) > bnx2x_max_uc_list(bp))
+		return -EINVAL;
+
+	netdev_for_each_uc_addr(ha, dev) {
+		/* copy mac */
+		config_cmd->config_table[i].msb_mac_addr =
+			swab16(*(u16 *)&bnx2x_uc_addr(ha)[0]);
+		config_cmd->config_table[i].middle_mac_addr =
+			swab16(*(u16 *)&bnx2x_uc_addr(ha)[2]);
+		config_cmd->config_table[i].lsb_mac_addr =
+			swab16(*(u16 *)&bnx2x_uc_addr(ha)[4]);
+
+		config_cmd->config_table[i].vlan_id = 0;
+		config_cmd->config_table[i].pf_id = BP_FUNC(bp);
+		config_cmd->config_table[i].clients_bit_vector =
+			cpu_to_le32(1 << BP_L_ID(bp));
+
+		SET_FLAG(config_cmd->config_table[i].flags,
+			MAC_CONFIGURATION_ENTRY_ACTION_TYPE,
+			T_ETH_MAC_COMMAND_SET);
+
+		DP(NETIF_MSG_IFUP,
+		   "setting UCAST[%d] (%04x:%04x:%04x)\n", i,
+		   config_cmd->config_table[i].msb_mac_addr,
+		   config_cmd->config_table[i].middle_mac_addr,
+		   config_cmd->config_table[i].lsb_mac_addr);
+
+		i++;
+
+		/* Set uc MAC in NIG */
+		bnx2x_set_mac_in_nig(bp, 1, bnx2x_uc_addr(ha),
+				     LLH_CAM_ETH_LINE + i);
+	}
+	old = config_cmd->hdr.length;
+	if (old > i) {
+		for (; i < old; i++) {
+			if (CAM_IS_INVALID(config_cmd->
+					   config_table[i])) {
+				/* already invalidated */
+				break;
+			}
+			/* invalidate */
+			SET_FLAG(config_cmd->config_table[i].flags,
+				MAC_CONFIGURATION_ENTRY_ACTION_TYPE,
+				T_ETH_MAC_COMMAND_INVALIDATE);
+		}
+	}
+
+	wmb();
+
+	config_cmd->hdr.length = i;
+	config_cmd->hdr.offset = offset;
+	config_cmd->hdr.client_id = 0xff;
+	/* Mark that this ramrod doesn't use bp->set_mac_pending for
+	 * synchronization.
+	 */
+	config_cmd->hdr.echo = 0;
+
+	mb();
+
+	return bnx2x_sp_post(bp, RAMROD_CMD_ID_COMMON_SET_MAC, 0,
+		   U64_HI(config_cmd_map), U64_LO(config_cmd_map), 1);
+
+}
+
+void bnx2x_invalidate_uc_list(struct bnx2x *bp)
+{
+	int i;
+	struct mac_configuration_cmd *config_cmd = bnx2x_sp(bp, uc_mac_config);
+	dma_addr_t config_cmd_map = bnx2x_sp_mapping(bp, uc_mac_config);
+	int ramrod_flags = WAIT_RAMROD_COMMON;
+	u8 offset = bnx2x_uc_list_cam_offset(bp);
+	u8 max_list_size = bnx2x_max_uc_list(bp);
+
+	for (i = 0; i < max_list_size; i++) {
+		SET_FLAG(config_cmd->config_table[i].flags,
+			MAC_CONFIGURATION_ENTRY_ACTION_TYPE,
+			T_ETH_MAC_COMMAND_INVALIDATE);
+		bnx2x_set_mac_in_nig(bp, 0, NULL, LLH_CAM_ETH_LINE + 1 + i);
+	}
+
+	wmb();
+
+	config_cmd->hdr.length = max_list_size;
+	config_cmd->hdr.offset = offset;
+	config_cmd->hdr.client_id = 0xff;
+	/* We'll wait for a completion this time... */
+	config_cmd->hdr.echo = 1;
+
+	bp->set_mac_pending = 1;
+
+	mb();
+
+	bnx2x_sp_post(bp, RAMROD_CMD_ID_COMMON_SET_MAC, 0,
+		      U64_HI(config_cmd_map), U64_LO(config_cmd_map), 1);
+
+	/* Wait for a completion */
+	bnx2x_wait_ramrod(bp, 0, 0, &bp->set_mac_pending,
+				ramrod_flags);
+
+}
+
+static inline int bnx2x_set_mc_list(struct bnx2x *bp)
+{
+	/* some multicasts */
+	if (CHIP_IS_E1(bp)) {
+		return bnx2x_set_e1_mc_list(bp);
+	} else { /* E1H and newer */
+		return bnx2x_set_e1h_mc_list(bp);
+	}
+}
+
 /* called with netif_tx_lock from dev_mcast.c */
 void bnx2x_set_rx_mode(struct net_device *dev)
 {
 	struct bnx2x *bp = netdev_priv(dev);
 	u32 rx_mode = BNX2X_RX_MODE_NORMAL;
-	int port = BP_PORT(bp);
 
 	if (bp->state != BNX2X_STATE_OPEN) {
 		DP(NETIF_MSG_IFUP, "state is %x, returning\n", bp->state);
@@ -8829,47 +9102,16 @@ void bnx2x_set_rx_mode(struct net_device *dev)
 
 	if (dev->flags & IFF_PROMISC)
 		rx_mode = BNX2X_RX_MODE_PROMISC;
-	else if ((dev->flags & IFF_ALLMULTI) ||
-		 ((netdev_mc_count(dev) > BNX2X_MAX_MULTICAST) &&
-		  CHIP_IS_E1(bp)))
+	else if (dev->flags & IFF_ALLMULTI)
 		rx_mode = BNX2X_RX_MODE_ALLMULTI;
-	else { /* some multicasts */
-		if (CHIP_IS_E1(bp)) {
-			/*
-			 * set mc list, do not wait as wait implies sleep
-			 * and set_rx_mode can be invoked from non-sleepable
-			 * context
-			 */
-			u8 offset = (CHIP_REV_IS_SLOW(bp) ?
-				     BNX2X_MAX_EMUL_MULTI*(1 + port) :
-				     BNX2X_MAX_MULTICAST*(1 + port));
-
-			bnx2x_set_e1_mc_list(bp, offset);
-		} else { /* E1H */
-			/* Accept one or more multicasts */
-			struct netdev_hw_addr *ha;
-			u32 mc_filter[MC_HASH_SIZE];
-			u32 crc, bit, regidx;
-			int i;
-
-			memset(mc_filter, 0, 4 * MC_HASH_SIZE);
-
-			netdev_for_each_mc_addr(ha, dev) {
-				DP(NETIF_MSG_IFUP, "Adding mcast MAC: %pM\n",
-				   bnx2x_mc_addr(ha));
-
-				crc = crc32c_le(0, bnx2x_mc_addr(ha),
-						ETH_ALEN);
-				bit = (crc >> 24) & 0xff;
-				regidx = bit >> 5;
-				bit &= 0x1f;
-				mc_filter[regidx] |= (1 << bit);
-			}
+	else {
+		/* some multicasts */
+		if (bnx2x_set_mc_list(bp))
+			rx_mode = BNX2X_RX_MODE_ALLMULTI;
 
-			for (i = 0; i < MC_HASH_SIZE; i++)
-				REG_WR(bp, MC_HASH_OFFSET(bp, i),
-				       mc_filter[i]);
-		}
+		/* some unicasts */
+		if (bnx2x_set_uc_list(bp))
+			rx_mode = BNX2X_RX_MODE_PROMISC;
 	}
 
 	bp->rx_mode = rx_mode;
@@ -8950,7 +9192,7 @@ static const struct net_device_ops bnx2x_netdev_ops = {
 	.ndo_stop		= bnx2x_close,
 	.ndo_start_xmit		= bnx2x_start_xmit,
 	.ndo_select_queue	= bnx2x_select_queue,
-	.ndo_set_multicast_list	= bnx2x_set_rx_mode,
+	.ndo_set_rx_mode	= bnx2x_set_rx_mode,
 	.ndo_set_mac_address	= bnx2x_change_mac_addr,
 	.ndo_validate_addr	= eth_validate_addr,
 	.ndo_do_ioctl		= bnx2x_ioctl,
@@ -9776,15 +10018,21 @@ static void bnx2x_cnic_sp_post(struct bnx2x *bp, int count)
 					HW_CID(bp, BNX2X_ISCSI_ETH_CID));
 		}
 
-		/* There may be not more than 8 L2 and COMMON SPEs and not more
-		 * than 8 L5 SPEs in the air.
+		/* There may be not more than 8 L2 and not more than 8 L5 SPEs
+		 * We also check that the number of outstanding
+		 * COMMON ramrods is not more than the EQ and SPQ can
+		 * accommodate.
 		 */
-		if ((type == NONE_CONNECTION_TYPE) ||
-		    (type == ETH_CONNECTION_TYPE)) {
-			if (!atomic_read(&bp->spq_left))
+		if (type == ETH_CONNECTION_TYPE) {
+			if (!atomic_read(&bp->cq_spq_left))
+				break;
+			else
+				atomic_dec(&bp->cq_spq_left);
+		} else if (type == NONE_CONNECTION_TYPE) {
+			if (!atomic_read(&bp->eq_spq_left))
 				break;
 			else
-				atomic_dec(&bp->spq_left);
+				atomic_dec(&bp->eq_spq_left);
 		} else if ((type == ISCSI_CONNECTION_TYPE) ||
 			   (type == FCOE_CONNECTION_TYPE)) {
 			if (bp->cnic_spq_pending >=
@@ -9976,7 +10224,7 @@ static int bnx2x_drv_ctl(struct net_device *dev, struct drv_ctl_info *ctl)
 		int count = ctl->data.credit.credit_count;
 
 		smp_mb__before_atomic_inc();
-		atomic_add(count, &bp->spq_left);
+		atomic_add(count, &bp->cq_spq_left);
 		smp_mb__after_atomic_inc();
 		break;
 	}
-- 
1.7.0.4



^ permalink raw reply related

* Re: tlan: Code cleanup: checkpatch.pl is relatively happy now.
From: Sakari Ailus @ 2011-02-06 13:24 UTC (permalink / raw)
  To: Dan Carpenter; +Cc: netdev
In-Reply-To: <20110206104330.GA4384@bicker>

Hi Dan,

Dan Carpenter wrote:
> Commit c659c38b279657 "tlan: Code cleanup: checkpatch.pl is relatively
> happy now." includes the following change without explanation.
>
> -               if ( ( head_list->cStat&  TLAN_CSTAT_READY ) == TLAN_CSTAT_READY ) {
> +               if (head_list->c_stat&  TLAN_CSTAT_READY) {
>
> Was this a bug fix or a bug introduce?

Ouch. Introduce in this case, unfortunately. I *thought* 
TLAN_CSTAT_READY would have been a single bit instead of a bit mask. I 
should have actually checked it, and still put that change into a 
separate patch.

This might not be the one and only place where this kind of shortcut was 
made --- for 80 characters per line compliance. There are very few, 
anyway, in similar places.

I'll recheck the patch and provide a correction, in the coming days likely.

Many thanks for finding this!

-- 
Sakari Ailus
sakari.ailus@iki.fi

^ permalink raw reply

* [PATCH net-2.6] bnx2x: Duplication in promisc mode
From: Vladislav Zolotarov @ 2011-02-06 13:14 UTC (permalink / raw)
  To: Dave Miller; +Cc: netdev list, Eilon Greenstein

Prevent packets duplication for frames targeting FCoE L2 ring:
packets were arriving to stack from both L2 RSS and from FCoE
L2 in a promiscuous mode.

Configure FCoE L2 ring to DROP_ALL rx mode, when interface is
configured to PROMISC, and to accept only unicast frames, when
interface is configured to ALL_MULTI.

Signed-off-by: Vladislav Zolotarov <vladz@broadcom.com>
Signed-off-by: Eilon Greenstein <eilong@broadcom.com>
---
 drivers/net/bnx2x/bnx2x_main.c |   32 +++++++++++++++++++++++---------
 1 files changed, 23 insertions(+), 9 deletions(-)

diff --git a/drivers/net/bnx2x/bnx2x_main.c b/drivers/net/bnx2x/bnx2x_main.c
index ae8d20a..84608c8 100644
--- a/drivers/net/bnx2x/bnx2x_main.c
+++ b/drivers/net/bnx2x/bnx2x_main.c
@@ -4281,9 +4281,12 @@ void bnx2x_set_storm_rx_mode(struct bnx2x *bp)
 		def_q_filters |= BNX2X_ACCEPT_UNICAST | BNX2X_ACCEPT_BROADCAST |
 				BNX2X_ACCEPT_MULTICAST;
 #ifdef BCM_CNIC
-		cl_id = bnx2x_fcoe(bp, cl_id);
-		bnx2x_rxq_set_mac_filters(bp, cl_id, BNX2X_ACCEPT_UNICAST |
-					  BNX2X_ACCEPT_MULTICAST);
+		if (!NO_FCOE(bp)) {
+			cl_id = bnx2x_fcoe(bp, cl_id);
+			bnx2x_rxq_set_mac_filters(bp, cl_id,
+						  BNX2X_ACCEPT_UNICAST |
+						  BNX2X_ACCEPT_MULTICAST);
+		}
 #endif
 		break;
 
@@ -4291,18 +4294,29 @@ void bnx2x_set_storm_rx_mode(struct bnx2x *bp)
 		def_q_filters |= BNX2X_ACCEPT_UNICAST | BNX2X_ACCEPT_BROADCAST |
 				BNX2X_ACCEPT_ALL_MULTICAST;
 #ifdef BCM_CNIC
-		cl_id = bnx2x_fcoe(bp, cl_id);
-		bnx2x_rxq_set_mac_filters(bp, cl_id, BNX2X_ACCEPT_UNICAST |
-					  BNX2X_ACCEPT_MULTICAST);
+		/*
+		 *  Prevent duplication of multicast packets by configuring FCoE
+		 *  L2 Client to receive only matched unicast frames.
+		 */
+		if (!NO_FCOE(bp)) {
+			cl_id = bnx2x_fcoe(bp, cl_id);
+			bnx2x_rxq_set_mac_filters(bp, cl_id,
+						  BNX2X_ACCEPT_UNICAST);
+		}
 #endif
 		break;
 
 	case BNX2X_RX_MODE_PROMISC:
 		def_q_filters |= BNX2X_PROMISCUOUS_MODE;
 #ifdef BCM_CNIC
-		cl_id = bnx2x_fcoe(bp, cl_id);
-		bnx2x_rxq_set_mac_filters(bp, cl_id, BNX2X_ACCEPT_UNICAST |
-					  BNX2X_ACCEPT_MULTICAST);
+		/*
+		 *  Prevent packets duplication by configuring DROP_ALL for FCoE
+		 *  L2 Client.
+		 */
+		if (!NO_FCOE(bp)) {
+			cl_id = bnx2x_fcoe(bp, cl_id);
+			bnx2x_rxq_set_mac_filters(bp, cl_id, BNX2X_ACCEPT_NONE);
+		}
 #endif
 		/* pass management unicast packets as well */
 		llh_mask |= NIG_LLH0_BRB1_DRV_MASK_REG_LLH0_BRB1_DRV_MASK_UNCST;
-- 
1.7.0.4





^ permalink raw reply related

* Re: [Aranym-dev] [PATCH 4/4] m68k/atari: ARAnyM - Add support for network access
From: Milan Jurik @ 2011-02-06 12:52 UTC (permalink / raw)
  To: aranym
  Cc: linux-m68k, linux-kernel, cz-bobek-lists-aranym, Milan Jurik,
	Michael Schmitz, netdev, Geert Uytterhoeven
In-Reply-To: <1296989469-7844-5-git-send-email-geert@linux-m68k.org>

Hi,

Signed-off-by: Milan Jurik <milan.jurik@xylab.cz>

The original e-mail address is dead for some time.

Best regards,

Milan

Geert Uytterhoeven píše v ne 06. 02. 2011 v 11:51 +0100:
> From: Michael Schmitz <schmitz@opal.biophys.uni-duesseldorf.de>
> 
> Should be signed off by Milan and Petr, really.
> 
> [geert] Cleanups and updates
> Signed-off-by: Geert Uytterhoeven <geert@linux-m68k.org>
> Cc: Petr Stehlik <pstehlik@sophics.cz>
> Cc: Milan Jurik <M.Jurik@sh.cvut.cz>
> Cc: netdev@vger.kernel.org
> 
> ---
> Changelog:
>   - Convert to net_device_ops,
>   - nfeth doesn't need obsolete <net/ieee80211.h>,
>   - Convert print_mac to %pM,
>   - Break too long lines,
>   - Make needlessly global functions static,
>   - Make version[] const,
>   - Use pr_*(),
>   - Use net_device_stats from struct net_device instead of our own,
>   - Propagate error code from request_irq(),
>   - Remove unused variable "handled".
> ---
>  arch/m68k/Kconfig      |    8 ++
>  arch/m68k/emu/Makefile |    1 +
>  arch/m68k/emu/nfeth.c  |  272 ++++++++++++++++++++++++++++++++++++++++++++++++
>  3 files changed, 281 insertions(+), 0 deletions(-)
>  create mode 100644 arch/m68k/emu/nfeth.c
> 
> diff --git a/arch/m68k/Kconfig b/arch/m68k/Kconfig
> index 6719c56..80df6ee 100644
> --- a/arch/m68k/Kconfig
> +++ b/arch/m68k/Kconfig
> @@ -263,6 +263,14 @@ config NFCON
>  	  which allows the console output to be redirected to the stderr
>  	  output of ARAnyM.
>  
> +config NFETH
> +	tristate "NatFeat Ethernet support"
> +	depends on NET_ETHERNET && NATFEAT
> +	help
> +	  Say Y to include support for the ARAnyM NatFeat network device
> +	  which will emulate a regular ethernet device while presenting an
> +	  ethertap device to the host system.
> +
>  comment "Processor type"
>  
>  config M68020
> diff --git a/arch/m68k/emu/Makefile b/arch/m68k/emu/Makefile
> index a83ef1e..7dc2010 100644
> --- a/arch/m68k/emu/Makefile
> +++ b/arch/m68k/emu/Makefile
> @@ -6,3 +6,4 @@ obj-y			+= natfeat.o
>  
>  obj-$(CONFIG_NFBLOCK)	+= nfblock.o
>  obj-$(CONFIG_NFCON)	+= nfcon.o
> +obj-$(CONFIG_NFETH)	+= nfeth.o
> diff --git a/arch/m68k/emu/nfeth.c b/arch/m68k/emu/nfeth.c
> new file mode 100644
> index 0000000..5b2a33d
> --- /dev/null
> +++ b/arch/m68k/emu/nfeth.c
> @@ -0,0 +1,272 @@
> +/*
> + * atari_nfeth.c - ARAnyM ethernet card driver for GNU/Linux
> + *
> + * Copyright (c) 2005 Milan Jurik, Petr Stehlik of ARAnyM dev team
> + *
> + * Based on ARAnyM driver for FreeMiNT written by Standa Opichal
> + *
> + * This software may be used and distributed according to the terms of
> + * the GNU General Public License (GPL), incorporated herein by reference.
> + */
> +
> +#include <linux/netdevice.h>
> +#include <linux/etherdevice.h>
> +#include <linux/module.h>
> +#include <asm/natfeat.h>
> +#include <asm/virtconvert.h>
> +
> +enum {
> +	GET_VERSION = 0,/* no parameters, return NFAPI_VERSION in d0 */
> +	XIF_INTLEVEL,	/* no parameters, return Interrupt Level in d0 */
> +	XIF_IRQ,	/* acknowledge interrupt from host */
> +	XIF_START,	/* (ethX), called on 'ifup', start receiver thread */
> +	XIF_STOP,	/* (ethX), called on 'ifdown', stop the thread */
> +	XIF_READLENGTH,	/* (ethX), return size of network data block to read */
> +	XIF_READBLOCK,	/* (ethX, buffer, size), read block of network data */
> +	XIF_WRITEBLOCK,	/* (ethX, buffer, size), write block of network data */
> +	XIF_GET_MAC,	/* (ethX, buffer, size), return MAC HW addr in buffer */
> +	XIF_GET_IPHOST,	/* (ethX, buffer, size), return IP address of host */
> +	XIF_GET_IPATARI,/* (ethX, buffer, size), return IP address of atari */
> +	XIF_GET_NETMASK	/* (ethX, buffer, size), return IP netmask */
> +};
> +
> +#define DRV_NAME	"nfeth"
> +#define DRV_VERSION	"0.3"
> +#define DRV_RELDATE	"10/12/2005"
> +
> +#define MAX_UNIT	8
> +
> +/* These identify the driver base version and may not be removed. */
> +static const char version[] __devinitdata =
> +	KERN_INFO DRV_NAME ".c:v" DRV_VERSION " " DRV_RELDATE
> +	" S.Opichal, M.Jurik, P.Stehlik\n"
> +	KERN_INFO " http://aranym.atari.org/\n";
> +
> +MODULE_AUTHOR("Milan Jurik");
> +MODULE_DESCRIPTION("Atari NFeth driver");
> +MODULE_LICENSE("GPL");
> +/*
> +MODULE_PARM(nfeth_debug, "i");
> +MODULE_PARM_DESC(nfeth_debug, "nfeth_debug level (1-2)");
> +*/
> +
> +
> +static long nfEtherID;
> +static int nfEtherIRQ;
> +
> +struct nfeth_private {
> +	int ethX;
> +};
> +
> +static struct net_device *nfeth_dev[MAX_UNIT];
> +
> +static int nfeth_open(struct net_device *dev)
> +{
> +	struct nfeth_private *priv = netdev_priv(dev);
> +	int res;
> +
> +	res = nf_call(nfEtherID + XIF_START, priv->ethX);
> +
> +	pr_debug(DRV_NAME ": open %d\n", res);
> +
> +	/* Ready for data */
> +	netif_start_queue(dev);
> +
> +	return 0;
> +}
> +
> +static int nfeth_stop(struct net_device *dev)
> +{
> +	struct nfeth_private *priv = netdev_priv(dev);
> +
> +	/* No more data */
> +	netif_stop_queue(dev);
> +
> +	nf_call(nfEtherID + XIF_STOP, priv->ethX);
> +
> +	return 0;
> +}
> +
> +/*
> + * Read a packet out of the adapter and pass it to the upper layers
> + */
> +static inline void recv_packet(struct net_device *dev)
> +{
> +	struct nfeth_private *priv = netdev_priv(dev);
> +	unsigned short pktlen;
> +	struct sk_buff *skb;
> +
> +	/* read packet length (excluding 32 bit crc) */
> +	pktlen = nf_call(nfEtherID + XIF_READLENGTH, priv->ethX);
> +
> +	pr_debug(DRV_NAME ": recv_packet: %i\n", pktlen);
> +
> +	if (!pktlen) {
> +		pr_debug(DRV_NAME ": recv_packet: pktlen == 0\n");
> +		dev->stats.rx_errors++;
> +		return;
> +	}
> +
> +	skb = dev_alloc_skb(pktlen + 2);
> +	if (!skb) {
> +		pr_debug(DRV_NAME
> +			 ": recv_packet: out of mem (buf_alloc failed)\n");
> +		dev->stats.rx_dropped++;
> +		return;
> +	}
> +
> +	skb->dev = dev;
> +	skb_reserve(skb, 2);		/* 16 Byte align  */
> +	skb_put(skb, pktlen);		/* make room */
> +	nf_call(nfEtherID + XIF_READBLOCK, priv->ethX, virt_to_phys(skb->data),
> +		pktlen);
> +
> +	skb->protocol = eth_type_trans(skb, dev);
> +	netif_rx(skb);
> +	dev->last_rx = jiffies;
> +	dev->stats.rx_packets++;
> +	dev->stats.rx_bytes += pktlen;
> +
> +	/* and enqueue packet */
> +	return;
> +}
> +
> +static irqreturn_t nfeth_interrupt(int irq, void *dev_id)
> +{
> +	int i, m, mask;
> +
> +	mask = nf_call(nfEtherID + XIF_IRQ, 0);
> +	for (i = 0, m = 1; i < MAX_UNIT; m <<= 1, i++) {
> +		if (mask & m && nfeth_dev[i]) {
> +			recv_packet(nfeth_dev[i]);
> +			nf_call(nfEtherID + XIF_IRQ, m);
> +		}
> +	}
> +	return IRQ_HANDLED;
> +}
> +
> +static int nfeth_xmit(struct sk_buff *skb, struct net_device *dev)
> +{
> +	int len;
> +	char *data, shortpkt[ETH_ZLEN];
> +	struct nfeth_private *priv = netdev_priv(dev);
> +
> +	data = skb->data;
> +	len = skb->len;
> +	if (len < ETH_ZLEN) {
> +		memset(shortpkt, 0, ETH_ZLEN);
> +		memcpy(shortpkt, data, len);
> +		data = shortpkt;
> +		len = ETH_ZLEN;
> +	}
> +
> +	dev->trans_start = jiffies;
> +
> +	pr_debug(DRV_NAME ": send %d bytes\n", len);
> +	nf_call(nfEtherID + XIF_WRITEBLOCK, priv->ethX, virt_to_phys(data),
> +		len);
> +
> +	dev->stats.tx_packets++;
> +	dev->stats.tx_bytes += len;
> +
> +	dev_kfree_skb(skb);
> +	return 0;
> +}
> +
> +static void nfeth_tx_timeout(struct net_device *dev)
> +{
> +	dev->stats.tx_errors++;
> +	netif_wake_queue(dev);
> +}
> +
> +static const struct net_device_ops nfeth_netdev_ops = {
> +	.ndo_open		= nfeth_open,
> +	.ndo_stop		= nfeth_stop,
> +	.ndo_start_xmit		= nfeth_xmit,
> +	.ndo_tx_timeout		= nfeth_tx_timeout,
> +	.ndo_validate_addr	= eth_validate_addr,
> +	.ndo_change_mtu		= eth_change_mtu,
> +	.ndo_set_mac_address	= eth_mac_addr,
> +};
> +
> +static struct net_device * __init nfeth_probe(int unit)
> +{
> +	struct net_device *dev;
> +	struct nfeth_private *priv;
> +	char mac[ETH_ALEN], host_ip[32], local_ip[32];
> +	int err;
> +
> +	if (!nf_call(nfEtherID + XIF_GET_MAC, unit, mac, ETH_ALEN))
> +		return NULL;
> +
> +	dev = alloc_etherdev(sizeof(struct nfeth_private));
> +	if (!dev)
> +		return NULL;
> +
> +	dev->irq = nfEtherIRQ;
> +	dev->netdev_ops = &nfeth_netdev_ops;
> +
> +	dev->flags |= NETIF_F_NO_CSUM;
> +	memcpy(dev->dev_addr, mac, ETH_ALEN);
> +
> +	priv = netdev_priv(dev);
> +	priv->ethX = unit;
> +
> +	err = register_netdev(dev);
> +	if (err) {
> +		free_netdev(dev);
> +		return NULL;
> +	}
> +
> +	nf_call(nfEtherID + XIF_GET_IPHOST, unit,
> +		host_ip, sizeof(host_ip));
> +	nf_call(nfEtherID + XIF_GET_IPATARI, unit,
> +		local_ip, sizeof(local_ip));
> +
> +	pr_info("%s: nfeth addr:%s (%s) HWaddr:%pM\n", dev->name, host_ip,
> +		local_ip, mac);
> +
> +	return dev;
> +}
> +
> +static int __init nfeth_init(void)
> +{
> +	long ver;
> +	int error, i;
> +
> +	nfEtherID = nf_get_id("ETHERNET");
> +	if (!nfEtherID)
> +		return -ENODEV;
> +
> +	ver = nf_call(nfEtherID + GET_VERSION);
> +	pr_info("nfeth API %lu\n", ver);
> +
> +	nfEtherIRQ = nf_call(nfEtherID + XIF_INTLEVEL);
> +	error = request_irq(nfEtherIRQ, nfeth_interrupt, IRQF_SHARED,
> +			    "eth emu", nfeth_interrupt);
> +	if (error) {
> +		pr_err("nfeth: request for irq %d failed", nfEtherIRQ);
> +		return error;
> +	}
> +
> +	for (i = 0; i < MAX_UNIT; i++)
> +		nfeth_dev[i] = nfeth_probe(i);
> +
> +	return 0;
> +}
> +
> +static void __exit nfeth_cleanup(void)
> +{
> +	int i;
> +
> +	for (i = 0; i < MAX_UNIT; i++) {
> +		if (nfeth_dev[i]) {
> +			unregister_netdev(nfeth_dev[0]);
> +			free_netdev(nfeth_dev[0]);
> +		}
> +	}
> +	free_irq(nfEtherIRQ, nfeth_interrupt);
> +}
> +
> +module_init(nfeth_init);
> +module_exit(nfeth_cleanup);

^ permalink raw reply

* [PATCH net-next] bnx2x: MTU for FCoE L2 ring
From: Vladislav Zolotarov @ 2011-02-06 12:49 UTC (permalink / raw)
  To: Dave Miller; +Cc: netdev list, Eilon Greenstein

Always configure an FCoE L2 ring with a mini-jumbo MTU size (2500).
To do that we had to move the rx_buf_size parameter from per
function level to a per ring level.

Signed-off-by: Vladislav Zolotarov <vladz@broadcom.com>
Signed-off-by: Eilon Greenstein <eilong@broadcom.com>
---
 drivers/net/bnx2x/bnx2x.h         |    7 ++++-
 drivers/net/bnx2x/bnx2x_cmn.c     |   53 +++++++++++++++++++++++++++----------
 drivers/net/bnx2x/bnx2x_cmn.h     |    6 ++--
 drivers/net/bnx2x/bnx2x_ethtool.c |    2 +-
 drivers/net/bnx2x/bnx2x_main.c    |   10 +++++-
 5 files changed, 57 insertions(+), 21 deletions(-)

diff --git a/drivers/net/bnx2x/bnx2x.h b/drivers/net/bnx2x/bnx2x.h
index ff87ec3..c29b37e 100644
--- a/drivers/net/bnx2x/bnx2x.h
+++ b/drivers/net/bnx2x/bnx2x.h
@@ -341,6 +341,8 @@ struct bnx2x_fastpath {
 	/* chip independed shortcut into rx_prods_offset memory */
 	u32			ustorm_rx_prods_offset;

+	u32			rx_buf_size;
+
 	dma_addr_t		status_blk_mapping;

 	struct sw_tx_bd		*tx_buf_ring;
@@ -428,6 +430,10 @@ struct bnx2x_fastpath {
 };

 #define bnx2x_fp(bp, nr, var)		(bp->fp[nr].var)
+
+/* Use 2500 as a mini-jumbo MTU for FCoE */
+#define BNX2X_FCOE_MINI_JUMBO_MTU	2500
+
 #ifdef BCM_CNIC
 /* FCoE L2 `fastpath' is right after the eth entries */
 #define FCOE_IDX			BNX2X_NUM_ETH_QUEUES(bp)
@@ -911,7 +917,6 @@ struct bnx2x {
 	int			tx_ring_size;

 	u32			rx_csum;
-	u32			rx_buf_size;
 /* L2 header size + 2*VLANs (8 bytes) + LLC SNAP (8 bytes) */
 #define ETH_OVREHEAD		(ETH_HLEN + 8 + 8)
 #define ETH_MIN_PACKET_SIZE		60
diff --git a/drivers/net/bnx2x/bnx2x_cmn.c b/drivers/net/bnx2x/bnx2x_cmn.c
index 710ce5d..844afce 100644
--- a/drivers/net/bnx2x/bnx2x_cmn.c
+++ b/drivers/net/bnx2x/bnx2x_cmn.c
@@ -232,7 +232,7 @@ static void bnx2x_tpa_start(struct bnx2x_fastpath *fp, u16 queue,
 	/* move empty skb from pool to prod and map it */
 	prod_rx_buf->skb = fp->tpa_pool[queue].skb;
 	mapping = dma_map_single(&bp->pdev->dev, fp->tpa_pool[queue].skb->data,
-				 bp->rx_buf_size, DMA_FROM_DEVICE);
+				 fp->rx_buf_size, DMA_FROM_DEVICE);
 	dma_unmap_addr_set(prod_rx_buf, mapping, mapping);

 	/* move partial skb from cons to pool (don't unmap yet) */
@@ -333,13 +333,13 @@ static void bnx2x_tpa_stop(struct bnx2x *bp, struct bnx2x_fastpath *fp,
 	struct sw_rx_bd *rx_buf = &fp->tpa_pool[queue];
 	struct sk_buff *skb = rx_buf->skb;
 	/* alloc new skb */
-	struct sk_buff *new_skb = netdev_alloc_skb(bp->dev, bp->rx_buf_size);
+	struct sk_buff *new_skb = netdev_alloc_skb(bp->dev, fp->rx_buf_size);

 	/* Unmap skb in the pool anyway, as we are going to change
 	   pool entry status to BNX2X_TPA_STOP even if new skb allocation
 	   fails. */
 	dma_unmap_single(&bp->pdev->dev, dma_unmap_addr(rx_buf, mapping),
-			 bp->rx_buf_size, DMA_FROM_DEVICE);
+			 fp->rx_buf_size, DMA_FROM_DEVICE);

 	if (likely(new_skb)) {
 		/* fix ip xsum and give it to the stack */
@@ -349,10 +349,10 @@ static void bnx2x_tpa_stop(struct bnx2x *bp, struct bnx2x_fastpath *fp,
 		prefetch(((char *)(skb)) + L1_CACHE_BYTES);

 #ifdef BNX2X_STOP_ON_ERROR
-		if (pad + len > bp->rx_buf_size) {
+		if (pad + len > fp->rx_buf_size) {
 			BNX2X_ERR("skb_put is about to fail...  "
 				  "pad %d  len %d  rx_buf_size %d\n",
-				  pad, len, bp->rx_buf_size);
+				  pad, len, fp->rx_buf_size);
 			bnx2x_panic();
 			return;
 		}
@@ -582,7 +582,7 @@ int bnx2x_rx_int(struct bnx2x_fastpath *fp, int budget)
 			if (likely(bnx2x_alloc_rx_skb(bp, fp, bd_prod) == 0)) {
 				dma_unmap_single(&bp->pdev->dev,
 					dma_unmap_addr(rx_buf, mapping),
-						 bp->rx_buf_size,
+						 fp->rx_buf_size,
 						 DMA_FROM_DEVICE);
 				skb_reserve(skb, pad);
 				skb_put(skb, len);
@@ -821,19 +821,16 @@ void bnx2x_init_rx_rings(struct bnx2x *bp)
 	u16 ring_prod;
 	int i, j;

-	bp->rx_buf_size = bp->dev->mtu + ETH_OVREHEAD + BNX2X_RX_ALIGN +
-		IP_HEADER_ALIGNMENT_PADDING;
-
-	DP(NETIF_MSG_IFUP,
-	   "mtu %d  rx_buf_size %d\n", bp->dev->mtu, bp->rx_buf_size);
-
 	for_each_rx_queue(bp, j) {
 		struct bnx2x_fastpath *fp = &bp->fp[j];

+		DP(NETIF_MSG_IFUP,
+		   "mtu %d  rx_buf_size %d\n", bp->dev->mtu, fp->rx_buf_size);
+
 		if (!fp->disable_tpa) {
 			for (i = 0; i < max_agg_queues; i++) {
 				fp->tpa_pool[i].skb =
-				   netdev_alloc_skb(bp->dev, bp->rx_buf_size);
+				   netdev_alloc_skb(bp->dev, fp->rx_buf_size);
 				if (!fp->tpa_pool[i].skb) {
 					BNX2X_ERR("Failed to allocate TPA "
 						  "skb pool for queue[%d] - "
@@ -941,7 +938,7 @@ static void bnx2x_free_rx_skbs(struct bnx2x *bp)

 			dma_unmap_single(&bp->pdev->dev,
 					 dma_unmap_addr(rx_buf, mapping),
-					 bp->rx_buf_size, DMA_FROM_DEVICE);
+					 fp->rx_buf_size, DMA_FROM_DEVICE);

 			rx_buf->skb = NULL;
 			dev_kfree_skb(skb);
@@ -1249,6 +1246,31 @@ static inline int bnx2x_set_real_num_queues(struct bnx2x *bp)
 	return rc;
 }

+static inline void bnx2x_set_rx_buf_size(struct bnx2x *bp)
+{
+	int i;
+
+	for_each_queue(bp, i) {
+		struct bnx2x_fastpath *fp = &bp->fp[i];
+
+		/* Always use a mini-jumbo MTU for the FCoE L2 ring */
+		if (IS_FCOE_IDX(i))
+			/*
+			 * Although there are no IP frames expected to arrive to
+			 * this ring we still want to add an
+			 * IP_HEADER_ALIGNMENT_PADDING to prevent a buffer
+			 * overrun attack.
+			 */
+			fp->rx_buf_size =
+				BNX2X_FCOE_MINI_JUMBO_MTU + ETH_OVREHEAD +
+				BNX2X_RX_ALIGN + IP_HEADER_ALIGNMENT_PADDING;
+		else
+			fp->rx_buf_size =
+				bp->dev->mtu + ETH_OVREHEAD + BNX2X_RX_ALIGN +
+				IP_HEADER_ALIGNMENT_PADDING;
+	}
+}
+
 /* must be called with rtnl_lock */
 int bnx2x_nic_load(struct bnx2x *bp, int load_mode)
 {
@@ -1272,6 +1294,9 @@ int bnx2x_nic_load(struct bnx2x *bp, int load_mode)
 	/* must be called before memory allocation and HW init */
 	bnx2x_ilt_set_info(bp);

+	/* Set the receive queues buffer size */
+	bnx2x_set_rx_buf_size(bp);
+
 	if (bnx2x_alloc_mem(bp))
 		return -ENOMEM;

diff --git a/drivers/net/bnx2x/bnx2x_cmn.h b/drivers/net/bnx2x/bnx2x_cmn.h
index 03eb4d6..f062d5d 100644
--- a/drivers/net/bnx2x/bnx2x_cmn.h
+++ b/drivers/net/bnx2x/bnx2x_cmn.h
@@ -822,11 +822,11 @@ static inline int bnx2x_alloc_rx_skb(struct bnx2x *bp,
 	struct eth_rx_bd *rx_bd = &fp->rx_desc_ring[index];
 	dma_addr_t mapping;

-	skb = netdev_alloc_skb(bp->dev, bp->rx_buf_size);
+	skb = netdev_alloc_skb(bp->dev, fp->rx_buf_size);
 	if (unlikely(skb == NULL))
 		return -ENOMEM;

-	mapping = dma_map_single(&bp->pdev->dev, skb->data, bp->rx_buf_size,
+	mapping = dma_map_single(&bp->pdev->dev, skb->data, fp->rx_buf_size,
 				 DMA_FROM_DEVICE);
 	if (unlikely(dma_mapping_error(&bp->pdev->dev, mapping))) {
 		dev_kfree_skb(skb);
@@ -892,7 +892,7 @@ static inline void bnx2x_free_tpa_pool(struct bnx2x *bp,
 		if (fp->tpa_state[i] == BNX2X_TPA_START)
 			dma_unmap_single(&bp->pdev->dev,
 					 dma_unmap_addr(rx_buf, mapping),
-					 bp->rx_buf_size, DMA_FROM_DEVICE);
+					 fp->rx_buf_size, DMA_FROM_DEVICE);

 		dev_kfree_skb(skb);
 		rx_buf->skb = NULL;
diff --git a/drivers/net/bnx2x/bnx2x_ethtool.c b/drivers/net/bnx2x/bnx2x_ethtool.c
index 5b44a8b..816fef6 100644
--- a/drivers/net/bnx2x/bnx2x_ethtool.c
+++ b/drivers/net/bnx2x/bnx2x_ethtool.c
@@ -1618,7 +1618,7 @@ static int bnx2x_run_loopback(struct bnx2x *bp, int loopback_mode, u8 link_up)
 	/* prepare the loopback packet */
 	pkt_size = (((bp->dev->mtu < ETH_MAX_PACKET_SIZE) ?
 		     bp->dev->mtu : ETH_MAX_PACKET_SIZE) + ETH_HLEN);
-	skb = netdev_alloc_skb(bp->dev, bp->rx_buf_size);
+	skb = netdev_alloc_skb(bp->dev, fp_rx->rx_buf_size);
 	if (!skb) {
 		rc = -ENOMEM;
 		goto test_loopback_exit;
diff --git a/drivers/net/bnx2x/bnx2x_main.c b/drivers/net/bnx2x/bnx2x_main.c
index ae8d20a..4b2cc1f 100644
--- a/drivers/net/bnx2x/bnx2x_main.c
+++ b/drivers/net/bnx2x/bnx2x_main.c
@@ -2478,8 +2478,14 @@ static void bnx2x_pf_rx_cl_prep(struct bnx2x *bp,
 	rxq_init->sge_map = fp->rx_sge_mapping;
 	rxq_init->rcq_map = fp->rx_comp_mapping;
 	rxq_init->rcq_np_map = fp->rx_comp_mapping + BCM_PAGE_SIZE;
-	rxq_init->mtu = bp->dev->mtu;
-	rxq_init->buf_sz = bp->rx_buf_size;
+
+	/* Always use mini-jumbo MTU for FCoE L2 ring */
+	if (IS_FCOE_FP(fp))
+		rxq_init->mtu = BNX2X_FCOE_MINI_JUMBO_MTU;
+	else
+		rxq_init->mtu = bp->dev->mtu;
+
+	rxq_init->buf_sz = fp->rx_buf_size;
 	rxq_init->cl_qzone_id = fp->cl_qzone_id;
 	rxq_init->cl_id = fp->cl_id;
 	rxq_init->spcl_id = fp->cl_id;
--
1.7.0.4





^ permalink raw reply related

* Re: [PATCH 4/4] m68k/atari: ARAnyM - Add support for network access
From: Petr Stehlik @ 2011-02-06 12:30 UTC (permalink / raw)
  To: Geert Uytterhoeven
  Cc: linux-m68k, linux-kernel, cz-bobek-lists-aranym, Michael Schmitz,
	Milan Jurik, netdev
In-Reply-To: <1296989469-7844-5-git-send-email-geert@linux-m68k.org>

Geert Uytterhoeven píše v Ne 06. 02. 2011 v 11:51 +0100:
> From: Michael Schmitz <schmitz@opal.biophys.uni-duesseldorf.de>
> 
> Should be signed off by Milan and Petr, really.
> 
> [geert] Cleanups and updates
> Signed-off-by: Geert Uytterhoeven <geert@linux-m68k.org>
> Cc: Petr Stehlik <pstehlik@sophics.cz>

Signed-off-by: Petr Stehlik <pstehlik@sophics.cz>

Petr

P.S. you might want to update the URL - ARAnyM got its own domain:

> +	" S.Opichal, M.Jurik, P.Stehlik\n"
> +	KERN_INFO " http://aranym.atari.org/\n";

+	KERN_INFO " http://aranym.org/\n";

^ permalink raw reply

* [PATCH 4/4] m68k/atari: ARAnyM - Add support for network access
From: Geert Uytterhoeven @ 2011-02-06 10:51 UTC (permalink / raw)
  To: linux-m68k, linux-kernel, cz-bobek-lists-aranym
  Cc: Michael Schmitz, Geert Uytterhoeven, Petr Stehlik, Milan Jurik,
	netdev
In-Reply-To: <1296989469-7844-1-git-send-email-geert@linux-m68k.org>

From: Michael Schmitz <schmitz@opal.biophys.uni-duesseldorf.de>

Should be signed off by Milan and Petr, really.

[geert] Cleanups and updates
Signed-off-by: Geert Uytterhoeven <geert@linux-m68k.org>
Cc: Petr Stehlik <pstehlik@sophics.cz>
Cc: Milan Jurik <M.Jurik@sh.cvut.cz>
Cc: netdev@vger.kernel.org

---
Changelog:
  - Convert to net_device_ops,
  - nfeth doesn't need obsolete <net/ieee80211.h>,
  - Convert print_mac to %pM,
  - Break too long lines,
  - Make needlessly global functions static,
  - Make version[] const,
  - Use pr_*(),
  - Use net_device_stats from struct net_device instead of our own,
  - Propagate error code from request_irq(),
  - Remove unused variable "handled".
---
 arch/m68k/Kconfig      |    8 ++
 arch/m68k/emu/Makefile |    1 +
 arch/m68k/emu/nfeth.c  |  272 ++++++++++++++++++++++++++++++++++++++++++++++++
 3 files changed, 281 insertions(+), 0 deletions(-)
 create mode 100644 arch/m68k/emu/nfeth.c

diff --git a/arch/m68k/Kconfig b/arch/m68k/Kconfig
index 6719c56..80df6ee 100644
--- a/arch/m68k/Kconfig
+++ b/arch/m68k/Kconfig
@@ -263,6 +263,14 @@ config NFCON
 	  which allows the console output to be redirected to the stderr
 	  output of ARAnyM.
 
+config NFETH
+	tristate "NatFeat Ethernet support"
+	depends on NET_ETHERNET && NATFEAT
+	help
+	  Say Y to include support for the ARAnyM NatFeat network device
+	  which will emulate a regular ethernet device while presenting an
+	  ethertap device to the host system.
+
 comment "Processor type"
 
 config M68020
diff --git a/arch/m68k/emu/Makefile b/arch/m68k/emu/Makefile
index a83ef1e..7dc2010 100644
--- a/arch/m68k/emu/Makefile
+++ b/arch/m68k/emu/Makefile
@@ -6,3 +6,4 @@ obj-y			+= natfeat.o
 
 obj-$(CONFIG_NFBLOCK)	+= nfblock.o
 obj-$(CONFIG_NFCON)	+= nfcon.o
+obj-$(CONFIG_NFETH)	+= nfeth.o
diff --git a/arch/m68k/emu/nfeth.c b/arch/m68k/emu/nfeth.c
new file mode 100644
index 0000000..5b2a33d
--- /dev/null
+++ b/arch/m68k/emu/nfeth.c
@@ -0,0 +1,272 @@
+/*
+ * atari_nfeth.c - ARAnyM ethernet card driver for GNU/Linux
+ *
+ * Copyright (c) 2005 Milan Jurik, Petr Stehlik of ARAnyM dev team
+ *
+ * Based on ARAnyM driver for FreeMiNT written by Standa Opichal
+ *
+ * This software may be used and distributed according to the terms of
+ * the GNU General Public License (GPL), incorporated herein by reference.
+ */
+
+#include <linux/netdevice.h>
+#include <linux/etherdevice.h>
+#include <linux/module.h>
+#include <asm/natfeat.h>
+#include <asm/virtconvert.h>
+
+enum {
+	GET_VERSION = 0,/* no parameters, return NFAPI_VERSION in d0 */
+	XIF_INTLEVEL,	/* no parameters, return Interrupt Level in d0 */
+	XIF_IRQ,	/* acknowledge interrupt from host */
+	XIF_START,	/* (ethX), called on 'ifup', start receiver thread */
+	XIF_STOP,	/* (ethX), called on 'ifdown', stop the thread */
+	XIF_READLENGTH,	/* (ethX), return size of network data block to read */
+	XIF_READBLOCK,	/* (ethX, buffer, size), read block of network data */
+	XIF_WRITEBLOCK,	/* (ethX, buffer, size), write block of network data */
+	XIF_GET_MAC,	/* (ethX, buffer, size), return MAC HW addr in buffer */
+	XIF_GET_IPHOST,	/* (ethX, buffer, size), return IP address of host */
+	XIF_GET_IPATARI,/* (ethX, buffer, size), return IP address of atari */
+	XIF_GET_NETMASK	/* (ethX, buffer, size), return IP netmask */
+};
+
+#define DRV_NAME	"nfeth"
+#define DRV_VERSION	"0.3"
+#define DRV_RELDATE	"10/12/2005"
+
+#define MAX_UNIT	8
+
+/* These identify the driver base version and may not be removed. */
+static const char version[] __devinitdata =
+	KERN_INFO DRV_NAME ".c:v" DRV_VERSION " " DRV_RELDATE
+	" S.Opichal, M.Jurik, P.Stehlik\n"
+	KERN_INFO " http://aranym.atari.org/\n";
+
+MODULE_AUTHOR("Milan Jurik");
+MODULE_DESCRIPTION("Atari NFeth driver");
+MODULE_LICENSE("GPL");
+/*
+MODULE_PARM(nfeth_debug, "i");
+MODULE_PARM_DESC(nfeth_debug, "nfeth_debug level (1-2)");
+*/
+
+
+static long nfEtherID;
+static int nfEtherIRQ;
+
+struct nfeth_private {
+	int ethX;
+};
+
+static struct net_device *nfeth_dev[MAX_UNIT];
+
+static int nfeth_open(struct net_device *dev)
+{
+	struct nfeth_private *priv = netdev_priv(dev);
+	int res;
+
+	res = nf_call(nfEtherID + XIF_START, priv->ethX);
+
+	pr_debug(DRV_NAME ": open %d\n", res);
+
+	/* Ready for data */
+	netif_start_queue(dev);
+
+	return 0;
+}
+
+static int nfeth_stop(struct net_device *dev)
+{
+	struct nfeth_private *priv = netdev_priv(dev);
+
+	/* No more data */
+	netif_stop_queue(dev);
+
+	nf_call(nfEtherID + XIF_STOP, priv->ethX);
+
+	return 0;
+}
+
+/*
+ * Read a packet out of the adapter and pass it to the upper layers
+ */
+static inline void recv_packet(struct net_device *dev)
+{
+	struct nfeth_private *priv = netdev_priv(dev);
+	unsigned short pktlen;
+	struct sk_buff *skb;
+
+	/* read packet length (excluding 32 bit crc) */
+	pktlen = nf_call(nfEtherID + XIF_READLENGTH, priv->ethX);
+
+	pr_debug(DRV_NAME ": recv_packet: %i\n", pktlen);
+
+	if (!pktlen) {
+		pr_debug(DRV_NAME ": recv_packet: pktlen == 0\n");
+		dev->stats.rx_errors++;
+		return;
+	}
+
+	skb = dev_alloc_skb(pktlen + 2);
+	if (!skb) {
+		pr_debug(DRV_NAME
+			 ": recv_packet: out of mem (buf_alloc failed)\n");
+		dev->stats.rx_dropped++;
+		return;
+	}
+
+	skb->dev = dev;
+	skb_reserve(skb, 2);		/* 16 Byte align  */
+	skb_put(skb, pktlen);		/* make room */
+	nf_call(nfEtherID + XIF_READBLOCK, priv->ethX, virt_to_phys(skb->data),
+		pktlen);
+
+	skb->protocol = eth_type_trans(skb, dev);
+	netif_rx(skb);
+	dev->last_rx = jiffies;
+	dev->stats.rx_packets++;
+	dev->stats.rx_bytes += pktlen;
+
+	/* and enqueue packet */
+	return;
+}
+
+static irqreturn_t nfeth_interrupt(int irq, void *dev_id)
+{
+	int i, m, mask;
+
+	mask = nf_call(nfEtherID + XIF_IRQ, 0);
+	for (i = 0, m = 1; i < MAX_UNIT; m <<= 1, i++) {
+		if (mask & m && nfeth_dev[i]) {
+			recv_packet(nfeth_dev[i]);
+			nf_call(nfEtherID + XIF_IRQ, m);
+		}
+	}
+	return IRQ_HANDLED;
+}
+
+static int nfeth_xmit(struct sk_buff *skb, struct net_device *dev)
+{
+	int len;
+	char *data, shortpkt[ETH_ZLEN];
+	struct nfeth_private *priv = netdev_priv(dev);
+
+	data = skb->data;
+	len = skb->len;
+	if (len < ETH_ZLEN) {
+		memset(shortpkt, 0, ETH_ZLEN);
+		memcpy(shortpkt, data, len);
+		data = shortpkt;
+		len = ETH_ZLEN;
+	}
+
+	dev->trans_start = jiffies;
+
+	pr_debug(DRV_NAME ": send %d bytes\n", len);
+	nf_call(nfEtherID + XIF_WRITEBLOCK, priv->ethX, virt_to_phys(data),
+		len);
+
+	dev->stats.tx_packets++;
+	dev->stats.tx_bytes += len;
+
+	dev_kfree_skb(skb);
+	return 0;
+}
+
+static void nfeth_tx_timeout(struct net_device *dev)
+{
+	dev->stats.tx_errors++;
+	netif_wake_queue(dev);
+}
+
+static const struct net_device_ops nfeth_netdev_ops = {
+	.ndo_open		= nfeth_open,
+	.ndo_stop		= nfeth_stop,
+	.ndo_start_xmit		= nfeth_xmit,
+	.ndo_tx_timeout		= nfeth_tx_timeout,
+	.ndo_validate_addr	= eth_validate_addr,
+	.ndo_change_mtu		= eth_change_mtu,
+	.ndo_set_mac_address	= eth_mac_addr,
+};
+
+static struct net_device * __init nfeth_probe(int unit)
+{
+	struct net_device *dev;
+	struct nfeth_private *priv;
+	char mac[ETH_ALEN], host_ip[32], local_ip[32];
+	int err;
+
+	if (!nf_call(nfEtherID + XIF_GET_MAC, unit, mac, ETH_ALEN))
+		return NULL;
+
+	dev = alloc_etherdev(sizeof(struct nfeth_private));
+	if (!dev)
+		return NULL;
+
+	dev->irq = nfEtherIRQ;
+	dev->netdev_ops = &nfeth_netdev_ops;
+
+	dev->flags |= NETIF_F_NO_CSUM;
+	memcpy(dev->dev_addr, mac, ETH_ALEN);
+
+	priv = netdev_priv(dev);
+	priv->ethX = unit;
+
+	err = register_netdev(dev);
+	if (err) {
+		free_netdev(dev);
+		return NULL;
+	}
+
+	nf_call(nfEtherID + XIF_GET_IPHOST, unit,
+		host_ip, sizeof(host_ip));
+	nf_call(nfEtherID + XIF_GET_IPATARI, unit,
+		local_ip, sizeof(local_ip));
+
+	pr_info("%s: nfeth addr:%s (%s) HWaddr:%pM\n", dev->name, host_ip,
+		local_ip, mac);
+
+	return dev;
+}
+
+static int __init nfeth_init(void)
+{
+	long ver;
+	int error, i;
+
+	nfEtherID = nf_get_id("ETHERNET");
+	if (!nfEtherID)
+		return -ENODEV;
+
+	ver = nf_call(nfEtherID + GET_VERSION);
+	pr_info("nfeth API %lu\n", ver);
+
+	nfEtherIRQ = nf_call(nfEtherID + XIF_INTLEVEL);
+	error = request_irq(nfEtherIRQ, nfeth_interrupt, IRQF_SHARED,
+			    "eth emu", nfeth_interrupt);
+	if (error) {
+		pr_err("nfeth: request for irq %d failed", nfEtherIRQ);
+		return error;
+	}
+
+	for (i = 0; i < MAX_UNIT; i++)
+		nfeth_dev[i] = nfeth_probe(i);
+
+	return 0;
+}
+
+static void __exit nfeth_cleanup(void)
+{
+	int i;
+
+	for (i = 0; i < MAX_UNIT; i++) {
+		if (nfeth_dev[i]) {
+			unregister_netdev(nfeth_dev[0]);
+			free_netdev(nfeth_dev[0]);
+		}
+	}
+	free_irq(nfEtherIRQ, nfeth_interrupt);
+}
+
+module_init(nfeth_init);
+module_exit(nfeth_cleanup);
-- 
1.7.0.4

^ permalink raw reply related

* re: tlan: Code cleanup: checkpatch.pl is relatively happy now.
From: Dan Carpenter @ 2011-02-06 10:43 UTC (permalink / raw)
  To: Sakari Ailus; +Cc: netdev

Commit c659c38b279657 "tlan: Code cleanup: checkpatch.pl is relatively
happy now." includes the following change without explanation.

-               if ( ( head_list->cStat & TLAN_CSTAT_READY ) == TLAN_CSTAT_READY ) {
+               if (head_list->c_stat & TLAN_CSTAT_READY) {

Was this a bug fix or a bug introduce?

regards,
dan carpenter

^ permalink raw reply

* RE: [net-next-2.6 4/5] enic: Clean up: Remove support for an older version of hardware
From: Vasanthy Kolluri (vkolluri) @ 2011-02-06  3:13 UTC (permalink / raw)
  To: David Miller; +Cc: netdev
In-Reply-To: <20110205.175702.226777511.davem@davemloft.net>

This hardware was never shipped to customers. So we are safe removing
it.

Thanks
Vasanthy

-----Original Message-----
From: David Miller [mailto:davem@davemloft.net] 
Sent: Saturday, February 05, 2011 5:57 PM
To: Vasanthy Kolluri (vkolluri)
Cc: netdev@vger.kernel.org
Subject: Re: [net-next-2.6 4/5] enic: Clean up: Remove support for an
older version of hardware


If this hardware ever shipped to any customers, you cannot
simply remove support for it.

Such code must be retained.

^ permalink raw reply

* Re: [PATCH] tcp: Increase the initial congestion window to 10.
From: David Miller @ 2011-02-06  2:14 UTC (permalink / raw)
  To: alexander.zimmermann; +Cc: netdev, dccp, therbert
In-Reply-To: <C9A0E70E-D1DB-45CF-ABB1-8CF9A9D03144@comsys.rwth-aachen.de>

From: Alexander Zimmermann <alexander.zimmermann@comsys.rwth-aachen.de>
Date: Fri, 04 Feb 2011 09:38:34 +0100

> Could you add a reference to draft?
> 
>> +/* TCP initial congestion window */
>> +#define TCP_INIT_CWND		10
>> +
>> extern struct inet_timewait_death_row tcp_death_row;

Sure, done.

--------------------
tcp: Add reference to initial CWND ietf draft.

Suggested by Alexander Zimmermann

Signed-off-by: David S. Miller <davem@davemloft.net>
---
 include/net/tcp.h |    2 +-
 1 files changed, 1 insertions(+), 1 deletions(-)

diff --git a/include/net/tcp.h b/include/net/tcp.h
index 7118668..adfe6db 100644
--- a/include/net/tcp.h
+++ b/include/net/tcp.h
@@ -196,7 +196,7 @@ extern void tcp_time_wait(struct sock *sk, int state, int timeo);
 /* TCP thin-stream limits */
 #define TCP_THIN_LINEAR_RETRIES 6       /* After 6 linear retries, do exp. backoff */
 
-/* TCP initial congestion window */
+/* TCP initial congestion window as per draft-hkchu-tcpm-initcwnd-01 */
 #define TCP_INIT_CWND		10
 
 extern struct inet_timewait_death_row tcp_death_row;
-- 
1.7.4


^ permalink raw reply related

* Re: [PATCH] sis900: Fix mem leak in sis900_rx error path
From: David Miller @ 2011-02-06  2:09 UTC (permalink / raw)
  To: jj; +Cc: venza, netdev, linux-kernel
In-Reply-To: <alpine.LNX.2.00.1102052139150.12305@swampdragon.chaosbits.net>

From: Jesper Juhl <jj@chaosbits.net>
Date: Sat, 5 Feb 2011 21:41:53 +0100 (CET)

> Fix memory leak in error path of sis900_rx(). If we don't do this we'll 
> leak the skb we dev_alloc_skb()'ed just a few lines above when the 
> variable goes out of scope.
> 
> Signed-off-by: Jesper Juhl <jj@chaosbits.net>

Applied, thanks Jesper.

^ permalink raw reply

* Re: [PATCH] ServerEngines, benet: Avoid potential null deref in be_cmd_get_seeprom_data()
From: David Miller @ 2011-02-06  1:58 UTC (permalink / raw)
  To: ajit.khaparde; +Cc: netdev, jj, linux-kernel
In-Reply-To: <20110205031828.GA12772@akhaparde-VBox>

From: Ajit Khaparde <ajit.khaparde@emulex.com>
Date: Fri, 4 Feb 2011 21:18:28 -0600

> [PATCH] ServerEngines, benet: Avoid potential null deref in be_cmd_get_seeprom_data()
> 
> Found by: Jesper Juhl <jj@chaosbits.net>
> 
> Signed-off-by: Ajit Khaparde <ajit.khaparde@emulex.com>

Applied, thanks.

^ permalink raw reply

* Re: [net-next-2.6 4/5] enic: Clean up: Remove support for an older version of hardware
From: David Miller @ 2011-02-06  1:57 UTC (permalink / raw)
  To: vkolluri; +Cc: netdev


If this hardware ever shipped to any customers, you cannot
simply remove support for it.

Such code must be retained.

^ permalink raw reply

* Re: [PATCH 4/5] ipv4: share sysctl net/ipv4/conf/DEVNAME/ tables
From: Eric W. Biederman @ 2011-02-05 21:16 UTC (permalink / raw)
  To: Lucian Adrian Grijincu
  Cc: linux-kernel, netdev, Eric Dumazet, David S. Miller,
	Octavian Purdila
In-Reply-To: <cf6a4b19f6b0264f58367afb659586efb84d2a69.1296793770.git.lucian.grijincu@gmail.com>

Lucian Adrian Grijincu <lucian.grijincu@gmail.com> writes:

> Before this, for each network device DEVNAME that supports ipv4 a new
> sysctl table was registered in $PROC/sys/net/ipv4/conf/DEVNAME/.
>
> The sysctl table was identical for all network devices, except for:
> * data: pointer to the data to be accessed in the sysctl
> * extra1: the 'struct ipv4_devconf*' of the network device
> * extra2: the 'struct net*' of the network namespace
>
> Assuming we have a device name and a 'struct net*', we can get the
> 'struct net_device*'. From there we can compute:
> * data: each entry corresponds to a position in 'struct ipv4_devconf*'
> * extra1: 'struct ipv4_devconf*' can be reached from 'struct net_device*'
> * extra2: the 'struct net*' that we assumed to have
>
> The device name is determined from the path to the file (the name of
> the parent dentry).
>
> The 'struct net*' is stored in the parent 'struct ctl_table*' path by
> register_net_sysctl_table_pathdata().

I don't like this direction.  This makes the code more complicated and
probably racy (think what happens when you are running this sysctl when
someone is renaming the network device) for a questionable gain in space
efficiency.

Size of the sysctl data structures is interesting especially when we
have a lot of instances of this data structure but so is algorithmic
complexity.  The ugly problem is right now inserts of N network devices
is O(N^2) where it could/should be O(Nlog(N)).

I think these last three patches increase reliance on slightly dubious
properties of the sysctl interface and are likely to make it hard to fix
the O(N^2) complexity that increases rtnl_lock hold times and is
otherwise a real pain when adding and deleting network devices.

Eric




> Signed-off-by: Lucian Adrian Grijincu <lucian.grijincu@gmail.com>
> ---
>  fs/proc/proc_sysctl.c      |   16 +++-
>  include/linux/inetdevice.h |   12 +++-
>  net/ipv4/devinet.c         |  203 +++++++++++++++++++++++++++++---------------
>  3 files changed, 161 insertions(+), 70 deletions(-)
>
> diff --git a/fs/proc/proc_sysctl.c b/fs/proc/proc_sysctl.c
> index fb707e0..fe392f1 100644
> --- a/fs/proc/proc_sysctl.c
> +++ b/fs/proc/proc_sysctl.c
> @@ -128,6 +128,11 @@ out:
>  	return err;
>  }
>  
> +
> +typedef int proc_handler_extended(struct ctl_table *ctl, int write,
> +				  void __user *buffer, size_t *lenp, loff_t *ppos,
> +				  struct file *filp);
> +
>  static ssize_t proc_sys_call_handler(struct file *filp, void __user *buf,
>  		size_t count, loff_t *ppos, int write)
>  {
> @@ -136,6 +141,7 @@ static ssize_t proc_sys_call_handler(struct file *filp, void __user *buf,
>  	struct ctl_table *table = PROC_I(inode)->sysctl_entry;
>  	ssize_t error;
>  	size_t res;
> +	proc_handler_extended *phx = (proc_handler_extended *) table->proc_handler;
>  
>  	if (IS_ERR(head))
>  		return PTR_ERR(head);
> @@ -155,7 +161,15 @@ static ssize_t proc_sys_call_handler(struct file *filp, void __user *buf,
>  
>  	/* careful: calling conventions are nasty here */
>  	res = count;
> -	error = table->proc_handler(table, write, buf, &res, ppos);
> +	/* Most handlers only use the first 5 arguments (without @filp).
> +	 * Changing all is too much of work, as, at the time of writting only
> +	 * the devinet.c proc_handlers know about and use the @filp.
> +	 *
> +	 * This is just a HACK for now, I did this this way to not
> +	 * waste time changing all the handlers, in the final version
> +	 * I'll change all the handlers if there's not other solution.
> +	 */
> +	error = phx(table, write, buf, &res, ppos, filp);
>  	if (!error)
>  		error = res;
>  out:
> diff --git a/include/linux/inetdevice.h b/include/linux/inetdevice.h
> index ae8fdc5..caf06b3 100644
> --- a/include/linux/inetdevice.h
> +++ b/include/linux/inetdevice.h
> @@ -43,8 +43,18 @@ enum
>  
>  #define IPV4_DEVCONF_MAX (__IPV4_DEVCONF_MAX - 1)
>  
> +
> +struct devinet_sysctl {
> +	/* dev_name holds a copy of dev_name, because '.procname' is
> +	 * regarded as const by sysctl and we wouldn't want anyone to
> +	 * change it under our feet (see SIOCSIFNAME). */
> +	char *dev_name;
> +	struct ctl_table_header *sysctl_header;
> +};
> +
> +
>  struct ipv4_devconf {
> -	void	*sysctl;
> +	struct devinet_sysctl devinet_sysctl;
>  	int	data[IPV4_DEVCONF_MAX];
>  	DECLARE_BITMAP(state, IPV4_DEVCONF_MAX);
>  };
> diff --git a/net/ipv4/devinet.c b/net/ipv4/devinet.c
> index 748cb5b..774d347 100644
> --- a/net/ipv4/devinet.c
> +++ b/net/ipv4/devinet.c
> @@ -147,7 +147,7 @@ void in_dev_finish_destroy(struct in_device *idev)
>  }
>  EXPORT_SYMBOL(in_dev_finish_destroy);
>  
> -static struct in_device *inetdev_init(struct net_device *dev)
> +struct in_device *inetdev_init(struct net_device *dev)
>  {
>  	struct in_device *in_dev;
>  
> @@ -158,7 +158,8 @@ static struct in_device *inetdev_init(struct net_device *dev)
>  		goto out;
>  	memcpy(&in_dev->cnf, dev_net(dev)->ipv4.devconf_dflt,
>  			sizeof(in_dev->cnf));
> -	in_dev->cnf.sysctl = NULL;
> +	in_dev->cnf.devinet_sysctl.dev_name = NULL;
> +	in_dev->cnf.devinet_sysctl.sysctl_header = NULL;
>  	in_dev->dev = dev;
>  	in_dev->arp_parms = neigh_parms_alloc(dev, &arp_tbl);
>  	if (!in_dev->arp_parms)
> @@ -1375,6 +1376,67 @@ static void inet_forward_change(struct net *net)
>  	}
>  }
>  
> +
> +
> +static int devinet_conf_handler(ctl_table *ctl, int write,
> +				void __user *buffer,
> +				size_t *lenp, loff_t *ppos,
> +				struct file *filp,
> +				proc_handler *proc_handler)
> +{
> +	/* The path to this file is of the form:
> +	 *  $PROC_MOUNT/sys/net/ipv4/conf/$DEVNAME/$CTL
> +	 *
> +	 * The array of 'struct ctl_table' of devinet entries is
> +	 * shared between all ipv4 network devices and the 'data'
> +	 * field of each structure only hold the offset into the
> +	 * 'data' field of 'struct ipv4_devconf'.
> +	 *
> +	 * To find the propper location of the data that must be
> +	 * accessed by this handler we need the device name and the
> +	 * network namespace in which it belongs.
> +	 */
> +
> +	/* We store the network namespace in the parent table's ->extra2 */
> +	struct inode *parent_inode = filp->f_path.dentry->d_parent->d_inode;
> +	struct ctl_table *parent_table = PROC_I(parent_inode)->sysctl_entry;
> +	struct net *net = parent_table->extra2;
> +
> +	const char *dev_name = filp->f_path.dentry->d_parent->d_name.name;
> +	struct ctl_table tmp_ctl;
> +	struct net_device *dev = NULL;
> +	struct in_device *in_dev = NULL;
> +	struct ipv4_devconf *cnf;
> +	int ret;
> +
> +	if (strcmp(dev_name, "all") == 0) {
> +		cnf = net->ipv4.devconf_all;
> +	} else if (strcmp(dev_name, "default") == 0) {
> +		cnf = net->ipv4.devconf_dflt;
> +	} else {
> +		/* the device could have been renamed (SIOCSIFADDR) or
> +		 * deleted since we started accessing it's proc sysctl */
> +		dev = dev_get_by_name(net, dev_name);
> +		if (dev == NULL)
> +			return -ENOENT;
> +		in_dev = in_dev_get(dev);
> +		cnf = &in_dev->cnf;
> +	}
> +
> +	tmp_ctl = *ctl;
> +	tmp_ctl.data += (char *)cnf - (char *)&ipv4_devconf;
> +	tmp_ctl.extra1 = cnf;
> +	tmp_ctl.extra2 = net;
> +
> +	ret = proc_handler(&tmp_ctl, write, buffer, lenp, ppos);
> +
> +	if (in_dev)
> +		in_dev_put(in_dev);
> +	if (dev)
> +		dev_put(dev);
> +	return ret;
> +}
> +
>  static int devinet_conf_proc(ctl_table *ctl, int write,
>  			     void __user *buffer,
>  			     size_t *lenp, loff_t *ppos)
> @@ -1445,6 +1507,33 @@ static int ipv4_doint_and_flush(ctl_table *ctl, int write,
>  	return ret;
>  }
>  
> +static int devinet_conf_proc__(ctl_table *ctl, int write,
> +			       void __user *buffer,
> +			       size_t *lenp, loff_t *ppos,
> +			       struct file *filp)
> +{
> +	return devinet_conf_handler(ctl, write, buffer, lenp, ppos, filp,
> +				    devinet_conf_proc);
> +}
> +
> +static int devinet_sysctl_forward__(ctl_table *ctl, int write,
> +				    void __user *buffer,
> +				    size_t *lenp, loff_t *ppos,
> +				    struct file *filp)
> +{
> +	return devinet_conf_handler(ctl, write, buffer, lenp, ppos, filp,
> +				    devinet_sysctl_forward);
> +}
> +
> +static int ipv4_doint_and_flush__(ctl_table *ctl, int write,
> +				  void __user *buffer,
> +				  size_t *lenp, loff_t *ppos,
> +				  struct file *filp)
> +{
> +	return devinet_conf_handler(ctl, write, buffer, lenp, ppos, filp,
> +				    ipv4_doint_and_flush);
> +}
> +
>  #define DEVINET_SYSCTL_ENTRY(attr, name, mval, proc) \
>  	{ \
>  		.procname	= name, \
> @@ -1452,67 +1541,60 @@ static int ipv4_doint_and_flush(ctl_table *ctl, int write,
>  				  IPV4_DEVCONF_ ## attr - 1, \
>  		.maxlen		= sizeof(int), \
>  		.mode		= mval, \
> -		.proc_handler	= proc, \
> -		.extra1		= &ipv4_devconf, \
> +		.proc_handler	= (proc_handler *) proc, \
>  	}
>  
>  #define DEVINET_SYSCTL_RW_ENTRY(attr, name) \
> -	DEVINET_SYSCTL_ENTRY(attr, name, 0644, devinet_conf_proc)
> +	DEVINET_SYSCTL_ENTRY(attr, name, 0644, devinet_conf_proc__)
>  
>  #define DEVINET_SYSCTL_RO_ENTRY(attr, name) \
> -	DEVINET_SYSCTL_ENTRY(attr, name, 0444, devinet_conf_proc)
> +	DEVINET_SYSCTL_ENTRY(attr, name, 0444, devinet_conf_proc__)
>  
>  #define DEVINET_SYSCTL_COMPLEX_ENTRY(attr, name, proc) \
>  	DEVINET_SYSCTL_ENTRY(attr, name, 0644, proc)
>  
>  #define DEVINET_SYSCTL_FLUSHING_ENTRY(attr, name) \
> -	DEVINET_SYSCTL_COMPLEX_ENTRY(attr, name, ipv4_doint_and_flush)
> -
> -static struct devinet_sysctl_table {
> -	struct ctl_table_header *sysctl_header;
> -	struct ctl_table devinet_vars[__IPV4_DEVCONF_MAX];
> -	char *dev_name;
> -} devinet_sysctl = {
> -	.devinet_vars = {
> -		DEVINET_SYSCTL_COMPLEX_ENTRY(FORWARDING, "forwarding",
> -					     devinet_sysctl_forward),
> -		DEVINET_SYSCTL_RO_ENTRY(MC_FORWARDING, "mc_forwarding"),
> -
> -		DEVINET_SYSCTL_RW_ENTRY(ACCEPT_REDIRECTS, "accept_redirects"),
> -		DEVINET_SYSCTL_RW_ENTRY(SECURE_REDIRECTS, "secure_redirects"),
> -		DEVINET_SYSCTL_RW_ENTRY(SHARED_MEDIA, "shared_media"),
> -		DEVINET_SYSCTL_RW_ENTRY(RP_FILTER, "rp_filter"),
> -		DEVINET_SYSCTL_RW_ENTRY(SEND_REDIRECTS, "send_redirects"),
> -		DEVINET_SYSCTL_RW_ENTRY(ACCEPT_SOURCE_ROUTE,
> -					"accept_source_route"),
> -		DEVINET_SYSCTL_RW_ENTRY(ACCEPT_LOCAL, "accept_local"),
> -		DEVINET_SYSCTL_RW_ENTRY(SRC_VMARK, "src_valid_mark"),
> -		DEVINET_SYSCTL_RW_ENTRY(PROXY_ARP, "proxy_arp"),
> -		DEVINET_SYSCTL_RW_ENTRY(MEDIUM_ID, "medium_id"),
> -		DEVINET_SYSCTL_RW_ENTRY(BOOTP_RELAY, "bootp_relay"),
> -		DEVINET_SYSCTL_RW_ENTRY(LOG_MARTIANS, "log_martians"),
> -		DEVINET_SYSCTL_RW_ENTRY(TAG, "tag"),
> -		DEVINET_SYSCTL_RW_ENTRY(ARPFILTER, "arp_filter"),
> -		DEVINET_SYSCTL_RW_ENTRY(ARP_ANNOUNCE, "arp_announce"),
> -		DEVINET_SYSCTL_RW_ENTRY(ARP_IGNORE, "arp_ignore"),
> -		DEVINET_SYSCTL_RW_ENTRY(ARP_ACCEPT, "arp_accept"),
> -		DEVINET_SYSCTL_RW_ENTRY(ARP_NOTIFY, "arp_notify"),
> -		DEVINET_SYSCTL_RW_ENTRY(PROXY_ARP_PVLAN, "proxy_arp_pvlan"),
> -
> -		DEVINET_SYSCTL_FLUSHING_ENTRY(NOXFRM, "disable_xfrm"),
> -		DEVINET_SYSCTL_FLUSHING_ENTRY(NOPOLICY, "disable_policy"),
> -		DEVINET_SYSCTL_FLUSHING_ENTRY(FORCE_IGMP_VERSION,
> -					      "force_igmp_version"),
> -		DEVINET_SYSCTL_FLUSHING_ENTRY(PROMOTE_SECONDARIES,
> -					      "promote_secondaries"),
> -	},
> +	DEVINET_SYSCTL_COMPLEX_ENTRY(attr, name, ipv4_doint_and_flush__)
> +
> +const struct ctl_table ipv4_devinet_sysctl_table[__IPV4_DEVCONF_MAX] = {
> +	DEVINET_SYSCTL_COMPLEX_ENTRY(FORWARDING, "forwarding",
> +				     devinet_sysctl_forward__),
> +	DEVINET_SYSCTL_RO_ENTRY(MC_FORWARDING, "mc_forwarding"),
> +
> +	DEVINET_SYSCTL_RW_ENTRY(ACCEPT_REDIRECTS, "accept_redirects"),
> +	DEVINET_SYSCTL_RW_ENTRY(SECURE_REDIRECTS, "secure_redirects"),
> +	DEVINET_SYSCTL_RW_ENTRY(SHARED_MEDIA, "shared_media"),
> +	DEVINET_SYSCTL_RW_ENTRY(RP_FILTER, "rp_filter"),
> +	DEVINET_SYSCTL_RW_ENTRY(SEND_REDIRECTS, "send_redirects"),
> +	DEVINET_SYSCTL_RW_ENTRY(ACCEPT_SOURCE_ROUTE,
> +				"accept_source_route"),
> +	DEVINET_SYSCTL_RW_ENTRY(ACCEPT_LOCAL, "accept_local"),
> +	DEVINET_SYSCTL_RW_ENTRY(SRC_VMARK, "src_valid_mark"),
> +	DEVINET_SYSCTL_RW_ENTRY(PROXY_ARP, "proxy_arp"),
> +	DEVINET_SYSCTL_RW_ENTRY(MEDIUM_ID, "medium_id"),
> +	DEVINET_SYSCTL_RW_ENTRY(BOOTP_RELAY, "bootp_relay"),
> +	DEVINET_SYSCTL_RW_ENTRY(LOG_MARTIANS, "log_martians"),
> +	DEVINET_SYSCTL_RW_ENTRY(TAG, "tag"),
> +	DEVINET_SYSCTL_RW_ENTRY(ARPFILTER, "arp_filter"),
> +	DEVINET_SYSCTL_RW_ENTRY(ARP_ANNOUNCE, "arp_announce"),
> +	DEVINET_SYSCTL_RW_ENTRY(ARP_IGNORE, "arp_ignore"),
> +	DEVINET_SYSCTL_RW_ENTRY(ARP_ACCEPT, "arp_accept"),
> +	DEVINET_SYSCTL_RW_ENTRY(ARP_NOTIFY, "arp_notify"),
> +	DEVINET_SYSCTL_RW_ENTRY(PROXY_ARP_PVLAN, "proxy_arp_pvlan"),
> +
> +	DEVINET_SYSCTL_FLUSHING_ENTRY(NOXFRM, "disable_xfrm"),
> +	DEVINET_SYSCTL_FLUSHING_ENTRY(NOPOLICY, "disable_policy"),
> +	DEVINET_SYSCTL_FLUSHING_ENTRY(FORCE_IGMP_VERSION,
> +				      "force_igmp_version"),
> +	DEVINET_SYSCTL_FLUSHING_ENTRY(PROMOTE_SECONDARIES,
> +				      "promote_secondaries"),
> +	{ }
>  };
>  
>  static int __devinet_sysctl_register(struct net *net, char *dev_name,
> -					struct ipv4_devconf *p)
> +				     struct ipv4_devconf *cnf)
>  {
> -	int i;
> -	struct devinet_sysctl_table *t;
> +	struct devinet_sysctl *t = &cnf->devinet_sysctl;
>  
>  #define DEVINET_CTL_PATH_DEV	3
>  
> @@ -1524,16 +1606,6 @@ static int __devinet_sysctl_register(struct net *net, char *dev_name,
>  		{ },
>  	};
>  
> -	t = kmemdup(&devinet_sysctl, sizeof(*t), GFP_KERNEL);
> -	if (!t)
> -		goto out;
> -
> -	for (i = 0; i < ARRAY_SIZE(t->devinet_vars) - 1; i++) {
> -		t->devinet_vars[i].data += (char *)p - (char *)&ipv4_devconf;
> -		t->devinet_vars[i].extra1 = p;
> -		t->devinet_vars[i].extra2 = net;
> -	}
> -
>  	/*
>  	 * Make a copy of dev_name, because '.procname' is regarded as const
>  	 * by sysctl and we wouldn't want anyone to change it under our feet
> @@ -1541,37 +1613,32 @@ static int __devinet_sysctl_register(struct net *net, char *dev_name,
>  	 */
>  	t->dev_name = kstrdup(dev_name, GFP_KERNEL);
>  	if (!t->dev_name)
> -		goto free;
> +		goto out;
>  
>  	devinet_ctl_path[DEVINET_CTL_PATH_DEV].procname = t->dev_name;
>  
> -	t->sysctl_header = register_net_sysctl_table(net, devinet_ctl_path,
> -			t->devinet_vars);
> +	t->sysctl_header = register_net_sysctl_table_pathdata(net,
> +			 devinet_ctl_path, ipv4_devinet_sysctl_table, net);
>  	if (!t->sysctl_header)
>  		goto free_procname;
>  
> -	p->sysctl = t;
>  	return 0;
>  
>  free_procname:
>  	kfree(t->dev_name);
> -free:
> -	kfree(t);
>  out:
>  	return -ENOBUFS;
>  }
>  
>  static void __devinet_sysctl_unregister(struct ipv4_devconf *cnf)
>  {
> -	struct devinet_sysctl_table *t = cnf->sysctl;
> +	struct devinet_sysctl *t = &cnf->devinet_sysctl;
>  
>  	if (t == NULL)
>  		return;
>  
> -	cnf->sysctl = NULL;
>  	unregister_sysctl_table(t->sysctl_header);
>  	kfree(t->dev_name);
> -	kfree(t);
>  }
>  
>  static void devinet_sysctl_register(struct in_device *idev)

^ permalink raw reply

* [PATCH] sis900: Fix mem leak in sis900_rx error path
From: Jesper Juhl @ 2011-02-05 20:41 UTC (permalink / raw)
  To: Daniele Venzano; +Cc: netdev, linux-kernel

Fix memory leak in error path of sis900_rx(). If we don't do this we'll 
leak the skb we dev_alloc_skb()'ed just a few lines above when the 
variable goes out of scope.

Signed-off-by: Jesper Juhl <jj@chaosbits.net>
---
 sis900.c |    1 +
 1 file changed, 1 insertion(+)

diff --git a/drivers/net/sis900.c b/drivers/net/sis900.c
index 5976d1d..640e368 100644
--- a/drivers/net/sis900.c
+++ b/drivers/net/sis900.c
@@ -1777,6 +1777,7 @@ static int sis900_rx(struct net_device *net_dev)
 					      "cur_rx:%4.4d, dirty_rx:%4.4d\n",
 					      net_dev->name, sis_priv->cur_rx,
 					      sis_priv->dirty_rx);
+				dev_kfree_skb(skb);
 				break;
 			}
 

-- 
Jesper Juhl <jj@chaosbits.net>            http://www.chaosbits.net/
Don't top-post http://www.catb.org/~esr/jargon/html/T/top-post.html
Plain text mails only, please.

^ permalink raw reply related

* Re: [net-2.6 PATCH 2/3] net: dcb: use _safe() version of list iterators
From: John Fastabend @ 2011-02-05 19:40 UTC (permalink / raw)
  To: David Miller; +Cc: netdev@vger.kernel.org
In-Reply-To: <20110131.204214.71133534.davem@davemloft.net>

On 1/31/2011 8:42 PM, David Miller wrote:
> From: John Fastabend <john.r.fastabend@intel.com>
> Date: Mon, 31 Jan 2011 14:00:54 -0800
> 
>> Use _safe() version of list iterator macros in dcb_setapp().
>>
>> Signed-off-by: John Fastabend <john.r.fastabend@intel.com>
> 
> Why?  It's unnecessary overhead, since we always branch to "out", and
> therefore out of the list traversal loop, any time we list_del()
> something on the list.

Of course you are right there is no reason for this. Thanks.

^ permalink raw reply

* Re: [net-2.6 PATCH 1/3] net: dcb: match dcb_app protocol field with 802.1Qaz spec
From: John Fastabend @ 2011-02-05 19:39 UTC (permalink / raw)
  To: David Miller; +Cc: netdev@vger.kernel.org
In-Reply-To: <20110131.204104.226756946.davem@davemloft.net>

On 1/31/2011 8:41 PM, David Miller wrote:
> From: John Fastabend <john.r.fastabend@intel.com>
> Date: Mon, 31 Jan 2011 14:00:49 -0800
> 
>> The dcb_app protocol field is a __u32 however the 802.1Qaz
>> specification defines it as a 16 bit field. This patch brings
>> the structure inline with the spec making it a __u16.
>>
>> Signed-off-by: John Fastabend <john.r.fastabend@intel.com>
>  ...
>> @@ -101,7 +101,7 @@ struct ieee_pfc {
>>   */
>>  struct dcb_app {
>>  	__u8	selector;
>> -	__u32	protocol;
>> +	__u16	protocol;
>>  	__u8	priority;
>>  };
>>  
> 
> If we're going to do this, please fix this wasteful structure
> layout.  Put the "protocol" either first, or last, so that the
> structure size is 4 bytes, rather than something like 8.

OK I will fix this. Thanks

^ permalink raw reply

* Re: 2.6.37 regression: adding main interface to a bridge breaks vlan interface RX
From: chriss @ 2011-02-05 15:34 UTC (permalink / raw)
  To: netdev
In-Reply-To: <201101241625.45367.maciej.rutecki@gmail.com>

Maciej Rutecki <maciej.rutecki <at> gmail.com> writes:

> 
> On niedziela, 23 stycznia 2011 o 22:29:02 Jesse Gross wrote:
> > On Sun, Jan 23, 2011 at 9:45 AM, Maciej Rutecki
> > 
> > <maciej.rutecki <at> gmail.com> wrote:
> > > I created a Bugzilla entry at
> > > https://bugzilla.kernel.org/show_bug.cgi?id=27432
> > > for your bug report, please add your address to the CC list in there,
> > > thanks!
> > 
> > This isn't a bug - the change resolved behavior that varied depending
> > on what NIC was in use.
> 
> Thanks for the update. Closing.
> 
> Regards


Hi

How am i supposed to put my eth to a bridge and have a seprate vlan besides that
bridge?

regards


^ permalink raw reply

* Re: [PATCH 0/5] net: sysctl: share ipv4/ipv6 sysctl tables
From: Lucian Adrian Grijincu @ 2011-02-05 14:59 UTC (permalink / raw)
  To: Alexey Dobriyan
  Cc: linux-kernel, netdev, Eric W. Biederman, Eric Dumazet,
	David S. Miller, Octavian Purdila
In-Reply-To: <20110205142648.GA9814@p183.telecom.by>

On Sat, Feb 5, 2011 at 4:26 PM, Alexey Dobriyan <adobriyan@gmail.com> wrote:
>> I'm not sure what I have to do to pass the name of a device (e.g.
>> "eth0") instead of "default" but at least "default" and "all" work and
>> have valid dentries.
>
> You do ->parent->procname.
>
> But, but you removed parent.


To be more exact I do:
  const char *dev_name = filp->f_path.dentry->d_parent->d_name.name;


If the sysctl table is shared between all network devices, the last
registered node will set the ->parent.

So accessing /proc/sys/net/ipv4/conf/$DEVNAME/$CTL will access $CTL
for the last network device registered not for $DEVNAME.

-- 
 .
..: Lucian

^ permalink raw reply

* Re: [PATCH 0/5] net: sysctl: share ipv4/ipv6 sysctl tables
From: Alexey Dobriyan @ 2011-02-05 14:26 UTC (permalink / raw)
  To: Lucian Adrian Grijincu
  Cc: linux-kernel, netdev, Eric W. Biederman, Eric Dumazet,
	David S. Miller, Octavian Purdila
In-Reply-To: <AANLkTik=a3NmibvYM6NxvqCiSiaE0oUFNtRaqn4+g_+D@mail.gmail.com>

On Fri, Feb 04, 2011 at 05:59:24PM +0200, Lucian Adrian Grijincu wrote:
> On Fri, Feb 4, 2011 at 12:49 PM, Alexey Dobriyan <adobriyan@gmail.com> wrote:
> >> Finally share the leaf sysctl tables for ipv4/ipv6:
> >>
> >>  [PATCH 4/5] ipv4: share sysctl net/ipv4/conf/DEVNAME/ tables
> >>  [PATCH 5/5] ipv6: share sysctl net/ipv6/conf/DEVNAME/ tables
> >
> > Meh.
> >
> > First you remove ->parent, then heroically pass "struct file *"
> > to sysctl handlers which duplicates all information already passed
> > and brings dcache into picture.
> >
> > Binary sysctl rewrite confused you into thinking that d_name.name
> > is the way, but it isn't.
> > For binary sysctl(2) you wouldn't get d_name.name.
> 
> 
> Are you really sure?
> 
> I ran this code on a machine with and without these patches. It seems
> to work fine.
> 
> It reads the value from /proc/sys/net/ipv4/conf/default/tag and writes 42 back.
> 
> I'm not sure what I have to do to pass the name of a device (e.g.
> "eth0") instead of "default" but at least "default" and "all" work and
> have valid dentries.

You do ->parent->procname.

But, but you removed parent.

^ permalink raw reply

* Re: [PATCH] tcp: Increase the initial congestion window to 10.
From: Gerrit Renker @ 2011-02-05 13:58 UTC (permalink / raw)
  To: Leandro Melo de Sales; +Cc: netdev, dccp
In-Reply-To: <AANLkTimuYxHd5AtGSB2+wg2JE7LEKPjGssoQZuOWYrw-@mail.gmail.com>

Leandro,
| >  include/net/tcp.h      |   12 +++---------
| >  net/dccp/ccids/ccid2.c |    9 +++++++++
|
David's change only affects CCID-2, CCID-3/4 remain unaffected,
they use rfc3390_initial_rate() (which does almost the same).
 
|     I don't think this change will make sense for DCCP, once IW10 is
| for the cases of short-lived flows. DCCP is used on scenarios for
| multimedia flows, which are, in general, long-lived flows. So, IMO the
| way how we calculate IW for DCCP is appropriate, at least considering
| a quick answer. 
I agree with you, and also vote to eventually bring CCID-2 on a par with
the state of art in TCP. Before we can do this, the CCID-2 implementation
needs some work (as per separate thread with Samuel Jero).

| In fact, nowadays we need better congestion control algorithms for DCCP,
| and in this sense we are working on adapt TCP Cubic for DCCP as a CCID,
| and also we started some work to make DCCP support TCP pluggable
| mechanism , which will allow us to use TCP congestion control
| algorithms in DCCP.
This is very good news and am very much looking forward to the new approach.


| DCCP should calculate its IW as specified in RFC3390 rather than set
| it to IW10. For the moment, I understand that for DCCP, we have to 
| discuss more about this in a separated thread.
Agree that we should keep an eye on this - perhaps too early to turn it into a
should. Networking speeds are growing, and many of the simulations were based
on TCP Reno which stems from the 10 Mbit ethernet era.

^ 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