* 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
page: next (older) | prev (newer) | latest
- recent:[subjects (threaded)|topics (new)|topics (active)]
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox