* linux-next: manual merge of the net tree with the net-current tree
From: Stephen Rothwell @ 2009-11-24 3:11 UTC (permalink / raw)
To: David Miller, netdev; +Cc: linux-next, linux-kernel, Bruce Allan, Jeff Kirsher
Hi all,
Today's linux-next merge of the net tree got a conflict in
drivers/net/e1000e/ich8lan.c between commit
818f33313caab9be2a10458500dbed4a88c1b334 ("e1000e: do not initiate
autonegotiation during OEM configuration") from the net-current tree and
commit 94d8186a693284344ee5cb9734086c7a2370241a ("e1000e: cleanup ops
function pointers") from the net tree.
Just context changes. I fixed it up (see below) and can carry the fix for
a while.
--
Cheers,
Stephen Rothwell sfr@canb.auug.org.au
diff --cc drivers/net/e1000e/ich8lan.c
index eff3f47,568bb25..0000000
--- a/drivers/net/e1000e/ich8lan.c
+++ b/drivers/net/e1000e/ich8lan.c
@@@ -1118,12 -1110,11 +1110,12 @@@ static s32 e1000_oem_bits_config_ich8la
oem_reg |= HV_OEM_BITS_LPLU;
}
/* Restart auto-neg to activate the bits */
- oem_reg |= HV_OEM_BITS_RESTART_AN;
+ if (!e1000_check_reset_block(hw))
+ oem_reg |= HV_OEM_BITS_RESTART_AN;
- ret_val = hw->phy.ops.write_phy_reg_locked(hw, HV_OEM_BITS, oem_reg);
+ ret_val = hw->phy.ops.write_reg_locked(hw, HV_OEM_BITS, oem_reg);
out:
- hw->phy.ops.release_phy(hw);
+ hw->phy.ops.release(hw);
return ret_val;
}
^ permalink raw reply
* [PATCH 17/17] sfc: Log interrupt and reset type names, not numbers
From: Ben Hutchings @ 2009-11-24 2:08 UTC (permalink / raw)
To: David Miller; +Cc: netdev, linux-net-drivers
Define name tables for these enumerations in a similar way as for
loopback. Move the loopback name table together with them.
Signed-off-by: Ben Hutchings <bhutchings@solarflare.com>
---
drivers/net/sfc/efx.c | 51 +++++++++++++++++++++++++++++++++++++++--
drivers/net/sfc/enum.h | 6 -----
drivers/net/sfc/ethtool.c | 15 +-----------
drivers/net/sfc/falcon.c | 2 +-
drivers/net/sfc/net_driver.h | 19 ++++++++++++++-
drivers/net/sfc/selftest.c | 4 +-
6 files changed, 69 insertions(+), 28 deletions(-)
diff --git a/drivers/net/sfc/efx.c b/drivers/net/sfc/efx.c
index cb78995..4787faa 100644
--- a/drivers/net/sfc/efx.c
+++ b/drivers/net/sfc/efx.c
@@ -25,6 +25,50 @@
#include "mdio_10g.h"
#include "falcon.h"
+/**************************************************************************
+ *
+ * Type name strings
+ *
+ **************************************************************************
+ */
+
+/* Loopback mode names (see LOOPBACK_MODE()) */
+const unsigned int efx_loopback_mode_max = LOOPBACK_MAX;
+const char *efx_loopback_mode_names[] = {
+ [LOOPBACK_NONE] = "NONE",
+ [LOOPBACK_GMAC] = "GMAC",
+ [LOOPBACK_XGMII] = "XGMII",
+ [LOOPBACK_XGXS] = "XGXS",
+ [LOOPBACK_XAUI] = "XAUI",
+ [LOOPBACK_GPHY] = "GPHY",
+ [LOOPBACK_PHYXS] = "PHYXS",
+ [LOOPBACK_PCS] = "PCS",
+ [LOOPBACK_PMAPMD] = "PMA/PMD",
+ [LOOPBACK_NETWORK] = "NETWORK",
+};
+
+/* Interrupt mode names (see INT_MODE())) */
+const unsigned int efx_interrupt_mode_max = EFX_INT_MODE_MAX;
+const char *efx_interrupt_mode_names[] = {
+ [EFX_INT_MODE_MSIX] = "MSI-X",
+ [EFX_INT_MODE_MSI] = "MSI",
+ [EFX_INT_MODE_LEGACY] = "legacy",
+};
+
+const unsigned int efx_reset_type_max = RESET_TYPE_MAX;
+const char *efx_reset_type_names[] = {
+ [RESET_TYPE_INVISIBLE] = "INVISIBLE",
+ [RESET_TYPE_ALL] = "ALL",
+ [RESET_TYPE_WORLD] = "WORLD",
+ [RESET_TYPE_DISABLE] = "DISABLE",
+ [RESET_TYPE_TX_WATCHDOG] = "TX_WATCHDOG",
+ [RESET_TYPE_INT_ERROR] = "INT_ERROR",
+ [RESET_TYPE_RX_RECOVERY] = "RX_RECOVERY",
+ [RESET_TYPE_RX_DESC_FETCH] = "RX_DESC_FETCH",
+ [RESET_TYPE_TX_DESC_FETCH] = "TX_DESC_FETCH",
+ [RESET_TYPE_TX_SKIP] = "TX_SKIP",
+};
+
#define EFX_MAX_MTU (9 * 1024)
/* RX slow fill workqueue. If memory allocation fails in the fast path,
@@ -1772,7 +1816,7 @@ static int efx_reset(struct efx_nic *efx)
goto out_unlock;
}
- EFX_INFO(efx, "resetting (%d)\n", method);
+ EFX_INFO(efx, "resetting (%s)\n", RESET_TYPE(method));
efx_reset_down(efx, method, &ecmd);
@@ -1851,9 +1895,10 @@ void efx_schedule_reset(struct efx_nic *efx, enum reset_type type)
}
if (method != type)
- EFX_LOG(efx, "scheduling reset (%d:%d)\n", type, method);
+ EFX_LOG(efx, "scheduling %s reset for %s\n",
+ RESET_TYPE(method), RESET_TYPE(type));
else
- EFX_LOG(efx, "scheduling reset (%d)\n", method);
+ EFX_LOG(efx, "scheduling %s reset\n", RESET_TYPE(method));
efx->reset_pending = method;
diff --git a/drivers/net/sfc/enum.h b/drivers/net/sfc/enum.h
index 60cbc6e..fcd14b7 100644
--- a/drivers/net/sfc/enum.h
+++ b/drivers/net/sfc/enum.h
@@ -40,12 +40,6 @@ enum efx_loopback_mode {
#define LOOPBACK_TEST_MAX LOOPBACK_PMAPMD
-extern const char *efx_loopback_mode_names[];
-#define LOOPBACK_MODE_NAME(mode) \
- STRING_TABLE_LOOKUP(mode, efx_loopback_mode)
-#define LOOPBACK_MODE(efx) \
- LOOPBACK_MODE_NAME(efx->loopback_mode)
-
/* These loopbacks occur within the controller */
#define LOOPBACKS_INTERNAL ((1 << LOOPBACK_GMAC) | \
(1 << LOOPBACK_XGMII)| \
diff --git a/drivers/net/sfc/ethtool.c b/drivers/net/sfc/ethtool.c
index e8afd78..d8915b9 100644
--- a/drivers/net/sfc/ethtool.c
+++ b/drivers/net/sfc/ethtool.c
@@ -20,19 +20,6 @@
#include "spi.h"
#include "mdio_10g.h"
-const char *efx_loopback_mode_names[] = {
- [LOOPBACK_NONE] = "NONE",
- [LOOPBACK_GMAC] = "GMAC",
- [LOOPBACK_XGMII] = "XGMII",
- [LOOPBACK_XGXS] = "XGXS",
- [LOOPBACK_XAUI] = "XAUI",
- [LOOPBACK_GPHY] = "GPHY",
- [LOOPBACK_PHYXS] = "PHYXS",
- [LOOPBACK_PCS] = "PCS",
- [LOOPBACK_PMAPMD] = "PMA/PMD",
- [LOOPBACK_NETWORK] = "NETWORK",
-};
-
struct ethtool_string {
char name[ETH_GSTRING_LEN];
};
@@ -290,7 +277,7 @@ static void efx_fill_test(unsigned int test_index,
#define EFX_TX_QUEUE_NAME(_tx_queue) "txq%d", _tx_queue->queue
#define EFX_RX_QUEUE_NAME(_rx_queue) "rxq%d", _rx_queue->queue
#define EFX_LOOPBACK_NAME(_mode, _counter) \
- "loopback.%s." _counter, LOOPBACK_MODE_NAME(mode)
+ "loopback.%s." _counter, STRING_TABLE_LOOKUP(_mode, efx_loopback_mode)
/**
* efx_fill_loopback_test - fill in a block of loopback self-test entries
diff --git a/drivers/net/sfc/falcon.c b/drivers/net/sfc/falcon.c
index 6eee4b7..41a321b 100644
--- a/drivers/net/sfc/falcon.c
+++ b/drivers/net/sfc/falcon.c
@@ -2485,7 +2485,7 @@ int falcon_reset_hw(struct efx_nic *efx, enum reset_type method)
efx_oword_t glb_ctl_reg_ker;
int rc;
- EFX_LOG(efx, "performing hardware reset (%d)\n", method);
+ EFX_LOG(efx, "performing %s hardware reset\n", RESET_TYPE(method));
/* Initiate device reset */
if (method == RESET_TYPE_WORLD) {
diff --git a/drivers/net/sfc/net_driver.h b/drivers/net/sfc/net_driver.h
index f2df324..ac808d5 100644
--- a/drivers/net/sfc/net_driver.h
+++ b/drivers/net/sfc/net_driver.h
@@ -394,8 +394,23 @@ enum efx_led_mode {
EFX_LED_DEFAULT = 2
};
-#define STRING_TABLE_LOOKUP(val, member) \
- member ## _names[val]
+#define STRING_TABLE_LOOKUP(val, member) \
+ ((val) < member ## _max) ? member ## _names[val] : "(invalid)"
+
+extern const char *efx_loopback_mode_names[];
+extern const unsigned int efx_loopback_mode_max;
+#define LOOPBACK_MODE(efx) \
+ STRING_TABLE_LOOKUP((efx)->loopback_mode, efx_loopback_mode)
+
+extern const char *efx_interrupt_mode_names[];
+extern const unsigned int efx_interrupt_mode_max;
+#define INT_MODE(efx) \
+ STRING_TABLE_LOOKUP(efx->interrupt_mode, efx_interrupt_mode)
+
+extern const char *efx_reset_type_names[];
+extern const unsigned int efx_reset_type_max;
+#define RESET_TYPE(type) \
+ STRING_TABLE_LOOKUP(type, efx_reset_type)
enum efx_int_mode {
/* Be careful if altering to correct macro below */
diff --git a/drivers/net/sfc/selftest.c b/drivers/net/sfc/selftest.c
index afac1cc..63ff295 100644
--- a/drivers/net/sfc/selftest.c
+++ b/drivers/net/sfc/selftest.c
@@ -175,8 +175,8 @@ static int efx_test_interrupts(struct efx_nic *efx,
return -ETIMEDOUT;
success:
- EFX_LOG(efx, "test interrupt (mode %d) seen on CPU%d\n",
- efx->interrupt_mode, efx->last_irq_cpu);
+ EFX_LOG(efx, "%s test interrupt seen on CPU%d\n", INT_MODE(efx),
+ efx->last_irq_cpu);
tests->interrupt = 1;
return 0;
}
--
Ben Hutchings, Senior Software Engineer, Solarflare Communications
Not speaking for my employer; that's the marketing department's job.
They asked us to note that Solarflare product names are trademarked.
^ permalink raw reply related
* [PATCH 16/17] sfc: Combine high-level header files
From: Ben Hutchings @ 2009-11-24 2:07 UTC (permalink / raw)
To: David Miller; +Cc: netdev, linux-net-drivers
All files that include ethtool.h, rx.h or tx.h are also including
efx.h, and there is no good reason to separate out the few
declarations they contain. Therefore fold them into efx.h.
Signed-off-by: Ben Hutchings <bhutchings@solarflare.com>
---
drivers/net/sfc/efx.c | 3 ---
drivers/net/sfc/efx.h | 27 +++++++++++++++++++++++++--
drivers/net/sfc/ethtool.c | 1 -
drivers/net/sfc/ethtool.h | 27 ---------------------------
drivers/net/sfc/rx.c | 1 -
drivers/net/sfc/rx.h | 26 --------------------------
drivers/net/sfc/selftest.c | 1 -
drivers/net/sfc/tx.c | 1 -
drivers/net/sfc/tx.h | 25 -------------------------
9 files changed, 25 insertions(+), 87 deletions(-)
delete mode 100644 drivers/net/sfc/ethtool.h
delete mode 100644 drivers/net/sfc/rx.h
delete mode 100644 drivers/net/sfc/tx.h
diff --git a/drivers/net/sfc/efx.c b/drivers/net/sfc/efx.c
index ea31141..cb78995 100644
--- a/drivers/net/sfc/efx.c
+++ b/drivers/net/sfc/efx.c
@@ -21,9 +21,6 @@
#include <linux/ethtool.h>
#include <linux/topology.h>
#include "net_driver.h"
-#include "ethtool.h"
-#include "tx.h"
-#include "rx.h"
#include "efx.h"
#include "mdio_10g.h"
#include "falcon.h"
diff --git a/drivers/net/sfc/efx.h b/drivers/net/sfc/efx.h
index 9d83322..3497b03 100644
--- a/drivers/net/sfc/efx.h
+++ b/drivers/net/sfc/efx.h
@@ -23,8 +23,15 @@
#define EFX_MEM_BAR 2
/* TX */
-extern netdev_tx_t efx_enqueue_skb(struct efx_tx_queue *tx_queue,
- struct sk_buff *skb);
+extern int efx_probe_tx_queue(struct efx_tx_queue *tx_queue);
+extern void efx_remove_tx_queue(struct efx_tx_queue *tx_queue);
+extern void efx_init_tx_queue(struct efx_tx_queue *tx_queue);
+extern void efx_fini_tx_queue(struct efx_tx_queue *tx_queue);
+extern void efx_release_tx_buffers(struct efx_tx_queue *tx_queue);
+extern netdev_tx_t
+efx_hard_start_xmit(struct sk_buff *skb, struct net_device *net_dev);
+extern netdev_tx_t
+efx_enqueue_skb(struct efx_tx_queue *tx_queue, struct sk_buff *skb);
extern void efx_xmit_done(struct efx_tx_queue *tx_queue, unsigned int index);
extern void efx_stop_queue(struct efx_nic *efx);
extern void efx_wake_queue(struct efx_nic *efx);
@@ -32,6 +39,15 @@ extern void efx_wake_queue(struct efx_nic *efx);
#define EFX_TXQ_MASK (EFX_TXQ_SIZE - 1)
/* RX */
+extern int efx_probe_rx_queue(struct efx_rx_queue *rx_queue);
+extern void efx_remove_rx_queue(struct efx_rx_queue *rx_queue);
+extern void efx_init_rx_queue(struct efx_rx_queue *rx_queue);
+extern void efx_fini_rx_queue(struct efx_rx_queue *rx_queue);
+extern void efx_rx_strategy(struct efx_channel *channel);
+extern void efx_fast_push_rx_descriptors(struct efx_rx_queue *rx_queue);
+extern void efx_rx_work(struct work_struct *data);
+extern void __efx_rx_packet(struct efx_channel *channel,
+ struct efx_rx_buffer *rx_buf, bool checksummed);
extern void efx_rx_packet(struct efx_rx_queue *rx_queue, unsigned int index,
unsigned int len, bool checksummed, bool discard);
extern void efx_schedule_slow_fill(struct efx_rx_queue *rx_queue, int delay);
@@ -50,6 +66,13 @@ extern void efx_stats_enable(struct efx_nic *efx);
extern void efx_reconfigure_port(struct efx_nic *efx);
extern void __efx_reconfigure_port(struct efx_nic *efx);
+/* Ethtool support */
+extern int efx_ethtool_get_settings(struct net_device *net_dev,
+ struct ethtool_cmd *ecmd);
+extern int efx_ethtool_set_settings(struct net_device *net_dev,
+ struct ethtool_cmd *ecmd);
+extern const struct ethtool_ops efx_ethtool_ops;
+
/* Reset handling */
extern void efx_reset_down(struct efx_nic *efx, enum reset_type method,
struct ethtool_cmd *ecmd);
diff --git a/drivers/net/sfc/ethtool.c b/drivers/net/sfc/ethtool.c
index eb12f20..e8afd78 100644
--- a/drivers/net/sfc/ethtool.c
+++ b/drivers/net/sfc/ethtool.c
@@ -16,7 +16,6 @@
#include "workarounds.h"
#include "selftest.h"
#include "efx.h"
-#include "ethtool.h"
#include "falcon.h"
#include "spi.h"
#include "mdio_10g.h"
diff --git a/drivers/net/sfc/ethtool.h b/drivers/net/sfc/ethtool.h
deleted file mode 100644
index 295ead4..0000000
--- a/drivers/net/sfc/ethtool.h
+++ /dev/null
@@ -1,27 +0,0 @@
-/****************************************************************************
- * Driver for Solarflare Solarstorm network controllers and boards
- * Copyright 2005 Fen Systems Ltd.
- * Copyright 2006 Solarflare Communications Inc.
- *
- * This program is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 as published
- * by the Free Software Foundation, incorporated herein by reference.
- */
-
-#ifndef EFX_ETHTOOL_H
-#define EFX_ETHTOOL_H
-
-#include "net_driver.h"
-
-/*
- * Ethtool support
- */
-
-extern int efx_ethtool_get_settings(struct net_device *net_dev,
- struct ethtool_cmd *ecmd);
-extern int efx_ethtool_set_settings(struct net_device *net_dev,
- struct ethtool_cmd *ecmd);
-
-extern const struct ethtool_ops efx_ethtool_ops;
-
-#endif /* EFX_ETHTOOL_H */
diff --git a/drivers/net/sfc/rx.c b/drivers/net/sfc/rx.c
index 9f22d15..accf055 100644
--- a/drivers/net/sfc/rx.c
+++ b/drivers/net/sfc/rx.c
@@ -16,7 +16,6 @@
#include <net/ip.h>
#include <net/checksum.h>
#include "net_driver.h"
-#include "rx.h"
#include "efx.h"
#include "falcon.h"
#include "selftest.h"
diff --git a/drivers/net/sfc/rx.h b/drivers/net/sfc/rx.h
deleted file mode 100644
index 42ee755..0000000
--- a/drivers/net/sfc/rx.h
+++ /dev/null
@@ -1,26 +0,0 @@
-/****************************************************************************
- * Driver for Solarflare Solarstorm network controllers and boards
- * Copyright 2006 Solarflare Communications Inc.
- *
- * This program is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 as published
- * by the Free Software Foundation, incorporated herein by reference.
- */
-
-#ifndef EFX_RX_H
-#define EFX_RX_H
-
-#include "net_driver.h"
-
-int efx_probe_rx_queue(struct efx_rx_queue *rx_queue);
-void efx_remove_rx_queue(struct efx_rx_queue *rx_queue);
-void efx_init_rx_queue(struct efx_rx_queue *rx_queue);
-void efx_fini_rx_queue(struct efx_rx_queue *rx_queue);
-
-void efx_rx_strategy(struct efx_channel *channel);
-void efx_fast_push_rx_descriptors(struct efx_rx_queue *rx_queue);
-void efx_rx_work(struct work_struct *data);
-void __efx_rx_packet(struct efx_channel *channel,
- struct efx_rx_buffer *rx_buf, bool checksummed);
-
-#endif /* EFX_RX_H */
diff --git a/drivers/net/sfc/selftest.c b/drivers/net/sfc/selftest.c
index eab8c2e..afac1cc 100644
--- a/drivers/net/sfc/selftest.c
+++ b/drivers/net/sfc/selftest.c
@@ -20,7 +20,6 @@
#include <linux/rtnetlink.h>
#include <asm/io.h>
#include "net_driver.h"
-#include "ethtool.h"
#include "efx.h"
#include "falcon.h"
#include "selftest.h"
diff --git a/drivers/net/sfc/tx.c b/drivers/net/sfc/tx.c
index a5e541d..c54fa30 100644
--- a/drivers/net/sfc/tx.c
+++ b/drivers/net/sfc/tx.c
@@ -15,7 +15,6 @@
#include <linux/if_ether.h>
#include <linux/highmem.h>
#include "net_driver.h"
-#include "tx.h"
#include "efx.h"
#include "falcon.h"
#include "workarounds.h"
diff --git a/drivers/net/sfc/tx.h b/drivers/net/sfc/tx.h
deleted file mode 100644
index e367896..0000000
--- a/drivers/net/sfc/tx.h
+++ /dev/null
@@ -1,25 +0,0 @@
-/****************************************************************************
- * Driver for Solarflare Solarstorm network controllers and boards
- * Copyright 2006 Fen Systems Ltd.
- * Copyright 2006-2008 Solarflare Communications Inc.
- *
- * This program is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 as published
- * by the Free Software Foundation, incorporated herein by reference.
- */
-
-#ifndef EFX_TX_H
-#define EFX_TX_H
-
-#include "net_driver.h"
-
-int efx_probe_tx_queue(struct efx_tx_queue *tx_queue);
-void efx_remove_tx_queue(struct efx_tx_queue *tx_queue);
-void efx_init_tx_queue(struct efx_tx_queue *tx_queue);
-void efx_fini_tx_queue(struct efx_tx_queue *tx_queue);
-
-netdev_tx_t efx_hard_start_xmit(struct sk_buff *skb,
- struct net_device *net_dev);
-void efx_release_tx_buffers(struct efx_tx_queue *tx_queue);
-
-#endif /* EFX_TX_H */
--
Ben Hutchings, Senior Software Engineer, Solarflare Communications
Not speaking for my employer; that's the marketing department's job.
They asked us to note that Solarflare product names are trademarked.
^ permalink raw reply related
* [PATCH 15/17] sfc: Remove redundant efx_xmit() function
From: Ben Hutchings @ 2009-11-24 2:07 UTC (permalink / raw)
To: David Miller; +Cc: netdev, linux-net-drivers
Signed-off-by: Ben Hutchings <bhutchings@solarflare.com>
---
drivers/net/sfc/efx.h | 5 ++---
drivers/net/sfc/selftest.c | 2 +-
drivers/net/sfc/tx.c | 26 +++++---------------------
3 files changed, 8 insertions(+), 25 deletions(-)
diff --git a/drivers/net/sfc/efx.h b/drivers/net/sfc/efx.h
index 6f46394..9d83322 100644
--- a/drivers/net/sfc/efx.h
+++ b/drivers/net/sfc/efx.h
@@ -23,9 +23,8 @@
#define EFX_MEM_BAR 2
/* TX */
-extern netdev_tx_t efx_xmit(struct efx_nic *efx,
- struct efx_tx_queue *tx_queue,
- struct sk_buff *skb);
+extern netdev_tx_t efx_enqueue_skb(struct efx_tx_queue *tx_queue,
+ struct sk_buff *skb);
extern void efx_xmit_done(struct efx_tx_queue *tx_queue, unsigned int index);
extern void efx_stop_queue(struct efx_nic *efx);
extern void efx_wake_queue(struct efx_nic *efx);
diff --git a/drivers/net/sfc/selftest.c b/drivers/net/sfc/selftest.c
index 70eb5f1..eab8c2e 100644
--- a/drivers/net/sfc/selftest.c
+++ b/drivers/net/sfc/selftest.c
@@ -425,7 +425,7 @@ static int efx_begin_loopback(struct efx_tx_queue *tx_queue)
if (efx_dev_registered(efx))
netif_tx_lock_bh(efx->net_dev);
- rc = efx_xmit(efx, tx_queue, skb);
+ rc = efx_enqueue_skb(tx_queue, skb);
if (efx_dev_registered(efx))
netif_tx_unlock_bh(efx->net_dev);
diff --git a/drivers/net/sfc/tx.c b/drivers/net/sfc/tx.c
index e11632b..a5e541d 100644
--- a/drivers/net/sfc/tx.c
+++ b/drivers/net/sfc/tx.c
@@ -152,11 +152,13 @@ efx_max_tx_len(struct efx_nic *efx, dma_addr_t dma_addr)
* If any DMA mapping fails, any mapped fragments will be unmapped,
* the queue's insert pointer will be restored to its original value.
*
+ * This function is split out from efx_hard_start_xmit to allow the
+ * loopback test to direct packets via specific TX queues.
+ *
* Returns NETDEV_TX_OK or NETDEV_TX_BUSY
* You must hold netif_tx_lock() to call this function.
*/
-static netdev_tx_t efx_enqueue_skb(struct efx_tx_queue *tx_queue,
- struct sk_buff *skb)
+netdev_tx_t efx_enqueue_skb(struct efx_tx_queue *tx_queue, struct sk_buff *skb)
{
struct efx_nic *efx = tx_queue->efx;
struct pci_dev *pci_dev = efx->pci_dev;
@@ -352,24 +354,6 @@ static void efx_dequeue_buffers(struct efx_tx_queue *tx_queue,
}
}
-/* Initiate a packet transmission on the specified TX queue.
- * Note that returning anything other than NETDEV_TX_OK will cause the
- * OS to free the skb.
- *
- * This function is split out from efx_hard_start_xmit to allow the
- * loopback test to direct packets via specific TX queues. It is
- * therefore a non-static inline, so as not to penalise performance
- * for non-loopback transmissions.
- *
- * Context: netif_tx_lock held
- */
-inline netdev_tx_t efx_xmit(struct efx_nic *efx,
- struct efx_tx_queue *tx_queue, struct sk_buff *skb)
-{
- /* Map fragments for DMA and add to TX queue */
- return efx_enqueue_skb(tx_queue, skb);
-}
-
/* Initiate a packet transmission. We use one channel per CPU
* (sharing when we have more CPUs than channels). On Falcon, the TX
* completion events will be directed back to the CPU that transmitted
@@ -393,7 +377,7 @@ netdev_tx_t efx_hard_start_xmit(struct sk_buff *skb,
else
tx_queue = &efx->tx_queue[EFX_TX_QUEUE_NO_CSUM];
- return efx_xmit(efx, tx_queue, skb);
+ return efx_enqueue_skb(tx_queue, skb);
}
void efx_xmit_done(struct efx_tx_queue *tx_queue, unsigned int index)
--
Ben Hutchings, Senior Software Engineer, Solarflare Communications
Not speaking for my employer; that's the marketing department's job.
They asked us to note that Solarflare product names are trademarked.
^ permalink raw reply related
* [PATCH 14/17] sfc: Remove unnecessary casts to struct sk_buff *
From: Ben Hutchings @ 2009-11-24 2:06 UTC (permalink / raw)
To: David Miller; +Cc: netdev, linux-net-drivers
At some point these casts were used to remove const qualification, but
they are now unneeded.
Signed-off-by: Ben Hutchings <bhutchings@solarflare.com>
---
drivers/net/sfc/tx.c | 6 +++---
1 files changed, 3 insertions(+), 3 deletions(-)
diff --git a/drivers/net/sfc/tx.c b/drivers/net/sfc/tx.c
index 303919a..e11632b 100644
--- a/drivers/net/sfc/tx.c
+++ b/drivers/net/sfc/tx.c
@@ -173,7 +173,7 @@ static netdev_tx_t efx_enqueue_skb(struct efx_tx_queue *tx_queue,
EFX_BUG_ON_PARANOID(tx_queue->write_count != tx_queue->insert_count);
- if (skb_shinfo((struct sk_buff *)skb)->gso_size)
+ if (skb_shinfo(skb)->gso_size)
return efx_enqueue_skb_tso(tx_queue, skb);
/* Get size of the initial fragment */
@@ -287,7 +287,7 @@ static netdev_tx_t efx_enqueue_skb(struct efx_tx_queue *tx_queue,
skb_shinfo(skb)->nr_frags + 1);
/* Mark the packet as transmitted, and free the SKB ourselves */
- dev_kfree_skb_any((struct sk_buff *)skb);
+ dev_kfree_skb_any(skb);
goto unwind;
stop:
@@ -1102,7 +1102,7 @@ static int efx_enqueue_skb_tso(struct efx_tx_queue *tx_queue,
mem_err:
EFX_ERR(efx, "Out of memory for TSO headers, or PCI mapping error\n");
- dev_kfree_skb_any((struct sk_buff *)skb);
+ dev_kfree_skb_any(skb);
goto unwind;
stop:
--
Ben Hutchings, Senior Software Engineer, Solarflare Communications
Not speaking for my employer; that's the marketing department's job.
They asked us to note that Solarflare product names are trademarked.
^ permalink raw reply related
* [PATCH 13/17] sfc: Gather link state fields in struct efx_nic into new struct efx_link_state
From: Ben Hutchings @ 2009-11-24 2:06 UTC (permalink / raw)
To: David Miller; +Cc: netdev, linux-net-drivers
Signed-off-by: Ben Hutchings <bhutchings@solarflare.com>
---
drivers/net/sfc/efx.c | 12 +++++++-----
drivers/net/sfc/ethtool.c | 4 ++--
drivers/net/sfc/falcon.c | 21 +++++++++++----------
drivers/net/sfc/falcon_boards.c | 2 +-
drivers/net/sfc/falcon_gmac.c | 13 +++++++------
drivers/net/sfc/falcon_xmac.c | 8 ++++----
drivers/net/sfc/net_driver.h | 26 +++++++++++++++++---------
drivers/net/sfc/qt202x_phy.c | 11 ++++++-----
drivers/net/sfc/selftest.c | 2 +-
drivers/net/sfc/tenxpress.c | 22 ++++++++++++----------
10 files changed, 68 insertions(+), 53 deletions(-)
diff --git a/drivers/net/sfc/efx.c b/drivers/net/sfc/efx.c
index b913211..ea31141 100644
--- a/drivers/net/sfc/efx.c
+++ b/drivers/net/sfc/efx.c
@@ -543,6 +543,8 @@ void efx_schedule_slow_fill(struct efx_rx_queue *rx_queue, int delay)
*/
static void efx_link_status_changed(struct efx_nic *efx)
{
+ struct efx_link_state *link_state = &efx->link_state;
+
/* SFC Bug 5356: A net_dev notifier is registered, so we must ensure
* that no events are triggered between unregister_netdev() and the
* driver unloading. A more general condition is that NETDEV_CHANGE
@@ -555,19 +557,19 @@ static void efx_link_status_changed(struct efx_nic *efx)
return;
}
- if (efx->link_up != netif_carrier_ok(efx->net_dev)) {
+ if (link_state->up != netif_carrier_ok(efx->net_dev)) {
efx->n_link_state_changes++;
- if (efx->link_up)
+ if (link_state->up)
netif_carrier_on(efx->net_dev);
else
netif_carrier_off(efx->net_dev);
}
/* Status message for kernel log */
- if (efx->link_up) {
+ if (link_state->up) {
EFX_INFO(efx, "link up at %uMbps %s-duplex (MTU %d)%s\n",
- efx->link_speed, efx->link_fd ? "full" : "half",
+ link_state->speed, link_state->fd ? "full" : "half",
efx->net_dev->mtu,
(efx->promiscuous ? " [PROMISC]" : ""));
} else {
@@ -758,7 +760,7 @@ static void efx_fini_port(struct efx_nic *efx)
efx->phy_op->fini(efx);
efx->port_initialized = false;
- efx->link_up = false;
+ efx->link_state.up = false;
efx_link_status_changed(efx);
}
diff --git a/drivers/net/sfc/ethtool.c b/drivers/net/sfc/ethtool.c
index bb41532..eb12f20 100644
--- a/drivers/net/sfc/ethtool.c
+++ b/drivers/net/sfc/ethtool.c
@@ -539,7 +539,7 @@ static u32 efx_ethtool_get_link(struct net_device *net_dev)
{
struct efx_nic *efx = netdev_priv(net_dev);
- return efx->link_up;
+ return efx->link_state.up;
}
static int efx_ethtool_get_eeprom_len(struct net_device *net_dev)
@@ -699,7 +699,7 @@ static int efx_ethtool_set_pauseparam(struct net_device *net_dev,
if (EFX_WORKAROUND_11482(efx) && reset) {
if (falcon_rev(efx) >= FALCON_REV_B0) {
/* Recover by resetting the EM block */
- if (efx->link_up)
+ if (efx->link_state.up)
falcon_drain_tx_fifo(efx);
} else {
/* Schedule a reset to recover */
diff --git a/drivers/net/sfc/falcon.c b/drivers/net/sfc/falcon.c
index ff15b9d..6eee4b7 100644
--- a/drivers/net/sfc/falcon.c
+++ b/drivers/net/sfc/falcon.c
@@ -1905,7 +1905,7 @@ static int falcon_reset_macs(struct efx_nic *efx)
/* If we've reset the EM block and the link is up, then
* we'll have to kick the XAUI link so the PHY can recover */
- if (efx->link_up && EFX_IS10G(efx) && EFX_WORKAROUND_5147(efx))
+ if (efx->link_state.up && EFX_IS10G(efx) && EFX_WORKAROUND_5147(efx))
falcon_reset_xaui(efx);
return 0;
@@ -1939,17 +1939,18 @@ void falcon_deconfigure_mac_wrapper(struct efx_nic *efx)
EFX_SET_OWORD_FIELD(reg, FRF_BZ_RX_INGR_EN, 0);
efx_writeo(efx, ®, FR_AZ_RX_CFG);
- if (!efx->link_up)
+ if (!efx->link_state.up)
falcon_drain_tx_fifo(efx);
}
void falcon_reconfigure_mac_wrapper(struct efx_nic *efx)
{
+ struct efx_link_state *link_state = &efx->link_state;
efx_oword_t reg;
int link_speed;
bool tx_fc;
- switch (efx->link_speed) {
+ switch (link_state->speed) {
case 10000: link_speed = 3; break;
case 1000: link_speed = 2; break;
case 100: link_speed = 1; break;
@@ -1969,7 +1970,7 @@ void falcon_reconfigure_mac_wrapper(struct efx_nic *efx)
* discarded. */
if (falcon_rev(efx) >= FALCON_REV_B0) {
EFX_SET_OWORD_FIELD(reg, FRF_BB_TXFIFO_DRAIN_EN,
- !efx->link_up);
+ !link_state->up);
}
efx_writeo(efx, ®, FR_AB_MAC_CTRL);
@@ -1980,7 +1981,7 @@ void falcon_reconfigure_mac_wrapper(struct efx_nic *efx)
/* Transmission of pause frames when RX crosses the threshold is
* covered by RX_XOFF_MAC_EN and XM_TX_CFG_REG:XM_FCNTL.
* Action on receipt of pause frames is controller by XM_DIS_FCNTL */
- tx_fc = !!(efx->link_fc & EFX_FC_TX);
+ tx_fc = !!(efx->link_state.fc & EFX_FC_TX);
efx_reado(efx, ®, FR_AZ_RX_CFG);
EFX_SET_OWORD_FIELD(reg, FRF_AZ_RX_XOFF_MAC_EN, tx_fc);
@@ -2175,11 +2176,11 @@ int falcon_switch_mac(struct efx_nic *efx)
/* Internal loopbacks override the phy speed setting */
if (efx->loopback_mode == LOOPBACK_GMAC) {
- efx->link_speed = 1000;
- efx->link_fd = true;
+ efx->link_state.speed = 1000;
+ efx->link_state.fd = true;
} else if (LOOPBACK_INTERNAL(efx)) {
- efx->link_speed = 10000;
- efx->link_fd = true;
+ efx->link_state.speed = 10000;
+ efx->link_state.fd = true;
}
WARN_ON(!mutex_is_locked(&efx->mac_lock));
@@ -2752,7 +2753,7 @@ static int falcon_probe_nic_variant(struct efx_nic *efx)
}
/* Initial assumed speed */
- efx->link_speed = EFX_OWORD_FIELD(nic_stat, FRF_AB_STRAP_10G) ? 10000 : 1000;
+ efx->link_state.speed = EFX_OWORD_FIELD(nic_stat, FRF_AB_STRAP_10G) ? 10000 : 1000;
return 0;
}
diff --git a/drivers/net/sfc/falcon_boards.c b/drivers/net/sfc/falcon_boards.c
index cdf7a0d..333ccc1 100644
--- a/drivers/net/sfc/falcon_boards.c
+++ b/drivers/net/sfc/falcon_boards.c
@@ -85,7 +85,7 @@ static int efx_check_lm87(struct efx_nic *efx, unsigned mask)
s32 alarms1, alarms2;
/* If link is up then do not monitor temperature */
- if (EFX_WORKAROUND_7884(efx) && efx->link_up)
+ if (EFX_WORKAROUND_7884(efx) && efx->link_state.up)
return 0;
alarms1 = i2c_smbus_read_byte_data(client, LM87_REG_ALARMS1);
diff --git a/drivers/net/sfc/falcon_gmac.c b/drivers/net/sfc/falcon_gmac.c
index 8a1b80d..967f3fb 100644
--- a/drivers/net/sfc/falcon_gmac.c
+++ b/drivers/net/sfc/falcon_gmac.c
@@ -24,16 +24,17 @@
static void falcon_reconfigure_gmac(struct efx_nic *efx)
{
+ struct efx_link_state *link_state = &efx->link_state;
bool loopback, tx_fc, rx_fc, bytemode;
int if_mode;
unsigned int max_frame_len;
efx_oword_t reg;
/* Configuration register 1 */
- tx_fc = (efx->link_fc & EFX_FC_TX) || !efx->link_fd;
- rx_fc = !!(efx->link_fc & EFX_FC_RX);
+ tx_fc = (link_state->fc & EFX_FC_TX) || !link_state->fd;
+ rx_fc = !!(link_state->fc & EFX_FC_RX);
loopback = (efx->loopback_mode == LOOPBACK_GMAC);
- bytemode = (efx->link_speed == 1000);
+ bytemode = (link_state->speed == 1000);
EFX_POPULATE_OWORD_5(reg,
FRF_AB_GM_LOOP, loopback,
@@ -50,7 +51,7 @@ static void falcon_reconfigure_gmac(struct efx_nic *efx)
FRF_AB_GM_IF_MODE, if_mode,
FRF_AB_GM_PAD_CRC_EN, 1,
FRF_AB_GM_LEN_CHK, 1,
- FRF_AB_GM_FD, efx->link_fd,
+ FRF_AB_GM_FD, link_state->fd,
FRF_AB_GM_PAMBL_LEN, 0x7/*datasheet recommended */);
efx_writeo(efx, ®, FR_AB_GM_CFG2);
@@ -101,8 +102,8 @@ static void falcon_reconfigure_gmac(struct efx_nic *efx)
/* FIFO configuration register 5 */
efx_reado(efx, ®, FR_AB_GMF_CFG5);
EFX_SET_OWORD_FIELD(reg, FRF_AB_GMF_CFGBYTMODE, bytemode);
- EFX_SET_OWORD_FIELD(reg, FRF_AB_GMF_CFGHDPLX, !efx->link_fd);
- EFX_SET_OWORD_FIELD(reg, FRF_AB_GMF_HSTDRPLT64, !efx->link_fd);
+ EFX_SET_OWORD_FIELD(reg, FRF_AB_GMF_CFGHDPLX, !link_state->fd);
+ EFX_SET_OWORD_FIELD(reg, FRF_AB_GMF_HSTDRPLT64, !link_state->fd);
EFX_SET_OWORD_FIELD(reg, FRF_AB_GMF_HSTFLTRFRMDC_PAUSE, 0);
efx_writeo(efx, ®, FR_AB_GMF_CFG5);
udelay(10);
diff --git a/drivers/net/sfc/falcon_xmac.c b/drivers/net/sfc/falcon_xmac.c
index 7e57b4a..69cb55f 100644
--- a/drivers/net/sfc/falcon_xmac.c
+++ b/drivers/net/sfc/falcon_xmac.c
@@ -89,7 +89,7 @@ static void falcon_mask_status_intr(struct efx_nic *efx, bool enable)
return;
/* We expect xgmii faults if the wireside link is up */
- if (!EFX_WORKAROUND_5147(efx) || !efx->link_up)
+ if (!EFX_WORKAROUND_5147(efx) || !efx->link_state.up)
return;
/* We can only use this interrupt to signal the negative edge of
@@ -132,7 +132,7 @@ bool falcon_xaui_link_ok(struct efx_nic *efx)
efx_writeo(efx, ®, FR_AB_XX_CORE_STAT);
/* If the link is up, then check the phy side of the xaui link */
- if (efx->link_up && link_ok)
+ if (efx->link_state.up && link_ok)
if (efx->phy_op->mmds & (1 << MDIO_MMD_PHYXS))
link_ok = efx_mdio_phyxgxs_lane_sync(efx);
@@ -143,7 +143,7 @@ static void falcon_reconfigure_xmac_core(struct efx_nic *efx)
{
unsigned int max_frame_len;
efx_oword_t reg;
- bool rx_fc = !!(efx->link_fc & EFX_FC_RX);
+ bool rx_fc = !!(efx->link_state.fc & EFX_FC_RX);
/* Configure MAC - cut-thru mode is hard wired on */
EFX_POPULATE_DWORD_3(reg,
@@ -356,7 +356,7 @@ static void falcon_xmac_irq(struct efx_nic *efx)
static void falcon_poll_xmac(struct efx_nic *efx)
{
- if (!EFX_WORKAROUND_5147(efx) || !efx->link_up || efx->mac_up)
+ if (!EFX_WORKAROUND_5147(efx) || !efx->link_state.up || efx->mac_up)
return;
falcon_mask_status_intr(efx, false);
diff --git a/drivers/net/sfc/net_driver.h b/drivers/net/sfc/net_driver.h
index 55d45a7..f2df324 100644
--- a/drivers/net/sfc/net_driver.h
+++ b/drivers/net/sfc/net_driver.h
@@ -419,7 +419,7 @@ enum phy_type {
PHY_TYPE_MAX /* Insert any new items before this */
};
-#define EFX_IS10G(efx) ((efx)->link_speed == 10000)
+#define EFX_IS10G(efx) ((efx)->link_state.speed == 10000)
enum nic_state {
STATE_INIT = 0,
@@ -468,6 +468,20 @@ enum efx_mac_type {
};
/**
+ * struct efx_link_state - Current state of the link
+ * @up: Link is up
+ * @fd: Link is full-duplex
+ * @fc: Actual flow control flags
+ * @speed: Link speed (Mbps)
+ */
+struct efx_link_state {
+ bool up;
+ bool fd;
+ enum efx_fc_type fc;
+ unsigned int speed;
+};
+
+/**
* struct efx_mac_operations - Efx MAC operations table
* @reconfigure: Reconfigure MAC. Serialised by the mac_lock
* @update_stats: Update statistics
@@ -691,10 +705,7 @@ union efx_multicast_hash {
* @mdio: PHY MDIO interface
* @phy_mode: PHY operating mode. Serialised by @mac_lock.
* @mac_up: MAC link state
- * @link_up: Link status
- * @link_fd: Link is full duplex
- * @link_fc: Actualy flow control flags
- * @link_speed: Link speed (Mbps)
+ * @link_state: Current state of the link
* @n_link_state_changes: Number of times the link has changed state
* @promiscuous: Promiscuous flag. Protected by netif_tx_lock.
* @multicast_hash: Multicast hash table
@@ -780,10 +791,7 @@ struct efx_nic {
enum efx_phy_mode phy_mode;
bool mac_up;
- bool link_up;
- bool link_fd;
- enum efx_fc_type link_fc;
- unsigned int link_speed;
+ struct efx_link_state link_state;
unsigned int n_link_state_changes;
bool promiscuous;
diff --git a/drivers/net/sfc/qt202x_phy.c b/drivers/net/sfc/qt202x_phy.c
index 73bc5ad..8208ac0 100644
--- a/drivers/net/sfc/qt202x_phy.c
+++ b/drivers/net/sfc/qt202x_phy.c
@@ -182,13 +182,14 @@ static void qt202x_phy_poll(struct efx_nic *efx)
{
int link_up = qt202x_link_ok(efx);
/* Simulate a PHY event if link state has changed */
- if (link_up != efx->link_up)
+ if (link_up != efx->link_state.up)
falcon_sim_phy_event(efx);
}
static void qt202x_phy_reconfigure(struct efx_nic *efx)
{
struct qt202x_phy_data *phy_data = efx->phy_data;
+ struct efx_link_state *link_state = &efx->link_state;
if (efx->phy_type == PHY_TYPE_QT2025C) {
/* There are several different register bits which can
@@ -215,10 +216,10 @@ static void qt202x_phy_reconfigure(struct efx_nic *efx)
efx_mdio_phy_reconfigure(efx);
phy_data->phy_mode = efx->phy_mode;
- efx->link_up = qt202x_link_ok(efx);
- efx->link_speed = 10000;
- efx->link_fd = true;
- efx->link_fc = efx->wanted_fc;
+ link_state->up = qt202x_link_ok(efx);
+ link_state->speed = 10000;
+ link_state->fd = true;
+ link_state->fc = efx->wanted_fc;
}
static void qt202x_phy_get_settings(struct efx_nic *efx, struct ethtool_cmd *ecmd)
diff --git a/drivers/net/sfc/selftest.c b/drivers/net/sfc/selftest.c
index 7a9386f..70eb5f1 100644
--- a/drivers/net/sfc/selftest.c
+++ b/drivers/net/sfc/selftest.c
@@ -614,7 +614,7 @@ static int efx_test_loopbacks(struct efx_nic *efx, struct efx_self_tests *tests,
/* We need both the phy and xaui links to be ok.
* rather than relying on the falcon_xmac irq/poll
* regime, just poll xaui directly */
- link_up = efx->link_up;
+ link_up = efx->link_state.up;
if (link_up && EFX_IS10G(efx) &&
!falcon_xaui_link_ok(efx))
link_up = false;
diff --git a/drivers/net/sfc/tenxpress.c b/drivers/net/sfc/tenxpress.c
index cb5e057..b001f38 100644
--- a/drivers/net/sfc/tenxpress.c
+++ b/drivers/net/sfc/tenxpress.c
@@ -503,6 +503,7 @@ static void tenxpress_low_power(struct efx_nic *efx)
static void tenxpress_phy_reconfigure(struct efx_nic *efx)
{
struct tenxpress_phy_data *phy_data = efx->phy_data;
+ struct efx_link_state *link_state = &efx->link_state;
struct ethtool_cmd ecmd;
bool phy_mode_change, loop_reset;
@@ -545,37 +546,38 @@ static void tenxpress_phy_reconfigure(struct efx_nic *efx)
phy_data->phy_mode = efx->phy_mode;
if (efx->phy_type == PHY_TYPE_SFX7101) {
- efx->link_speed = 10000;
- efx->link_fd = true;
- efx->link_up = sfx7101_link_ok(efx);
+ link_state->speed = 10000;
+ link_state->fd = true;
+ link_state->up = sfx7101_link_ok(efx);
} else {
efx->phy_op->get_settings(efx, &ecmd);
- efx->link_speed = ecmd.speed;
- efx->link_fd = ecmd.duplex == DUPLEX_FULL;
- efx->link_up = sft9001_link_ok(efx, &ecmd);
+ link_state->speed = ecmd.speed;
+ link_state->fd = ecmd.duplex == DUPLEX_FULL;
+ link_state->up = sft9001_link_ok(efx, &ecmd);
}
- efx->link_fc = efx_mdio_get_pause(efx);
+ link_state->fc = efx_mdio_get_pause(efx);
}
/* Poll PHY for interrupt */
static void tenxpress_phy_poll(struct efx_nic *efx)
{
struct tenxpress_phy_data *phy_data = efx->phy_data;
+ struct efx_link_state *link_state = &efx->link_state;
bool change = false;
if (efx->phy_type == PHY_TYPE_SFX7101) {
bool link_ok = sfx7101_link_ok(efx);
- if (link_ok != efx->link_up) {
+ if (link_ok != link_state->up) {
change = true;
} else {
unsigned int link_fc = efx_mdio_get_pause(efx);
- if (link_fc != efx->link_fc)
+ if (link_fc != link_state->fc)
change = true;
}
sfx7101_check_bad_lp(efx, link_ok);
} else if (efx->loopback_mode) {
bool link_ok = sft9001_link_ok(efx, NULL);
- if (link_ok != efx->link_up)
+ if (link_ok != link_state->up)
change = true;
} else {
int status = efx_mdio_read(efx, MDIO_MMD_PMAPMD,
--
Ben Hutchings, Senior Software Engineer, Solarflare Communications
Not speaking for my employer; that's the marketing department's job.
They asked us to note that Solarflare product names are trademarked.
^ permalink raw reply related
* [PATCH 12/17] sfc: Move all I2C stuff into struct falcon_board
From: Ben Hutchings @ 2009-11-24 2:06 UTC (permalink / raw)
To: David Miller; +Cc: netdev, linux-net-drivers
Signed-off-by: Ben Hutchings <bhutchings@solarflare.com>
---
drivers/net/sfc/falcon.c | 26 +++++++++++++++-----------
drivers/net/sfc/falcon.h | 6 ++++--
drivers/net/sfc/falcon_boards.c | 18 ++++++++++--------
drivers/net/sfc/net_driver.h | 3 ---
4 files changed, 29 insertions(+), 24 deletions(-)
diff --git a/drivers/net/sfc/falcon.c b/drivers/net/sfc/falcon.c
index 490bda0..ff15b9d 100644
--- a/drivers/net/sfc/falcon.c
+++ b/drivers/net/sfc/falcon.c
@@ -2799,6 +2799,7 @@ static void falcon_probe_spi_devices(struct efx_nic *efx)
int falcon_probe_nic(struct efx_nic *efx)
{
struct falcon_nic_data *nic_data;
+ struct falcon_board *board;
int rc;
/* Allocate storage for hardware specific data */
@@ -2856,13 +2857,15 @@ int falcon_probe_nic(struct efx_nic *efx)
goto fail5;
/* Initialise I2C adapter */
- efx->i2c_adap.owner = THIS_MODULE;
- nic_data->i2c_data = falcon_i2c_bit_operations;
- nic_data->i2c_data.data = efx;
- efx->i2c_adap.algo_data = &nic_data->i2c_data;
- efx->i2c_adap.dev.parent = &efx->pci_dev->dev;
- strlcpy(efx->i2c_adap.name, "SFC4000 GPIO", sizeof(efx->i2c_adap.name));
- rc = i2c_bit_add_bus(&efx->i2c_adap);
+ board = falcon_board(efx);
+ board->i2c_adap.owner = THIS_MODULE;
+ board->i2c_data = falcon_i2c_bit_operations;
+ board->i2c_data.data = efx;
+ board->i2c_adap.algo_data = &board->i2c_data;
+ board->i2c_adap.dev.parent = &efx->pci_dev->dev;
+ strlcpy(board->i2c_adap.name, "SFC4000 GPIO",
+ sizeof(board->i2c_adap.name));
+ rc = i2c_bit_add_bus(&board->i2c_adap);
if (rc)
goto fail5;
@@ -2875,8 +2878,8 @@ int falcon_probe_nic(struct efx_nic *efx)
return 0;
fail6:
- BUG_ON(i2c_del_adapter(&efx->i2c_adap));
- memset(&efx->i2c_adap, 0, sizeof(efx->i2c_adap));
+ BUG_ON(i2c_del_adapter(&board->i2c_adap));
+ memset(&board->i2c_adap, 0, sizeof(board->i2c_adap));
fail5:
falcon_remove_spi_devices(efx);
falcon_free_buffer(efx, &efx->irq_status);
@@ -3066,14 +3069,15 @@ int falcon_init_nic(struct efx_nic *efx)
void falcon_remove_nic(struct efx_nic *efx)
{
struct falcon_nic_data *nic_data = efx->nic_data;
+ struct falcon_board *board = falcon_board(efx);
int rc;
falcon_board(efx)->fini(efx);
/* Remove I2C adapter and clear it in preparation for a retry */
- rc = i2c_del_adapter(&efx->i2c_adap);
+ rc = i2c_del_adapter(&board->i2c_adap);
BUG_ON(rc);
- memset(&efx->i2c_adap, 0, sizeof(efx->i2c_adap));
+ memset(&board->i2c_adap, 0, sizeof(board->i2c_adap));
falcon_remove_spi_devices(efx);
falcon_free_buffer(efx, &efx->irq_status);
diff --git a/drivers/net/sfc/falcon.h b/drivers/net/sfc/falcon.h
index 3e9696c..0da5ea7 100644
--- a/drivers/net/sfc/falcon.h
+++ b/drivers/net/sfc/falcon.h
@@ -40,6 +40,8 @@ static inline int falcon_rev(struct efx_nic *efx)
* @set_id_led: Set state of identifying LED or revert to automatic function
* @monitor: Board-specific health check function
* @fini: Shut down hardware and free resources
+ * @i2c_adap: I2C adapter for on-board peripherals
+ * @i2c_data: Data for bit-banging algorithm
* @hwmon_client: I2C client for hardware monitor
* @ioexp_client: I2C client for power/port control
*/
@@ -52,18 +54,18 @@ struct falcon_board {
void (*set_id_led) (struct efx_nic *efx, enum efx_led_mode mode);
int (*monitor) (struct efx_nic *nic);
void (*fini) (struct efx_nic *nic);
+ struct i2c_adapter i2c_adap;
+ struct i2c_algo_bit_data i2c_data;
struct i2c_client *hwmon_client, *ioexp_client;
};
/**
* struct falcon_nic_data - Falcon NIC state
* @pci_dev2: The secondary PCI device if present
- * @i2c_data: Operations and state for I2C bit-bashing algorithm
* @board: Board state and functions
*/
struct falcon_nic_data {
struct pci_dev *pci_dev2;
- struct i2c_algo_bit_data i2c_data;
struct falcon_board board;
};
diff --git a/drivers/net/sfc/falcon_boards.c b/drivers/net/sfc/falcon_boards.c
index 20aebe0..cdf7a0d 100644
--- a/drivers/net/sfc/falcon_boards.c
+++ b/drivers/net/sfc/falcon_boards.c
@@ -51,7 +51,8 @@
static int efx_init_lm87(struct efx_nic *efx, struct i2c_board_info *info,
const u8 *reg_values)
{
- struct i2c_client *client = i2c_new_device(&efx->i2c_adap, info);
+ struct falcon_board *board = falcon_board(efx);
+ struct i2c_client *client = i2c_new_device(&board->i2c_adap, info);
int rc;
if (!client)
@@ -65,7 +66,7 @@ static int efx_init_lm87(struct efx_nic *efx, struct i2c_board_info *info,
goto err;
}
- falcon_board(efx)->hwmon_client = client;
+ board->hwmon_client = client;
return 0;
err:
@@ -290,10 +291,11 @@ fail_on:
static int sfn4111t_reset(struct efx_nic *efx)
{
+ struct falcon_board *board = falcon_board(efx);
efx_oword_t reg;
/* GPIO 3 and the GPIO register are shared with I2C, so block that */
- i2c_lock_adapter(&efx->i2c_adap);
+ i2c_lock_adapter(&board->i2c_adap);
/* Pull RST_N (GPIO 2) low then let it up again, setting the
* FLASH_CFG_1 strap (GPIO 3) appropriately. Only change the
@@ -309,7 +311,7 @@ static int sfn4111t_reset(struct efx_nic *efx)
efx_writeo(efx, ®, FR_AB_GPIO_CTL);
msleep(1);
- i2c_unlock_adapter(&efx->i2c_adap);
+ i2c_unlock_adapter(&board->i2c_adap);
ssleep(1);
return 0;
@@ -416,10 +418,10 @@ static int sfe4001_init(struct efx_nic *efx)
#if defined(CONFIG_SENSORS_LM90) || defined(CONFIG_SENSORS_LM90_MODULE)
board->hwmon_client =
- i2c_new_device(&efx->i2c_adap, &sfe4001_hwmon_info);
+ i2c_new_device(&board->i2c_adap, &sfe4001_hwmon_info);
#else
board->hwmon_client =
- i2c_new_dummy(&efx->i2c_adap, sfe4001_hwmon_info.addr);
+ i2c_new_dummy(&board->i2c_adap, sfe4001_hwmon_info.addr);
#endif
if (!board->hwmon_client)
return -EIO;
@@ -430,7 +432,7 @@ static int sfe4001_init(struct efx_nic *efx)
if (rc)
goto fail_hwmon;
- board->ioexp_client = i2c_new_dummy(&efx->i2c_adap, PCA9539);
+ board->ioexp_client = i2c_new_dummy(&board->i2c_adap, PCA9539);
if (!board->ioexp_client) {
rc = -EIO;
goto fail_hwmon;
@@ -522,7 +524,7 @@ static int sfn4111t_init(struct efx_nic *efx)
int rc;
board->hwmon_client =
- i2c_new_device(&efx->i2c_adap,
+ i2c_new_device(&board->i2c_adap,
(board->minor < 5) ?
&sfn4111t_a0_hwmon_info :
&sfn4111t_r5_hwmon_info);
diff --git a/drivers/net/sfc/net_driver.h b/drivers/net/sfc/net_driver.h
index fdc9e15..55d45a7 100644
--- a/drivers/net/sfc/net_driver.h
+++ b/drivers/net/sfc/net_driver.h
@@ -639,7 +639,6 @@ union efx_multicast_hash {
* @interrupt_mode: Interrupt mode
* @irq_rx_adaptive: Adaptive IRQ moderation enabled for RX event queues
* @irq_rx_moderation: IRQ moderation time for RX event queues
- * @i2c_adap: I2C adapter
* @state: Device state flag. Serialised by the rtnl_lock.
* @reset_pending: Pending reset method (normally RESET_TYPE_NONE)
* @tx_queue: TX DMA queues
@@ -725,8 +724,6 @@ struct efx_nic {
bool irq_rx_adaptive;
unsigned int irq_rx_moderation;
- struct i2c_adapter i2c_adap;
-
enum nic_state state;
enum reset_type reset_pending;
--
Ben Hutchings, Senior Software Engineer, Solarflare Communications
Not speaking for my employer; that's the marketing department's job.
They asked us to note that Solarflare product names are trademarked.
^ permalink raw reply related
* [PATCH 11/17] sfc: Move struct falcon_board into struct falcon_nic_data
From: Ben Hutchings @ 2009-11-24 2:05 UTC (permalink / raw)
To: David Miller; +Cc: netdev, linux-net-drivers
Signed-off-by: Ben Hutchings <bhutchings@solarflare.com>
---
drivers/net/sfc/efx.c | 11 +----------
drivers/net/sfc/falcon.h | 30 +++++++++++++++++++++++++++++-
drivers/net/sfc/falcon_boards.c | 9 +++++++++
drivers/net/sfc/net_driver.h | 27 ---------------------------
4 files changed, 39 insertions(+), 38 deletions(-)
diff --git a/drivers/net/sfc/efx.c b/drivers/net/sfc/efx.c
index c9f8004..b913211 100644
--- a/drivers/net/sfc/efx.c
+++ b/drivers/net/sfc/efx.c
@@ -1878,7 +1878,7 @@ static struct pci_device_id efx_pci_table[] __devinitdata = {
/**************************************************************************
*
- * Dummy PHY/MAC/Board operations
+ * Dummy PHY/MAC operations
*
* Can be used for some unimplemented operations
* Needed so all function pointers are valid and do not have to be tested
@@ -1908,14 +1908,6 @@ static struct efx_phy_operations efx_dummy_phy_operations = {
.clear_interrupt = efx_port_dummy_op_void,
};
-static struct falcon_board efx_dummy_board_info = {
- .init = efx_port_dummy_op_int,
- .init_phy = efx_port_dummy_op_void,
- .set_id_led = efx_port_dummy_op_set_id_led,
- .monitor = efx_port_dummy_op_int,
- .fini = efx_port_dummy_op_void,
-};
-
/**************************************************************************
*
* Data housekeeping
@@ -1944,7 +1936,6 @@ static int efx_init_struct(struct efx_nic *efx, struct efx_nic_type *type,
efx->state = STATE_INIT;
efx->reset_pending = RESET_TYPE_NONE;
strlcpy(efx->name, pci_name(pci_dev), sizeof(efx->name));
- efx->board_info = efx_dummy_board_info;
efx->net_dev = net_dev;
efx->rx_checksum_enabled = true;
diff --git a/drivers/net/sfc/falcon.h b/drivers/net/sfc/falcon.h
index 46dd43b..3e9696c 100644
--- a/drivers/net/sfc/falcon.h
+++ b/drivers/net/sfc/falcon.h
@@ -31,18 +31,46 @@ static inline int falcon_rev(struct efx_nic *efx)
}
/**
+ * struct falcon_board - board information
+ * @type: Board model type
+ * @major: Major rev. ('A', 'B' ...)
+ * @minor: Minor rev. (0, 1, ...)
+ * @init: Allocate resources and initialise peripheral hardware
+ * @init_phy: Do board-specific PHY initialisation
+ * @set_id_led: Set state of identifying LED or revert to automatic function
+ * @monitor: Board-specific health check function
+ * @fini: Shut down hardware and free resources
+ * @hwmon_client: I2C client for hardware monitor
+ * @ioexp_client: I2C client for power/port control
+ */
+struct falcon_board {
+ int type;
+ int major;
+ int minor;
+ int (*init) (struct efx_nic *nic);
+ void (*init_phy) (struct efx_nic *efx);
+ void (*set_id_led) (struct efx_nic *efx, enum efx_led_mode mode);
+ int (*monitor) (struct efx_nic *nic);
+ void (*fini) (struct efx_nic *nic);
+ struct i2c_client *hwmon_client, *ioexp_client;
+};
+
+/**
* struct falcon_nic_data - Falcon NIC state
* @pci_dev2: The secondary PCI device if present
* @i2c_data: Operations and state for I2C bit-bashing algorithm
+ * @board: Board state and functions
*/
struct falcon_nic_data {
struct pci_dev *pci_dev2;
struct i2c_algo_bit_data i2c_data;
+ struct falcon_board board;
};
static inline struct falcon_board *falcon_board(struct efx_nic *efx)
{
- return &efx->board_info;
+ struct falcon_nic_data *data = efx->nic_data;
+ return &data->board;
}
extern struct efx_nic_type falcon_a_nic_type;
diff --git a/drivers/net/sfc/falcon_boards.c b/drivers/net/sfc/falcon_boards.c
index af7cd2a..20aebe0 100644
--- a/drivers/net/sfc/falcon_boards.c
+++ b/drivers/net/sfc/falcon_boards.c
@@ -721,12 +721,21 @@ static struct falcon_board_data board_data[] = {
sfn4112f_init },
};
+static struct falcon_board falcon_dummy_board = {
+ .init = efx_port_dummy_op_int,
+ .init_phy = efx_port_dummy_op_void,
+ .set_id_led = efx_port_dummy_op_set_id_led,
+ .monitor = efx_port_dummy_op_int,
+ .fini = efx_port_dummy_op_void,
+};
+
void falcon_probe_board(struct efx_nic *efx, u16 revision_info)
{
struct falcon_board *board = falcon_board(efx);
struct falcon_board_data *data = NULL;
int i;
+ *board = falcon_dummy_board;
board->type = FALCON_BOARD_TYPE(revision_info);
board->major = FALCON_BOARD_MAJOR(revision_info);
board->minor = FALCON_BOARD_MINOR(revision_info);
diff --git a/drivers/net/sfc/net_driver.h b/drivers/net/sfc/net_driver.h
index 9b84c3a..fdc9e15 100644
--- a/drivers/net/sfc/net_driver.h
+++ b/drivers/net/sfc/net_driver.h
@@ -394,31 +394,6 @@ enum efx_led_mode {
EFX_LED_DEFAULT = 2
};
-/**
- * struct falcon_board - board information
- * @type: Board model type
- * @major: Major rev. ('A', 'B' ...)
- * @minor: Minor rev. (0, 1, ...)
- * @init: Allocate resources and initialise peripheral hardware
- * @init_phy: Do board-specific PHY initialisation
- * @set_id_led: Set state of identifying LED or revert to automatic function
- * @monitor: Board-specific health check function
- * @fini: Shut down hardware and free resources
- * @hwmon_client: I2C client for hardware monitor
- * @ioexp_client: I2C client for power/port control
- */
-struct falcon_board {
- int type;
- int major;
- int minor;
- int (*init) (struct efx_nic *nic);
- void (*init_phy) (struct efx_nic *efx);
- void (*set_id_led) (struct efx_nic *efx, enum efx_led_mode mode);
- int (*monitor) (struct efx_nic *nic);
- void (*fini) (struct efx_nic *nic);
- struct i2c_client *hwmon_client, *ioexp_client;
-};
-
#define STRING_TABLE_LOOKUP(val, member) \
member ## _names[val]
@@ -665,7 +640,6 @@ union efx_multicast_hash {
* @irq_rx_adaptive: Adaptive IRQ moderation enabled for RX event queues
* @irq_rx_moderation: IRQ moderation time for RX event queues
* @i2c_adap: I2C adapter
- * @board_info: Board-level information
* @state: Device state flag. Serialised by the rtnl_lock.
* @reset_pending: Pending reset method (normally RESET_TYPE_NONE)
* @tx_queue: TX DMA queues
@@ -752,7 +726,6 @@ struct efx_nic {
unsigned int irq_rx_moderation;
struct i2c_adapter i2c_adap;
- struct falcon_board board_info;
enum nic_state state;
enum reset_type reset_pending;
--
Ben Hutchings, Senior Software Engineer, Solarflare Communications
Not speaking for my employer; that's the marketing department's job.
They asked us to note that Solarflare product names are trademarked.
^ permalink raw reply related
* [PATCH 10/17] sfc: Move definition of struct falcon_nic_data into falcon.h
From: Ben Hutchings @ 2009-11-24 2:05 UTC (permalink / raw)
To: David Miller; +Cc: netdev, linux-net-drivers
This is preparation for moving Falcon-specific state required by other
Falcon-specific code.
Signed-off-by: Ben Hutchings <bhutchings@solarflare.com>
---
drivers/net/sfc/falcon.c | 11 -----------
drivers/net/sfc/falcon.h | 11 +++++++++++
2 files changed, 11 insertions(+), 11 deletions(-)
diff --git a/drivers/net/sfc/falcon.c b/drivers/net/sfc/falcon.c
index 29e79f7..490bda0 100644
--- a/drivers/net/sfc/falcon.c
+++ b/drivers/net/sfc/falcon.c
@@ -14,7 +14,6 @@
#include <linux/module.h>
#include <linux/seq_file.h>
#include <linux/i2c.h>
-#include <linux/i2c-algo-bit.h>
#include <linux/mii.h>
#include "net_driver.h"
#include "bitfield.h"
@@ -33,16 +32,6 @@
* present in SFE400X evaluation boards
*/
-/**
- * struct falcon_nic_data - Falcon NIC state
- * @pci_dev2: The secondary PCI device if present
- * @i2c_data: Operations and state for I2C bit-bashing algorithm
- */
-struct falcon_nic_data {
- struct pci_dev *pci_dev2;
- struct i2c_algo_bit_data i2c_data;
-};
-
/**************************************************************************
*
* Configurable values
diff --git a/drivers/net/sfc/falcon.h b/drivers/net/sfc/falcon.h
index 54dad2d..46dd43b 100644
--- a/drivers/net/sfc/falcon.h
+++ b/drivers/net/sfc/falcon.h
@@ -11,6 +11,7 @@
#ifndef EFX_FALCON_H
#define EFX_FALCON_H
+#include <linux/i2c-algo-bit.h>
#include "net_driver.h"
#include "efx.h"
@@ -29,6 +30,16 @@ static inline int falcon_rev(struct efx_nic *efx)
return efx->pci_dev->revision;
}
+/**
+ * struct falcon_nic_data - Falcon NIC state
+ * @pci_dev2: The secondary PCI device if present
+ * @i2c_data: Operations and state for I2C bit-bashing algorithm
+ */
+struct falcon_nic_data {
+ struct pci_dev *pci_dev2;
+ struct i2c_algo_bit_data i2c_data;
+};
+
static inline struct falcon_board *falcon_board(struct efx_nic *efx)
{
return &efx->board_info;
--
Ben Hutchings, Senior Software Engineer, Solarflare Communications
Not speaking for my employer; that's the marketing department's job.
They asked us to note that Solarflare product names are trademarked.
^ permalink raw reply related
* [PATCH 09/17] sfc: Make board information explicitly Falcon-specific
From: Ben Hutchings @ 2009-11-24 2:05 UTC (permalink / raw)
To: David Miller; +Cc: netdev, linux-net-drivers
Rename struct efx_board to struct falcon_board.
Introduce and use inline function to look up board info from struct
efx_nic, in preparation for moving it.
Move board init and fini calls into NIC probe and remove functions.
Signed-off-by: Ben Hutchings <bhutchings@solarflare.com>
---
drivers/net/sfc/efx.c | 25 ++-------
drivers/net/sfc/ethtool.c | 6 +-
drivers/net/sfc/falcon.c | 11 ++++
drivers/net/sfc/falcon.h | 5 ++
drivers/net/sfc/falcon_boards.c | 106 +++++++++++++++++++++------------------
drivers/net/sfc/net_driver.h | 6 +-
drivers/net/sfc/qt202x_phy.c | 2 +-
drivers/net/sfc/tenxpress.c | 2 +-
8 files changed, 88 insertions(+), 75 deletions(-)
diff --git a/drivers/net/sfc/efx.c b/drivers/net/sfc/efx.c
index d7705a7..c9f8004 100644
--- a/drivers/net/sfc/efx.c
+++ b/drivers/net/sfc/efx.c
@@ -1265,7 +1265,7 @@ static void efx_monitor(struct work_struct *data)
goto out_requeue;
if (!efx->port_enabled)
goto out_unlock;
- rc = efx->board_info.monitor(efx);
+ rc = falcon_board(efx)->monitor(efx);
if (rc) {
EFX_ERR(efx, "Board sensor %s; shutting down PHY\n",
(rc == -ERANGE) ? "reported fault" : "failed");
@@ -1908,7 +1908,7 @@ static struct efx_phy_operations efx_dummy_phy_operations = {
.clear_interrupt = efx_port_dummy_op_void,
};
-static struct efx_board efx_dummy_board_info = {
+static struct falcon_board efx_dummy_board_info = {
.init = efx_port_dummy_op_int,
.init_phy = efx_port_dummy_op_void,
.set_id_led = efx_port_dummy_op_set_id_led,
@@ -2026,10 +2026,6 @@ static void efx_pci_remove_main(struct efx_nic *efx)
falcon_fini_interrupt(efx);
efx_fini_channels(efx);
efx_fini_port(efx);
-
- /* Shutdown the board, then the NIC and board state */
- efx->board_info.fini(efx);
-
efx_fini_napi(efx);
efx_remove_all(efx);
}
@@ -2089,39 +2085,30 @@ static int efx_pci_probe_main(struct efx_nic *efx)
if (rc)
goto fail2;
- /* Initialise the board */
- rc = efx->board_info.init(efx);
- if (rc) {
- EFX_ERR(efx, "failed to initialise board\n");
- goto fail3;
- }
-
rc = falcon_init_nic(efx);
if (rc) {
EFX_ERR(efx, "failed to initialise NIC\n");
- goto fail4;
+ goto fail3;
}
rc = efx_init_port(efx);
if (rc) {
EFX_ERR(efx, "failed to initialise port\n");
- goto fail5;
+ goto fail4;
}
efx_init_channels(efx);
rc = falcon_init_interrupt(efx);
if (rc)
- goto fail6;
+ goto fail5;
return 0;
- fail6:
+ fail5:
efx_fini_channels(efx);
efx_fini_port(efx);
- fail5:
fail4:
- efx->board_info.fini(efx);
fail3:
efx_fini_napi(efx);
fail2:
diff --git a/drivers/net/sfc/ethtool.c b/drivers/net/sfc/ethtool.c
index 18e0271..bb41532 100644
--- a/drivers/net/sfc/ethtool.c
+++ b/drivers/net/sfc/ethtool.c
@@ -188,14 +188,14 @@ static int efx_ethtool_phys_id(struct net_device *net_dev, u32 count)
struct efx_nic *efx = netdev_priv(net_dev);
do {
- efx->board_info.set_id_led(efx, EFX_LED_ON);
+ falcon_board(efx)->set_id_led(efx, EFX_LED_ON);
schedule_timeout_interruptible(HZ / 2);
- efx->board_info.set_id_led(efx, EFX_LED_OFF);
+ falcon_board(efx)->set_id_led(efx, EFX_LED_OFF);
schedule_timeout_interruptible(HZ / 2);
} while (!signal_pending(current) && --count != 0);
- efx->board_info.set_id_led(efx, EFX_LED_DEFAULT);
+ falcon_board(efx)->set_id_led(efx, EFX_LED_DEFAULT);
return 0;
}
diff --git a/drivers/net/sfc/falcon.c b/drivers/net/sfc/falcon.c
index 865638b..29e79f7 100644
--- a/drivers/net/sfc/falcon.c
+++ b/drivers/net/sfc/falcon.c
@@ -2877,8 +2877,17 @@ int falcon_probe_nic(struct efx_nic *efx)
if (rc)
goto fail5;
+ rc = falcon_board(efx)->init(efx);
+ if (rc) {
+ EFX_ERR(efx, "failed to initialise board\n");
+ goto fail6;
+ }
+
return 0;
+ fail6:
+ BUG_ON(i2c_del_adapter(&efx->i2c_adap));
+ memset(&efx->i2c_adap, 0, sizeof(efx->i2c_adap));
fail5:
falcon_remove_spi_devices(efx);
falcon_free_buffer(efx, &efx->irq_status);
@@ -3070,6 +3079,8 @@ void falcon_remove_nic(struct efx_nic *efx)
struct falcon_nic_data *nic_data = efx->nic_data;
int rc;
+ falcon_board(efx)->fini(efx);
+
/* Remove I2C adapter and clear it in preparation for a retry */
rc = i2c_del_adapter(&efx->i2c_adap);
BUG_ON(rc);
diff --git a/drivers/net/sfc/falcon.h b/drivers/net/sfc/falcon.h
index 4dd9657..54dad2d 100644
--- a/drivers/net/sfc/falcon.h
+++ b/drivers/net/sfc/falcon.h
@@ -29,6 +29,11 @@ static inline int falcon_rev(struct efx_nic *efx)
return efx->pci_dev->revision;
}
+static inline struct falcon_board *falcon_board(struct efx_nic *efx)
+{
+ return &efx->board_info;
+}
+
extern struct efx_nic_type falcon_a_nic_type;
extern struct efx_nic_type falcon_b_nic_type;
diff --git a/drivers/net/sfc/falcon_boards.c b/drivers/net/sfc/falcon_boards.c
index 429d3cd..af7cd2a 100644
--- a/drivers/net/sfc/falcon_boards.c
+++ b/drivers/net/sfc/falcon_boards.c
@@ -65,7 +65,7 @@ static int efx_init_lm87(struct efx_nic *efx, struct i2c_board_info *info,
goto err;
}
- efx->board_info.hwmon_client = client;
+ falcon_board(efx)->hwmon_client = client;
return 0;
err:
@@ -75,12 +75,12 @@ err:
static void efx_fini_lm87(struct efx_nic *efx)
{
- i2c_unregister_device(efx->board_info.hwmon_client);
+ i2c_unregister_device(falcon_board(efx)->hwmon_client);
}
static int efx_check_lm87(struct efx_nic *efx, unsigned mask)
{
- struct i2c_client *client = efx->board_info.hwmon_client;
+ struct i2c_client *client = falcon_board(efx)->hwmon_client;
s32 alarms1, alarms2;
/* If link is up then do not monitor temperature */
@@ -189,8 +189,8 @@ static inline int efx_check_lm87(struct efx_nic *efx, unsigned mask)
static void sfe4001_poweroff(struct efx_nic *efx)
{
- struct i2c_client *ioexp_client = efx->board_info.ioexp_client;
- struct i2c_client *hwmon_client = efx->board_info.hwmon_client;
+ struct i2c_client *ioexp_client = falcon_board(efx)->ioexp_client;
+ struct i2c_client *hwmon_client = falcon_board(efx)->hwmon_client;
/* Turn off all power rails and disable outputs */
i2c_smbus_write_byte_data(ioexp_client, P0_OUT, 0xff);
@@ -203,8 +203,8 @@ static void sfe4001_poweroff(struct efx_nic *efx)
static int sfe4001_poweron(struct efx_nic *efx)
{
- struct i2c_client *hwmon_client = efx->board_info.hwmon_client;
- struct i2c_client *ioexp_client = efx->board_info.ioexp_client;
+ struct i2c_client *ioexp_client = falcon_board(efx)->ioexp_client;
+ struct i2c_client *hwmon_client = falcon_board(efx)->hwmon_client;
unsigned int i, j;
int rc;
u8 out;
@@ -346,7 +346,7 @@ static ssize_t set_phy_flash_cfg(struct device *dev,
efx->phy_mode = new_mode;
if (new_mode & PHY_MODE_SPECIAL)
efx_stats_disable(efx);
- if (efx->board_info.type == FALCON_BOARD_SFE4001)
+ if (falcon_board(efx)->type == FALCON_BOARD_SFE4001)
err = sfe4001_poweron(efx);
else
err = sfn4111t_reset(efx);
@@ -363,12 +363,14 @@ static DEVICE_ATTR(phy_flash_cfg, 0644, show_phy_flash_cfg, set_phy_flash_cfg);
static void sfe4001_fini(struct efx_nic *efx)
{
+ struct falcon_board *board = falcon_board(efx);
+
EFX_INFO(efx, "%s\n", __func__);
device_remove_file(&efx->pci_dev->dev, &dev_attr_phy_flash_cfg);
sfe4001_poweroff(efx);
- i2c_unregister_device(efx->board_info.ioexp_client);
- i2c_unregister_device(efx->board_info.hwmon_client);
+ i2c_unregister_device(board->ioexp_client);
+ i2c_unregister_device(board->hwmon_client);
}
static int sfe4001_check_hw(struct efx_nic *efx)
@@ -387,7 +389,7 @@ static int sfe4001_check_hw(struct efx_nic *efx)
* the power undesirably.
* We know we can read from the IO expander because we did
* it during power-on. Assume failure now is bad news. */
- status = i2c_smbus_read_byte_data(efx->board_info.ioexp_client, P1_IN);
+ status = i2c_smbus_read_byte_data(falcon_board(efx)->ioexp_client, P1_IN);
if (status >= 0 &&
(status & ((1 << P1_AFE_PWD_LBN) | (1 << P1_DSP_PWD25_LBN))) != 0)
return 0;
@@ -409,36 +411,37 @@ static struct i2c_board_info sfe4001_hwmon_info = {
*/
static int sfe4001_init(struct efx_nic *efx)
{
+ struct falcon_board *board = falcon_board(efx);
int rc;
#if defined(CONFIG_SENSORS_LM90) || defined(CONFIG_SENSORS_LM90_MODULE)
- efx->board_info.hwmon_client =
+ board->hwmon_client =
i2c_new_device(&efx->i2c_adap, &sfe4001_hwmon_info);
#else
- efx->board_info.hwmon_client =
+ board->hwmon_client =
i2c_new_dummy(&efx->i2c_adap, sfe4001_hwmon_info.addr);
#endif
- if (!efx->board_info.hwmon_client)
+ if (!board->hwmon_client)
return -EIO;
/* Raise board/PHY high limit from 85 to 90 degrees Celsius */
- rc = i2c_smbus_write_byte_data(efx->board_info.hwmon_client,
+ rc = i2c_smbus_write_byte_data(board->hwmon_client,
MAX664X_REG_WLHO, 90);
if (rc)
goto fail_hwmon;
- efx->board_info.ioexp_client = i2c_new_dummy(&efx->i2c_adap, PCA9539);
- if (!efx->board_info.ioexp_client) {
+ board->ioexp_client = i2c_new_dummy(&efx->i2c_adap, PCA9539);
+ if (!board->ioexp_client) {
rc = -EIO;
goto fail_hwmon;
}
/* 10Xpress has fixed-function LED pins, so there is no board-specific
* blink code. */
- efx->board_info.set_id_led = tenxpress_set_id_led;
+ board->set_id_led = tenxpress_set_id_led;
- efx->board_info.monitor = sfe4001_check_hw;
- efx->board_info.fini = sfe4001_fini;
+ board->monitor = sfe4001_check_hw;
+ board->fini = sfe4001_fini;
if (efx->phy_mode & PHY_MODE_SPECIAL) {
/* PHY won't generate a 156.25 MHz clock and MAC stats fetch
@@ -459,9 +462,9 @@ static int sfe4001_init(struct efx_nic *efx)
fail_on:
sfe4001_poweroff(efx);
fail_ioexp:
- i2c_unregister_device(efx->board_info.ioexp_client);
+ i2c_unregister_device(board->ioexp_client);
fail_hwmon:
- i2c_unregister_device(efx->board_info.hwmon_client);
+ i2c_unregister_device(board->hwmon_client);
return rc;
}
@@ -474,7 +477,7 @@ static int sfn4111t_check_hw(struct efx_nic *efx)
return 0;
/* Test LHIGH, RHIGH, FAULT, EOT and IOT alarms */
- status = i2c_smbus_read_byte_data(efx->board_info.hwmon_client,
+ status = i2c_smbus_read_byte_data(falcon_board(efx)->hwmon_client,
MAX664X_REG_RSL);
if (status < 0)
return -EIO;
@@ -488,7 +491,7 @@ static void sfn4111t_fini(struct efx_nic *efx)
EFX_INFO(efx, "%s\n", __func__);
device_remove_file(&efx->pci_dev->dev, &dev_attr_phy_flash_cfg);
- i2c_unregister_device(efx->board_info.hwmon_client);
+ i2c_unregister_device(falcon_board(efx)->hwmon_client);
}
static struct i2c_board_info sfn4111t_a0_hwmon_info = {
@@ -515,20 +518,21 @@ static void sfn4111t_init_phy(struct efx_nic *efx)
static int sfn4111t_init(struct efx_nic *efx)
{
+ struct falcon_board *board = falcon_board(efx);
int rc;
- efx->board_info.hwmon_client =
+ board->hwmon_client =
i2c_new_device(&efx->i2c_adap,
- (efx->board_info.minor < 5) ?
+ (board->minor < 5) ?
&sfn4111t_a0_hwmon_info :
&sfn4111t_r5_hwmon_info);
- if (!efx->board_info.hwmon_client)
+ if (!board->hwmon_client)
return -EIO;
- efx->board_info.init_phy = sfn4111t_init_phy;
- efx->board_info.set_id_led = tenxpress_set_id_led;
- efx->board_info.monitor = sfn4111t_check_hw;
- efx->board_info.fini = sfn4111t_fini;
+ board->init_phy = sfn4111t_init_phy;
+ board->set_id_led = tenxpress_set_id_led;
+ board->monitor = sfn4111t_check_hw;
+ board->fini = sfn4111t_fini;
rc = device_create_file(&efx->pci_dev->dev, &dev_attr_phy_flash_cfg);
if (rc)
@@ -542,7 +546,7 @@ static int sfn4111t_init(struct efx_nic *efx)
return 0;
fail_hwmon:
- i2c_unregister_device(efx->board_info.hwmon_client);
+ i2c_unregister_device(board->hwmon_client);
return rc;
}
@@ -601,10 +605,12 @@ static void sfe4002_set_id_led(struct efx_nic *efx, enum efx_led_mode mode)
static int sfe4002_check_hw(struct efx_nic *efx)
{
+ struct falcon_board *board = falcon_board(efx);
+
/* A0 board rev. 4002s report a temperature fault the whole time
* (bad sensor) so we mask it out. */
unsigned alarm_mask =
- (efx->board_info.major == 0 && efx->board_info.minor == 0) ?
+ (board->major == 0 && board->minor == 0) ?
~LM87_ALARM_TEMP_EXT1 : ~0;
return efx_check_lm87(efx, alarm_mask);
@@ -612,13 +618,14 @@ static int sfe4002_check_hw(struct efx_nic *efx)
static int sfe4002_init(struct efx_nic *efx)
{
+ struct falcon_board *board = falcon_board(efx);
int rc = efx_init_lm87(efx, &sfe4002_hwmon_info, sfe4002_lm87_regs);
if (rc)
return rc;
- efx->board_info.monitor = sfe4002_check_hw;
- efx->board_info.init_phy = sfe4002_init_phy;
- efx->board_info.set_id_led = sfe4002_set_id_led;
- efx->board_info.fini = efx_fini_lm87;
+ board->monitor = sfe4002_check_hw;
+ board->init_phy = sfe4002_init_phy;
+ board->set_id_led = sfe4002_set_id_led;
+ board->fini = efx_fini_lm87;
return 0;
}
@@ -683,13 +690,15 @@ static int sfn4112f_check_hw(struct efx_nic *efx)
static int sfn4112f_init(struct efx_nic *efx)
{
+ struct falcon_board *board = falcon_board(efx);
+
int rc = efx_init_lm87(efx, &sfn4112f_hwmon_info, sfn4112f_lm87_regs);
if (rc)
return rc;
- efx->board_info.monitor = sfn4112f_check_hw;
- efx->board_info.init_phy = sfn4112f_init_phy;
- efx->board_info.set_id_led = sfn4112f_set_id_led;
- efx->board_info.fini = efx_fini_lm87;
+ board->monitor = sfn4112f_check_hw;
+ board->init_phy = sfn4112f_init_phy;
+ board->set_id_led = sfn4112f_set_id_led;
+ board->fini = efx_fini_lm87;
return 0;
}
@@ -714,24 +723,25 @@ static struct falcon_board_data board_data[] = {
void falcon_probe_board(struct efx_nic *efx, u16 revision_info)
{
+ struct falcon_board *board = falcon_board(efx);
struct falcon_board_data *data = NULL;
int i;
- efx->board_info.type = FALCON_BOARD_TYPE(revision_info);
- efx->board_info.major = FALCON_BOARD_MAJOR(revision_info);
- efx->board_info.minor = FALCON_BOARD_MINOR(revision_info);
+ board->type = FALCON_BOARD_TYPE(revision_info);
+ board->major = FALCON_BOARD_MAJOR(revision_info);
+ board->minor = FALCON_BOARD_MINOR(revision_info);
for (i = 0; i < ARRAY_SIZE(board_data); i++)
- if (board_data[i].type == efx->board_info.type)
+ if (board_data[i].type == board->type)
data = &board_data[i];
if (data) {
EFX_INFO(efx, "board is %s rev %c%d\n",
(efx->pci_dev->subsystem_vendor == EFX_VENDID_SFC)
? data->ref_model : data->gen_type,
- 'A' + efx->board_info.major, efx->board_info.minor);
- efx->board_info.init = data->init;
+ 'A' + board->major, board->minor);
+ board->init = data->init;
} else {
- EFX_ERR(efx, "unknown board type %d\n", efx->board_info.type);
+ EFX_ERR(efx, "unknown board type %d\n", board->type);
}
}
diff --git a/drivers/net/sfc/net_driver.h b/drivers/net/sfc/net_driver.h
index e1df589..9b84c3a 100644
--- a/drivers/net/sfc/net_driver.h
+++ b/drivers/net/sfc/net_driver.h
@@ -395,7 +395,7 @@ enum efx_led_mode {
};
/**
- * struct efx_board - board information
+ * struct falcon_board - board information
* @type: Board model type
* @major: Major rev. ('A', 'B' ...)
* @minor: Minor rev. (0, 1, ...)
@@ -407,7 +407,7 @@ enum efx_led_mode {
* @hwmon_client: I2C client for hardware monitor
* @ioexp_client: I2C client for power/port control
*/
-struct efx_board {
+struct falcon_board {
int type;
int major;
int minor;
@@ -752,7 +752,7 @@ struct efx_nic {
unsigned int irq_rx_moderation;
struct i2c_adapter i2c_adap;
- struct efx_board board_info;
+ struct falcon_board board_info;
enum nic_state state;
enum reset_type reset_pending;
diff --git a/drivers/net/sfc/qt202x_phy.c b/drivers/net/sfc/qt202x_phy.c
index f26684f..73bc5ad 100644
--- a/drivers/net/sfc/qt202x_phy.c
+++ b/drivers/net/sfc/qt202x_phy.c
@@ -126,7 +126,7 @@ static int qt202x_reset_phy(struct efx_nic *efx)
if (rc < 0)
goto fail;
- efx->board_info.init_phy(efx);
+ falcon_board(efx)->init_phy(efx);
return rc;
diff --git a/drivers/net/sfc/tenxpress.c b/drivers/net/sfc/tenxpress.c
index 2923e3d..cb5e057 100644
--- a/drivers/net/sfc/tenxpress.c
+++ b/drivers/net/sfc/tenxpress.c
@@ -303,7 +303,7 @@ static int tenxpress_phy_init(struct efx_nic *efx)
u16 old_adv, adv;
int rc = 0;
- efx->board_info.init_phy(efx);
+ falcon_board(efx)->init_phy(efx);
phy_data = kzalloc(sizeof(*phy_data), GFP_KERNEL);
if (!phy_data)
--
Ben Hutchings, Senior Software Engineer, Solarflare Communications
Not speaking for my employer; that's the marketing department's job.
They asked us to note that Solarflare product names are trademarked.
^ permalink raw reply related
* [PATCH 08/17] sfc: Rename efx_board::init_leds to init_phy and use for SFN4111T
From: Ben Hutchings @ 2009-11-24 2:04 UTC (permalink / raw)
To: David Miller; +Cc: netdev, linux-net-drivers
efx_board::init_leds was introduced as a second stage of
initialisation because of the inter-dependency between the board and
PHY. We want to move board initialisation into NIC probing, which is
too early to use MDIO, so SFN4111T initialisation also needs to be
split.
Signed-off-by: Ben Hutchings <bhutchings@solarflare.com>
---
drivers/net/sfc/efx.c | 2 +-
drivers/net/sfc/falcon_boards.c | 43 ++++++++++++++++++++++----------------
drivers/net/sfc/net_driver.h | 11 +++------
drivers/net/sfc/qt202x_phy.c | 2 +-
drivers/net/sfc/tenxpress.c | 2 +
5 files changed, 33 insertions(+), 27 deletions(-)
diff --git a/drivers/net/sfc/efx.c b/drivers/net/sfc/efx.c
index 612cd81..d7705a7 100644
--- a/drivers/net/sfc/efx.c
+++ b/drivers/net/sfc/efx.c
@@ -1910,7 +1910,7 @@ static struct efx_phy_operations efx_dummy_phy_operations = {
static struct efx_board efx_dummy_board_info = {
.init = efx_port_dummy_op_int,
- .init_leds = efx_port_dummy_op_void,
+ .init_phy = efx_port_dummy_op_void,
.set_id_led = efx_port_dummy_op_set_id_led,
.monitor = efx_port_dummy_op_int,
.fini = efx_port_dummy_op_void,
diff --git a/drivers/net/sfc/falcon_boards.c b/drivers/net/sfc/falcon_boards.c
index b2505fc..429d3cd 100644
--- a/drivers/net/sfc/falcon_boards.c
+++ b/drivers/net/sfc/falcon_boards.c
@@ -499,9 +499,22 @@ static struct i2c_board_info sfn4111t_r5_hwmon_info = {
I2C_BOARD_INFO("max6646", 0x4d),
};
+static void sfn4111t_init_phy(struct efx_nic *efx)
+{
+ if (!(efx->phy_mode & PHY_MODE_SPECIAL)) {
+ if (sft9001_wait_boot(efx) != -EINVAL)
+ return;
+
+ efx->phy_mode = PHY_MODE_SPECIAL;
+ efx_stats_disable(efx);
+ }
+
+ sfn4111t_reset(efx);
+ sft9001_wait_boot(efx);
+}
+
static int sfn4111t_init(struct efx_nic *efx)
{
- int i = 0;
int rc;
efx->board_info.hwmon_client =
@@ -512,6 +525,7 @@ static int sfn4111t_init(struct efx_nic *efx)
if (!efx->board_info.hwmon_client)
return -EIO;
+ efx->board_info.init_phy = sfn4111t_init_phy;
efx->board_info.set_id_led = tenxpress_set_id_led;
efx->board_info.monitor = sfn4111t_check_hw;
efx->board_info.fini = sfn4111t_fini;
@@ -520,20 +534,13 @@ static int sfn4111t_init(struct efx_nic *efx)
if (rc)
goto fail_hwmon;
- do {
- if (efx->phy_mode & PHY_MODE_SPECIAL) {
- /* PHY may not generate a 156.25 MHz clock and MAC
- * stats fetch will fail. */
- efx_stats_disable(efx);
- sfn4111t_reset(efx);
- }
- rc = sft9001_wait_boot(efx);
- if (rc == 0)
- return 0;
- efx->phy_mode = PHY_MODE_SPECIAL;
- } while (rc == -EINVAL && ++i < 2);
+ if (efx->phy_mode & PHY_MODE_SPECIAL)
+ /* PHY may not generate a 156.25 MHz clock and MAC
+ * stats fetch will fail. */
+ efx_stats_disable(efx);
+
+ return 0;
- device_remove_file(&efx->pci_dev->dev, &dev_attr_phy_flash_cfg);
fail_hwmon:
i2c_unregister_device(efx->board_info.hwmon_client);
return rc;
@@ -574,7 +581,7 @@ static struct i2c_board_info sfe4002_hwmon_info = {
#define SFE4002_RX_LED (0) /* Green */
#define SFE4002_TX_LED (1) /* Amber */
-static void sfe4002_init_leds(struct efx_nic *efx)
+static void sfe4002_init_phy(struct efx_nic *efx)
{
/* Set the TX and RX LEDs to reflect status and activity, and the
* fault LED off */
@@ -609,7 +616,7 @@ static int sfe4002_init(struct efx_nic *efx)
if (rc)
return rc;
efx->board_info.monitor = sfe4002_check_hw;
- efx->board_info.init_leds = sfe4002_init_leds;
+ efx->board_info.init_phy = sfe4002_init_phy;
efx->board_info.set_id_led = sfe4002_set_id_led;
efx->board_info.fini = efx_fini_lm87;
return 0;
@@ -641,7 +648,7 @@ static struct i2c_board_info sfn4112f_hwmon_info = {
#define SFN4112F_ACT_LED 0
#define SFN4112F_LINK_LED 1
-static void sfn4112f_init_leds(struct efx_nic *efx)
+static void sfn4112f_init_phy(struct efx_nic *efx)
{
falcon_qt202x_set_led(efx, SFN4112F_ACT_LED,
QUAKE_LED_RXLINK | QUAKE_LED_LINK_ACT);
@@ -680,7 +687,7 @@ static int sfn4112f_init(struct efx_nic *efx)
if (rc)
return rc;
efx->board_info.monitor = sfn4112f_check_hw;
- efx->board_info.init_leds = sfn4112f_init_leds;
+ efx->board_info.init_phy = sfn4112f_init_phy;
efx->board_info.set_id_led = sfn4112f_set_id_led;
efx->board_info.fini = efx_fini_lm87;
return 0;
diff --git a/drivers/net/sfc/net_driver.h b/drivers/net/sfc/net_driver.h
index 6b05d69..e1df589 100644
--- a/drivers/net/sfc/net_driver.h
+++ b/drivers/net/sfc/net_driver.h
@@ -399,11 +399,11 @@ enum efx_led_mode {
* @type: Board model type
* @major: Major rev. ('A', 'B' ...)
* @minor: Minor rev. (0, 1, ...)
- * @init: Initialisation function
- * @init_leds: Sets up board LEDs. May be called repeatedly.
+ * @init: Allocate resources and initialise peripheral hardware
+ * @init_phy: Do board-specific PHY initialisation
* @set_id_led: Set state of identifying LED or revert to automatic function
* @monitor: Board-specific health check function
- * @fini: Cleanup function
+ * @fini: Shut down hardware and free resources
* @hwmon_client: I2C client for hardware monitor
* @ioexp_client: I2C client for power/port control
*/
@@ -412,10 +412,7 @@ struct efx_board {
int major;
int minor;
int (*init) (struct efx_nic *nic);
- /* As the LEDs are typically attached to the PHY, LEDs
- * have a separate init callback that happens later than
- * board init. */
- void (*init_leds)(struct efx_nic *efx);
+ void (*init_phy) (struct efx_nic *efx);
void (*set_id_led) (struct efx_nic *efx, enum efx_led_mode mode);
int (*monitor) (struct efx_nic *nic);
void (*fini) (struct efx_nic *nic);
diff --git a/drivers/net/sfc/qt202x_phy.c b/drivers/net/sfc/qt202x_phy.c
index 05c0f9a..f26684f 100644
--- a/drivers/net/sfc/qt202x_phy.c
+++ b/drivers/net/sfc/qt202x_phy.c
@@ -126,7 +126,7 @@ static int qt202x_reset_phy(struct efx_nic *efx)
if (rc < 0)
goto fail;
- efx->board_info.init_leds(efx);
+ efx->board_info.init_phy(efx);
return rc;
diff --git a/drivers/net/sfc/tenxpress.c b/drivers/net/sfc/tenxpress.c
index 6a8e3ea..2923e3d 100644
--- a/drivers/net/sfc/tenxpress.c
+++ b/drivers/net/sfc/tenxpress.c
@@ -303,6 +303,8 @@ static int tenxpress_phy_init(struct efx_nic *efx)
u16 old_adv, adv;
int rc = 0;
+ efx->board_info.init_phy(efx);
+
phy_data = kzalloc(sizeof(*phy_data), GFP_KERNEL);
if (!phy_data)
return -ENOMEM;
--
Ben Hutchings, Senior Software Engineer, Solarflare Communications
Not speaking for my employer; that's the marketing department's job.
They asked us to note that Solarflare product names are trademarked.
^ permalink raw reply related
* [PATCH 07/17] sfc: Use a single blink implementation
From: Ben Hutchings @ 2009-11-24 2:03 UTC (permalink / raw)
To: David Miller; +Cc: netdev, linux-net-drivers
Only some PHYs have firmware support for a LED blink mode, so we
currently blink the others in a timer function. Since all PHYs have
simple on and off modes, we don't gain anything by using multiple
blink implementations. Also, since we have a process context there
is no need to use a timer.
Signed-off-by: Ben Hutchings <bhutchings@solarflare.com>
---
drivers/net/sfc/efx.c | 7 ++--
drivers/net/sfc/efx.h | 3 +-
drivers/net/sfc/ethtool.c | 16 +++++----
drivers/net/sfc/falcon_boards.c | 66 +++++++++++++--------------------------
drivers/net/sfc/net_driver.h | 18 +++++------
drivers/net/sfc/phy.h | 2 +-
drivers/net/sfc/qt202x_phy.c | 3 --
drivers/net/sfc/tenxpress.c | 24 +++++++++-----
8 files changed, 62 insertions(+), 77 deletions(-)
diff --git a/drivers/net/sfc/efx.c b/drivers/net/sfc/efx.c
index 0d0243b..612cd81 100644
--- a/drivers/net/sfc/efx.c
+++ b/drivers/net/sfc/efx.c
@@ -1890,7 +1890,9 @@ int efx_port_dummy_op_int(struct efx_nic *efx)
return 0;
}
void efx_port_dummy_op_void(struct efx_nic *efx) {}
-void efx_port_dummy_op_blink(struct efx_nic *efx, bool blink) {}
+void efx_port_dummy_op_set_id_led(struct efx_nic *efx, enum efx_led_mode mode)
+{
+}
static struct efx_mac_operations efx_dummy_mac_operations = {
.reconfigure = efx_port_dummy_op_void,
@@ -1909,9 +1911,8 @@ static struct efx_phy_operations efx_dummy_phy_operations = {
static struct efx_board efx_dummy_board_info = {
.init = efx_port_dummy_op_int,
.init_leds = efx_port_dummy_op_void,
- .set_id_led = efx_port_dummy_op_blink,
+ .set_id_led = efx_port_dummy_op_set_id_led,
.monitor = efx_port_dummy_op_int,
- .blink = efx_port_dummy_op_blink,
.fini = efx_port_dummy_op_void,
};
diff --git a/drivers/net/sfc/efx.h b/drivers/net/sfc/efx.h
index 179e0e3..6f46394 100644
--- a/drivers/net/sfc/efx.h
+++ b/drivers/net/sfc/efx.h
@@ -69,7 +69,8 @@ extern void efx_hex_dump(const u8 *, unsigned int, const char *);
/* Dummy PHY ops for PHY drivers */
extern int efx_port_dummy_op_int(struct efx_nic *efx);
extern void efx_port_dummy_op_void(struct efx_nic *efx);
-extern void efx_port_dummy_op_blink(struct efx_nic *efx, bool blink);
+extern void
+efx_port_dummy_op_set_id_led(struct efx_nic *efx, enum efx_led_mode mode);
/* MTD */
#ifdef CONFIG_SFC_MTD
diff --git a/drivers/net/sfc/ethtool.c b/drivers/net/sfc/ethtool.c
index a313b61..18e0271 100644
--- a/drivers/net/sfc/ethtool.c
+++ b/drivers/net/sfc/ethtool.c
@@ -187,13 +187,15 @@ static int efx_ethtool_phys_id(struct net_device *net_dev, u32 count)
{
struct efx_nic *efx = netdev_priv(net_dev);
- efx->board_info.blink(efx, 1);
- set_current_state(TASK_INTERRUPTIBLE);
- if (count)
- schedule_timeout(count * HZ);
- else
- schedule();
- efx->board_info.blink(efx, 0);
+ do {
+ efx->board_info.set_id_led(efx, EFX_LED_ON);
+ schedule_timeout_interruptible(HZ / 2);
+
+ efx->board_info.set_id_led(efx, EFX_LED_OFF);
+ schedule_timeout_interruptible(HZ / 2);
+ } while (!signal_pending(current) && --count != 0);
+
+ efx->board_info.set_id_led(efx, EFX_LED_DEFAULT);
return 0;
}
diff --git a/drivers/net/sfc/falcon_boards.c b/drivers/net/sfc/falcon_boards.c
index d31c134..b2505fc 100644
--- a/drivers/net/sfc/falcon_boards.c
+++ b/drivers/net/sfc/falcon_boards.c
@@ -29,40 +29,6 @@
#define FALCON_BOARD_SFN4111T 0x51
#define FALCON_BOARD_SFN4112F 0x52
-/* Blink support. If the PHY has no auto-blink mode so we hang it off a timer */
-#define BLINK_INTERVAL (HZ/2)
-
-static void blink_led_timer(unsigned long context)
-{
- struct efx_nic *efx = (struct efx_nic *)context;
- struct efx_board *board = &efx->board_info;
-
- board->set_id_led(efx, board->blink_state);
- board->blink_state = !board->blink_state;
- if (board->blink_resubmit)
- mod_timer(&board->blink_timer, jiffies + BLINK_INTERVAL);
-}
-
-static void board_blink(struct efx_nic *efx, bool blink)
-{
- struct efx_board *board = &efx->board_info;
-
- /* The rtnl mutex serialises all ethtool ioctls, so
- * nothing special needs doing here. */
- if (blink) {
- board->blink_resubmit = true;
- board->blink_state = false;
- setup_timer(&board->blink_timer, blink_led_timer,
- (unsigned long)efx);
- mod_timer(&board->blink_timer, jiffies + BLINK_INTERVAL);
- } else {
- board->blink_resubmit = false;
- if (board->blink_timer.function)
- del_timer_sync(&board->blink_timer);
- board->init_leds(efx);
- }
-}
-
/*****************************************************************************
* Support for LM87 sensor chip used on several boards
*/
@@ -469,7 +435,7 @@ static int sfe4001_init(struct efx_nic *efx)
/* 10Xpress has fixed-function LED pins, so there is no board-specific
* blink code. */
- efx->board_info.blink = tenxpress_phy_blink;
+ efx->board_info.set_id_led = tenxpress_set_id_led;
efx->board_info.monitor = sfe4001_check_hw;
efx->board_info.fini = sfe4001_fini;
@@ -546,7 +512,7 @@ static int sfn4111t_init(struct efx_nic *efx)
if (!efx->board_info.hwmon_client)
return -EIO;
- efx->board_info.blink = tenxpress_phy_blink;
+ efx->board_info.set_id_led = tenxpress_set_id_led;
efx->board_info.monitor = sfn4111t_check_hw;
efx->board_info.fini = sfn4111t_fini;
@@ -619,10 +585,11 @@ static void sfe4002_init_leds(struct efx_nic *efx)
falcon_qt202x_set_led(efx, SFE4002_FAULT_LED, QUAKE_LED_OFF);
}
-static void sfe4002_set_id_led(struct efx_nic *efx, bool state)
+static void sfe4002_set_id_led(struct efx_nic *efx, enum efx_led_mode mode)
{
- falcon_qt202x_set_led(efx, SFE4002_FAULT_LED, state ? QUAKE_LED_ON :
- QUAKE_LED_OFF);
+ falcon_qt202x_set_led(
+ efx, SFE4002_FAULT_LED,
+ (mode == EFX_LED_ON) ? QUAKE_LED_ON : QUAKE_LED_OFF);
}
static int sfe4002_check_hw(struct efx_nic *efx)
@@ -644,7 +611,6 @@ static int sfe4002_init(struct efx_nic *efx)
efx->board_info.monitor = sfe4002_check_hw;
efx->board_info.init_leds = sfe4002_init_leds;
efx->board_info.set_id_led = sfe4002_set_id_led;
- efx->board_info.blink = board_blink;
efx->board_info.fini = efx_fini_lm87;
return 0;
}
@@ -683,10 +649,23 @@ static void sfn4112f_init_leds(struct efx_nic *efx)
QUAKE_LED_RXLINK | QUAKE_LED_LINK_STAT);
}
-static void sfn4112f_set_id_led(struct efx_nic *efx, bool state)
+static void sfn4112f_set_id_led(struct efx_nic *efx, enum efx_led_mode mode)
{
- falcon_qt202x_set_led(efx, SFN4112F_LINK_LED,
- state ? QUAKE_LED_ON : QUAKE_LED_OFF);
+ int reg;
+
+ switch (mode) {
+ case EFX_LED_OFF:
+ reg = QUAKE_LED_OFF;
+ break;
+ case EFX_LED_ON:
+ reg = QUAKE_LED_ON;
+ break;
+ default:
+ reg = QUAKE_LED_RXLINK | QUAKE_LED_LINK_STAT;
+ break;
+ }
+
+ falcon_qt202x_set_led(efx, SFN4112F_LINK_LED, reg);
}
static int sfn4112f_check_hw(struct efx_nic *efx)
@@ -703,7 +682,6 @@ static int sfn4112f_init(struct efx_nic *efx)
efx->board_info.monitor = sfn4112f_check_hw;
efx->board_info.init_leds = sfn4112f_init_leds;
efx->board_info.set_id_led = sfn4112f_set_id_led;
- efx->board_info.blink = board_blink;
efx->board_info.fini = efx_fini_lm87;
return 0;
}
diff --git a/drivers/net/sfc/net_driver.h b/drivers/net/sfc/net_driver.h
index bc6fb2b..6b05d69 100644
--- a/drivers/net/sfc/net_driver.h
+++ b/drivers/net/sfc/net_driver.h
@@ -388,6 +388,12 @@ struct efx_channel {
};
+enum efx_led_mode {
+ EFX_LED_OFF = 0,
+ EFX_LED_ON = 1,
+ EFX_LED_DEFAULT = 2
+};
+
/**
* struct efx_board - board information
* @type: Board model type
@@ -395,13 +401,9 @@ struct efx_channel {
* @minor: Minor rev. (0, 1, ...)
* @init: Initialisation function
* @init_leds: Sets up board LEDs. May be called repeatedly.
- * @set_id_led: Turns the identification LED on or off
- * @blink: Starts/stops blinking
+ * @set_id_led: Set state of identifying LED or revert to automatic function
* @monitor: Board-specific health check function
* @fini: Cleanup function
- * @blink_state: Current blink state
- * @blink_resubmit: Blink timer resubmission flag
- * @blink_timer: Blink timer
* @hwmon_client: I2C client for hardware monitor
* @ioexp_client: I2C client for power/port control
*/
@@ -414,13 +416,9 @@ struct efx_board {
* have a separate init callback that happens later than
* board init. */
void (*init_leds)(struct efx_nic *efx);
- void (*set_id_led) (struct efx_nic *efx, bool state);
+ void (*set_id_led) (struct efx_nic *efx, enum efx_led_mode mode);
int (*monitor) (struct efx_nic *nic);
- void (*blink) (struct efx_nic *efx, bool start);
void (*fini) (struct efx_nic *nic);
- bool blink_state;
- bool blink_resubmit;
- struct timer_list blink_timer;
struct i2c_client *hwmon_client, *ioexp_client;
};
diff --git a/drivers/net/sfc/phy.h b/drivers/net/sfc/phy.h
index b5150f3..2ad1cec 100644
--- a/drivers/net/sfc/phy.h
+++ b/drivers/net/sfc/phy.h
@@ -16,7 +16,7 @@
extern struct efx_phy_operations falcon_sfx7101_phy_ops;
extern struct efx_phy_operations falcon_sft9001_phy_ops;
-extern void tenxpress_phy_blink(struct efx_nic *efx, bool blink);
+extern void tenxpress_set_id_led(struct efx_nic *efx, enum efx_led_mode mode);
/* Wait for the PHY to boot. Return 0 on success, -EINVAL if the PHY failed
* to boot due to corrupt flash, or some other negative error code. */
diff --git a/drivers/net/sfc/qt202x_phy.c b/drivers/net/sfc/qt202x_phy.c
index 560eb18..05c0f9a 100644
--- a/drivers/net/sfc/qt202x_phy.c
+++ b/drivers/net/sfc/qt202x_phy.c
@@ -228,9 +228,6 @@ static void qt202x_phy_get_settings(struct efx_nic *efx, struct ethtool_cmd *ecm
static void qt202x_phy_fini(struct efx_nic *efx)
{
- /* Clobber the LED if it was blinking */
- efx->board_info.blink(efx, false);
-
/* Free the context block */
kfree(efx->phy_data);
efx->phy_data = NULL;
diff --git a/drivers/net/sfc/tenxpress.c b/drivers/net/sfc/tenxpress.c
index 19c78d2..6a8e3ea 100644
--- a/drivers/net/sfc/tenxpress.c
+++ b/drivers/net/sfc/tenxpress.c
@@ -613,21 +613,29 @@ static void tenxpress_phy_fini(struct efx_nic *efx)
}
-/* Set the RX and TX LEDs and Link LED flashing. The other LEDs
- * (which probably aren't wired anyway) are left in AUTO mode */
-void tenxpress_phy_blink(struct efx_nic *efx, bool blink)
+/* Override the RX, TX and link LEDs */
+void tenxpress_set_id_led(struct efx_nic *efx, enum efx_led_mode mode)
{
int reg;
- if (blink)
- reg = (PMA_PMD_LED_FLASH << PMA_PMD_LED_TX_LBN) |
- (PMA_PMD_LED_FLASH << PMA_PMD_LED_RX_LBN) |
- (PMA_PMD_LED_FLASH << PMA_PMD_LED_LINK_LBN);
- else
+ switch (mode) {
+ case EFX_LED_OFF:
+ reg = (PMA_PMD_LED_OFF << PMA_PMD_LED_TX_LBN) |
+ (PMA_PMD_LED_OFF << PMA_PMD_LED_RX_LBN) |
+ (PMA_PMD_LED_OFF << PMA_PMD_LED_LINK_LBN);
+ break;
+ case EFX_LED_ON:
+ reg = (PMA_PMD_LED_ON << PMA_PMD_LED_TX_LBN) |
+ (PMA_PMD_LED_ON << PMA_PMD_LED_RX_LBN) |
+ (PMA_PMD_LED_ON << PMA_PMD_LED_LINK_LBN);
+ break;
+ default:
if (efx->phy_type == PHY_TYPE_SFX7101)
reg = SFX7101_PMA_PMD_LED_DEFAULT;
else
reg = SFT9001_PMA_PMD_LED_DEFAULT;
+ break;
+ }
efx_mdio_write(efx, MDIO_MMD_PMAPMD, PMA_PMD_LED_OVERR_REG, reg);
}
--
Ben Hutchings, Senior Software Engineer, Solarflare Communications
Not speaking for my employer; that's the marketing department's job.
They asked us to note that Solarflare product names are trademarked.
^ permalink raw reply related
* [PATCH 06/17] sfc: SFT9001: Reset LED configuration correctly after blinking
From: Ben Hutchings @ 2009-11-24 2:02 UTC (permalink / raw)
To: David Miller; +Cc: netdev, linux-net-drivers
Signed-off-by: Ben Hutchings <bhutchings@solarflare.com>
---
drivers/net/sfc/tenxpress.c | 11 +++++++----
1 files changed, 7 insertions(+), 4 deletions(-)
diff --git a/drivers/net/sfc/tenxpress.c b/drivers/net/sfc/tenxpress.c
index 390b27b..19c78d2 100644
--- a/drivers/net/sfc/tenxpress.c
+++ b/drivers/net/sfc/tenxpress.c
@@ -83,9 +83,9 @@
#define PMA_PMD_LED_FLASH (3)
#define PMA_PMD_LED_MASK 3
/* All LEDs under hardware control */
-#define PMA_PMD_LED_FULL_AUTO (0)
+#define SFT9001_PMA_PMD_LED_DEFAULT 0
/* Green and Amber under hardware control, Red off */
-#define PMA_PMD_LED_DEFAULT (PMA_PMD_LED_OFF << PMA_PMD_LED_RX_LBN)
+#define SFX7101_PMA_PMD_LED_DEFAULT (PMA_PMD_LED_OFF << PMA_PMD_LED_RX_LBN)
#define PMA_PMD_SPEED_ENABLE_REG 49192
#define PMA_PMD_100TX_ADV_LBN 1
@@ -291,7 +291,7 @@ static int tenxpress_init(struct efx_nic *efx)
efx_mdio_set_flag(efx, MDIO_MMD_PMAPMD, PMA_PMD_LED_CTRL_REG,
1 << PMA_PMA_LED_ACTIVITY_LBN, true);
efx_mdio_write(efx, MDIO_MMD_PMAPMD, PMA_PMD_LED_OVERR_REG,
- PMA_PMD_LED_DEFAULT);
+ SFX7101_PMA_PMD_LED_DEFAULT);
}
return 0;
@@ -624,7 +624,10 @@ void tenxpress_phy_blink(struct efx_nic *efx, bool blink)
(PMA_PMD_LED_FLASH << PMA_PMD_LED_RX_LBN) |
(PMA_PMD_LED_FLASH << PMA_PMD_LED_LINK_LBN);
else
- reg = PMA_PMD_LED_DEFAULT;
+ if (efx->phy_type == PHY_TYPE_SFX7101)
+ reg = SFX7101_PMA_PMD_LED_DEFAULT;
+ else
+ reg = SFT9001_PMA_PMD_LED_DEFAULT;
efx_mdio_write(efx, MDIO_MMD_PMAPMD, PMA_PMD_LED_OVERR_REG, reg);
}
--
Ben Hutchings, Senior Software Engineer, Solarflare Communications
Not speaking for my employer; that's the marketing department's job.
They asked us to note that Solarflare product names are trademarked.
^ permalink raw reply related
* [PATCH 05/17] sfc: Record RX queue number on GRO path
From: Ben Hutchings @ 2009-11-24 2:02 UTC (permalink / raw)
To: David Miller; +Cc: netdev, linux-net-drivers
Signed-off-by: Ben Hutchings <bhutchings@solarflare.com>
---
drivers/net/sfc/rx.c | 6 ++++--
1 files changed, 4 insertions(+), 2 deletions(-)
diff --git a/drivers/net/sfc/rx.c b/drivers/net/sfc/rx.c
index 9e33391..9f22d15 100644
--- a/drivers/net/sfc/rx.c
+++ b/drivers/net/sfc/rx.c
@@ -473,6 +473,8 @@ static void efx_rx_packet_lro(struct efx_channel *channel,
skb->ip_summed =
checksummed ? CHECKSUM_UNNECESSARY : CHECKSUM_NONE;
+ skb_record_rx_queue(skb, channel->channel);
+
gro_result = napi_gro_frags(napi);
} else {
struct sk_buff *skb = rx_buf->skb;
@@ -578,6 +580,8 @@ void __efx_rx_packet(struct efx_channel *channel,
* at the ethernet header */
rx_buf->skb->protocol = eth_type_trans(rx_buf->skb,
efx->net_dev);
+
+ skb_record_rx_queue(rx_buf->skb, channel->channel);
}
if (likely(checksummed || rx_buf->page)) {
@@ -593,8 +597,6 @@ void __efx_rx_packet(struct efx_channel *channel,
/* Set the SKB flags */
skb->ip_summed = CHECKSUM_NONE;
- skb_record_rx_queue(skb, channel->channel);
-
/* Pass the packet up */
netif_receive_skb(skb);
--
Ben Hutchings, Senior Software Engineer, Solarflare Communications
Not speaking for my employer; that's the marketing department's job.
They asked us to note that Solarflare product names are trademarked.
^ permalink raw reply related
* [PATCH 04/17] sfc: Move assertions and buffer cleanup earlier in efx_rx_packet_lro()
From: Ben Hutchings @ 2009-11-24 2:02 UTC (permalink / raw)
To: David Miller; +Cc: netdev, linux-net-drivers
This removes the need to use a label and goto, and makes the two
branches mirror each other more closely.
Signed-off-by: Ben Hutchings <bhutchings@solarflare.com>
---
drivers/net/sfc/rx.c | 26 ++++++++++++++------------
1 files changed, 14 insertions(+), 12 deletions(-)
diff --git a/drivers/net/sfc/rx.c b/drivers/net/sfc/rx.c
index c407352..9e33391 100644
--- a/drivers/net/sfc/rx.c
+++ b/drivers/net/sfc/rx.c
@@ -449,15 +449,19 @@ static void efx_rx_packet_lro(struct efx_channel *channel,
/* Pass the skb/page into the LRO engine */
if (rx_buf->page) {
- struct sk_buff *skb = napi_get_frags(napi);
+ struct page *page = rx_buf->page;
+ struct sk_buff *skb;
+ EFX_BUG_ON_PARANOID(rx_buf->skb);
+ rx_buf->page = NULL;
+
+ skb = napi_get_frags(napi);
if (!skb) {
- put_page(rx_buf->page);
- gro_result = GRO_DROP;
- goto out;
+ put_page(page);
+ return;
}
- skb_shinfo(skb)->frags[0].page = rx_buf->page;
+ skb_shinfo(skb)->frags[0].page = page;
skb_shinfo(skb)->frags[0].page_offset =
efx_rx_buf_offset(rx_buf);
skb_shinfo(skb)->frags[0].size = rx_buf->len;
@@ -470,16 +474,14 @@ static void efx_rx_packet_lro(struct efx_channel *channel,
checksummed ? CHECKSUM_UNNECESSARY : CHECKSUM_NONE;
gro_result = napi_gro_frags(napi);
-
-out:
- EFX_BUG_ON_PARANOID(rx_buf->skb);
- rx_buf->page = NULL;
} else {
- EFX_BUG_ON_PARANOID(!rx_buf->skb);
- EFX_BUG_ON_PARANOID(!checksummed);
+ struct sk_buff *skb = rx_buf->skb;
- gro_result = napi_gro_receive(napi, rx_buf->skb);
+ EFX_BUG_ON_PARANOID(!skb);
+ EFX_BUG_ON_PARANOID(!checksummed);
rx_buf->skb = NULL;
+
+ gro_result = napi_gro_receive(napi, skb);
}
if (gro_result == GRO_NORMAL) {
--
Ben Hutchings, Senior Software Engineer, Solarflare Communications
Not speaking for my employer; that's the marketing department's job.
They asked us to note that Solarflare product names are trademarked.
^ permalink raw reply related
* [PATCH 03/17] sfc: Remove ridiculously paranoid assertions
From: Ben Hutchings @ 2009-11-24 2:01 UTC (permalink / raw)
To: David Miller; +Cc: netdev, linux-net-drivers
Signed-off-by: Ben Hutchings <bhutchings@solarflare.com>
---
drivers/net/sfc/rx.c | 3 ---
1 files changed, 0 insertions(+), 3 deletions(-)
diff --git a/drivers/net/sfc/rx.c b/drivers/net/sfc/rx.c
index 32cfe40..c407352 100644
--- a/drivers/net/sfc/rx.c
+++ b/drivers/net/sfc/rx.c
@@ -586,9 +586,6 @@ void __efx_rx_packet(struct efx_channel *channel,
/* We now own the SKB */
skb = rx_buf->skb;
rx_buf->skb = NULL;
-
- EFX_BUG_ON_PARANOID(rx_buf->page);
- EFX_BUG_ON_PARANOID(rx_buf->skb);
EFX_BUG_ON_PARANOID(!skb);
/* Set the SKB flags */
--
Ben Hutchings, Senior Software Engineer, Solarflare Communications
Not speaking for my employer; that's the marketing department's job.
They asked us to note that Solarflare product names are trademarked.
^ permalink raw reply related
* [PATCH 02/17] sfc: Remove redundant gotos from __efx_rx_packet()
From: Ben Hutchings @ 2009-11-24 2:01 UTC (permalink / raw)
To: David Miller; +Cc: netdev, linux-net-drivers
This function no longer has any common cleanup code.
Signed-off-by: Ben Hutchings <bhutchings@solarflare.com>
---
drivers/net/sfc/rx.c | 7 ++-----
1 files changed, 2 insertions(+), 5 deletions(-)
diff --git a/drivers/net/sfc/rx.c b/drivers/net/sfc/rx.c
index a60c718..32cfe40 100644
--- a/drivers/net/sfc/rx.c
+++ b/drivers/net/sfc/rx.c
@@ -564,7 +564,7 @@ void __efx_rx_packet(struct efx_channel *channel,
if (unlikely(efx->loopback_selftest)) {
efx_loopback_rx_packet(efx, rx_buf->data, rx_buf->len);
efx_free_rx_buffer(efx, rx_buf);
- goto done;
+ return;
}
if (rx_buf->skb) {
@@ -580,7 +580,7 @@ void __efx_rx_packet(struct efx_channel *channel,
if (likely(checksummed || rx_buf->page)) {
efx_rx_packet_lro(channel, rx_buf, checksummed);
- goto done;
+ return;
}
/* We now own the SKB */
@@ -601,9 +601,6 @@ void __efx_rx_packet(struct efx_channel *channel,
/* Update allocation strategy method */
channel->rx_alloc_level += RX_ALLOC_FACTOR_SKB;
-
-done:
- ;
}
void efx_rx_strategy(struct efx_channel *channel)
--
Ben Hutchings, Senior Software Engineer, Solarflare Communications
Not speaking for my employer; that's the marketing department's job.
They asked us to note that Solarflare product names are trademarked.
^ permalink raw reply related
* [PATCH 01/17] sfc: Remove pointless abstraction of memory BAR number (2)
From: Ben Hutchings @ 2009-11-24 2:01 UTC (permalink / raw)
To: David Miller; +Cc: netdev, linux-net-drivers
Finish the job by removing the structure member.
Signed-off-by: Ben Hutchings <bhutchings@solarflare.com>
---
drivers/net/sfc/net_driver.h | 2 --
1 files changed, 0 insertions(+), 2 deletions(-)
diff --git a/drivers/net/sfc/net_driver.h b/drivers/net/sfc/net_driver.h
index bb3d258..bc6fb2b 100644
--- a/drivers/net/sfc/net_driver.h
+++ b/drivers/net/sfc/net_driver.h
@@ -848,7 +848,6 @@ static inline const char *efx_dev_name(struct efx_nic *efx)
/**
* struct efx_nic_type - Efx device type definition
- * @mem_bar: Memory BAR number
* @mem_map_size: Memory BAR mapped size
* @txd_ptr_tbl_base: TX descriptor ring base address
* @rxd_ptr_tbl_base: RX descriptor ring base address
@@ -863,7 +862,6 @@ static inline const char *efx_dev_name(struct efx_nic *efx)
* descriptors
*/
struct efx_nic_type {
- unsigned int mem_bar;
unsigned int mem_map_size;
unsigned int txd_ptr_tbl_base;
unsigned int rxd_ptr_tbl_base;
--
Ben Hutchings, Senior Software Engineer, Solarflare Communications
Not speaking for my employer; that's the marketing department's job.
They asked us to note that Solarflare product names are trademarked.
^ permalink raw reply related
* Re: macvlan: fix gso_max_size setting
From: Herbert Xu @ 2009-11-24 1:08 UTC (permalink / raw)
To: Patrick McHardy; +Cc: David Miller, netdev
In-Reply-To: <4B0B0DA1.7010403@trash.net>
On Mon, Nov 23, 2009 at 11:33:05PM +0100, Patrick McHardy wrote:
>
> Perhaps we should simply fall back to software in that case.
> Compile tested only.
Sure.
Since ixgbe appears to be the only driver in our entire tree
that has this limitation, I think it might make more sense to
move this special-case check into it and get it to do software
GSO just like tg3 does for a few other cases that the hardware
can't handle.
Cheers,
--
Visit Openswan at http://www.openswan.org/
Email: Herbert Xu ~{PmV>HI~} <herbert@gondor.apana.org.au>
Home Page: http://gondor.apana.org.au/~herbert/
PGP Key: http://gondor.apana.org.au/~herbert/pubkey.txt
^ permalink raw reply
* [PATCH 4/4] macvlan: export macvlan mode through netlink
From: Arnd Bergmann @ 2009-11-24 0:56 UTC (permalink / raw)
To: Arnd Bergmann
Cc: Eric Dumazet, linux-kernel, netdev, David Miller,
Stephen Hemminger, Herbert Xu, Patrick Mullaney,
Eric W. Biederman, Edge Virtual Bridging, Anna Fischer, bridge,
virtualization, Jens Osterkamp, Gerhard Stenzel, Patrick McHardy,
Mark Smith, Arnd Bergmann
In-Reply-To: <1259024166-28158-1-git-send-email-arnd@arndb.de>
In order to support all three modes of macvlan at
runtime, extend the existing netlink protocol
to allow choosing the mode per macvlan slave
interface.
This depends on a matching patch to iproute2
in order to become accessible in user land.
Signed-off-by: Arnd Bergmann <arnd@arndb.de>
---
drivers/net/macvlan.c | 63 ++++++++++++++++++++++++++++++++++++++++++----
include/linux/if_link.h | 15 +++++++++++
2 files changed, 72 insertions(+), 6 deletions(-)
diff --git a/drivers/net/macvlan.c b/drivers/net/macvlan.c
index b840b3a..3db96b9 100644
--- a/drivers/net/macvlan.c
+++ b/drivers/net/macvlan.c
@@ -33,12 +33,6 @@
#define MACVLAN_HASH_SIZE (1 << BITS_PER_BYTE)
-enum macvlan_mode {
- MACVLAN_MODE_PRIVATE = 1,
- MACVLAN_MODE_VEPA = 2,
- MACVLAN_MODE_BRIDGE = 4,
-};
-
struct macvlan_port {
struct net_device *dev;
struct hlist_head vlan_hash[MACVLAN_HASH_SIZE];
@@ -600,6 +594,18 @@ static int macvlan_validate(struct nlattr *tb[], struct nlattr *data[])
if (!is_valid_ether_addr(nla_data(tb[IFLA_ADDRESS])))
return -EADDRNOTAVAIL;
}
+
+ if (data && data[IFLA_MACVLAN_MODE]) {
+ u32 mode = nla_get_u32(data[IFLA_MACVLAN_MODE]);
+ switch (mode) {
+ case MACVLAN_MODE_PRIVATE:
+ case MACVLAN_MODE_VEPA:
+ case MACVLAN_MODE_BRIDGE:
+ break;
+ default:
+ return -EINVAL;
+ }
+ }
return 0;
}
@@ -664,6 +670,13 @@ static int macvlan_newlink(struct net *src_net, struct net_device *dev,
vlan->dev = dev;
vlan->port = port;
+ vlan->mode = MACVLAN_MODE_VEPA;
+ if (data && data[IFLA_MACVLAN_MODE]) {
+ u32 mode = nla_get_u32(data[IFLA_MACVLAN_MODE]);
+
+ vlan->mode = mode;
+ }
+
err = register_netdevice(dev);
if (err < 0)
return err;
@@ -685,6 +698,39 @@ static void macvlan_dellink(struct net_device *dev, struct list_head *head)
macvlan_port_destroy(port->dev);
}
+static int macvlan_changelink(struct net_device *dev,
+ struct nlattr *tb[], struct nlattr *data[])
+{
+ struct macvlan_dev *vlan = netdev_priv(dev);
+ if (data && data[IFLA_MACVLAN_MODE]) {
+ u32 mode = nla_get_u32(data[IFLA_MACVLAN_MODE]);
+ vlan->mode = mode;
+ }
+
+ return 0;
+}
+
+static size_t macvlan_get_size(const struct net_device *dev)
+{
+ return nla_total_size(4);
+}
+
+static int macvlan_fill_info(struct sk_buff *skb,
+ const struct net_device *dev)
+{
+ struct macvlan_dev *vlan = netdev_priv(dev);
+
+ NLA_PUT_U32(skb, IFLA_MACVLAN_MODE, vlan->mode);
+ return 0;
+
+nla_put_failure:
+ return -EMSGSIZE;
+}
+
+static const struct nla_policy macvlan_policy[IFLA_MACVLAN_MAX + 1] = {
+ [IFLA_MACVLAN_MODE] = { .type = NLA_U32 },
+};
+
static struct rtnl_link_ops macvlan_link_ops __read_mostly = {
.kind = "macvlan",
.priv_size = sizeof(struct macvlan_dev),
@@ -693,6 +739,11 @@ static struct rtnl_link_ops macvlan_link_ops __read_mostly = {
.validate = macvlan_validate,
.newlink = macvlan_newlink,
.dellink = macvlan_dellink,
+ .maxtype = IFLA_MACVLAN_MAX,
+ .policy = macvlan_policy,
+ .changelink = macvlan_changelink,
+ .get_size = macvlan_get_size,
+ .fill_info = macvlan_fill_info,
};
static int macvlan_device_event(struct notifier_block *unused,
diff --git a/include/linux/if_link.h b/include/linux/if_link.h
index 1d3b242..6674791 100644
--- a/include/linux/if_link.h
+++ b/include/linux/if_link.h
@@ -181,4 +181,19 @@ struct ifla_vlan_qos_mapping {
__u32 to;
};
+/* MACVLAN section */
+enum {
+ IFLA_MACVLAN_UNSPEC,
+ IFLA_MACVLAN_MODE,
+ __IFLA_MACVLAN_MAX,
+};
+
+#define IFLA_MACVLAN_MAX (__IFLA_MACVLAN_MAX - 1)
+
+enum macvlan_mode {
+ MACVLAN_MODE_PRIVATE = 1, /* don't talk to other macvlans */
+ MACVLAN_MODE_VEPA = 2, /* talk to other ports through ext bridge */
+ MACVLAN_MODE_BRIDGE = 4, /* talk to bridge ports directly */
+};
+
#endif /* _LINUX_IF_LINK_H */
--
1.6.3.3
^ permalink raw reply related
* [PATCH 3/4] macvlan: implement bridge, VEPA and private mode
From: Arnd Bergmann @ 2009-11-24 0:56 UTC (permalink / raw)
To: Arnd Bergmann
Cc: Herbert Xu, Eric Dumazet, Anna Fischer, netdev, bridge,
linux-kernel, virtualization, Mark Smith, Gerhard Stenzel,
Arnd Bergmann, Eric W. Biederman, Jens Osterkamp,
Patrick Mullaney, Stephen Hemminger, Edge Virtual Bridging,
David Miller
In-Reply-To: <1259024166-28158-1-git-send-email-arnd@arndb.de>
This allows each macvlan slave device to be in one
of three modes, depending on the use case:
MACVLAN_PRIVATE:
The device never communicates with any other device
on the same upper_dev. This even includes frames
coming back from a reflective relay, where supported
by the adjacent bridge.
MACVLAN_VEPA:
The new Virtual Ethernet Port Aggregator (VEPA) mode,
we assume that the adjacent bridge returns all frames
where both source and destination are local to the
macvlan port, i.e. the bridge is set up as a reflective
relay.
Broadcast frames coming in from the upper_dev get
flooded to all macvlan interfaces in VEPA mode.
We never deliver any frames locally.
MACVLAN_BRIDGE:
We provide the behavior of a simple bridge between
different macvlan interfaces on the same port. Frames
from one interface to another one get delivered directly
and are not sent out externally. Broadcast frames get
flooded to all other bridge ports and to the external
interface, but when they come back from a reflective
relay, we don't deliver them again.
Since we know all the MAC addresses, the macvlan bridge
mode does not require learning or STP like the bridge
module does.
Based on an earlier patch "macvlan: Reflect macvlan packets
meant for other macvlan devices" by Eric Biederman.
Signed-off-by: Arnd Bergmann <arnd@arndb.de>
Cc: Eric Biederman <ebiederm@xmission.com>
---
drivers/net/macvlan.c | 75 +++++++++++++++++++++++++++++++++++++++++++-----
1 files changed, 67 insertions(+), 8 deletions(-)
diff --git a/drivers/net/macvlan.c b/drivers/net/macvlan.c
index a0dea23..b840b3a 100644
--- a/drivers/net/macvlan.c
+++ b/drivers/net/macvlan.c
@@ -29,9 +29,16 @@
#include <linux/if_link.h>
#include <linux/if_macvlan.h>
#include <net/rtnetlink.h>
+#include <net/xfrm.h>
#define MACVLAN_HASH_SIZE (1 << BITS_PER_BYTE)
+enum macvlan_mode {
+ MACVLAN_MODE_PRIVATE = 1,
+ MACVLAN_MODE_VEPA = 2,
+ MACVLAN_MODE_BRIDGE = 4,
+};
+
struct macvlan_port {
struct net_device *dev;
struct hlist_head vlan_hash[MACVLAN_HASH_SIZE];
@@ -59,6 +66,7 @@ struct macvlan_dev {
struct macvlan_port *port;
struct net_device *lowerdev;
struct macvlan_rx_stats *rx_stats;
+ enum macvlan_mode mode;
};
@@ -129,11 +137,14 @@ static inline void macvlan_count_rx(const struct macvlan_dev *vlan, int length,
}
static int macvlan_broadcast_one(struct sk_buff *skb, struct net_device *dev,
- const struct ethhdr *eth)
+ const struct ethhdr *eth, int local)
{
if (!skb)
return NET_RX_DROP;
+ if (local)
+ return dev_forward_skb(dev, skb);
+
skb->dev = dev;
if (!compare_ether_addr_64bits(eth->h_dest,
dev->broadcast))
@@ -145,7 +156,9 @@ static int macvlan_broadcast_one(struct sk_buff *skb, struct net_device *dev,
}
static void macvlan_broadcast(struct sk_buff *skb,
- const struct macvlan_port *port)
+ const struct macvlan_port *port,
+ struct net_device *src,
+ enum macvlan_mode mode)
{
const struct ethhdr *eth = eth_hdr(skb);
const struct macvlan_dev *vlan;
@@ -159,8 +172,12 @@ static void macvlan_broadcast(struct sk_buff *skb,
for (i = 0; i < MACVLAN_HASH_SIZE; i++) {
hlist_for_each_entry_rcu(vlan, n, &port->vlan_hash[i], hlist) {
+ if ((vlan->dev == src) || !(vlan->mode & mode))
+ continue;
+
nskb = skb_clone(skb, GFP_ATOMIC);
- err = macvlan_broadcast_one(nskb, vlan->dev, eth);
+ err = macvlan_broadcast_one(nskb, vlan->dev, eth,
+ mode == MACVLAN_MODE_BRIDGE);
macvlan_count_rx(vlan, skb->len + ETH_HLEN,
likely(err == NET_RX_SUCCESS), 1);
}
@@ -173,6 +190,7 @@ static struct sk_buff *macvlan_handle_frame(struct sk_buff *skb)
const struct ethhdr *eth = eth_hdr(skb);
const struct macvlan_port *port;
const struct macvlan_dev *vlan;
+ const struct macvlan_dev *src;
struct net_device *dev;
port = rcu_dereference(skb->dev->macvlan_port);
@@ -180,7 +198,20 @@ static struct sk_buff *macvlan_handle_frame(struct sk_buff *skb)
return skb;
if (is_multicast_ether_addr(eth->h_dest)) {
- macvlan_broadcast(skb, port);
+ src = macvlan_hash_lookup(port, eth->h_source);
+ if (!src)
+ /* frame comes from an external address */
+ macvlan_broadcast(skb, port, NULL, MACVLAN_MODE_PRIVATE
+ | MACVLAN_MODE_VEPA | MACVLAN_MODE_BRIDGE);
+ else if (src->mode == MACVLAN_MODE_VEPA)
+ /* flood to everyone except source */
+ macvlan_broadcast(skb, port, src->dev,
+ MACVLAN_MODE_VEPA | MACVLAN_MODE_BRIDGE);
+ else if (src->mode == MACVLAN_MODE_BRIDGE)
+ /* flood only to VEPA ports, bridge ports
+ already saw the frame */
+ macvlan_broadcast(skb, port, src->dev,
+ MACVLAN_MODE_VEPA);
return skb;
}
@@ -203,18 +234,46 @@ static struct sk_buff *macvlan_handle_frame(struct sk_buff *skb)
return NULL;
}
+static int macvlan_queue_xmit(struct sk_buff *skb, struct net_device *dev)
+{
+ const struct macvlan_dev *vlan = netdev_priv(dev);
+ const struct macvlan_port *port = vlan->port;
+ const struct macvlan_dev *dest;
+
+ if (vlan->mode == MACVLAN_MODE_BRIDGE) {
+ const struct ethhdr *eth = (void *)skb->data;
+
+ /* send to other bridge ports directly */
+ if (is_multicast_ether_addr(eth->h_dest)) {
+ macvlan_broadcast(skb, port, dev, MACVLAN_MODE_BRIDGE);
+ goto xmit_world;
+ }
+
+ dest = macvlan_hash_lookup(port, eth->h_dest);
+ if (dest && dest->mode == MACVLAN_MODE_BRIDGE) {
+ int length = skb->len + ETH_HLEN;
+ int ret = dev_forward_skb(dest->dev, skb);
+ macvlan_count_rx(dest, length,
+ likely(ret == NET_RX_SUCCESS), 0);
+
+ return NET_XMIT_SUCCESS;
+ }
+ }
+
+xmit_world:
+ skb->dev = vlan->lowerdev;
+ return dev_queue_xmit(skb);
+}
+
static netdev_tx_t macvlan_start_xmit(struct sk_buff *skb,
struct net_device *dev)
{
int i = skb_get_queue_mapping(skb);
struct netdev_queue *txq = netdev_get_tx_queue(dev, i);
- const struct macvlan_dev *vlan = netdev_priv(dev);
unsigned int len = skb->len;
int ret;
- skb->dev = vlan->lowerdev;
- ret = dev_queue_xmit(skb);
-
+ ret = macvlan_queue_xmit(skb, dev);
if (likely(ret == NET_XMIT_SUCCESS)) {
txq->tx_packets++;
txq->tx_bytes += len;
--
1.6.3.3
^ permalink raw reply related
* [PATCH 2/4] macvlan: cleanup rx statistics
From: Arnd Bergmann @ 2009-11-24 0:56 UTC (permalink / raw)
To: Arnd Bergmann
Cc: Eric Dumazet, linux-kernel, netdev, David Miller,
Stephen Hemminger, Herbert Xu, Patrick Mullaney,
Eric W. Biederman, Edge Virtual Bridging, Anna Fischer, bridge,
virtualization, Jens Osterkamp, Gerhard Stenzel, Patrick McHardy,
Mark Smith, Arnd Bergmann
In-Reply-To: <1259024166-28158-1-git-send-email-arnd@arndb.de>
We have very similar code for rx statistics in
two places in the macvlan driver, with a third
one being added in the next patch.
Consolidate them into one function to improve
overall readability of the driver.
Signed-off-by: Arnd Bergmann <arnd@arndb.de>
---
drivers/net/macvlan.c | 63 +++++++++++++++++++++++++-----------------------
1 files changed, 33 insertions(+), 30 deletions(-)
diff --git a/drivers/net/macvlan.c b/drivers/net/macvlan.c
index ae2b5c7..a0dea23 100644
--- a/drivers/net/macvlan.c
+++ b/drivers/net/macvlan.c
@@ -116,42 +116,53 @@ static int macvlan_addr_busy(const struct macvlan_port *port,
return 0;
}
+static inline void macvlan_count_rx(const struct macvlan_dev *vlan, int length,
+ int success, int multicast)
+{
+ struct macvlan_rx_stats *rx_stats;
+
+ rx_stats = per_cpu_ptr(vlan->rx_stats, smp_processor_id());
+ rx_stats->rx_packets += success != 0;
+ rx_stats->rx_bytes += success ? length : 0;
+ rx_stats->multicast += success && multicast;
+ rx_stats->rx_errors += !success;
+}
+
+static int macvlan_broadcast_one(struct sk_buff *skb, struct net_device *dev,
+ const struct ethhdr *eth)
+{
+ if (!skb)
+ return NET_RX_DROP;
+
+ skb->dev = dev;
+ if (!compare_ether_addr_64bits(eth->h_dest,
+ dev->broadcast))
+ skb->pkt_type = PACKET_BROADCAST;
+ else
+ skb->pkt_type = PACKET_MULTICAST;
+
+ return netif_rx(skb);
+}
+
static void macvlan_broadcast(struct sk_buff *skb,
const struct macvlan_port *port)
{
const struct ethhdr *eth = eth_hdr(skb);
const struct macvlan_dev *vlan;
struct hlist_node *n;
- struct net_device *dev;
struct sk_buff *nskb;
unsigned int i;
- struct macvlan_rx_stats *rx_stats;
+ int err;
if (skb->protocol == htons(ETH_P_PAUSE))
return;
for (i = 0; i < MACVLAN_HASH_SIZE; i++) {
hlist_for_each_entry_rcu(vlan, n, &port->vlan_hash[i], hlist) {
- dev = vlan->dev;
- rx_stats = per_cpu_ptr(vlan->rx_stats, smp_processor_id());
-
nskb = skb_clone(skb, GFP_ATOMIC);
- if (nskb == NULL) {
- rx_stats->rx_errors++;
- continue;
- }
-
- rx_stats->rx_bytes += skb->len + ETH_HLEN;
- rx_stats->rx_packets++;
- rx_stats->multicast++;
-
- nskb->dev = dev;
- if (!compare_ether_addr_64bits(eth->h_dest, dev->broadcast))
- nskb->pkt_type = PACKET_BROADCAST;
- else
- nskb->pkt_type = PACKET_MULTICAST;
-
- netif_rx(nskb);
+ err = macvlan_broadcast_one(nskb, vlan->dev, eth);
+ macvlan_count_rx(vlan, skb->len + ETH_HLEN,
+ likely(err == NET_RX_SUCCESS), 1);
}
}
}
@@ -163,7 +174,6 @@ static struct sk_buff *macvlan_handle_frame(struct sk_buff *skb)
const struct macvlan_port *port;
const struct macvlan_dev *vlan;
struct net_device *dev;
- struct macvlan_rx_stats *rx_stats;
port = rcu_dereference(skb->dev->macvlan_port);
if (port == NULL)
@@ -183,15 +193,8 @@ static struct sk_buff *macvlan_handle_frame(struct sk_buff *skb)
kfree_skb(skb);
return NULL;
}
- rx_stats = per_cpu_ptr(vlan->rx_stats, smp_processor_id());
skb = skb_share_check(skb, GFP_ATOMIC);
- if (skb == NULL) {
- rx_stats->rx_errors++;
- return NULL;
- }
-
- rx_stats->rx_bytes += skb->len + ETH_HLEN;
- rx_stats->rx_packets++;
+ macvlan_count_rx(vlan, skb->len + ETH_HLEN, likely(skb != NULL), 0);
skb->dev = dev;
skb->pkt_type = PACKET_HOST;
--
1.6.3.3
^ permalink raw reply related
* [PATCH 1/4] veth: move loopback logic to common location
From: Arnd Bergmann @ 2009-11-24 0:56 UTC (permalink / raw)
To: Arnd Bergmann
Cc: Eric Dumazet, linux-kernel, netdev, David Miller,
Stephen Hemminger, Herbert Xu, Patrick Mullaney,
Eric W. Biederman, Edge Virtual Bridging, Anna Fischer, bridge,
virtualization, Jens Osterkamp, Gerhard Stenzel, Patrick McHardy,
Mark Smith, Arnd Bergmann
In-Reply-To: <1259024166-28158-1-git-send-email-arnd@arndb.de>
The veth driver contains code to forward an skb
from the start_xmit function of one network
device into the receive path of another device.
Moving that code into a common location lets us
reuse the code for direct forwarding of data
between macvlan ports, and possibly in other
drivers.
Signed-off-by: Arnd Bergmann <arnd@arndb.de>
---
drivers/net/veth.c | 17 +++--------------
include/linux/netdevice.h | 2 ++
net/core/dev.c | 36 ++++++++++++++++++++++++++++++++++++
3 files changed, 41 insertions(+), 14 deletions(-)
diff --git a/drivers/net/veth.c b/drivers/net/veth.c
index 2d657f2..6c4b5a2 100644
--- a/drivers/net/veth.c
+++ b/drivers/net/veth.c
@@ -155,8 +155,6 @@ static netdev_tx_t veth_xmit(struct sk_buff *skb, struct net_device *dev)
struct veth_net_stats *stats, *rcv_stats;
int length, cpu;
- skb_orphan(skb);
-
priv = netdev_priv(dev);
rcv = priv->peer;
rcv_priv = netdev_priv(rcv);
@@ -168,20 +166,12 @@ static netdev_tx_t veth_xmit(struct sk_buff *skb, struct net_device *dev)
if (!(rcv->flags & IFF_UP))
goto tx_drop;
- if (skb->len > (rcv->mtu + MTU_PAD))
- goto rx_drop;
-
- skb->tstamp.tv64 = 0;
- skb->pkt_type = PACKET_HOST;
- skb->protocol = eth_type_trans(skb, rcv);
if (dev->features & NETIF_F_NO_CSUM)
skb->ip_summed = rcv_priv->ip_summed;
- skb->mark = 0;
- secpath_reset(skb);
- nf_reset(skb);
-
- length = skb->len;
+ length = skb->len + ETH_HLEN;
+ if (dev_forward_skb(rcv, skb) != NET_RX_SUCCESS)
+ goto rx_drop;
stats->tx_bytes += length;
stats->tx_packets++;
@@ -189,7 +179,6 @@ static netdev_tx_t veth_xmit(struct sk_buff *skb, struct net_device *dev)
rcv_stats->rx_bytes += length;
rcv_stats->rx_packets++;
- netif_rx(skb);
return NETDEV_TX_OK;
tx_drop:
diff --git a/include/linux/netdevice.h b/include/linux/netdevice.h
index 97873e3..9428793 100644
--- a/include/linux/netdevice.h
+++ b/include/linux/netdevice.h
@@ -1562,6 +1562,8 @@ extern int dev_set_mac_address(struct net_device *,
extern int dev_hard_start_xmit(struct sk_buff *skb,
struct net_device *dev,
struct netdev_queue *txq);
+extern int dev_forward_skb(struct net_device *dev,
+ struct sk_buff *skb);
extern int netdev_budget;
diff --git a/net/core/dev.c b/net/core/dev.c
index ccefa24..ba18e82 100644
--- a/net/core/dev.c
+++ b/net/core/dev.c
@@ -105,6 +105,7 @@
#include <net/dst.h>
#include <net/pkt_sched.h>
#include <net/checksum.h>
+#include <net/xfrm.h>
#include <linux/highmem.h>
#include <linux/init.h>
#include <linux/kmod.h>
@@ -1419,6 +1420,41 @@ static inline void net_timestamp(struct sk_buff *skb)
skb->tstamp.tv64 = 0;
}
+/**
+ * dev_forward_skb - loopback an skb to another netif
+ *
+ * @dev: destination network device
+ * @skb: buffer to forward
+ *
+ * return values:
+ * NET_RX_SUCCESS (no congestion)
+ * NET_RX_DROP (packet was dropped)
+ *
+ * dev_forward_skb can be used for injecting an skb from the
+ * start_xmit function of one device into the receive queue
+ * of another device.
+ */
+int dev_forward_skb(struct net_device *dev, struct sk_buff *skb)
+{
+ skb_orphan(skb);
+
+ if (!(dev->flags & IFF_UP))
+ return NET_RX_DROP;
+
+ if (skb->len > (dev->mtu + dev->hard_header_len))
+ return NET_RX_DROP;
+
+ skb_dst_drop(skb);
+ skb->tstamp.tv64 = 0;
+ skb->pkt_type = PACKET_HOST;
+ skb->protocol = eth_type_trans(skb, dev);
+ skb->mark = 0;
+ secpath_reset(skb);
+ nf_reset(skb);
+ return netif_rx(skb);
+}
+EXPORT_SYMBOL_GPL(dev_forward_skb);
+
/*
* Support routine. Sends outgoing frames to any network
* taps currently in use.
--
1.6.3.3
^ permalink raw reply related
* [PATCHv2 0/4] macvlan: add vepa and bridge mode
From: Arnd Bergmann @ 2009-11-24 0:56 UTC (permalink / raw)
To: Arnd Bergmann
Cc: Eric Dumazet, linux-kernel, netdev, David Miller,
Stephen Hemminger, Herbert Xu, Patrick Mullaney,
Eric W. Biederman, Edge Virtual Bridging, Anna Fischer, bridge,
virtualization, Jens Osterkamp, Gerhard Stenzel, Patrick McHardy,
Mark Smith, Arnd Bergmann
Second version, all feedback so far addressed, thanks for the
help and interest!
The patch to iproute2 has not changed, so I'm not including
it this time. Patch 4/4 (the netlink interface) is basically
unchanged as well but included for completeness.
The other changes have moved forward a bit, to the point where
I find them a lot cleaner and am more confident in the code
being ready for inclusion. The implementation hardly resembles
Erics original patch now, so I've dropped his signed-off-by.
Please take a look and ack if you are happy so we can get it
into 2.6.33.
---
Version 1 description:
This is based on an earlier patch from Eric Biederman adding
forwarding between macvlans. I extended his approach to
allow the administrator to choose the mode for each macvlan,
and to implement a functional VEPA between macvlan.
Still missing from this is support for communication between
the lower device that the macvlans are based on. This would
be extremely useful but as others have found out before me
requires significant changes not only to macvlan but also
to the common transmit path.
I've tested VEPA operation with the hairpin support
added to the bridge driver by Anna Fischer.
Arnd <><
Arnd Bergmann (4):
veth: move loopback logic to common location
macvlan: cleanup rx statistics
macvlan: implement bridge, VEPA and private mode
macvlan: export macvlan mode through netlink
drivers/net/macvlan.c | 183 ++++++++++++++++++++++++++++++++++++---------
drivers/net/veth.c | 17 +----
include/linux/if_link.h | 15 ++++
include/linux/netdevice.h | 2 +
net/core/dev.c | 36 +++++++++
5 files changed, 204 insertions(+), 49 deletions(-)
^ permalink raw reply
* Re: icmp redirects problem
From: Alex Samad @ 2009-11-24 0:12 UTC (permalink / raw)
To: Jarek Poplawski; +Cc: netdev
In-Reply-To: <4B0B058E.3050906@gmail.com>
[-- Attachment #1: Type: text/plain, Size: 1965 bytes --]
On Mon, Nov 23, 2009 at 10:58:38PM +0100, Jarek Poplawski wrote:
> Alex Samad wrote, On 11/23/2009 05:31 AM:
>
[snip]
> >
> > laptop gets its ip from dchp server that make 192.168.11.1 the default
> > gateway and its 192.168.11.1 that sends out the icmp redirect.
>
> Btw, it seems you should fix your routing (by adding sydrt01's eth0
> the second ip or advertising 192.168.11.10 more) to avoid those
> redirects.
sorry I am lost on this statement, I can't add 192.168.11.10 to sydrt01
as it is not physically connected to the 192.168.10.0/24 any more, which
is why I had added the route on sydrt01 and which is why it send
icmp_rediercts.
I have updated the route table on each static machine, but the problem
is on the machines that get their ip via dhcp - I haven't looked at
pushing out route information via dhcp - I am not sure that it would
work in a mixed windows / linux environment.
what do you mean by advertising 192.168.11.10 more ?
>
> >
> > I had a quick look at the kernel tree for 2.6.31 (which is what I am
> > using).
>
> ...
>
> > Line 680
> > secure_redirects - BOOLEAN
> > 681 Accept ICMP redirect messages only for gateways,
> > 682 listed in default gateway list.
> > 683 secure_redirects for the interface will be enabled if at
> > least one of
> > 684 conf/{all,interface}/secure_redirects is set to TRUE,
> > 685 it will be disabled otherwise
> > 686 default TRUE
>
> Very helpful links. So, as you wrote "the documentation seems to suggest"
> something, and IMHO even if it doesn't, it's needlessly too concise
> considering your "lost time", and I'd suggest you sending a patch to fix
> this. (It seems it could "touch" shared_media, as well.)
Which is wrong the code or the documentation and which part the test or
the reliance on the shared_media or on the redirects flags
>
> Thanks,
> Jarek P.
>
[-- Attachment #2: Digital signature --]
[-- Type: application/pgp-signature, Size: 198 bytes --]
^ 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