* Re: spamm of cfg80211: Calling CRDA to update world regulatory domain
From: Thomas Backlund @ 2011-11-01 18:44 UTC (permalink / raw)
To: Justin P. Mattock; +Cc: linux-kernel, netdev, linux-wireless
In-Reply-To: <4EB00DD3.7090701@gmail.com>
Justin P. Mattock skrev 1.11.2011 17:18:
> is there a way to get rid of this annoying spamming of the regulatory?
>
>
> [ 338.519037] cfg80211: Calling CRDA to update world regulatory domain
> [ 338.523266] cfg80211: World regulatory domain updated:
> [ 338.523269] cfg80211: (start_freq - end_freq @ bandwidth),
> (max_antenna_gain, max_eirp)
> [ 338.523272] cfg80211: (2402000 KHz - 2472000 KHz @ 40000 KHz), (300
> mBi, 2000 mBm)
> [ 338.523276] cfg80211: (2457000 KHz - 2482000 KHz @ 20000 KHz), (300
> mBi, 2000 mBm)
> [ 338.523279] cfg80211: (2474000 KHz - 2494000 KHz @ 20000 KHz), (300
> mBi, 2000 mBm)
> [ 338.523281] cfg80211: (5170000 KHz - 5250000 KHz @ 40000 KHz), (300
> mBi, 2000 mBm)
> [ 338.523284] cfg80211: (5735000 KHz - 5835000 KHz @ 40000 KHz), (300
> mBi, 2000 mBm)
> [ 340.948738] wlan1: authenticate with 00:1d:a2:d8:7e:70 (try 1)
> [ 340.950479] wlan1: authenticated
> [ 340.950707] wlan1: associate with 00:1d:a2:d8:7e:70 (try 1)
> [ 340.953611] wlan1: RX ReassocResp from 00:1d:a2:d8:7e:70 (capab=0x401
> status=0 aid=79)
> [ 340.953614] wlan1: associated
> [ 458.646604] wlan1: deauthenticated from 00:1d:a2:d8:7e:70 (Reason: 2)
>
>
> my entire syslog is filled with the above.
>
Are you using networkmanager or systemd or even both ?
Atleast at some point networkmanager have had problems when trying to
activate wireless faster than the hw like, so you get into
auth/deauth loop, and for every time interface restart gets detected,
setting crda gets triggered.
For me systemd also has had the same problems for me from time to time,
and the only way to get wireless up then is to disable it for a
~5+ seconds with the hw killswitch, and when I re-enable it, network
comes up as intended.
This happends for me with atleast 3.0 and 3.1 kernels and Intel 4965AGN
wireless connecting to a 11N 5GHz AP.
--
Thomas
^ permalink raw reply
* [PATCH 16/18] net/irda: convert au1k_ir to platform driver.
From: Manuel Lauss @ 2011-11-01 19:03 UTC (permalink / raw)
To: Linux-MIPS, Ralf Baechle; +Cc: Manuel Lauss, Samuel Ortiz, netdev
In-Reply-To: <1320174224-27305-1-git-send-email-manuel.lauss@googlemail.com>
Moderate driver cleanup:
convert to platform driver, get rid of board-specific code.
Driver loads and runs on a DB1100 board. But since I have no other
IrDA hardware to exchange data with I can't say whether it really sends
and receives.
Cc: Samuel Ortiz <samuel@sortiz.org>
Cc: netdev@vger.kernel.org
Signed-off-by: Manuel Lauss <manuel.lauss@googlemail.com>
---
I'd like for this to go in via the MIPS tree since other mips patches depend
on it.
arch/mips/include/asm/mach-au1x00/au1000.h | 52 +-
drivers/net/irda/Kconfig | 6 +-
drivers/net/irda/au1000_ircc.h | 125 ---
drivers/net/irda/au1k_ir.c | 1226 +++++++++++++++------------
4 files changed, 700 insertions(+), 709 deletions(-)
delete mode 100644 drivers/net/irda/au1000_ircc.h
diff --git a/arch/mips/include/asm/mach-au1x00/au1000.h b/arch/mips/include/asm/mach-au1x00/au1000.h
index 65f1262..569828d 100644
--- a/arch/mips/include/asm/mach-au1x00/au1000.h
+++ b/arch/mips/include/asm/mach-au1x00/au1000.h
@@ -1265,44 +1265,20 @@ enum soc_au1200_ints {
#define SSI_ENABLE_CD (1 << 1)
#define SSI_ENABLE_E (1 << 0)
-/* IrDA Controller */
-#define IRDA_BASE 0xB0300000
-#define IR_RING_PTR_STATUS (IRDA_BASE + 0x00)
-#define IR_RING_BASE_ADDR_H (IRDA_BASE + 0x04)
-#define IR_RING_BASE_ADDR_L (IRDA_BASE + 0x08)
-#define IR_RING_SIZE (IRDA_BASE + 0x0C)
-#define IR_RING_PROMPT (IRDA_BASE + 0x10)
-#define IR_RING_ADDR_CMPR (IRDA_BASE + 0x14)
-#define IR_INT_CLEAR (IRDA_BASE + 0x18)
-#define IR_CONFIG_1 (IRDA_BASE + 0x20)
-# define IR_RX_INVERT_LED (1 << 0)
-# define IR_TX_INVERT_LED (1 << 1)
-# define IR_ST (1 << 2)
-# define IR_SF (1 << 3)
-# define IR_SIR (1 << 4)
-# define IR_MIR (1 << 5)
-# define IR_FIR (1 << 6)
-# define IR_16CRC (1 << 7)
-# define IR_TD (1 << 8)
-# define IR_RX_ALL (1 << 9)
-# define IR_DMA_ENABLE (1 << 10)
-# define IR_RX_ENABLE (1 << 11)
-# define IR_TX_ENABLE (1 << 12)
-# define IR_LOOPBACK (1 << 14)
-# define IR_SIR_MODE (IR_SIR | IR_DMA_ENABLE | \
- IR_RX_ALL | IR_RX_ENABLE | IR_SF | IR_16CRC)
-#define IR_SIR_FLAGS (IRDA_BASE + 0x24)
-#define IR_ENABLE (IRDA_BASE + 0x28)
-# define IR_RX_STATUS (1 << 9)
-# define IR_TX_STATUS (1 << 10)
-#define IR_READ_PHY_CONFIG (IRDA_BASE + 0x2C)
-#define IR_WRITE_PHY_CONFIG (IRDA_BASE + 0x30)
-#define IR_MAX_PKT_LEN (IRDA_BASE + 0x34)
-#define IR_RX_BYTE_CNT (IRDA_BASE + 0x38)
-#define IR_CONFIG_2 (IRDA_BASE + 0x3C)
-# define IR_MODE_INV (1 << 0)
-# define IR_ONE_PIN (1 << 1)
-#define IR_INTERFACE_CONFIG (IRDA_BASE + 0x40)
+
+/*
+ * The IrDA peripheral has an IRFIRSEL pin, but on the DB/PB boards it's not
+ * used to select FIR/SIR mode on the transceiver but as a GPIO. Instead a
+ * CPLD has to be told about the mode.
+ */
+#define AU1000_IRDA_PHY_MODE_OFF 0
+#define AU1000_IRDA_PHY_MODE_SIR 1
+#define AU1000_IRDA_PHY_MODE_FIR 2
+
+struct au1k_irda_platform_data {
+ void(*set_phy_mode)(int mode);
+};
+
/* GPIO */
#define SYS_PINFUNC 0xB190002C
diff --git a/drivers/net/irda/Kconfig b/drivers/net/irda/Kconfig
index d423d18..e535137 100644
--- a/drivers/net/irda/Kconfig
+++ b/drivers/net/irda/Kconfig
@@ -313,8 +313,12 @@ config TOSHIBA_FIR
donauboe.
config AU1000_FIR
- tristate "Alchemy Au1000 SIR/FIR"
+ tristate "Alchemy IrDA SIR/FIR"
depends on IRDA && MIPS_ALCHEMY
+ help
+ Say Y/M here to build suppor the the IrDA peripheral on the
+ Alchemy Au1000 and Au1100 SoCs.
+ Say M to build a module; it will be called au1k_ir.ko
config SMC_IRCC_FIR
tristate "SMSC IrCC (EXPERIMENTAL)"
diff --git a/drivers/net/irda/au1000_ircc.h b/drivers/net/irda/au1000_ircc.h
deleted file mode 100644
index c072c09..0000000
--- a/drivers/net/irda/au1000_ircc.h
+++ /dev/null
@@ -1,125 +0,0 @@
-/*
- *
- * BRIEF MODULE DESCRIPTION
- * Au1000 IrDA driver.
- *
- * Copyright 2001 MontaVista Software Inc.
- * Author: MontaVista Software, Inc.
- * ppopov@mvista.com or source@mvista.com
- *
- * This program is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License as published by the
- * Free Software Foundation; either version 2 of the License, or (at your
- * option) any later version.
- *
- * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED
- * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
- * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN
- * NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
- * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
- * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
- * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
- * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
- * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- *
- * You should have received a copy of the GNU General Public License along
- * with this program; if not, write to the Free Software Foundation, Inc.,
- * 675 Mass Ave, Cambridge, MA 02139, USA.
- */
-
-#ifndef AU1000_IRCC_H
-#define AU1000_IRCC_H
-
-#include <linux/time.h>
-
-#include <linux/spinlock.h>
-#include <linux/pm.h>
-#include <asm/io.h>
-
-#define NUM_IR_IFF 1
-#define NUM_IR_DESC 64
-#define RING_SIZE_4 0x0
-#define RING_SIZE_16 0x3
-#define RING_SIZE_64 0xF
-#define MAX_NUM_IR_DESC 64
-#define MAX_BUF_SIZE 2048
-
-#define BPS_115200 0
-#define BPS_57600 1
-#define BPS_38400 2
-#define BPS_19200 5
-#define BPS_9600 11
-#define BPS_2400 47
-
-/* Ring descriptor flags */
-#define AU_OWN (1<<7) /* tx,rx */
-
-#define IR_DIS_CRC (1<<6) /* tx */
-#define IR_BAD_CRC (1<<5) /* tx */
-#define IR_NEED_PULSE (1<<4) /* tx */
-#define IR_FORCE_UNDER (1<<3) /* tx */
-#define IR_DISABLE_TX (1<<2) /* tx */
-#define IR_HW_UNDER (1<<0) /* tx */
-#define IR_TX_ERROR (IR_DIS_CRC|IR_BAD_CRC|IR_HW_UNDER)
-
-#define IR_PHY_ERROR (1<<6) /* rx */
-#define IR_CRC_ERROR (1<<5) /* rx */
-#define IR_MAX_LEN (1<<4) /* rx */
-#define IR_FIFO_OVER (1<<3) /* rx */
-#define IR_SIR_ERROR (1<<2) /* rx */
-#define IR_RX_ERROR (IR_PHY_ERROR|IR_CRC_ERROR| \
- IR_MAX_LEN|IR_FIFO_OVER|IR_SIR_ERROR)
-
-typedef struct db_dest {
- struct db_dest *pnext;
- volatile u32 *vaddr;
- dma_addr_t dma_addr;
-} db_dest_t;
-
-
-typedef struct ring_desc {
- u8 count_0; /* 7:0 */
- u8 count_1; /* 12:8 */
- u8 reserved;
- u8 flags;
- u8 addr_0; /* 7:0 */
- u8 addr_1; /* 15:8 */
- u8 addr_2; /* 23:16 */
- u8 addr_3; /* 31:24 */
-} ring_dest_t;
-
-
-/* Private data for each instance */
-struct au1k_private {
-
- db_dest_t *pDBfree;
- db_dest_t db[2*NUM_IR_DESC];
- volatile ring_dest_t *rx_ring[NUM_IR_DESC];
- volatile ring_dest_t *tx_ring[NUM_IR_DESC];
- db_dest_t *rx_db_inuse[NUM_IR_DESC];
- db_dest_t *tx_db_inuse[NUM_IR_DESC];
- u32 rx_head;
- u32 tx_head;
- u32 tx_tail;
- u32 tx_full;
-
- iobuff_t rx_buff;
-
- struct net_device *netdev;
-
- struct timeval stamp;
- struct timeval now;
- struct qos_info qos;
- struct irlap_cb *irlap;
-
- u8 open;
- u32 speed;
- u32 newspeed;
-
- u32 intr_work_done; /* number of Rx and Tx pkts processed in the isr */
- struct timer_list timer;
-
- spinlock_t lock; /* For serializing operations */
-};
-#endif /* AU1000_IRCC_H */
diff --git a/drivers/net/irda/au1k_ir.c b/drivers/net/irda/au1k_ir.c
index 670bb05..fc503aa 100644
--- a/drivers/net/irda/au1k_ir.c
+++ b/drivers/net/irda/au1k_ir.c
@@ -18,101 +18,220 @@
* with this program; if not, write to the Free Software Foundation, Inc.,
* 59 Temple Place - Suite 330, Boston MA 02111-1307, USA.
*/
-#include <linux/module.h>
-#include <linux/types.h>
+
#include <linux/init.h>
-#include <linux/errno.h>
+#include <linux/module.h>
#include <linux/netdevice.h>
-#include <linux/slab.h>
-#include <linux/rtnetlink.h>
#include <linux/interrupt.h>
-#include <linux/pm.h>
-#include <linux/bitops.h>
-
-#include <asm/irq.h>
-#include <asm/io.h>
-#include <asm/au1000.h>
-#if defined(CONFIG_MIPS_DB1000)
-#include <asm/mach-db1x00/bcsr.h>
-#else
-#error au1k_ir: unsupported board
-#endif
+#include <linux/platform_device.h>
+#include <linux/slab.h>
+#include <linux/time.h>
+#include <linux/types.h>
#include <net/irda/irda.h>
#include <net/irda/irmod.h>
#include <net/irda/wrapper.h>
#include <net/irda/irda_device.h>
-#include "au1000_ircc.h"
+#include <asm/mach-au1x00/au1000.h>
+
+/* registers */
+#define IR_RING_PTR_STATUS 0x00
+#define IR_RING_BASE_ADDR_H 0x04
+#define IR_RING_BASE_ADDR_L 0x08
+#define IR_RING_SIZE 0x0C
+#define IR_RING_PROMPT 0x10
+#define IR_RING_ADDR_CMPR 0x14
+#define IR_INT_CLEAR 0x18
+#define IR_CONFIG_1 0x20
+#define IR_SIR_FLAGS 0x24
+#define IR_STATUS 0x28
+#define IR_READ_PHY_CONFIG 0x2C
+#define IR_WRITE_PHY_CONFIG 0x30
+#define IR_MAX_PKT_LEN 0x34
+#define IR_RX_BYTE_CNT 0x38
+#define IR_CONFIG_2 0x3C
+#define IR_ENABLE 0x40
+
+/* Config1 */
+#define IR_RX_INVERT_LED (1 << 0)
+#define IR_TX_INVERT_LED (1 << 1)
+#define IR_ST (1 << 2)
+#define IR_SF (1 << 3)
+#define IR_SIR (1 << 4)
+#define IR_MIR (1 << 5)
+#define IR_FIR (1 << 6)
+#define IR_16CRC (1 << 7)
+#define IR_TD (1 << 8)
+#define IR_RX_ALL (1 << 9)
+#define IR_DMA_ENABLE (1 << 10)
+#define IR_RX_ENABLE (1 << 11)
+#define IR_TX_ENABLE (1 << 12)
+#define IR_LOOPBACK (1 << 14)
+#define IR_SIR_MODE (IR_SIR | IR_DMA_ENABLE | \
+ IR_RX_ALL | IR_RX_ENABLE | IR_SF | \
+ IR_16CRC)
+
+/* ir_status */
+#define IR_RX_STATUS (1 << 9)
+#define IR_TX_STATUS (1 << 10)
+#define IR_PHYEN (1 << 15)
+
+/* ir_write_phy_config */
+#define IR_BR(x) (((x) & 0x3f) << 10) /* baud rate */
+#define IR_PW(x) (((x) & 0x1f) << 5) /* pulse width */
+#define IR_P(x) ((x) & 0x1f) /* preamble bits */
+
+/* Config2 */
+#define IR_MODE_INV (1 << 0)
+#define IR_ONE_PIN (1 << 1)
+#define IR_PHYCLK_40MHZ (0 << 2)
+#define IR_PHYCLK_48MHZ (1 << 2)
+#define IR_PHYCLK_56MHZ (2 << 2)
+#define IR_PHYCLK_64MHZ (3 << 2)
+#define IR_DP (1 << 4)
+#define IR_DA (1 << 5)
+#define IR_FLT_HIGH (0 << 6)
+#define IR_FLT_MEDHI (1 << 6)
+#define IR_FLT_MEDLO (2 << 6)
+#define IR_FLT_LO (3 << 6)
+#define IR_IEN (1 << 8)
+
+/* ir_enable */
+#define IR_HC (1 << 3) /* divide SBUS clock by 2 */
+#define IR_CE (1 << 2) /* clock enable */
+#define IR_C (1 << 1) /* coherency bit */
+#define IR_BE (1 << 0) /* set in big endian mode */
+
+#define NUM_IR_DESC 64
+#define RING_SIZE_4 0x0
+#define RING_SIZE_16 0x3
+#define RING_SIZE_64 0xF
+#define MAX_NUM_IR_DESC 64
+#define MAX_BUF_SIZE 2048
+
+/* Ring descriptor flags */
+#define AU_OWN (1 << 7) /* tx,rx */
+#define IR_DIS_CRC (1 << 6) /* tx */
+#define IR_BAD_CRC (1 << 5) /* tx */
+#define IR_NEED_PULSE (1 << 4) /* tx */
+#define IR_FORCE_UNDER (1 << 3) /* tx */
+#define IR_DISABLE_TX (1 << 2) /* tx */
+#define IR_HW_UNDER (1 << 0) /* tx */
+#define IR_TX_ERROR (IR_DIS_CRC | IR_BAD_CRC | IR_HW_UNDER)
+
+#define IR_PHY_ERROR (1 << 6) /* rx */
+#define IR_CRC_ERROR (1 << 5) /* rx */
+#define IR_MAX_LEN (1 << 4) /* rx */
+#define IR_FIFO_OVER (1 << 3) /* rx */
+#define IR_SIR_ERROR (1 << 2) /* rx */
+#define IR_RX_ERROR (IR_PHY_ERROR | IR_CRC_ERROR | \
+ IR_MAX_LEN | IR_FIFO_OVER | IR_SIR_ERROR)
+
+struct db_dest {
+ struct db_dest *pnext;
+ volatile u32 *vaddr;
+ dma_addr_t dma_addr;
+};
+
+struct ring_dest {
+ u8 count_0; /* 7:0 */
+ u8 count_1; /* 12:8 */
+ u8 reserved;
+ u8 flags;
+ u8 addr_0; /* 7:0 */
+ u8 addr_1; /* 15:8 */
+ u8 addr_2; /* 23:16 */
+ u8 addr_3; /* 31:24 */
+};
+
+/* Private data for each instance */
+struct au1k_private {
+ void __iomem *iobase;
+ int irq_rx, irq_tx;
+
+ struct db_dest *pDBfree;
+ struct db_dest db[2 * NUM_IR_DESC];
+ volatile struct ring_dest *rx_ring[NUM_IR_DESC];
+ volatile struct ring_dest *tx_ring[NUM_IR_DESC];
+ struct db_dest *rx_db_inuse[NUM_IR_DESC];
+ struct db_dest *tx_db_inuse[NUM_IR_DESC];
+ u32 rx_head;
+ u32 tx_head;
+ u32 tx_tail;
+ u32 tx_full;
+
+ iobuff_t rx_buff;
+
+ struct net_device *netdev;
+ struct timeval stamp;
+ struct timeval now;
+ struct qos_info qos;
+ struct irlap_cb *irlap;
+
+ u8 open;
+ u32 speed;
+ u32 newspeed;
-static int au1k_irda_net_init(struct net_device *);
-static int au1k_irda_start(struct net_device *);
-static int au1k_irda_stop(struct net_device *dev);
-static int au1k_irda_hard_xmit(struct sk_buff *, struct net_device *);
-static int au1k_irda_rx(struct net_device *);
-static void au1k_irda_interrupt(int, void *);
-static void au1k_tx_timeout(struct net_device *);
-static int au1k_irda_ioctl(struct net_device *, struct ifreq *, int);
-static int au1k_irda_set_speed(struct net_device *dev, int speed);
+ struct timer_list timer;
-static void *dma_alloc(size_t, dma_addr_t *);
-static void dma_free(void *, size_t);
+ struct resource *ioarea;
+ struct au1k_irda_platform_data *platdata;
+};
static int qos_mtt_bits = 0x07; /* 1 ms or more */
-static struct net_device *ir_devs[NUM_IR_IFF];
-static char version[] __devinitdata =
- "au1k_ircc:1.2 ppopov@mvista.com\n";
#define RUN_AT(x) (jiffies + (x))
-static DEFINE_SPINLOCK(ir_lock);
+static void au1k_irda_plat_set_phy_mode(struct au1k_private *p, int mode)
+{
+ if (p->platdata && p->platdata->set_phy_mode)
+ p->platdata->set_phy_mode(mode);
+}
-/*
- * IrDA peripheral bug. You have to read the register
- * twice to get the right value.
- */
-u32 read_ir_reg(u32 addr)
-{
- readl(addr);
- return readl(addr);
+static inline unsigned long irda_read(struct au1k_private *p,
+ unsigned long ofs)
+{
+ /*
+ * IrDA peripheral bug. You have to read the register
+ * twice to get the right value.
+ */
+ (void)__raw_readl(p->iobase + ofs);
+ return __raw_readl(p->iobase + ofs);
}
+static inline void irda_write(struct au1k_private *p, unsigned long ofs,
+ unsigned long val)
+{
+ __raw_writel(val, p->iobase + ofs);
+ wmb();
+}
/*
* Buffer allocation/deallocation routines. The buffer descriptor returned
- * has the virtual and dma address of a buffer suitable for
+ * has the virtual and dma address of a buffer suitable for
* both, receive and transmit operations.
*/
-static db_dest_t *GetFreeDB(struct au1k_private *aup)
+static struct db_dest *GetFreeDB(struct au1k_private *aup)
{
- db_dest_t *pDB;
- pDB = aup->pDBfree;
-
- if (pDB) {
- aup->pDBfree = pDB->pnext;
- }
- return pDB;
-}
+ struct db_dest *db;
+ db = aup->pDBfree;
-static void ReleaseDB(struct au1k_private *aup, db_dest_t *pDB)
-{
- db_dest_t *pDBfree = aup->pDBfree;
- if (pDBfree)
- pDBfree->pnext = pDB;
- aup->pDBfree = pDB;
+ if (db)
+ aup->pDBfree = db->pnext;
+ return db;
}
-
/*
DMA memory allocation, derived from pci_alloc_consistent.
However, the Au1000 data cache is coherent (when programmed
so), therefore we return KSEG0 address, not KSEG1.
*/
-static void *dma_alloc(size_t size, dma_addr_t * dma_handle)
+static void *dma_alloc(size_t size, dma_addr_t *dma_handle)
{
void *ret;
int gfp = GFP_ATOMIC | GFP_DMA;
- ret = (void *) __get_free_pages(gfp, get_order(size));
+ ret = (void *)__get_free_pages(gfp, get_order(size));
if (ret != NULL) {
memset(ret, 0, size);
@@ -122,7 +241,6 @@ static void *dma_alloc(size_t size, dma_addr_t * dma_handle)
return ret;
}
-
static void dma_free(void *vaddr, size_t size)
{
vaddr = (void *)KSEG0ADDR(vaddr);
@@ -130,206 +248,306 @@ static void dma_free(void *vaddr, size_t size)
}
-static void
-setup_hw_rings(struct au1k_private *aup, u32 rx_base, u32 tx_base)
+static void setup_hw_rings(struct au1k_private *aup, u32 rx_base, u32 tx_base)
{
int i;
- for (i=0; i<NUM_IR_DESC; i++) {
- aup->rx_ring[i] = (volatile ring_dest_t *)
- (rx_base + sizeof(ring_dest_t)*i);
+ for (i = 0; i < NUM_IR_DESC; i++) {
+ aup->rx_ring[i] = (volatile struct ring_dest *)
+ (rx_base + sizeof(struct ring_dest) * i);
}
- for (i=0; i<NUM_IR_DESC; i++) {
- aup->tx_ring[i] = (volatile ring_dest_t *)
- (tx_base + sizeof(ring_dest_t)*i);
+ for (i = 0; i < NUM_IR_DESC; i++) {
+ aup->tx_ring[i] = (volatile struct ring_dest *)
+ (tx_base + sizeof(struct ring_dest) * i);
}
}
-static int au1k_irda_init(void)
-{
- static unsigned version_printed = 0;
- struct au1k_private *aup;
- struct net_device *dev;
- int err;
-
- if (version_printed++ == 0) printk(version);
-
- dev = alloc_irdadev(sizeof(struct au1k_private));
- if (!dev)
- return -ENOMEM;
-
- dev->irq = AU1000_IRDA_RX_INT; /* TX has its own interrupt */
- err = au1k_irda_net_init(dev);
- if (err)
- goto out;
- err = register_netdev(dev);
- if (err)
- goto out1;
- ir_devs[0] = dev;
- printk(KERN_INFO "IrDA: Registered device %s\n", dev->name);
- return 0;
-
-out1:
- aup = netdev_priv(dev);
- dma_free((void *)aup->db[0].vaddr,
- MAX_BUF_SIZE * 2*NUM_IR_DESC);
- dma_free((void *)aup->rx_ring[0],
- 2 * MAX_NUM_IR_DESC*(sizeof(ring_dest_t)));
- kfree(aup->rx_buff.head);
-out:
- free_netdev(dev);
- return err;
-}
-
static int au1k_irda_init_iobuf(iobuff_t *io, int size)
{
io->head = kmalloc(size, GFP_KERNEL);
if (io->head != NULL) {
- io->truesize = size;
- io->in_frame = FALSE;
- io->state = OUTSIDE_FRAME;
- io->data = io->head;
+ io->truesize = size;
+ io->in_frame = FALSE;
+ io->state = OUTSIDE_FRAME;
+ io->data = io->head;
}
return io->head ? 0 : -ENOMEM;
}
-static const struct net_device_ops au1k_irda_netdev_ops = {
- .ndo_open = au1k_irda_start,
- .ndo_stop = au1k_irda_stop,
- .ndo_start_xmit = au1k_irda_hard_xmit,
- .ndo_tx_timeout = au1k_tx_timeout,
- .ndo_do_ioctl = au1k_irda_ioctl,
-};
-
-static int au1k_irda_net_init(struct net_device *dev)
+/*
+ * Set the IrDA communications speed.
+ */
+static int au1k_irda_set_speed(struct net_device *dev, int speed)
{
struct au1k_private *aup = netdev_priv(dev);
- int i, retval = 0, err;
- db_dest_t *pDB, *pDBfree;
- dma_addr_t temp;
+ volatile struct ring_dest *ptxd;
+ unsigned long control;
+ int ret = 0, timeout = 10, i;
- err = au1k_irda_init_iobuf(&aup->rx_buff, 14384);
- if (err)
- goto out1;
+ if (speed == aup->speed)
+ return ret;
- dev->netdev_ops = &au1k_irda_netdev_ops;
+ /* disable PHY first */
+ au1k_irda_plat_set_phy_mode(aup, AU1000_IRDA_PHY_MODE_OFF);
+ irda_write(aup, IR_STATUS, irda_read(aup, IR_STATUS) & ~IR_PHYEN);
- irda_init_max_qos_capabilies(&aup->qos);
+ /* disable RX/TX */
+ irda_write(aup, IR_CONFIG_1,
+ irda_read(aup, IR_CONFIG_1) & ~(IR_RX_ENABLE | IR_TX_ENABLE));
+ msleep(20);
+ while (irda_read(aup, IR_STATUS) & (IR_RX_STATUS | IR_TX_STATUS)) {
+ msleep(20);
+ if (!timeout--) {
+ printk(KERN_ERR "%s: rx/tx disable timeout\n",
+ dev->name);
+ break;
+ }
+ }
- /* The only value we must override it the baudrate */
- aup->qos.baud_rate.bits = IR_9600|IR_19200|IR_38400|IR_57600|
- IR_115200|IR_576000 |(IR_4000000 << 8);
-
- aup->qos.min_turn_time.bits = qos_mtt_bits;
- irda_qos_bits_to_value(&aup->qos);
+ /* disable DMA */
+ irda_write(aup, IR_CONFIG_1,
+ irda_read(aup, IR_CONFIG_1) & ~IR_DMA_ENABLE);
+ msleep(20);
- retval = -ENOMEM;
+ /* After we disable tx/rx. the index pointers go back to zero. */
+ aup->tx_head = aup->tx_tail = aup->rx_head = 0;
+ for (i = 0; i < NUM_IR_DESC; i++) {
+ ptxd = aup->tx_ring[i];
+ ptxd->flags = 0;
+ ptxd->count_0 = 0;
+ ptxd->count_1 = 0;
+ }
- /* Tx ring follows rx ring + 512 bytes */
- /* we need a 1k aligned buffer */
- aup->rx_ring[0] = (ring_dest_t *)
- dma_alloc(2*MAX_NUM_IR_DESC*(sizeof(ring_dest_t)), &temp);
- if (!aup->rx_ring[0])
- goto out2;
+ for (i = 0; i < NUM_IR_DESC; i++) {
+ ptxd = aup->rx_ring[i];
+ ptxd->count_0 = 0;
+ ptxd->count_1 = 0;
+ ptxd->flags = AU_OWN;
+ }
- /* allocate the data buffers */
- aup->db[0].vaddr =
- (void *)dma_alloc(MAX_BUF_SIZE * 2*NUM_IR_DESC, &temp);
- if (!aup->db[0].vaddr)
- goto out3;
+ if (speed == 4000000)
+ au1k_irda_plat_set_phy_mode(aup, AU1000_IRDA_PHY_MODE_FIR);
+ else
+ au1k_irda_plat_set_phy_mode(aup, AU1000_IRDA_PHY_MODE_SIR);
- setup_hw_rings(aup, (u32)aup->rx_ring[0], (u32)aup->rx_ring[0] + 512);
+ switch (speed) {
+ case 9600:
+ irda_write(aup, IR_WRITE_PHY_CONFIG, IR_BR(11) | IR_PW(12));
+ irda_write(aup, IR_CONFIG_1, IR_SIR_MODE);
+ break;
+ case 19200:
+ irda_write(aup, IR_WRITE_PHY_CONFIG, IR_BR(5) | IR_PW(12));
+ irda_write(aup, IR_CONFIG_1, IR_SIR_MODE);
+ break;
+ case 38400:
+ irda_write(aup, IR_WRITE_PHY_CONFIG, IR_BR(2) | IR_PW(12));
+ irda_write(aup, IR_CONFIG_1, IR_SIR_MODE);
+ break;
+ case 57600:
+ irda_write(aup, IR_WRITE_PHY_CONFIG, IR_BR(1) | IR_PW(12));
+ irda_write(aup, IR_CONFIG_1, IR_SIR_MODE);
+ break;
+ case 115200:
+ irda_write(aup, IR_WRITE_PHY_CONFIG, IR_PW(12));
+ irda_write(aup, IR_CONFIG_1, IR_SIR_MODE);
+ break;
+ case 4000000:
+ irda_write(aup, IR_WRITE_PHY_CONFIG, IR_P(15));
+ irda_write(aup, IR_CONFIG_1, IR_FIR | IR_DMA_ENABLE |
+ IR_RX_ENABLE);
+ break;
+ default:
+ printk(KERN_ERR "%s unsupported speed %x\n", dev->name, speed);
+ ret = -EINVAL;
+ break;
+ }
- pDBfree = NULL;
- pDB = aup->db;
- for (i=0; i<(2*NUM_IR_DESC); i++) {
- pDB->pnext = pDBfree;
- pDBfree = pDB;
- pDB->vaddr =
- (u32 *)((unsigned)aup->db[0].vaddr + MAX_BUF_SIZE*i);
- pDB->dma_addr = (dma_addr_t)virt_to_bus(pDB->vaddr);
- pDB++;
+ aup->speed = speed;
+ irda_write(aup, IR_STATUS, irda_read(aup, IR_STATUS) | IR_PHYEN);
+
+ control = irda_read(aup, IR_STATUS);
+ irda_write(aup, IR_RING_PROMPT, 0);
+
+ if (control & (1 << 14)) {
+ printk(KERN_ERR "%s: configuration error\n", dev->name);
+ } else {
+ if (control & (1 << 11))
+ printk(KERN_DEBUG "%s Valid SIR config\n", dev->name);
+ if (control & (1 << 12))
+ printk(KERN_DEBUG "%s Valid MIR config\n", dev->name);
+ if (control & (1 << 13))
+ printk(KERN_DEBUG "%s Valid FIR config\n", dev->name);
+ if (control & (1 << 10))
+ printk(KERN_DEBUG "%s TX enabled\n", dev->name);
+ if (control & (1 << 9))
+ printk(KERN_DEBUG "%s RX enabled\n", dev->name);
}
- aup->pDBfree = pDBfree;
- /* attach a data buffer to each descriptor */
- for (i=0; i<NUM_IR_DESC; i++) {
- pDB = GetFreeDB(aup);
- if (!pDB) goto out;
- aup->rx_ring[i]->addr_0 = (u8)(pDB->dma_addr & 0xff);
- aup->rx_ring[i]->addr_1 = (u8)((pDB->dma_addr>>8) & 0xff);
- aup->rx_ring[i]->addr_2 = (u8)((pDB->dma_addr>>16) & 0xff);
- aup->rx_ring[i]->addr_3 = (u8)((pDB->dma_addr>>24) & 0xff);
- aup->rx_db_inuse[i] = pDB;
+ return ret;
+}
+
+static void update_rx_stats(struct net_device *dev, u32 status, u32 count)
+{
+ struct net_device_stats *ps = &dev->stats;
+
+ ps->rx_packets++;
+
+ if (status & IR_RX_ERROR) {
+ ps->rx_errors++;
+ if (status & (IR_PHY_ERROR | IR_FIFO_OVER))
+ ps->rx_missed_errors++;
+ if (status & IR_MAX_LEN)
+ ps->rx_length_errors++;
+ if (status & IR_CRC_ERROR)
+ ps->rx_crc_errors++;
+ } else
+ ps->rx_bytes += count;
+}
+
+static void update_tx_stats(struct net_device *dev, u32 status, u32 pkt_len)
+{
+ struct net_device_stats *ps = &dev->stats;
+
+ ps->tx_packets++;
+ ps->tx_bytes += pkt_len;
+
+ if (status & IR_TX_ERROR) {
+ ps->tx_errors++;
+ ps->tx_aborted_errors++;
}
- for (i=0; i<NUM_IR_DESC; i++) {
- pDB = GetFreeDB(aup);
- if (!pDB) goto out;
- aup->tx_ring[i]->addr_0 = (u8)(pDB->dma_addr & 0xff);
- aup->tx_ring[i]->addr_1 = (u8)((pDB->dma_addr>>8) & 0xff);
- aup->tx_ring[i]->addr_2 = (u8)((pDB->dma_addr>>16) & 0xff);
- aup->tx_ring[i]->addr_3 = (u8)((pDB->dma_addr>>24) & 0xff);
- aup->tx_ring[i]->count_0 = 0;
- aup->tx_ring[i]->count_1 = 0;
- aup->tx_ring[i]->flags = 0;
- aup->tx_db_inuse[i] = pDB;
+}
+
+static void au1k_tx_ack(struct net_device *dev)
+{
+ struct au1k_private *aup = netdev_priv(dev);
+ volatile struct ring_dest *ptxd;
+
+ ptxd = aup->tx_ring[aup->tx_tail];
+ while (!(ptxd->flags & AU_OWN) && (aup->tx_tail != aup->tx_head)) {
+ update_tx_stats(dev, ptxd->flags,
+ (ptxd->count_1 << 8) | ptxd->count_0);
+ ptxd->count_0 = 0;
+ ptxd->count_1 = 0;
+ wmb();
+ aup->tx_tail = (aup->tx_tail + 1) & (NUM_IR_DESC - 1);
+ ptxd = aup->tx_ring[aup->tx_tail];
+
+ if (aup->tx_full) {
+ aup->tx_full = 0;
+ netif_wake_queue(dev);
+ }
}
-#if defined(CONFIG_MIPS_DB1000)
- /* power on */
- bcsr_mod(BCSR_RESETS, BCSR_RESETS_IRDA_MODE_MASK,
- BCSR_RESETS_IRDA_MODE_FULL);
-#endif
+ if (aup->tx_tail == aup->tx_head) {
+ if (aup->newspeed) {
+ au1k_irda_set_speed(dev, aup->newspeed);
+ aup->newspeed = 0;
+ } else {
+ irda_write(aup, IR_CONFIG_1,
+ irda_read(aup, IR_CONFIG_1) & ~IR_TX_ENABLE);
+ irda_write(aup, IR_CONFIG_1,
+ irda_read(aup, IR_CONFIG_1) | IR_RX_ENABLE);
+ irda_write(aup, IR_RING_PROMPT, 0);
+ }
+ }
+}
- return 0;
+static int au1k_irda_rx(struct net_device *dev)
+{
+ struct au1k_private *aup = netdev_priv(dev);
+ volatile struct ring_dest *prxd;
+ struct sk_buff *skb;
+ struct db_dest *pDB;
+ u32 flags, count;
-out3:
- dma_free((void *)aup->rx_ring[0],
- 2 * MAX_NUM_IR_DESC*(sizeof(ring_dest_t)));
-out2:
- kfree(aup->rx_buff.head);
-out1:
- printk(KERN_ERR "au1k_init_module failed. Returns %d\n", retval);
- return retval;
+ prxd = aup->rx_ring[aup->rx_head];
+ flags = prxd->flags;
+
+ while (!(flags & AU_OWN)) {
+ pDB = aup->rx_db_inuse[aup->rx_head];
+ count = (prxd->count_1 << 8) | prxd->count_0;
+ if (!(flags & IR_RX_ERROR)) {
+ /* good frame */
+ update_rx_stats(dev, flags, count);
+ skb = alloc_skb(count + 1, GFP_ATOMIC);
+ if (skb == NULL) {
+ dev->stats.rx_dropped++;
+ continue;
+ }
+ skb_reserve(skb, 1);
+ if (aup->speed == 4000000)
+ skb_put(skb, count);
+ else
+ skb_put(skb, count - 2);
+ skb_copy_to_linear_data(skb, (void *)pDB->vaddr,
+ count - 2);
+ skb->dev = dev;
+ skb_reset_mac_header(skb);
+ skb->protocol = htons(ETH_P_IRDA);
+ netif_rx(skb);
+ prxd->count_0 = 0;
+ prxd->count_1 = 0;
+ }
+ prxd->flags |= AU_OWN;
+ aup->rx_head = (aup->rx_head + 1) & (NUM_IR_DESC - 1);
+ irda_write(aup, IR_RING_PROMPT, 0);
+
+ /* next descriptor */
+ prxd = aup->rx_ring[aup->rx_head];
+ flags = prxd->flags;
+
+ }
+ return 0;
}
+static irqreturn_t au1k_irda_interrupt(int dummy, void *dev_id)
+{
+ struct net_device *dev = dev_id;
+ struct au1k_private *aup = netdev_priv(dev);
+
+ irda_write(aup, IR_INT_CLEAR, 0); /* ack irda interrupts */
+
+ au1k_irda_rx(dev);
+ au1k_tx_ack(dev);
+
+ return IRQ_HANDLED;
+}
static int au1k_init(struct net_device *dev)
{
struct au1k_private *aup = netdev_priv(dev);
+ u32 enable, ring_address;
int i;
- u32 control;
- u32 ring_address;
- /* bring the device out of reset */
- control = 0xe; /* coherent, clock enable, one half system clock */
-
+ enable = IR_HC | IR_CE | IR_C;
#ifndef CONFIG_CPU_LITTLE_ENDIAN
- control |= 1;
+ enable |= IR_BE;
#endif
aup->tx_head = 0;
aup->tx_tail = 0;
aup->rx_head = 0;
- for (i=0; i<NUM_IR_DESC; i++) {
+ for (i = 0; i < NUM_IR_DESC; i++)
aup->rx_ring[i]->flags = AU_OWN;
- }
- writel(control, IR_INTERFACE_CONFIG);
- au_sync_delay(10);
+ irda_write(aup, IR_ENABLE, enable);
+ msleep(20);
- writel(read_ir_reg(IR_ENABLE) & ~0x8000, IR_ENABLE); /* disable PHY */
- au_sync_delay(1);
+ /* disable PHY */
+ au1k_irda_plat_set_phy_mode(aup, AU1000_IRDA_PHY_MODE_OFF);
+ irda_write(aup, IR_STATUS, irda_read(aup, IR_STATUS) & ~IR_PHYEN);
+ msleep(20);
- writel(MAX_BUF_SIZE, IR_MAX_PKT_LEN);
+ irda_write(aup, IR_MAX_PKT_LEN, MAX_BUF_SIZE);
ring_address = (u32)virt_to_phys((void *)aup->rx_ring[0]);
- writel(ring_address >> 26, IR_RING_BASE_ADDR_H);
- writel((ring_address >> 10) & 0xffff, IR_RING_BASE_ADDR_L);
+ irda_write(aup, IR_RING_BASE_ADDR_H, ring_address >> 26);
+ irda_write(aup, IR_RING_BASE_ADDR_L, (ring_address >> 10) & 0xffff);
- writel(RING_SIZE_64<<8 | RING_SIZE_64<<12, IR_RING_SIZE);
+ irda_write(aup, IR_RING_SIZE,
+ (RING_SIZE_64 << 8) | (RING_SIZE_64 << 12));
- writel(1<<2 | IR_ONE_PIN, IR_CONFIG_2); /* 48MHz */
- writel(0, IR_RING_ADDR_CMPR);
+ irda_write(aup, IR_CONFIG_2, IR_PHYCLK_48MHZ | IR_ONE_PIN);
+ irda_write(aup, IR_RING_ADDR_CMPR, 0);
au1k_irda_set_speed(dev, 9600);
return 0;
@@ -337,25 +555,28 @@ static int au1k_init(struct net_device *dev)
static int au1k_irda_start(struct net_device *dev)
{
- int retval;
- char hwname[32];
struct au1k_private *aup = netdev_priv(dev);
+ char hwname[32];
+ int retval;
- if ((retval = au1k_init(dev))) {
+ retval = au1k_init(dev);
+ if (retval) {
printk(KERN_ERR "%s: error in au1k_init\n", dev->name);
return retval;
}
- if ((retval = request_irq(AU1000_IRDA_TX_INT, au1k_irda_interrupt,
- 0, dev->name, dev))) {
- printk(KERN_ERR "%s: unable to get IRQ %d\n",
+ retval = request_irq(aup->irq_tx, &au1k_irda_interrupt, 0,
+ dev->name, dev);
+ if (retval) {
+ printk(KERN_ERR "%s: unable to get IRQ %d\n",
dev->name, dev->irq);
return retval;
}
- if ((retval = request_irq(AU1000_IRDA_RX_INT, au1k_irda_interrupt,
- 0, dev->name, dev))) {
- free_irq(AU1000_IRDA_TX_INT, dev);
- printk(KERN_ERR "%s: unable to get IRQ %d\n",
+ retval = request_irq(aup->irq_rx, &au1k_irda_interrupt, 0,
+ dev->name, dev);
+ if (retval) {
+ free_irq(aup->irq_tx, dev);
+ printk(KERN_ERR "%s: unable to get IRQ %d\n",
dev->name, dev->irq);
return retval;
}
@@ -365,9 +586,13 @@ static int au1k_irda_start(struct net_device *dev)
aup->irlap = irlap_open(dev, &aup->qos, hwname);
netif_start_queue(dev);
- writel(read_ir_reg(IR_CONFIG_2) | 1<<8, IR_CONFIG_2); /* int enable */
+ /* int enable */
+ irda_write(aup, IR_CONFIG_2, irda_read(aup, IR_CONFIG_2) | IR_IEN);
- aup->timer.expires = RUN_AT((3*HZ));
+ /* power up */
+ au1k_irda_plat_set_phy_mode(aup, AU1000_IRDA_PHY_MODE_SIR);
+
+ aup->timer.expires = RUN_AT((3 * HZ));
aup->timer.data = (unsigned long)dev;
return 0;
}
@@ -376,11 +601,12 @@ static int au1k_irda_stop(struct net_device *dev)
{
struct au1k_private *aup = netdev_priv(dev);
+ au1k_irda_plat_set_phy_mode(aup, AU1000_IRDA_PHY_MODE_OFF);
+
/* disable interrupts */
- writel(read_ir_reg(IR_CONFIG_2) & ~(1<<8), IR_CONFIG_2);
- writel(0, IR_CONFIG_1);
- writel(0, IR_INTERFACE_CONFIG); /* disable clock */
- au_sync();
+ irda_write(aup, IR_CONFIG_2, irda_read(aup, IR_CONFIG_2) & ~IR_IEN);
+ irda_write(aup, IR_CONFIG_1, 0);
+ irda_write(aup, IR_ENABLE, 0); /* disable clock */
if (aup->irlap) {
irlap_close(aup->irlap);
@@ -391,83 +617,12 @@ static int au1k_irda_stop(struct net_device *dev)
del_timer(&aup->timer);
/* disable the interrupt */
- free_irq(AU1000_IRDA_TX_INT, dev);
- free_irq(AU1000_IRDA_RX_INT, dev);
- return 0;
-}
-
-static void __exit au1k_irda_exit(void)
-{
- struct net_device *dev = ir_devs[0];
- struct au1k_private *aup = netdev_priv(dev);
-
- unregister_netdev(dev);
-
- dma_free((void *)aup->db[0].vaddr,
- MAX_BUF_SIZE * 2*NUM_IR_DESC);
- dma_free((void *)aup->rx_ring[0],
- 2 * MAX_NUM_IR_DESC*(sizeof(ring_dest_t)));
- kfree(aup->rx_buff.head);
- free_netdev(dev);
-}
-
-
-static inline void
-update_tx_stats(struct net_device *dev, u32 status, u32 pkt_len)
-{
- struct au1k_private *aup = netdev_priv(dev);
- struct net_device_stats *ps = &aup->stats;
-
- ps->tx_packets++;
- ps->tx_bytes += pkt_len;
-
- if (status & IR_TX_ERROR) {
- ps->tx_errors++;
- ps->tx_aborted_errors++;
- }
-}
-
-
-static void au1k_tx_ack(struct net_device *dev)
-{
- struct au1k_private *aup = netdev_priv(dev);
- volatile ring_dest_t *ptxd;
-
- ptxd = aup->tx_ring[aup->tx_tail];
- while (!(ptxd->flags & AU_OWN) && (aup->tx_tail != aup->tx_head)) {
- update_tx_stats(dev, ptxd->flags,
- ptxd->count_1<<8 | ptxd->count_0);
- ptxd->count_0 = 0;
- ptxd->count_1 = 0;
- au_sync();
-
- aup->tx_tail = (aup->tx_tail + 1) & (NUM_IR_DESC - 1);
- ptxd = aup->tx_ring[aup->tx_tail];
-
- if (aup->tx_full) {
- aup->tx_full = 0;
- netif_wake_queue(dev);
- }
- }
+ free_irq(aup->irq_tx, dev);
+ free_irq(aup->irq_rx, dev);
- if (aup->tx_tail == aup->tx_head) {
- if (aup->newspeed) {
- au1k_irda_set_speed(dev, aup->newspeed);
- aup->newspeed = 0;
- }
- else {
- writel(read_ir_reg(IR_CONFIG_1) & ~IR_TX_ENABLE,
- IR_CONFIG_1);
- au_sync();
- writel(read_ir_reg(IR_CONFIG_1) | IR_RX_ENABLE,
- IR_CONFIG_1);
- writel(0, IR_RING_PROMPT);
- au_sync();
- }
- }
+ return 0;
}
-
/*
* Au1000 transmit routine.
*/
@@ -475,15 +630,12 @@ static int au1k_irda_hard_xmit(struct sk_buff *skb, struct net_device *dev)
{
struct au1k_private *aup = netdev_priv(dev);
int speed = irda_get_next_speed(skb);
- volatile ring_dest_t *ptxd;
- u32 len;
-
- u32 flags;
- db_dest_t *pDB;
+ volatile struct ring_dest *ptxd;
+ struct db_dest *pDB;
+ u32 len, flags;
- if (speed != aup->speed && speed != -1) {
+ if (speed != aup->speed && speed != -1)
aup->newspeed = speed;
- }
if ((skb->len == 0) && (aup->newspeed)) {
if (aup->tx_tail == aup->tx_head) {
@@ -501,138 +653,47 @@ static int au1k_irda_hard_xmit(struct sk_buff *skb, struct net_device *dev)
printk(KERN_DEBUG "%s: tx_full\n", dev->name);
netif_stop_queue(dev);
aup->tx_full = 1;
- return NETDEV_TX_BUSY;
- }
- else if (((aup->tx_head + 1) & (NUM_IR_DESC - 1)) == aup->tx_tail) {
+ return 1;
+ } else if (((aup->tx_head + 1) & (NUM_IR_DESC - 1)) == aup->tx_tail) {
printk(KERN_DEBUG "%s: tx_full\n", dev->name);
netif_stop_queue(dev);
aup->tx_full = 1;
- return NETDEV_TX_BUSY;
+ return 1;
}
pDB = aup->tx_db_inuse[aup->tx_head];
#if 0
- if (read_ir_reg(IR_RX_BYTE_CNT) != 0) {
- printk("tx warning: rx byte cnt %x\n",
- read_ir_reg(IR_RX_BYTE_CNT));
+ if (irda_read(aup, IR_RX_BYTE_CNT) != 0) {
+ printk(KERN_DEBUG "tx warning: rx byte cnt %x\n",
+ irda_read(aup, IR_RX_BYTE_CNT));
}
#endif
-
+
if (aup->speed == 4000000) {
/* FIR */
- skb_copy_from_linear_data(skb, pDB->vaddr, skb->len);
+ skb_copy_from_linear_data(skb, (void *)pDB->vaddr, skb->len);
ptxd->count_0 = skb->len & 0xff;
ptxd->count_1 = (skb->len >> 8) & 0xff;
-
- }
- else {
+ } else {
/* SIR */
len = async_wrap_skb(skb, (u8 *)pDB->vaddr, MAX_BUF_SIZE);
ptxd->count_0 = len & 0xff;
ptxd->count_1 = (len >> 8) & 0xff;
ptxd->flags |= IR_DIS_CRC;
- au_writel(au_readl(0xae00000c) & ~(1<<13), 0xae00000c);
}
ptxd->flags |= AU_OWN;
- au_sync();
+ wmb();
- writel(read_ir_reg(IR_CONFIG_1) | IR_TX_ENABLE, IR_CONFIG_1);
- writel(0, IR_RING_PROMPT);
- au_sync();
+ irda_write(aup, IR_CONFIG_1,
+ irda_read(aup, IR_CONFIG_1) | IR_TX_ENABLE);
+ irda_write(aup, IR_RING_PROMPT, 0);
dev_kfree_skb(skb);
aup->tx_head = (aup->tx_head + 1) & (NUM_IR_DESC - 1);
return NETDEV_TX_OK;
}
-
-static inline void
-update_rx_stats(struct net_device *dev, u32 status, u32 count)
-{
- struct au1k_private *aup = netdev_priv(dev);
- struct net_device_stats *ps = &aup->stats;
-
- ps->rx_packets++;
-
- if (status & IR_RX_ERROR) {
- ps->rx_errors++;
- if (status & (IR_PHY_ERROR|IR_FIFO_OVER))
- ps->rx_missed_errors++;
- if (status & IR_MAX_LEN)
- ps->rx_length_errors++;
- if (status & IR_CRC_ERROR)
- ps->rx_crc_errors++;
- }
- else
- ps->rx_bytes += count;
-}
-
-/*
- * Au1000 receive routine.
- */
-static int au1k_irda_rx(struct net_device *dev)
-{
- struct au1k_private *aup = netdev_priv(dev);
- struct sk_buff *skb;
- volatile ring_dest_t *prxd;
- u32 flags, count;
- db_dest_t *pDB;
-
- prxd = aup->rx_ring[aup->rx_head];
- flags = prxd->flags;
-
- while (!(flags & AU_OWN)) {
- pDB = aup->rx_db_inuse[aup->rx_head];
- count = prxd->count_1<<8 | prxd->count_0;
- if (!(flags & IR_RX_ERROR)) {
- /* good frame */
- update_rx_stats(dev, flags, count);
- skb=alloc_skb(count+1,GFP_ATOMIC);
- if (skb == NULL) {
- aup->netdev->stats.rx_dropped++;
- continue;
- }
- skb_reserve(skb, 1);
- if (aup->speed == 4000000)
- skb_put(skb, count);
- else
- skb_put(skb, count-2);
- skb_copy_to_linear_data(skb, pDB->vaddr, count - 2);
- skb->dev = dev;
- skb_reset_mac_header(skb);
- skb->protocol = htons(ETH_P_IRDA);
- netif_rx(skb);
- prxd->count_0 = 0;
- prxd->count_1 = 0;
- }
- prxd->flags |= AU_OWN;
- aup->rx_head = (aup->rx_head + 1) & (NUM_IR_DESC - 1);
- writel(0, IR_RING_PROMPT);
- au_sync();
-
- /* next descriptor */
- prxd = aup->rx_ring[aup->rx_head];
- flags = prxd->flags;
-
- }
- return 0;
-}
-
-
-static irqreturn_t au1k_irda_interrupt(int dummy, void *dev_id)
-{
- struct net_device *dev = dev_id;
-
- writel(0, IR_INT_CLEAR); /* ack irda interrupts */
-
- au1k_irda_rx(dev);
- au1k_tx_ack(dev);
-
- return IRQ_HANDLED;
-}
-
-
/*
* The Tx ring has been full longer than the watchdog timeout
* value. The transmitter must be hung?
@@ -650,142 +711,7 @@ static void au1k_tx_timeout(struct net_device *dev)
netif_wake_queue(dev);
}
-
-/*
- * Set the IrDA communications speed.
- */
-static int
-au1k_irda_set_speed(struct net_device *dev, int speed)
-{
- unsigned long flags;
- struct au1k_private *aup = netdev_priv(dev);
- u32 control;
- int ret = 0, timeout = 10, i;
- volatile ring_dest_t *ptxd;
-#if defined(CONFIG_MIPS_DB1000)
- unsigned long irda_resets;
-#endif
-
- if (speed == aup->speed)
- return ret;
-
- spin_lock_irqsave(&ir_lock, flags);
-
- /* disable PHY first */
- writel(read_ir_reg(IR_ENABLE) & ~0x8000, IR_ENABLE);
-
- /* disable RX/TX */
- writel(read_ir_reg(IR_CONFIG_1) & ~(IR_RX_ENABLE|IR_TX_ENABLE),
- IR_CONFIG_1);
- au_sync_delay(1);
- while (read_ir_reg(IR_ENABLE) & (IR_RX_STATUS | IR_TX_STATUS)) {
- mdelay(1);
- if (!timeout--) {
- printk(KERN_ERR "%s: rx/tx disable timeout\n",
- dev->name);
- break;
- }
- }
-
- /* disable DMA */
- writel(read_ir_reg(IR_CONFIG_1) & ~IR_DMA_ENABLE, IR_CONFIG_1);
- au_sync_delay(1);
-
- /*
- * After we disable tx/rx. the index pointers
- * go back to zero.
- */
- aup->tx_head = aup->tx_tail = aup->rx_head = 0;
- for (i=0; i<NUM_IR_DESC; i++) {
- ptxd = aup->tx_ring[i];
- ptxd->flags = 0;
- ptxd->count_0 = 0;
- ptxd->count_1 = 0;
- }
-
- for (i=0; i<NUM_IR_DESC; i++) {
- ptxd = aup->rx_ring[i];
- ptxd->count_0 = 0;
- ptxd->count_1 = 0;
- ptxd->flags = AU_OWN;
- }
-
- if (speed == 4000000) {
-#if defined(CONFIG_MIPS_DB1000)
- bcsr_mod(BCSR_RESETS, 0, BCSR_RESETS_FIR_SEL);
-#else /* Pb1000 and Pb1100 */
- writel(1<<13, CPLD_AUX1);
-#endif
- }
- else {
-#if defined(CONFIG_MIPS_DB1000)
- bcsr_mod(BCSR_RESETS, BCSR_RESETS_FIR_SEL, 0);
-#else /* Pb1000 and Pb1100 */
- writel(readl(CPLD_AUX1) & ~(1<<13), CPLD_AUX1);
-#endif
- }
-
- switch (speed) {
- case 9600:
- writel(11<<10 | 12<<5, IR_WRITE_PHY_CONFIG);
- writel(IR_SIR_MODE, IR_CONFIG_1);
- break;
- case 19200:
- writel(5<<10 | 12<<5, IR_WRITE_PHY_CONFIG);
- writel(IR_SIR_MODE, IR_CONFIG_1);
- break;
- case 38400:
- writel(2<<10 | 12<<5, IR_WRITE_PHY_CONFIG);
- writel(IR_SIR_MODE, IR_CONFIG_1);
- break;
- case 57600:
- writel(1<<10 | 12<<5, IR_WRITE_PHY_CONFIG);
- writel(IR_SIR_MODE, IR_CONFIG_1);
- break;
- case 115200:
- writel(12<<5, IR_WRITE_PHY_CONFIG);
- writel(IR_SIR_MODE, IR_CONFIG_1);
- break;
- case 4000000:
- writel(0xF, IR_WRITE_PHY_CONFIG);
- writel(IR_FIR|IR_DMA_ENABLE|IR_RX_ENABLE, IR_CONFIG_1);
- break;
- default:
- printk(KERN_ERR "%s unsupported speed %x\n", dev->name, speed);
- ret = -EINVAL;
- break;
- }
-
- aup->speed = speed;
- writel(read_ir_reg(IR_ENABLE) | 0x8000, IR_ENABLE);
- au_sync();
-
- control = read_ir_reg(IR_ENABLE);
- writel(0, IR_RING_PROMPT);
- au_sync();
-
- if (control & (1<<14)) {
- printk(KERN_ERR "%s: configuration error\n", dev->name);
- }
- else {
- if (control & (1<<11))
- printk(KERN_DEBUG "%s Valid SIR config\n", dev->name);
- if (control & (1<<12))
- printk(KERN_DEBUG "%s Valid MIR config\n", dev->name);
- if (control & (1<<13))
- printk(KERN_DEBUG "%s Valid FIR config\n", dev->name);
- if (control & (1<<10))
- printk(KERN_DEBUG "%s TX enabled\n", dev->name);
- if (control & (1<<9))
- printk(KERN_DEBUG "%s RX enabled\n", dev->name);
- }
-
- spin_unlock_irqrestore(&ir_lock, flags);
- return ret;
-}
-
-static int
-au1k_irda_ioctl(struct net_device *dev, struct ifreq *ifreq, int cmd)
+static int au1k_irda_ioctl(struct net_device *dev, struct ifreq *ifreq, int cmd)
{
struct if_irda_req *rq = (struct if_irda_req *)ifreq;
struct au1k_private *aup = netdev_priv(dev);
@@ -826,8 +752,218 @@ au1k_irda_ioctl(struct net_device *dev, struct ifreq *ifreq, int cmd)
return ret;
}
+static const struct net_device_ops au1k_irda_netdev_ops = {
+ .ndo_open = au1k_irda_start,
+ .ndo_stop = au1k_irda_stop,
+ .ndo_start_xmit = au1k_irda_hard_xmit,
+ .ndo_tx_timeout = au1k_tx_timeout,
+ .ndo_do_ioctl = au1k_irda_ioctl,
+};
+
+static int __devinit au1k_irda_net_init(struct net_device *dev)
+{
+ struct au1k_private *aup = netdev_priv(dev);
+ struct db_dest *pDB, *pDBfree;
+ int i, err, retval = 0;
+ dma_addr_t temp;
+
+ err = au1k_irda_init_iobuf(&aup->rx_buff, 14384);
+ if (err)
+ goto out1;
+
+ dev->netdev_ops = &au1k_irda_netdev_ops;
+
+ irda_init_max_qos_capabilies(&aup->qos);
+
+ /* The only value we must override it the baudrate */
+ aup->qos.baud_rate.bits = IR_9600 | IR_19200 | IR_38400 |
+ IR_57600 | IR_115200 | IR_576000 | (IR_4000000 << 8);
+
+ aup->qos.min_turn_time.bits = qos_mtt_bits;
+ irda_qos_bits_to_value(&aup->qos);
+
+ retval = -ENOMEM;
+
+ /* Tx ring follows rx ring + 512 bytes */
+ /* we need a 1k aligned buffer */
+ aup->rx_ring[0] = (struct ring_dest *)
+ dma_alloc(2 * MAX_NUM_IR_DESC * (sizeof(struct ring_dest)),
+ &temp);
+ if (!aup->rx_ring[0])
+ goto out2;
+
+ /* allocate the data buffers */
+ aup->db[0].vaddr =
+ (void *)dma_alloc(MAX_BUF_SIZE * 2 * NUM_IR_DESC, &temp);
+ if (!aup->db[0].vaddr)
+ goto out3;
+
+ setup_hw_rings(aup, (u32)aup->rx_ring[0], (u32)aup->rx_ring[0] + 512);
+
+ pDBfree = NULL;
+ pDB = aup->db;
+ for (i = 0; i < (2 * NUM_IR_DESC); i++) {
+ pDB->pnext = pDBfree;
+ pDBfree = pDB;
+ pDB->vaddr =
+ (u32 *)((unsigned)aup->db[0].vaddr + (MAX_BUF_SIZE * i));
+ pDB->dma_addr = (dma_addr_t)virt_to_bus(pDB->vaddr);
+ pDB++;
+ }
+ aup->pDBfree = pDBfree;
+
+ /* attach a data buffer to each descriptor */
+ for (i = 0; i < NUM_IR_DESC; i++) {
+ pDB = GetFreeDB(aup);
+ if (!pDB)
+ goto out3;
+ aup->rx_ring[i]->addr_0 = (u8)(pDB->dma_addr & 0xff);
+ aup->rx_ring[i]->addr_1 = (u8)((pDB->dma_addr >> 8) & 0xff);
+ aup->rx_ring[i]->addr_2 = (u8)((pDB->dma_addr >> 16) & 0xff);
+ aup->rx_ring[i]->addr_3 = (u8)((pDB->dma_addr >> 24) & 0xff);
+ aup->rx_db_inuse[i] = pDB;
+ }
+ for (i = 0; i < NUM_IR_DESC; i++) {
+ pDB = GetFreeDB(aup);
+ if (!pDB)
+ goto out3;
+ aup->tx_ring[i]->addr_0 = (u8)(pDB->dma_addr & 0xff);
+ aup->tx_ring[i]->addr_1 = (u8)((pDB->dma_addr >> 8) & 0xff);
+ aup->tx_ring[i]->addr_2 = (u8)((pDB->dma_addr >> 16) & 0xff);
+ aup->tx_ring[i]->addr_3 = (u8)((pDB->dma_addr >> 24) & 0xff);
+ aup->tx_ring[i]->count_0 = 0;
+ aup->tx_ring[i]->count_1 = 0;
+ aup->tx_ring[i]->flags = 0;
+ aup->tx_db_inuse[i] = pDB;
+ }
+
+ return 0;
+
+out3:
+ dma_free((void *)aup->rx_ring[0],
+ 2 * MAX_NUM_IR_DESC * (sizeof(struct ring_dest)));
+out2:
+ kfree(aup->rx_buff.head);
+out1:
+ printk(KERN_ERR "au1k_irda_net_init() failed. Returns %d\n", retval);
+ return retval;
+}
+
+static int __devinit au1k_irda_probe(struct platform_device *pdev)
+{
+ struct au1k_private *aup;
+ struct net_device *dev;
+ struct resource *r;
+ int err;
+
+ dev = alloc_irdadev(sizeof(struct au1k_private));
+ if (!dev)
+ return -ENOMEM;
+
+ aup = netdev_priv(dev);
+
+ aup->platdata = pdev->dev.platform_data;
+
+ err = -EINVAL;
+ r = platform_get_resource(pdev, IORESOURCE_IRQ, 0);
+ if (!r)
+ goto out;
+
+ aup->irq_tx = r->start;
+
+ r = platform_get_resource(pdev, IORESOURCE_IRQ, 1);
+ if (!r)
+ goto out;
+
+ aup->irq_rx = r->start;
+
+ r = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+ if (!r)
+ goto out;
+
+ err = -EBUSY;
+ aup->ioarea = request_mem_region(r->start, r->end - r->start + 1,
+ pdev->name);
+ if (!aup->ioarea)
+ goto out;
+
+ aup->iobase = ioremap_nocache(r->start, r->end - r->start + 1);
+ if (!aup->iobase)
+ goto out2;
+
+ dev->irq = aup->irq_rx;
+
+ err = au1k_irda_net_init(dev);
+ if (err)
+ goto out3;
+ err = register_netdev(dev);
+ if (err)
+ goto out4;
+
+ platform_set_drvdata(pdev, dev);
+
+ printk(KERN_INFO "IrDA: Registered device %s\n", dev->name);
+ return 0;
+
+out4:
+ dma_free((void *)aup->db[0].vaddr,
+ MAX_BUF_SIZE * 2 * NUM_IR_DESC);
+ dma_free((void *)aup->rx_ring[0],
+ 2 * MAX_NUM_IR_DESC * (sizeof(struct ring_dest)));
+ kfree(aup->rx_buff.head);
+out3:
+ iounmap(aup->iobase);
+out2:
+ release_resource(aup->ioarea);
+ kfree(aup->ioarea);
+out:
+ free_netdev(dev);
+ return err;
+}
+
+static int __devexit au1k_irda_remove(struct platform_device *pdev)
+{
+ struct net_device *dev = platform_get_drvdata(pdev);
+ struct au1k_private *aup = netdev_priv(dev);
+
+ unregister_netdev(dev);
+
+ dma_free((void *)aup->db[0].vaddr,
+ MAX_BUF_SIZE * 2 * NUM_IR_DESC);
+ dma_free((void *)aup->rx_ring[0],
+ 2 * MAX_NUM_IR_DESC * (sizeof(struct ring_dest)));
+ kfree(aup->rx_buff.head);
+
+ iounmap(aup->iobase);
+ release_resource(aup->ioarea);
+ kfree(aup->ioarea);
+
+ free_netdev(dev);
+
+ return 0;
+}
+
+static struct platform_driver au1k_irda_driver = {
+ .driver = {
+ .name = "au1000-irda",
+ .owner = THIS_MODULE,
+ },
+ .probe = au1k_irda_probe,
+ .remove = __devexit_p(au1k_irda_remove),
+};
+
+static int __init au1k_irda_load(void)
+{
+ return platform_driver_register(&au1k_irda_driver);
+}
+
+static void __exit au1k_irda_unload(void)
+{
+ return platform_driver_unregister(&au1k_irda_driver);
+}
+
MODULE_AUTHOR("Pete Popov <ppopov@mvista.com>");
MODULE_DESCRIPTION("Au1000 IrDA Device Driver");
-module_init(au1k_irda_init);
-module_exit(au1k_irda_exit);
+module_init(au1k_irda_load);
+module_exit(au1k_irda_unload);
--
1.7.7.1
^ permalink raw reply related
* Re: [PATCH] sysfs: Make sysfs_rename safe with sysfs_dirents in rbtrees.
From: Greg KH @ 2011-11-01 21:19 UTC (permalink / raw)
To: Eric W. Biederman
Cc: Linus Torvalds, Jiri Slaby, David Miller, Mikulas Patocka, akpm,
netdev, linux-kernel, Jiri Slaby
In-Reply-To: <m1mxcgrl7q.fsf_-_@fess.ebiederm.org>
On Tue, Nov 01, 2011 at 07:06:17AM -0700, Eric W. Biederman wrote:
>
> In sysfs_rename remove the optimization of not calling sysfs_unlink_sibling
> and sysfs_link_sibling if the renamed parent directory is not changing.
> This optimization is no longer valid now that sysfs dirents are stored in an
> rbtree sorted by name.
>
> Move the assignment of s_ns before the call of sysfs_link_sibling. With no
> sysfs_dirent fields changing after the call of sysfs_link_sibling this allows
> sysfs_link_sibling to take any of the directory entries into account when
> it builds the rbtrees, and s_ns looks like a prime canidate to be used
> in the rbtree in the future.
>
> Signed-off-by: Eric W. Biederman <ebiederm@xmission.com>
Looks good, Linus, thanks for taking this in your tree already.
greg k-h
^ permalink raw reply
* Re: [PATCH] IPv6 - support for NLM_F_* flags at IPv6 routing requests
From: Stephen Hemminger @ 2011-11-01 21:43 UTC (permalink / raw)
To: Matti Vaittinen; +Cc: davem, netdev
In-Reply-To: <1320157347.11816.3.camel@lakki>
On Tue, 01 Nov 2011 16:22:27 +0200
Matti Vaittinen <matti.vaittinen@nsn.com> wrote:
>
> +#define RT6_CANT_CREATE ((int)-1)
> #define RT6_DEBUG 2
Rather than introduce a new error flag, why not convert the code
to use the kernel standard PTR_ERR() macros?
^ permalink raw reply
* Re: [PATCH] neigh: print nud_state in neigh timer handler.
From: David Miller @ 2011-11-01 21:44 UTC (permalink / raw)
To: dbaluta
Cc: eric.dumazet, gregory.v.rose, jeffrey.t.kirsher, netdev,
daniel.baluta
In-Reply-To: <1320095448-5228-1-git-send-email-dbaluta@ixiacom.com>
From: Daniel Baluta <dbaluta@ixiacom.com>
Date: Mon, 31 Oct 2011 23:10:48 +0200
> From: Daniel Baluta <daniel.baluta@gmail.com>
>
> For debugging purposes it is useful to know the exact state of a
> non NUD_IN_TIMER neighbour entry whose timer handler just expired.
>
> Signed-off-by: Daniel Baluta <dbaluta@ixiacom.com>
This debugging log message is dubious.
Also, it is protected by !SMP and I can almost guarentee you that whatever
condition makes it happen leigitmately on SMP also can be triggered with
preemption enabled on !SMP.
So I'm going to simply remove this debug message entirely instead.
^ permalink raw reply
* Re: [PATCH] vlan: Don't propagate flag changes on down interfaces.
From: David Miller @ 2011-11-01 21:51 UTC (permalink / raw)
To: matthijs; +Cc: netdev
In-Reply-To: <1320072793-16490-1-git-send-email-matthijs@stdin.nl>
From: Matthijs Kooijman <matthijs@stdin.nl>
Date: Mon, 31 Oct 2011 15:53:13 +0100
> When (de)configuring a vlan interface, the IFF_ALLMULTI ans IFF_PROMISC
> flags are cleared or set on the underlying interface. So, if these flags
> are changed on a vlan interface that is not up, the flags underlying
> interface might be set or cleared twice.
>
> Only propagating flag changes when a device is up makes sure this does
> not happen. It also makes sure that an underlying device is not set to
> promiscuous or allmulti mode for a vlan device that is down.
>
> Signed-off-by: Matthijs Kooijman <matthijs@stdin.nl>
Applied, thanks.
^ permalink raw reply
* Re: [PATCH] bonding:update speed/duplex for NETDEV_CHANGE
From: David Miller @ 2011-11-01 21:53 UTC (permalink / raw)
To: wpan; +Cc: netdev, fubar, andy, linux-kernel
In-Reply-To: <9765cb601d0b4330cf7775ec3cd6b9e1ea13c71e.1320117071.git.wpan@redhat.com>
From: Weiping Pan <wpan@redhat.com>
Date: Tue, 1 Nov 2011 11:20:48 +0800
> Zheng Liang(lzheng@redhat.com) found a bug that if we config bonding with
> arp monitor, sometimes bonding driver cannot get the speed and duplex from
> its slaves, it will assume them to be 100Mb/sec and Full, please see
> /proc/net/bonding/bond0.
> But there is no such problem when uses miimon.
>
> (Take igb for example)
> I find that the reason is that after dev_open() in bond_enslave(),
> bond_update_speed_duplex() will call igb_get_settings()
> , but in that function,
> it runs ethtool_cmd_speed_set(ecmd, -1); ecmd->duplex = -1;
> because igb get an error value of status.
> So even dev_open() is called, but the device is not really ready to get its
> settings.
>
> Maybe it is safe for us to call igb_get_settings() only after
> this message shows up, that is "igb: p4p1 NIC Link is Up 1000 Mbps Full Duplex,
> Flow Control: RX".
>
> So I prefer to update the speed and duplex for a slave when reseices
> NETDEV_CHANGE/NETDEV_UP event.
>
> Changelog
> V2:
> 1 remove the "fake 100/Full" logic in bond_update_speed_duplex(),
> set speed and duplex to -1 when it gets error value of speed and duplex.
> 2 delete the warning in bond_enslave() if bond_update_speed_duplex() returns
> error.
> 3 make bond_info_show_slave() handle bad values of speed and duplex.
>
> Signed-off-by: Weiping Pan <wpan@redhat.com>
Looks good, applied, thanks!
^ permalink raw reply
* Re: [PATCH] net: make the tcp and udp file_operations for the /proc stuff const
From: David Miller @ 2011-11-01 21:56 UTC (permalink / raw)
To: arjan; +Cc: netdev
In-Reply-To: <20111030094630.47e247ae@infradead.org>
From: Arjan van de Ven <arjan@infradead.org>
Date: Sun, 30 Oct 2011 09:46:30 -0700
> the tcp and udp code creates a set of struct file_operations at runtime
> while it can also be done at compile time, with the added benefit of then
> having these file operations be const.
>
> the trickiest part was to get the "THIS_MODULE" reference right; the naive
> method of declaring a struct in the place of registration would not work
> for this reason.
>
> Signed-off-by: Arjan van de Ven <arjan@linux.intel.com>
I have no problem with this, applied, thanks.
^ permalink raw reply
* Re: [PATCH] [RESEND] [TRIVIAL] isdn: hisax: Fix typo 'HISAX_DE_AOC'
From: David Miller @ 2011-11-01 21:59 UTC (permalink / raw)
To: pebolle; +Cc: trivial, linux-kernel, isdn, netdev
In-Reply-To: <1319976044.14409.14.camel@x61.thuisdomein>
From: Paul Bolle <pebolle@tiscali.nl>
Date: Sun, 30 Oct 2011 13:00:44 +0100
> That should probably be 'CONFIG_DE_AOC'.
>
> Signed-off-by: Paul Bolle <pebolle@tiscali.nl>
Applied, thanks.
^ permalink raw reply
* PROBLEM: pppol2tp over pppoe NULL pointer dereference
From: Misha Labjuk @ 2011-11-01 22:00 UTC (permalink / raw)
To: netdev
pppol2tp over pppoe NULL pointer dereference
Kernel panic after establishing pppol2tp tunnel over pppoe connection.
Get panic in 5-15 min with 10 mbit/s data transfer speed.
pppoe and pppol2tp connections stable separately.
Linux version 3.1.0 (user@host) (gcc version 4.6.1 (Gentoo 4.6.1-r1
p1.0, pie-0.4.5) ) #1 SMP Mon Oct 31 18:48:18 MSK 2011
[ 151.913193] L2TP core driver, V2.0
[ 151.974584] L2TP netlink interface
[ 151.993803] PPPoL2TP kernel driver, V2.0
[ 437.496670] BUG: unable to handle kernel NULL pointer dereference
at 0000000000000008
[ 437.496683] IP: [<ffffffffa03679dc>] l2tp_recv_common+0x4d3/0x621 [l2tp_core]
[ 437.496691] PGD d7840067 PUD cd4e7067 PMD 0
[ 437.496697] Oops: 0002 [#1] SMP
[ 437.496702] CPU 0
[ 437.496704] Modules linked in: l2tp_ppp l2tp_netlink l2tp_core
firewire_sbp2 sit tunnel4 netconsole it87 hwmon_vid coretemp pppoe
pppox ppp_generic slhc ipt_MASQUERADE iptable_nat nf_nat
nf_conntrack_ipv4 nf_conntrack nf_defrag_ipv4 xt_TCPMSS iptable_mangle
ip_tables snd_seq_midi snd_emu10k1_synth snd_emux_synth
snd_seq_virmidi snd_seq_midi_emul snd_seq_dummy snd_seq_oss
snd_seq_midi_event snd_seq snd_pcm_oss snd_mixer_oss nfsd lockd
nfs_acl auth_rpcgss sunrpc usb_storage usb_libusual uas usbhid ipv6
snd_emu10k1 8250_pnp snd_rawmidi snd_hda_codec_realtek snd_ac97_codec
snd_hda_intel snd_hda_codec uhci_hcd ac97_bus snd_pcm ehci_hcd usbcore
snd_seq_device snd_timer 8250 snd_util_mem snd_hwdep psmouse snd
firewire_ohci firewire_core serial_core intel_agp intel_gtt pcspkr
soundcore r8169 crc_itu_t mii snd_page_alloc processor button
[ 437.497005]
[ 437.497005] Pid: 3274, comm: qbittorrent Not tainted 3.1.0 #1
Gigabyte Technology Co., Ltd. EP45-EXTREME/EP45-EXTREME
[ 437.497005] RIP: 0010:[<ffffffffa03679dc>] [<ffffffffa03679dc>]
l2tp_recv_common+0x4d3/0x621 [l2tp_core]
[ 437.497005] RSP: 0000:ffff88011fc03b90 EFLAGS: 00010296
[ 437.497005] RAX: 0000000000000000 RBX: ffff8800d79e8200 RCX: ffff88011fc10bd0
[ 437.497005] RDX: 0000000000000000 RSI: 0000000000004002 RDI: ffff8800d79e8254
[ 437.497005] RBP: ffff88011fc03be0 R08: 0000000000004002 R09: 0000000000004002
[ 437.497005] R10: ffff8801091ec87a R11: ffff88011b300000 R12: ffff880118922300
[ 437.497005] R13: 0000000000000000 R14: ffff8800d79e8254 R15: ffff8800d79e826c
[ 437.497005] FS: 00007f0ced3e8700(0000) GS:ffff88011fc00000(0000)
knlGS:0000000000000000
[ 437.497005] CS: 0010 DS: 0000 ES: 0000 CR0: 0000000080050033
[ 437.497005] CR2: 0000000000000008 CR3: 00000000c8811000 CR4: 00000000000406f0
[ 437.497005] DR0: 0000000000000000 DR1: 0000000000000000 DR2: 0000000000000000
[ 437.497005] DR3: 0000000000000000 DR6: 00000000ffff0ff0 DR7: 0000000000000400
[ 437.497005] Process qbittorrent (pid: 3274, threadinfo
ffff8800c9906000, task ffff8800db999200)
[ 437.497005] Stack:
[ 437.497005] ffff88011fc03bb0 ffff8801091ec872 ffff8800d79e8240
0000052000000520
[ 437.497005] ffff88011fc03be0 ffff8800d7844e00 ffff880119099200
ffff8801091ec872
[ 437.497005] ffff8800db8b6400 00000000000050cd ffff88011fc03c60
ffffffffa0367e65
[ 437.497005] Call Trace:
[ 437.497005] <IRQ>
[ 437.497005] [<ffffffffa0367e65>] l2tp_udp_encap_recv+0x33b/0x3e6 [l2tp_core]
[ 437.497005] [<ffffffffa0377d96>] ? pppol2tp_setsockopt+0x2e0/0x2e0
[l2tp_ppp]
[ 437.497005] [<ffffffffa030640c>] ? ipv4_confirm+0x17e/0x198
[nf_conntrack_ipv4]
[ 437.497005] [<ffffffffa0377d96>] ? pppol2tp_setsockopt+0x2e0/0x2e0
[l2tp_ppp]
[ 437.497005] [<ffffffff812eb32b>] udp_queue_rcv_skb+0xee/0x2ce
[ 437.497005] [<ffffffff812ebba3>] __udp4_lib_rcv+0x2d2/0x536
[ 437.497005] [<ffffffff812cb046>] ? ip_rcv_finish+0x29a/0x29a
[ 437.497005] [<ffffffff812ebe1c>] udp_rcv+0x15/0x17
[ 437.497005] [<ffffffff812cb165>] ip_local_deliver_finish+0x11f/0x1c7
[ 437.497005] [<ffffffff812cb361>] ip_local_deliver+0x75/0x7c
[ 437.497005] [<ffffffff812cb023>] ip_rcv_finish+0x277/0x29a
[ 437.497005] [<ffffffff812cb5a1>] ip_rcv+0x239/0x260
[ 437.497005] [<ffffffff812a46cd>] ? napi_skb_finish+0x21/0x38
[ 437.497005] [<ffffffff812a3adb>] __netif_receive_skb+0x430/0x462
[ 437.497005] [<ffffffff8102342f>] ? update_curr+0x53/0x89
[ 437.497005] [<ffffffff812a3b9d>] process_backlog+0x90/0x151
[ 437.497005] [<ffffffff812a3e6a>] net_rx_action+0x9e/0x171
[ 437.497005] [<ffffffff810344b0>] __do_softirq+0x93/0x129
[ 437.497005] [<ffffffff8133034c>] call_softirq+0x1c/0x30
[ 437.497005] [<ffffffff8100351c>] do_softirq+0x33/0x6b
[ 437.497005] [<ffffffff8103470b>] irq_exit+0x52/0xac
[ 437.497005] [<ffffffff81003251>] do_IRQ+0x98/0xaf
[ 437.497005] [<ffffffff8132eb6b>] common_interrupt+0x6b/0x6b
[ 437.497005] <EOI>
[ 437.497005] [<ffffffff8132f17b>] ? system_call_fastpath+0x16/0x1b
[ 437.497005] Code: 6c e8 57 03 fc e0 e9 22 01 00 00 ff 4b 50 4c 89
f7 49 8b 14 24 49 c7 04 24 00 00 00 00 49 8b 44 24 08 49 c7 44 24 08
00 00 00 00
[ 437.497005] 89 42 08 48 89 10 e8 1d 6f fc e0 41 0f b7 54 24 3e 48 8b 43
[ 437.497005] RIP [<ffffffffa03679dc>] l2tp_recv_common+0x4d3/0x621
[l2tp_core]
[ 437.497005] RSP <ffff88011fc03b90>
[ 437.497005] CR2: 0000000000000008
[ 437.498126] ---[ end trace 053df4c7c6743d26 ]---
[ 437.498184] Kernel panic - not syncing: Fatal exception in interrupt
[ 437.498187] Pid: 3274, comm: qbittorrent Tainted: G D 3.1.0 #1
[ 437.498189] Call Trace:
[ 437.498190] <IRQ> [<ffffffff81327c11>] panic+0x8c/0x189
[ 437.498197] [<ffffffff8100471d>] oops_end+0x81/0x8e
[ 437.498200] [<ffffffff8132765b>] no_context+0x1fe/0x20d
[ 437.498203] [<ffffffff81327829>] __bad_area_nosemaphore+0x1bf/0x1e0
[ 437.498206] [<ffffffff812a5308>] ? dev_hard_start_xmit+0x412/0x51b
[ 437.498210] [<ffffffff81327858>] bad_area_nosemaphore+0xe/0x10
[ 437.498213] [<ffffffff8101c858>] do_page_fault+0x175/0x371
[ 437.498217] [<ffffffff812a1eba>] ? netif_rx+0xc5/0xd0
[ 437.498281] [<ffffffffa031ee7d>] ?
ppp_receive_nonmp_frame+0x58f/0x5cf [ppp_generic]
[ 437.498286] [<ffffffffa0320625>] ? ppp_receive_frame+0x5c1/0x5e2
[ppp_generic]
[ 437.498290] [<ffffffff8132ed6f>] page_fault+0x1f/0x30
[ 437.498293] [<ffffffffa03679dc>] ? l2tp_recv_common+0x4d3/0x621 [l2tp_core]
[ 437.498298] [<ffffffffa0367e65>] l2tp_udp_encap_recv+0x33b/0x3e6 [l2tp_core]
[ 437.498302] [<ffffffffa0377d96>] ? pppol2tp_setsockopt+0x2e0/0x2e0
[l2tp_ppp]
[ 437.498306] [<ffffffffa030640c>] ? ipv4_confirm+0x17e/0x198
[nf_conntrack_ipv4]
[ 437.498310] [<ffffffffa0377d96>] ? pppol2tp_setsockopt+0x2e0/0x2e0
[l2tp_ppp]
[ 437.498314] [<ffffffff812eb32b>] udp_queue_rcv_skb+0xee/0x2ce
[ 437.498317] [<ffffffff812ebba3>] __udp4_lib_rcv+0x2d2/0x536
[ 437.498321] [<ffffffff812cb046>] ? ip_rcv_finish+0x29a/0x29a
[ 437.498324] [<ffffffff812ebe1c>] udp_rcv+0x15/0x17
[ 437.498328] [<ffffffff812cb165>] ip_local_deliver_finish+0x11f/0x1c7
[ 437.498332] [<ffffffff812cb361>] ip_local_deliver+0x75/0x7c
[ 437.498391] [<ffffffff812cb023>] ip_rcv_finish+0x277/0x29a
[ 437.498394] [<ffffffff812cb5a1>] ip_rcv+0x239/0x260
[ 437.498398] [<ffffffff812a46cd>] ? napi_skb_finish+0x21/0x38
[ 437.498401] [<ffffffff812a3adb>] __netif_receive_skb+0x430/0x462
[ 437.498404] [<ffffffff8102342f>] ? update_curr+0x53/0x89
[ 437.498408] [<ffffffff812a3b9d>] process_backlog+0x90/0x151
Software:
Gnu C 4.6.1
Gnu make 3.82
binutils 2.21.1
openl2tp 1.8-r3
l2tp_recv_common+0x4d3/0x621 is match to
net/l2tp/l2tp_core.c:429:__skb_unlink(skb, &session->reorder_q);
skb->next is NULL.
^ permalink raw reply
* Re: [PATCH] neigh: print nud_state in neigh timer handler.
From: Daniel Baluta @ 2011-11-01 22:05 UTC (permalink / raw)
To: David Miller; +Cc: eric.dumazet, gregory.v.rose, jeffrey.t.kirsher, netdev
In-Reply-To: <20111101.174411.1200019350687608200.davem@davemloft.net>
On Tue, Nov 1, 2011 at 11:44 PM, David Miller <davem@davemloft.net> wrote:
> From: Daniel Baluta <dbaluta@ixiacom.com>
> Date: Mon, 31 Oct 2011 23:10:48 +0200
>
>> From: Daniel Baluta <daniel.baluta@gmail.com>
>>
>> For debugging purposes it is useful to know the exact state of a
>> non NUD_IN_TIMER neighbour entry whose timer handler just expired.
>>
>> Signed-off-by: Daniel Baluta <dbaluta@ixiacom.com>
>
> This debugging log message is dubious.
>
> Also, it is protected by !SMP and I can almost guarentee you that whatever
> condition makes it happen leigitmately on SMP also can be triggered with
> preemption enabled on !SMP.
>
> So I'm going to simply remove this debug message entirely instead.
Agree. If you can figure out when this condition is true, it is nice
to have a comment.
Daniel.
^ permalink raw reply
* ethtool back on git.kernel.org
From: Ben Hutchings @ 2011-11-01 22:18 UTC (permalink / raw)
To: netdev
As of this afternoon, ethtool is again available from:
git://git.kernel.org/pub/scm/network/ethtool/ethtool.git
There are no tarballs available at the moment, as the new upload service
on kernel.org is in limited beta.
Ben.
--
Ben Hutchings, Staff Engineer, Solarflare
Not speaking for my employer; that's the marketing department's job.
They asked us to note that Solarflare product names are trademarked.
^ permalink raw reply
* [PATCH ethtool 00/21] ethtool refactoring and misc changes
From: Ben Hutchings @ 2011-11-01 22:35 UTC (permalink / raw)
To: netdev; +Cc: linux-net-drivers
As I looked into supporting features cleanly within the existing -k/-K
options, it became clear that ethtool was overdue for refactoring. And
in order to be confident about doing that, I needed to add some tests.
So I intend to push the following changes:
1. Reporting of pause frame autonegotiation. I don't believe this
requires a new command in the kernel interface; it just needs drivers
to fill out the AN flags.
2. Minor fixes to manual page and online help.
3. Cleanup of ethtool-bitops.h and ethtool-util.h.
4. Encapsulate shared command state into a structure passed into each
sub-command function (and several others).
5. Test argument parsing. Currently this just checks that each command
line is accepted or rejected as expected.
6. For each sub-command (option), move all argument parsing into the
function that implements it. Move the associated static variables
likewise. Declare static constants as const, so that there are no
static variables left (outside of the test wrapper).
7. Run the main ethtool code in the same process as the test code.
This will allow for test cases that cover the ioctl requests and
responses.
Ben.
Ben Hutchings (21):
Report pause frame autonegotiation result
ethtool.8: Fix initial blank line/page
Combine ethtool-{bitops,util}.h into internal.h
Fix type of bit-number parameter to set_bit() and clear_bit()
ethtool.8: Change device name metavariable from 'ethX' to 'devname'
ethtool.8: Allow line-break in description of parameters after -N
Fix format of help text for -f option
Use standard indentation for definition of struct option args
Encapsulate command context in a structure
Add test cases for command-line parsing
Add more test cases for command-line parsing
Move argument parsing to sub-command functions
Support arbitrary numbers of option names for each mode
Fix reference to cmdline_ring in do_schannels()
Convert cmdline_msglvl into array of named flags; convert back at
run-time
Replace global devname variable with a field in struct cmd_context
Change most static global variables into automatic variables
rxclass: Replace global rmgr with automatic variable/parameter
Declare static variables const as appropriate
Run tests in-process
Rearrange definitions and remove unnecessary forward declarations
Makefile.am | 7 +-
amd8111e.c | 2 +-
at76c50x-usb.c | 2 +-
configure.ac | 1 +
de2104x.c | 2 +-
e100.c | 2 +-
e1000.c | 2 +-
ethtool-bitops.h | 25 -
ethtool.8.in | 70 +-
ethtool.c | 2352 +++++++++++++++++++-----------------------
fec_8xx.c | 2 +-
ibm_emac.c | 2 +-
igb.c | 2 +-
ethtool-util.h => internal.h | 57 +-
ixgb.c | 2 +-
ixgbe.c | 2 +-
marvell.c | 2 +-
natsemi.c | 2 +-
pcnet32.c | 2 +-
realtek.c | 2 +-
rxclass.c | 129 +--
sfc.c | 2 +-
smsc911x.c | 2 +-
stmmac.c | 2 +-
test-cmdline.c | 240 +++++
test-common.c | 101 ++
tg3.c | 2 +-
vioc.c | 2 +-
28 files changed, 1565 insertions(+), 1455 deletions(-)
delete mode 100644 ethtool-bitops.h
rename ethtool-util.h => internal.h (71%)
create mode 100644 test-cmdline.c
create mode 100644 test-common.c
--
1.7.4.4
--
Ben Hutchings, Staff Engineer, Solarflare
Not speaking for my employer; that's the marketing department's job.
They asked us to note that Solarflare product names are trademarked.
^ permalink raw reply
* Re: PROBLEM: pppol2tp over pppoe NULL pointer dereference
From: Eric Dumazet @ 2011-11-01 22:35 UTC (permalink / raw)
To: Misha Labjuk; +Cc: netdev
In-Reply-To: <CAKpUy7Z5KOfHbKfBp-qg+77cED=OxUAkm2P4pQacHaHKmKBQpw@mail.gmail.com>
Le mercredi 02 novembre 2011 à 01:00 +0300, Misha Labjuk a écrit :
> pppol2tp over pppoe NULL pointer dereference
>
> Kernel panic after establishing pppol2tp tunnel over pppoe connection.
> Get panic in 5-15 min with 10 mbit/s data transfer speed.
> pppoe and pppol2tp connections stable separately.
>
> Linux version 3.1.0 (user@host) (gcc version 4.6.1 (Gentoo 4.6.1-r1
> p1.0, pie-0.4.5) ) #1 SMP Mon Oct 31 18:48:18 MSK 2011
>
> [ 151.913193] L2TP core driver, V2.0
> [ 151.974584] L2TP netlink interface
> [ 151.993803] PPPoL2TP kernel driver, V2.0
> [ 437.496670] BUG: unable to handle kernel NULL pointer dereference
> at 0000000000000008
> [ 437.496683] IP: [<ffffffffa03679dc>] l2tp_recv_common+0x4d3/0x621 [l2tp_core]
> [ 437.496691] PGD d7840067 PUD cd4e7067 PMD 0
> [ 437.496697] Oops: 0002 [#1] SMP
> [ 437.496702] CPU 0
> [ 437.496704] Modules linked in: l2tp_ppp l2tp_netlink l2tp_core
> firewire_sbp2 sit tunnel4 netconsole it87 hwmon_vid coretemp pppoe
> pppox ppp_generic slhc ipt_MASQUERADE iptable_nat nf_nat
> nf_conntrack_ipv4 nf_conntrack nf_defrag_ipv4 xt_TCPMSS iptable_mangle
> ip_tables snd_seq_midi snd_emu10k1_synth snd_emux_synth
> snd_seq_virmidi snd_seq_midi_emul snd_seq_dummy snd_seq_oss
> snd_seq_midi_event snd_seq snd_pcm_oss snd_mixer_oss nfsd lockd
> nfs_acl auth_rpcgss sunrpc usb_storage usb_libusual uas usbhid ipv6
> snd_emu10k1 8250_pnp snd_rawmidi snd_hda_codec_realtek snd_ac97_codec
> snd_hda_intel snd_hda_codec uhci_hcd ac97_bus snd_pcm ehci_hcd usbcore
> snd_seq_device snd_timer 8250 snd_util_mem snd_hwdep psmouse snd
> firewire_ohci firewire_core serial_core intel_agp intel_gtt pcspkr
> soundcore r8169 crc_itu_t mii snd_page_alloc processor button
> [ 437.497005]
> [ 437.497005] Pid: 3274, comm: qbittorrent Not tainted 3.1.0 #1
> Gigabyte Technology Co., Ltd. EP45-EXTREME/EP45-EXTREME
> [ 437.497005] RIP: 0010:[<ffffffffa03679dc>] [<ffffffffa03679dc>]
> l2tp_recv_common+0x4d3/0x621 [l2tp_core]
> [ 437.497005] RSP: 0000:ffff88011fc03b90 EFLAGS: 00010296
> [ 437.497005] RAX: 0000000000000000 RBX: ffff8800d79e8200 RCX: ffff88011fc10bd0
> [ 437.497005] RDX: 0000000000000000 RSI: 0000000000004002 RDI: ffff8800d79e8254
> [ 437.497005] RBP: ffff88011fc03be0 R08: 0000000000004002 R09: 0000000000004002
> [ 437.497005] R10: ffff8801091ec87a R11: ffff88011b300000 R12: ffff880118922300
> [ 437.497005] R13: 0000000000000000 R14: ffff8800d79e8254 R15: ffff8800d79e826c
> [ 437.497005] FS: 00007f0ced3e8700(0000) GS:ffff88011fc00000(0000)
> knlGS:0000000000000000
> [ 437.497005] CS: 0010 DS: 0000 ES: 0000 CR0: 0000000080050033
> [ 437.497005] CR2: 0000000000000008 CR3: 00000000c8811000 CR4: 00000000000406f0
> [ 437.497005] DR0: 0000000000000000 DR1: 0000000000000000 DR2: 0000000000000000
> [ 437.497005] DR3: 0000000000000000 DR6: 00000000ffff0ff0 DR7: 0000000000000400
> [ 437.497005] Process qbittorrent (pid: 3274, threadinfo
> ffff8800c9906000, task ffff8800db999200)
> [ 437.497005] Stack:
> [ 437.497005] ffff88011fc03bb0 ffff8801091ec872 ffff8800d79e8240
> 0000052000000520
> [ 437.497005] ffff88011fc03be0 ffff8800d7844e00 ffff880119099200
> ffff8801091ec872
> [ 437.497005] ffff8800db8b6400 00000000000050cd ffff88011fc03c60
> ffffffffa0367e65
> [ 437.497005] Call Trace:
> [ 437.497005] <IRQ>
> [ 437.497005] [<ffffffffa0367e65>] l2tp_udp_encap_recv+0x33b/0x3e6 [l2tp_core]
> [ 437.497005] [<ffffffffa0377d96>] ? pppol2tp_setsockopt+0x2e0/0x2e0
> [l2tp_ppp]
> [ 437.497005] [<ffffffffa030640c>] ? ipv4_confirm+0x17e/0x198
> [nf_conntrack_ipv4]
> [ 437.497005] [<ffffffffa0377d96>] ? pppol2tp_setsockopt+0x2e0/0x2e0
> [l2tp_ppp]
> [ 437.497005] [<ffffffff812eb32b>] udp_queue_rcv_skb+0xee/0x2ce
> [ 437.497005] [<ffffffff812ebba3>] __udp4_lib_rcv+0x2d2/0x536
> [ 437.497005] [<ffffffff812cb046>] ? ip_rcv_finish+0x29a/0x29a
> [ 437.497005] [<ffffffff812ebe1c>] udp_rcv+0x15/0x17
> [ 437.497005] [<ffffffff812cb165>] ip_local_deliver_finish+0x11f/0x1c7
> [ 437.497005] [<ffffffff812cb361>] ip_local_deliver+0x75/0x7c
> [ 437.497005] [<ffffffff812cb023>] ip_rcv_finish+0x277/0x29a
> [ 437.497005] [<ffffffff812cb5a1>] ip_rcv+0x239/0x260
> [ 437.497005] [<ffffffff812a46cd>] ? napi_skb_finish+0x21/0x38
> [ 437.497005] [<ffffffff812a3adb>] __netif_receive_skb+0x430/0x462
> [ 437.497005] [<ffffffff8102342f>] ? update_curr+0x53/0x89
> [ 437.497005] [<ffffffff812a3b9d>] process_backlog+0x90/0x151
> [ 437.497005] [<ffffffff812a3e6a>] net_rx_action+0x9e/0x171
> [ 437.497005] [<ffffffff810344b0>] __do_softirq+0x93/0x129
> [ 437.497005] [<ffffffff8133034c>] call_softirq+0x1c/0x30
> [ 437.497005] [<ffffffff8100351c>] do_softirq+0x33/0x6b
> [ 437.497005] [<ffffffff8103470b>] irq_exit+0x52/0xac
> [ 437.497005] [<ffffffff81003251>] do_IRQ+0x98/0xaf
> [ 437.497005] [<ffffffff8132eb6b>] common_interrupt+0x6b/0x6b
> [ 437.497005] <EOI>
> [ 437.497005] [<ffffffff8132f17b>] ? system_call_fastpath+0x16/0x1b
> [ 437.497005] Code: 6c e8 57 03 fc e0 e9 22 01 00 00 ff 4b 50 4c 89
> f7 49 8b 14 24 49 c7 04 24 00 00 00 00 49 8b 44 24 08 49 c7 44 24 08
> 00 00 00 00
> [ 437.497005] 89 42 08 48 89 10 e8 1d 6f fc e0 41 0f b7 54 24 3e 48 8b 43
> [ 437.497005] RIP [<ffffffffa03679dc>] l2tp_recv_common+0x4d3/0x621
> [l2tp_core]
> [ 437.497005] RSP <ffff88011fc03b90>
> [ 437.497005] CR2: 0000000000000008
> [ 437.498126] ---[ end trace 053df4c7c6743d26 ]---
> [ 437.498184] Kernel panic - not syncing: Fatal exception in interrupt
> [ 437.498187] Pid: 3274, comm: qbittorrent Tainted: G D 3.1.0 #1
> [ 437.498189] Call Trace:
> [ 437.498190] <IRQ> [<ffffffff81327c11>] panic+0x8c/0x189
> [ 437.498197] [<ffffffff8100471d>] oops_end+0x81/0x8e
> [ 437.498200] [<ffffffff8132765b>] no_context+0x1fe/0x20d
> [ 437.498203] [<ffffffff81327829>] __bad_area_nosemaphore+0x1bf/0x1e0
> [ 437.498206] [<ffffffff812a5308>] ? dev_hard_start_xmit+0x412/0x51b
> [ 437.498210] [<ffffffff81327858>] bad_area_nosemaphore+0xe/0x10
> [ 437.498213] [<ffffffff8101c858>] do_page_fault+0x175/0x371
> [ 437.498217] [<ffffffff812a1eba>] ? netif_rx+0xc5/0xd0
> [ 437.498281] [<ffffffffa031ee7d>] ?
> ppp_receive_nonmp_frame+0x58f/0x5cf [ppp_generic]
> [ 437.498286] [<ffffffffa0320625>] ? ppp_receive_frame+0x5c1/0x5e2
> [ppp_generic]
> [ 437.498290] [<ffffffff8132ed6f>] page_fault+0x1f/0x30
> [ 437.498293] [<ffffffffa03679dc>] ? l2tp_recv_common+0x4d3/0x621 [l2tp_core]
> [ 437.498298] [<ffffffffa0367e65>] l2tp_udp_encap_recv+0x33b/0x3e6 [l2tp_core]
> [ 437.498302] [<ffffffffa0377d96>] ? pppol2tp_setsockopt+0x2e0/0x2e0
> [l2tp_ppp]
> [ 437.498306] [<ffffffffa030640c>] ? ipv4_confirm+0x17e/0x198
> [nf_conntrack_ipv4]
> [ 437.498310] [<ffffffffa0377d96>] ? pppol2tp_setsockopt+0x2e0/0x2e0
> [l2tp_ppp]
> [ 437.498314] [<ffffffff812eb32b>] udp_queue_rcv_skb+0xee/0x2ce
> [ 437.498317] [<ffffffff812ebba3>] __udp4_lib_rcv+0x2d2/0x536
> [ 437.498321] [<ffffffff812cb046>] ? ip_rcv_finish+0x29a/0x29a
> [ 437.498324] [<ffffffff812ebe1c>] udp_rcv+0x15/0x17
> [ 437.498328] [<ffffffff812cb165>] ip_local_deliver_finish+0x11f/0x1c7
> [ 437.498332] [<ffffffff812cb361>] ip_local_deliver+0x75/0x7c
> [ 437.498391] [<ffffffff812cb023>] ip_rcv_finish+0x277/0x29a
> [ 437.498394] [<ffffffff812cb5a1>] ip_rcv+0x239/0x260
> [ 437.498398] [<ffffffff812a46cd>] ? napi_skb_finish+0x21/0x38
> [ 437.498401] [<ffffffff812a3adb>] __netif_receive_skb+0x430/0x462
> [ 437.498404] [<ffffffff8102342f>] ? update_curr+0x53/0x89
> [ 437.498408] [<ffffffff812a3b9d>] process_backlog+0x90/0x151
>
>
> Software:
> Gnu C 4.6.1
> Gnu make 3.82
> binutils 2.21.1
> openl2tp 1.8-r3
>
> l2tp_recv_common+0x4d3/0x621 is match to
> net/l2tp/l2tp_core.c:429:__skb_unlink(skb, &session->reorder_q);
> skb->next is NULL.
Hi Misha
On what kind of NIC this is happening ?
^ permalink raw reply
* [PATCH] udp: fix a race in encap_rcv handling
From: Eric Dumazet @ 2011-11-01 22:56 UTC (permalink / raw)
To: David Miller; +Cc: netdev
In-Reply-To: <CAKpUy7Z5KOfHbKfBp-qg+77cED=OxUAkm2P4pQacHaHKmKBQpw@mail.gmail.com>
udp_queue_rcv_skb() has a possible race in encap_rcv handling, since
this pointer can be changed anytime.
We should use ACCESS_ONCE() to close the race.
Signed-off-by: Eric Dumazet <eric.dumazet@gmail.com>
---
net/ipv4/udp.c | 8 +++++---
1 file changed, 5 insertions(+), 3 deletions(-)
diff --git a/net/ipv4/udp.c b/net/ipv4/udp.c
index ebaa96b..15b50df 100644
--- a/net/ipv4/udp.c
+++ b/net/ipv4/udp.c
@@ -1397,6 +1397,8 @@ int udp_queue_rcv_skb(struct sock *sk, struct sk_buff *skb)
nf_reset(skb);
if (up->encap_type) {
+ int (*encap_rcv)(struct sock *sk, struct sk_buff *skb);
+
/*
* This is an encapsulation socket so pass the skb to
* the socket's udp_encap_rcv() hook. Otherwise, just
@@ -1409,11 +1411,11 @@ int udp_queue_rcv_skb(struct sock *sk, struct sk_buff *skb)
*/
/* if we're overly short, let UDP handle it */
- if (skb->len > sizeof(struct udphdr) &&
- up->encap_rcv != NULL) {
+ encap_rcv = ACCESS_ONCE(up->encap_rcv);
+ if (skb->len > sizeof(struct udphdr) && encap_rcv != NULL) {
int ret;
- ret = (*up->encap_rcv)(sk, skb);
+ ret = encap_rcv(sk, skb);
if (ret <= 0) {
UDP_INC_STATS_BH(sock_net(sk),
UDP_MIB_INDATAGRAMS,
^ permalink raw reply related
* [PATCH ethtool 01/21] Report pause frame autonegotiation result
From: Ben Hutchings @ 2011-11-01 23:13 UTC (permalink / raw)
To: netdev; +Cc: linux-net-drivers, Matt Carlson
In-Reply-To: <1320186901.2758.30.camel@bwh-desktop>
If pause frame autonegotiation is enabled and the driver reports the
link partner's advertising flags, report the result of autonegotiation.
Signed-off-by: Ben Hutchings <bhutchings@solarflare.com>
---
ethtool.c | 46 ++++++++++++++++++++++++++++++++++++++++------
1 files changed, 40 insertions(+), 6 deletions(-)
diff --git a/ethtool.c b/ethtool.c
index a4e8b58..ad2d583 100644
--- a/ethtool.c
+++ b/ethtool.c
@@ -1745,7 +1745,7 @@ static int dump_test(struct ethtool_drvinfo *info, struct ethtool_test *test,
return rc;
}
-static int dump_pause(void)
+static int dump_pause(u32 advertising, u32 lp_advertising)
{
fprintf(stdout,
"Autonegotiate: %s\n"
@@ -1755,6 +1755,30 @@ static int dump_pause(void)
epause.rx_pause ? "on" : "off",
epause.tx_pause ? "on" : "off");
+ if (lp_advertising) {
+ int an_rx = 0, an_tx = 0;
+
+ /* Work out negotiated pause frame usage per
+ * IEEE 802.3-2005 table 28B-3.
+ */
+ if (advertising & lp_advertising & ADVERTISED_Pause) {
+ an_tx = 1;
+ an_rx = 1;
+ } else if (advertising & lp_advertising &
+ ADVERTISED_Asym_Pause) {
+ if (advertising & ADVERTISED_Pause)
+ an_rx = 1;
+ else if (lp_advertising & ADVERTISED_Pause)
+ an_tx = 1;
+ }
+
+ fprintf(stdout,
+ "RX negotiated: %s\n"
+ "TX negotiated: %s\n",
+ an_rx ? "on" : "off",
+ an_tx ? "on" : "off");
+ }
+
fprintf(stdout, "\n");
return 0;
}
@@ -2051,6 +2075,7 @@ static int do_gdrv(int fd, struct ifreq *ifr)
static int do_gpause(int fd, struct ifreq *ifr)
{
+ struct ethtool_cmd ecmd;
int err;
fprintf(stdout, "Pause parameters for %s:\n", devname);
@@ -2058,15 +2083,24 @@ static int do_gpause(int fd, struct ifreq *ifr)
epause.cmd = ETHTOOL_GPAUSEPARAM;
ifr->ifr_data = (caddr_t)&epause;
err = send_ioctl(fd, ifr);
- if (err == 0) {
- err = dump_pause();
- if (err)
- return err;
- } else {
+ if (err) {
perror("Cannot get device pause settings");
return 76;
}
+ if (epause.autoneg) {
+ ecmd.cmd = ETHTOOL_GSET;
+ ifr->ifr_data = (caddr_t)&ecmd;
+ err = send_ioctl(fd, ifr);
+ if (err) {
+ perror("Cannot get device settings");
+ return 1;
+ }
+ dump_pause(ecmd.advertising, ecmd.lp_advertising);
+ } else {
+ dump_pause(0, 0);
+ }
+
return 0;
}
--
1.7.4.4
--
Ben Hutchings, Staff Engineer, Solarflare
Not speaking for my employer; that's the marketing department's job.
They asked us to note that Solarflare product names are trademarked.
^ permalink raw reply related
* [PATCH ethtool 02/21] ethtool.8: Fix initial blank line/page
From: Ben Hutchings @ 2011-11-01 23:13 UTC (permalink / raw)
To: netdev; +Cc: linux-net-drivers
In-Reply-To: <1320186901.2758.30.camel@bwh-desktop>
Commit 8d63f72ccdcb1b19358d753a8f48f08dcd2136f0 included a regression
of the problem fixed in commit 97b5471fc446d60f8772631b9c4e6d824404336d.
Signed-off-by: Ben Hutchings <bhutchings@solarflare.com>
---
ethtool.8.in | 2 +-
1 files changed, 1 insertions(+), 1 deletions(-)
diff --git a/ethtool.8.in b/ethtool.8.in
index f9d3633..286d089 100644
--- a/ethtool.8.in
+++ b/ethtool.8.in
@@ -75,7 +75,7 @@
.\" \(*NC - Network Classifier type values
.\"
.ds NC \fBether\fP|\fBip4\fP|\fBtcp4\fP|\fBudp4\fP|\fBsctp4\fP|\fBah4\fP|\fBesp4\fP
-
+..
.\"
.\" Start URL.
.de UR
--
1.7.4.4
--
Ben Hutchings, Staff Engineer, Solarflare
Not speaking for my employer; that's the marketing department's job.
They asked us to note that Solarflare product names are trademarked.
^ permalink raw reply related
* [PATCH ethtool 03/21] Combine ethtool-{bitops,util}.h into internal.h
From: Ben Hutchings @ 2011-11-01 23:14 UTC (permalink / raw)
To: netdev; +Cc: linux-net-drivers
In-Reply-To: <1320186901.2758.30.camel@bwh-desktop>
ethtool-util.h contains all kinds of declarations, not just utility
functions or macros.
ethtool-bitops.h contains just a few extra definitions, and its only
user also includes ethtool-util.h.
Signed-off-by: Ben Hutchings <bhutchings@solarflare.com>
---
Makefile.am | 2 +-
amd8111e.c | 2 +-
at76c50x-usb.c | 2 +-
de2104x.c | 2 +-
e100.c | 2 +-
e1000.c | 2 +-
ethtool-bitops.h | 25 -------------------------
ethtool.c | 2 +-
fec_8xx.c | 2 +-
ibm_emac.c | 2 +-
igb.c | 2 +-
ethtool-util.h => internal.h | 27 ++++++++++++++++++++++++---
ixgb.c | 2 +-
ixgbe.c | 2 +-
marvell.c | 2 +-
natsemi.c | 2 +-
pcnet32.c | 2 +-
realtek.c | 2 +-
rxclass.c | 3 +--
sfc.c | 2 +-
smsc911x.c | 2 +-
stmmac.c | 2 +-
tg3.c | 2 +-
vioc.c | 2 +-
24 files changed, 46 insertions(+), 51 deletions(-)
delete mode 100644 ethtool-bitops.h
rename ethtool-util.h => internal.h (86%)
diff --git a/Makefile.am b/Makefile.am
index c87fb39..1e05640 100644
--- a/Makefile.am
+++ b/Makefile.am
@@ -4,7 +4,7 @@ man_MANS = ethtool.8
EXTRA_DIST = LICENSE ethtool.8 ethtool.spec.in aclocal.m4 ChangeLog autogen.sh
sbin_PROGRAMS = ethtool
-ethtool_SOURCES = ethtool.c ethtool-bitops.h ethtool-copy.h ethtool-util.h \
+ethtool_SOURCES = ethtool.c ethtool-copy.h internal.h \
amd8111e.c de2104x.c e100.c e1000.c igb.c \
fec_8xx.c ibm_emac.c ixgb.c ixgbe.c natsemi.c \
pcnet32.c realtek.c tg3.c marvell.c vioc.c \
diff --git a/amd8111e.c b/amd8111e.c
index b4cd65d..23478f0 100644
--- a/amd8111e.c
+++ b/amd8111e.c
@@ -1,7 +1,7 @@
/* Copyright (C) 2003 Advanced Micro Devices Inc. */
#include <stdio.h>
-#include "ethtool-util.h"
+#include "internal.h"
typedef enum {
/* VAL2 */
diff --git a/at76c50x-usb.c b/at76c50x-usb.c
index 4c2a1a8..39e24a4 100644
--- a/at76c50x-usb.c
+++ b/at76c50x-usb.c
@@ -1,5 +1,5 @@
#include <stdio.h>
-#include "ethtool-util.h"
+#include "internal.h"
static char *hw_versions[] = {
"503_ISL3861",
diff --git a/de2104x.c b/de2104x.c
index f64e1b2..856e0c0 100644
--- a/de2104x.c
+++ b/de2104x.c
@@ -1,6 +1,6 @@
/* Copyright 2001 Sun Microsystems (thockin@sun.com) */
#include <stdio.h>
-#include "ethtool-util.h"
+#include "internal.h"
static const char * const csr0_tap[4] = {
"No transmit automatic polling",
diff --git a/e100.c b/e100.c
index 4d1cef3..65627ab 100644
--- a/e100.c
+++ b/e100.c
@@ -1,6 +1,6 @@
/* Copyright (c) 2002 Intel Corporation */
#include <stdio.h>
-#include "ethtool-util.h"
+#include "internal.h"
#define D102_REV_ID 12
diff --git a/e1000.c b/e1000.c
index 2eb3ac6..d1d3c73 100644
--- a/e1000.c
+++ b/e1000.c
@@ -1,6 +1,6 @@
/* Copyright (c) 2002 Intel Corporation */
#include <stdio.h>
-#include "ethtool-util.h"
+#include "internal.h"
/* Register Bit Masks */
/* Device Control */
diff --git a/ethtool-bitops.h b/ethtool-bitops.h
deleted file mode 100644
index b1eb426..0000000
--- a/ethtool-bitops.h
+++ /dev/null
@@ -1,25 +0,0 @@
-#ifndef ETHTOOL_BITOPS_H__
-#define ETHTOOL_BITOPS_H__
-
-#define BITS_PER_BYTE 8
-#define BITS_PER_LONG (BITS_PER_BYTE * sizeof(long))
-#define DIV_ROUND_UP(n, d) (((n) + (d) - 1) / (d))
-#define BITS_TO_LONGS(nr) DIV_ROUND_UP(nr, BITS_PER_LONG)
-
-static inline void set_bit(int nr, unsigned long *addr)
-{
- addr[nr / BITS_PER_LONG] |= 1UL << (nr % BITS_PER_LONG);
-}
-
-static inline void clear_bit(int nr, unsigned long *addr)
-{
- addr[nr / BITS_PER_LONG] &= ~(1UL << (nr % BITS_PER_LONG));
-}
-
-static inline int test_bit(unsigned int nr, const unsigned long *addr)
-{
- return !!((1UL << (nr % BITS_PER_LONG)) &
- (((unsigned long *)addr)[nr / BITS_PER_LONG]));
-}
-
-#endif
diff --git a/ethtool.c b/ethtool.c
index ad2d583..f772f61 100644
--- a/ethtool.c
+++ b/ethtool.c
@@ -23,7 +23,7 @@
* * show settings for all devices
*/
-#include "ethtool-util.h"
+#include "internal.h"
#include <string.h>
#include <stdlib.h>
#include <sys/stat.h>
diff --git a/fec_8xx.c b/fec_8xx.c
index 06a25d9..69db8c8 100644
--- a/fec_8xx.c
+++ b/fec_8xx.c
@@ -7,7 +7,7 @@
#include <stdint.h>
#include <stddef.h>
-#include "ethtool-util.h"
+#include "internal.h"
struct fec {
uint32_t addr_low; /* lower 32 bits of station address */
diff --git a/ibm_emac.c b/ibm_emac.c
index 7974836..e128e48 100644
--- a/ibm_emac.c
+++ b/ibm_emac.c
@@ -6,7 +6,7 @@
#include <stdint.h>
#include <stddef.h>
-#include "ethtool-util.h"
+#include "internal.h"
/* Ethtool get_regs complex data.
* we want to get not just EMAC registers, but also MAL, ZMII, RGMII, TAH
diff --git a/igb.c b/igb.c
index 4b836d9..ec35d36 100644
--- a/igb.c
+++ b/igb.c
@@ -1,6 +1,6 @@
/* Copyright (c) 2007 Intel Corporation */
#include <stdio.h>
-#include "ethtool-util.h"
+#include "internal.h"
/* Register Bit Masks */
/* Device Control */
diff --git a/ethtool-util.h b/internal.h
similarity index 86%
rename from ethtool-util.h
rename to internal.h
index 79be7f2..693b091 100644
--- a/ethtool-util.h
+++ b/internal.h
@@ -1,7 +1,7 @@
/* Portions Copyright 2001 Sun Microsystems (thockin@sun.com) */
/* Portions Copyright 2002 Intel (scott.feldman@intel.com) */
-#ifndef ETHTOOL_UTIL_H__
-#define ETHTOOL_UTIL_H__
+#ifndef ETHTOOL_INTERNAL_H__
+#define ETHTOOL_INTERNAL_H__
#ifdef HAVE_CONFIG_H
#include "ethtool-config.h"
@@ -57,6 +57,27 @@ static inline u64 cpu_to_be64(u64 value)
#define ntohll cpu_to_be64
#define htonll cpu_to_be64
+#define BITS_PER_BYTE 8
+#define BITS_PER_LONG (BITS_PER_BYTE * sizeof(long))
+#define DIV_ROUND_UP(n, d) (((n) + (d) - 1) / (d))
+#define BITS_TO_LONGS(nr) DIV_ROUND_UP(nr, BITS_PER_LONG)
+
+static inline void set_bit(int nr, unsigned long *addr)
+{
+ addr[nr / BITS_PER_LONG] |= 1UL << (nr % BITS_PER_LONG);
+}
+
+static inline void clear_bit(int nr, unsigned long *addr)
+{
+ addr[nr / BITS_PER_LONG] &= ~(1UL << (nr % BITS_PER_LONG));
+}
+
+static inline int test_bit(unsigned int nr, const unsigned long *addr)
+{
+ return !!((1UL << (nr % BITS_PER_LONG)) &
+ (((unsigned long *)addr)[nr / BITS_PER_LONG]));
+}
+
#ifndef ARRAY_SIZE
#define ARRAY_SIZE(x) (sizeof(x) / sizeof((x)[0]))
#endif
@@ -140,4 +161,4 @@ int rxclass_rule_ins(int fd, struct ifreq *ifr,
struct ethtool_rx_flow_spec *fsp);
int rxclass_rule_del(int fd, struct ifreq *ifr, __u32 loc);
-#endif /* ETHTOOL_UTIL_H__ */
+#endif /* ETHTOOL_INTERNAL_H__ */
diff --git a/ixgb.c b/ixgb.c
index 00c90d3..8687c21 100644
--- a/ixgb.c
+++ b/ixgb.c
@@ -1,6 +1,6 @@
/* Copyright (c) 2006 Intel Corporation */
#include <stdio.h>
-#include "ethtool-util.h"
+#include "internal.h"
/* CTRL0 Bit Masks */
#define IXGB_CTRL0_LRST 0x00000008
diff --git a/ixgbe.c b/ixgbe.c
index e64d34a..dae11d4 100644
--- a/ixgbe.c
+++ b/ixgbe.c
@@ -1,6 +1,6 @@
/* Copyright (c) 2007 Intel Corporation */
#include <stdio.h>
-#include "ethtool-util.h"
+#include "internal.h"
/* Register Bit Masks */
#define IXGBE_FCTRL_SBP 0x00000002
diff --git a/marvell.c b/marvell.c
index af38c21..e583c82 100644
--- a/marvell.c
+++ b/marvell.c
@@ -7,7 +7,7 @@
#include <stdio.h>
-#include "ethtool-util.h"
+#include "internal.h"
static void dump_addr(int n, const u8 *a)
{
diff --git a/natsemi.c b/natsemi.c
index 24a7cb3..eaf83e2 100644
--- a/natsemi.c
+++ b/natsemi.c
@@ -1,6 +1,6 @@
/* Copyright 2001 Sun Microsystems (thockin@sun.com) */
#include <stdio.h>
-#include "ethtool-util.h"
+#include "internal.h"
#define PCI_VENDOR_NATSEMI 0x100b
#define PCI_DEVICE_DP83815 0x0020
diff --git a/pcnet32.c b/pcnet32.c
index 1dac02d..b87cee7 100644
--- a/pcnet32.c
+++ b/pcnet32.c
@@ -2,7 +2,7 @@
#include <stdio.h>
#include <stdlib.h>
-#include "ethtool-util.h"
+#include "internal.h"
#define BIT0 0x0001
#define BIT1 0x0002
diff --git a/realtek.c b/realtek.c
index 11ed835..c3d7ae5 100644
--- a/realtek.c
+++ b/realtek.c
@@ -1,7 +1,7 @@
/* Copyright 2001 Sun Microsystems (thockin@sun.com) */
#include <stdio.h>
#include <stdlib.h>
-#include "ethtool-util.h"
+#include "internal.h"
#define ARRAY_SIZE(x) (sizeof(x) / sizeof((x)[0]))
diff --git a/rxclass.c b/rxclass.c
index b227901..809b073 100644
--- a/rxclass.c
+++ b/rxclass.c
@@ -10,8 +10,7 @@
#include <linux/sockios.h>
#include <arpa/inet.h>
-#include "ethtool-util.h"
-#include "ethtool-bitops.h"
+#include "internal.h"
static void invert_flow_mask(struct ethtool_rx_flow_spec *fsp)
{
diff --git a/sfc.c b/sfc.c
index c8ca74a..46a617b 100644
--- a/sfc.c
+++ b/sfc.c
@@ -9,7 +9,7 @@
#include <stdio.h>
#include <string.h>
-#include "ethtool-util.h"
+#include "internal.h"
#ifndef ARRAY_SIZE
#define ARRAY_SIZE(x) (sizeof(x) / sizeof((x)[0]))
diff --git a/smsc911x.c b/smsc911x.c
index 1aa39a1..c55b97b 100644
--- a/smsc911x.c
+++ b/smsc911x.c
@@ -1,6 +1,6 @@
#include <stdio.h>
#include <string.h>
-#include "ethtool-util.h"
+#include "internal.h"
int smsc911x_dump_regs(struct ethtool_drvinfo *info, struct ethtool_regs *regs)
{
diff --git a/stmmac.c b/stmmac.c
index ad4311c..fb69bfe 100644
--- a/stmmac.c
+++ b/stmmac.c
@@ -12,7 +12,7 @@
#include <stdio.h>
#include <string.h>
-#include "ethtool-util.h"
+#include "internal.h"
int st_mac100_dump_regs(struct ethtool_drvinfo *info,
struct ethtool_regs *regs)
diff --git a/tg3.c b/tg3.c
index 4868504..3232339 100644
--- a/tg3.c
+++ b/tg3.c
@@ -1,6 +1,6 @@
#include <stdio.h>
#include <string.h>
-#include "ethtool-util.h"
+#include "internal.h"
#define TG3_MAGIC 0x669955aa
diff --git a/vioc.c b/vioc.c
index c771737..eff533d 100644
--- a/vioc.c
+++ b/vioc.c
@@ -2,7 +2,7 @@
#include <stdio.h>
#include <stdlib.h>
-#include "ethtool-util.h"
+#include "internal.h"
struct regs_line {
u32 addr;
--
1.7.4.4
--
Ben Hutchings, Staff Engineer, Solarflare
Not speaking for my employer; that's the marketing department's job.
They asked us to note that Solarflare product names are trademarked.
^ permalink raw reply related
* [PATCH ethtool 04/21] Fix type of bit-number parameter to set_bit() and clear_bit()
From: Ben Hutchings @ 2011-11-01 23:14 UTC (permalink / raw)
To: netdev; +Cc: linux-net-drivers, Alexander Duyck
In-Reply-To: <1320186901.2758.30.camel@bwh-desktop>
The index must not be negative, so the parameter does not need to be
signed. Division and modulus on signed operands generally cannot be
optimised to right-shift and bitwise-and.
Signed-off-by: Ben Hutchings <bhutchings@solarflare.com>
---
internal.h | 4 ++--
1 files changed, 2 insertions(+), 2 deletions(-)
diff --git a/internal.h b/internal.h
index 693b091..2b6a54a 100644
--- a/internal.h
+++ b/internal.h
@@ -62,12 +62,12 @@ static inline u64 cpu_to_be64(u64 value)
#define DIV_ROUND_UP(n, d) (((n) + (d) - 1) / (d))
#define BITS_TO_LONGS(nr) DIV_ROUND_UP(nr, BITS_PER_LONG)
-static inline void set_bit(int nr, unsigned long *addr)
+static inline void set_bit(unsigned int nr, unsigned long *addr)
{
addr[nr / BITS_PER_LONG] |= 1UL << (nr % BITS_PER_LONG);
}
-static inline void clear_bit(int nr, unsigned long *addr)
+static inline void clear_bit(unsigned int nr, unsigned long *addr)
{
addr[nr / BITS_PER_LONG] &= ~(1UL << (nr % BITS_PER_LONG));
}
--
1.7.4.4
--
Ben Hutchings, Staff Engineer, Solarflare
Not speaking for my employer; that's the marketing department's job.
They asked us to note that Solarflare product names are trademarked.
^ permalink raw reply related
* [PATCH ethtool 05/21] ethtool.8: Change device name metavariable from 'ethX' to 'devname'
From: Ben Hutchings @ 2011-11-01 23:15 UTC (permalink / raw)
To: netdev; +Cc: linux-net-drivers
In-Reply-To: <1320186901.2758.30.camel@bwh-desktop>
The name 'ethX' is a poor choice because:
- Many ethtool options are applicable to non-Ethernet devices
- Ethernet device names don't have to begin with 'eth', and the
new convention is to use the prefix 'lan' for LAN-on-motherboard
or 'pci' for PCI plug-in cards
The online help text already uses 'DEVNAME' instead, so change the
manual page to be consistent.
Signed-off-by: Ben Hutchings <bhutchings@solarflare.com>
---
ethtool.8.in | 62 +++++++++++++++++++++++++++++-----------------------------
1 files changed, 31 insertions(+), 31 deletions(-)
diff --git a/ethtool.8.in b/ethtool.8.in
index 286d089..65392d6 100644
--- a/ethtool.8.in
+++ b/ethtool.8.in
@@ -123,26 +123,26 @@ ethtool \- query or control network driver and hardware settings
.nh
.HP
.B ethtool
-.I ethX
+.I devname
.HP
.B ethtool \-h|\-\-help
.HP
.B ethtool \-\-version
.HP
.B ethtool \-a|\-\-show\-pause
-.I ethX
+.I devname
.HP
.B ethtool \-A|\-\-pause
-.I ethX
+.I devname
.B2 autoneg on off
.B2 rx on off
.B2 tx on off
.HP
.B ethtool \-c|\-\-show\-coalesce
-.I ethX
+.I devname
.HP
.B ethtool \-C|\-\-coalesce
-.I ethX
+.I devname
.B2 adaptive\-rx on off
.B2 adaptive\-tx on off
.BN rx\-usecs
@@ -167,43 +167,43 @@ ethtool \- query or control network driver and hardware settings
.BN sample\-interval
.HP
.B ethtool \-g|\-\-show\-ring
-.I ethX
+.I devname
.HP
.B ethtool \-G|\-\-set\-ring
-.I ethX
+.I devname
.BN rx
.BN rx\-mini
.BN rx\-jumbo
.BN tx
.HP
.B ethtool \-i|\-\-driver
-.I ethX
+.I devname
.HP
.B ethtool \-d|\-\-register\-dump
-.I ethX
+.I devname
.B2 raw on off
.B2 hex on off
.RB [ file
.IR name ]
.HP
.B ethtool \-e|\-\-eeprom\-dump
-.I ethX
+.I devname
.B2 raw on off
.BN offset
.BN length
.HP
.B ethtool \-E|\-\-change\-eeprom
-.I ethX
+.I devname
.BN magic
.BN offset
.BN length
.BN value
.HP
.B ethtool \-k|\-\-show\-offload
-.I ethX
+.I devname
.HP
.B ethtool \-K|\-\-offload
-.I ethX
+.I devname
.B2 rx on off
.B2 tx on off
.B2 sg on off
@@ -217,24 +217,24 @@ ethtool \- query or control network driver and hardware settings
.B2 rxhash on off
.HP
.B ethtool \-p|\-\-identify
-.I ethX
+.I devname
.RI [ N ]
.HP
.B ethtool \-P|\-\-show\-permaddr
-.I ethX
+.I devname
.HP
.B ethtool \-r|\-\-negotiate
-.I ethX
+.I devname
.HP
.B ethtool \-S|\-\-statistics
-.I ethX
+.I devname
.HP
.B ethtool \-t|\-\-test
-.I ethX
+.I devname
.RI [\*(SD]
.HP
.B ethtool \-s
-.I ethX
+.I devname
.BI speed \ N
.B2 duplex half full
.B4 port tp aui bnc mii fibre
@@ -251,27 +251,27 @@ ethtool \- query or control network driver and hardware settings
.RB ...]
.HP
.B ethtool \-n
-.I ethX
+.I devname
.RB [ rx\-flow\-hash \ \*(FL]
.HP
.B ethtool \-N
-.I ethX
+.I devname
.RB [ rx\-flow\-hash \ \*(FL \ \*(HO]
.HP
.B ethtool \-w|\-\-get\-dump
-.I ethX
+.I devname
.RB [ data
.IR filename ]
.HP
.B ethtool\ \-W|\-\-set\-dump
-.I ethX
+.I devname
.BI \ N
.HP
.B ethtool \-x|\-\-show\-rxfh\-indir
-.I ethX
+.I devname
.HP
.B ethtool \-X|\-\-set\-rxfh\-indir
-.I ethX
+.I devname
.RB [\ equal
.IR N \ |
.BI weight\ W0
@@ -279,15 +279,15 @@ ethtool \- query or control network driver and hardware settings
.RB ...\ ]
.HP
.B ethtool \-f|\-\-flash
-.I ethX
+.I devname
.RI FILE
.RI [ N ]
.HP
.B ethtool \-u|\-\-show\-ntuple
-.I ethX
+.I devname
.BN rule
.HP
-.BI ethtool\ \-U|\-\-config\-ntuple \ ethX
+.BI ethtool\ \-U|\-\-config\-ntuple \ devname
.BN delete
.RB [\ flow\-type \ \*(NC
.RB [ src \ \*(MA\ [ m \ \*(MA]]
@@ -309,10 +309,10 @@ ethtool \- query or control network driver and hardware settings
.RB ]
.HP
.B ethtool \-l|\-\-show\-channels
-.I ethX
+.I devname
.HP
.B ethtool \-L|\-\-set\-channels
-.I ethX
+.I devname
.BN rx
.BN tx
.BN other
@@ -327,7 +327,7 @@ ethtool \- query or control network driver and hardware settings
is used to query and control network device driver and hardware
settings, particularly for wired Ethernet devices.
-.I ethX
+.I devname
is the name of the network device on which ethtool should operate.
.SH OPTIONS
--
1.7.4.4
--
Ben Hutchings, Staff Engineer, Solarflare
Not speaking for my employer; that's the marketing department's job.
They asked us to note that Solarflare product names are trademarked.
^ permalink raw reply related
* [PATCH ethtool 06/21] ethtool.8: Allow line-break in description of parameters after -N
From: Ben Hutchings @ 2011-11-01 23:15 UTC (permalink / raw)
To: netdev; +Cc: linux-net-drivers
In-Reply-To: <1320186901.2758.30.camel@bwh-desktop>
These lines are currently unbreakable and result in ugly wrapping
in an 80-column window.
Signed-off-by: Ben Hutchings <bhutchings@solarflare.com>
---
ethtool.8.in | 4 ++--
1 files changed, 2 insertions(+), 2 deletions(-)
diff --git a/ethtool.8.in b/ethtool.8.in
index 65392d6..3304fe5 100644
--- a/ethtool.8.in
+++ b/ethtool.8.in
@@ -256,7 +256,7 @@ ethtool \- query or control network driver and hardware settings
.HP
.B ethtool \-N
.I devname
-.RB [ rx\-flow\-hash \ \*(FL \ \*(HO]
+.RB [ rx\-flow\-hash \ \*(FL \: \*(HO]
.HP
.B ethtool \-w|\-\-get\-dump
.I devname
@@ -605,7 +605,7 @@ sctp6 SCTP over IPv6
.B \-N \-\-config\-nfc
Configures the receive network flow classification.
.TP
-.BR rx\-flow\-hash \ \*(FL \ \*(HO
+.BR rx\-flow\-hash \ \*(FL \: \*(HO
Configures the hash options for the specified network traffic type.
.TS
nokeep;
--
1.7.4.4
--
Ben Hutchings, Staff Engineer, Solarflare
Not speaking for my employer; that's the marketing department's job.
They asked us to note that Solarflare product names are trademarked.
^ permalink raw reply related
* [PATCH ethtool 07/21] Fix format of help text for -f option
From: Ben Hutchings @ 2011-11-01 23:15 UTC (permalink / raw)
To: netdev; +Cc: linux-net-drivers
In-Reply-To: <1320186901.2758.30.camel@bwh-desktop>
Signed-off-by: Ben Hutchings <bhutchings@solarflare.com>
---
ethtool.c | 4 ++--
1 files changed, 2 insertions(+), 2 deletions(-)
diff --git a/ethtool.c b/ethtool.c
index f772f61..aab1e41 100644
--- a/ethtool.c
+++ b/ethtool.c
@@ -229,9 +229,9 @@ static struct option {
"options",
" [ rx-flow-hash tcp4|udp4|ah4|esp4|sctp4|"
"tcp6|udp6|ah6|esp6|sctp6 ]\n" },
- { "-f", "--flash", MODE_FLASHDEV, "FILENAME " "Flash firmware image "
+ { "-f", "--flash", MODE_FLASHDEV, "Flash firmware image "
"from the specified file to a region on the device",
- " [ REGION-NUMBER-TO-FLASH ]\n" },
+ " FILENAME [ REGION-NUMBER-TO-FLASH ]\n" },
{ "-N", "--config-nfc", MODE_SNFC, "Configure Rx network flow "
"classification options",
" [ rx-flow-hash tcp4|udp4|ah4|esp4|sctp4|"
--
1.7.4.4
--
Ben Hutchings, Staff Engineer, Solarflare
Not speaking for my employer; that's the marketing department's job.
They asked us to note that Solarflare product names are trademarked.
^ permalink raw reply related
* [PATCH ethtool 08/21] Use standard indentation for definition of struct option args
From: Ben Hutchings @ 2011-11-01 23:15 UTC (permalink / raw)
To: netdev; +Cc: linux-net-drivers
In-Reply-To: <1320186901.2758.30.camel@bwh-desktop>
Also put the whole of the help string on a line of its own where
necessary.
Signed-off-by: Ben Hutchings <bhutchings@solarflare.com>
---
ethtool.c | 280 +++++++++++++++++++++++++++++++------------------------------
1 files changed, 142 insertions(+), 138 deletions(-)
diff --git a/ethtool.c b/ethtool.c
index aab1e41..f967f84 100644
--- a/ethtool.c
+++ b/ethtool.c
@@ -140,145 +140,149 @@ static enum {
} mode = MODE_GSET;
static struct option {
- char *srt, *lng;
- int Mode;
- char *help;
- char *opthelp;
+ char *srt, *lng;
+ int Mode;
+ char *help;
+ char *opthelp;
} args[] = {
- { "-s", "--change", MODE_SSET, "Change generic options",
- " [ speed %d ]\n"
- " [ duplex half|full ]\n"
- " [ port tp|aui|bnc|mii|fibre ]\n"
- " [ autoneg on|off ]\n"
- " [ advertise %x ]\n"
- " [ phyad %d ]\n"
- " [ xcvr internal|external ]\n"
- " [ wol p|u|m|b|a|g|s|d... ]\n"
- " [ sopass %x:%x:%x:%x:%x:%x ]\n"
- " [ msglvl %d | msglvl type on|off ... ]\n" },
- { "-a", "--show-pause", MODE_GPAUSE, "Show pause options" },
- { "-A", "--pause", MODE_SPAUSE, "Set pause options",
- " [ autoneg on|off ]\n"
- " [ rx on|off ]\n"
- " [ tx on|off ]\n" },
- { "-c", "--show-coalesce", MODE_GCOALESCE, "Show coalesce options" },
- { "-C", "--coalesce", MODE_SCOALESCE, "Set coalesce options",
- " [adaptive-rx on|off]\n"
- " [adaptive-tx on|off]\n"
- " [rx-usecs N]\n"
- " [rx-frames N]\n"
- " [rx-usecs-irq N]\n"
- " [rx-frames-irq N]\n"
- " [tx-usecs N]\n"
- " [tx-frames N]\n"
- " [tx-usecs-irq N]\n"
- " [tx-frames-irq N]\n"
- " [stats-block-usecs N]\n"
- " [pkt-rate-low N]\n"
- " [rx-usecs-low N]\n"
- " [rx-frames-low N]\n"
- " [tx-usecs-low N]\n"
- " [tx-frames-low N]\n"
- " [pkt-rate-high N]\n"
- " [rx-usecs-high N]\n"
- " [rx-frames-high N]\n"
- " [tx-usecs-high N]\n"
- " [tx-frames-high N]\n"
- " [sample-interval N]\n" },
- { "-g", "--show-ring", MODE_GRING, "Query RX/TX ring parameters" },
- { "-G", "--set-ring", MODE_SRING, "Set RX/TX ring parameters",
- " [ rx N ]\n"
- " [ rx-mini N ]\n"
- " [ rx-jumbo N ]\n"
- " [ tx N ]\n" },
- { "-k", "--show-offload", MODE_GOFFLOAD, "Get protocol offload information" },
- { "-K", "--offload", MODE_SOFFLOAD, "Set protocol offload",
- " [ rx on|off ]\n"
- " [ tx on|off ]\n"
- " [ sg on|off ]\n"
- " [ tso on|off ]\n"
- " [ ufo on|off ]\n"
- " [ gso on|off ]\n"
- " [ gro on|off ]\n"
- " [ lro on|off ]\n"
- " [ rxvlan on|off ]\n"
- " [ txvlan on|off ]\n"
- " [ ntuple on|off ]\n"
- " [ rxhash on|off ]\n"
- },
- { "-i", "--driver", MODE_GDRV, "Show driver information" },
- { "-d", "--register-dump", MODE_GREGS, "Do a register dump",
- " [ raw on|off ]\n"
- " [ file FILENAME ]\n" },
- { "-e", "--eeprom-dump", MODE_GEEPROM, "Do a EEPROM dump",
- " [ raw on|off ]\n"
- " [ offset N ]\n"
- " [ length N ]\n" },
- { "-E", "--change-eeprom", MODE_SEEPROM, "Change bytes in device EEPROM",
- " [ magic N ]\n"
- " [ offset N ]\n"
- " [ length N ]\n"
- " [ value N ]\n" },
- { "-r", "--negotiate", MODE_NWAY_RST, "Restart N-WAY negotiation" },
- { "-p", "--identify", MODE_PHYS_ID, "Show visible port identification (e.g. blinking)",
- " [ TIME-IN-SECONDS ]\n" },
- { "-t", "--test", MODE_TEST, "Execute adapter self test",
- " [ online | offline | external_lb ]\n" },
- { "-S", "--statistics", MODE_GSTATS, "Show adapter statistics" },
- { "-n", "--show-nfc", MODE_GNFC, "Show Rx network flow classification "
- "options",
- " [ rx-flow-hash tcp4|udp4|ah4|esp4|sctp4|"
- "tcp6|udp6|ah6|esp6|sctp6 ]\n" },
- { "-f", "--flash", MODE_FLASHDEV, "Flash firmware image "
- "from the specified file to a region on the device",
- " FILENAME [ REGION-NUMBER-TO-FLASH ]\n" },
- { "-N", "--config-nfc", MODE_SNFC, "Configure Rx network flow "
- "classification options",
- " [ rx-flow-hash tcp4|udp4|ah4|esp4|sctp4|"
- "tcp6|udp6|ah6|esp6|sctp6 m|v|t|s|d|f|n|r... ]\n" },
- { "-x", "--show-rxfh-indir", MODE_GRXFHINDIR, "Show Rx flow hash "
- "indirection" },
- { "-X", "--set-rxfh-indir", MODE_SRXFHINDIR, "Set Rx flow hash indirection",
- " equal N | weight W0 W1 ...\n" },
- { "-U", "--config-ntuple", MODE_SCLSRULE, "Configure Rx ntuple filters "
- "and actions",
- " [ delete %d ] |\n"
- " [ flow-type ether|ip4|tcp4|udp4|sctp4|ah4|esp4\n"
- " [ src %x:%x:%x:%x:%x:%x [m %x:%x:%x:%x:%x:%x] ]\n"
- " [ dst %x:%x:%x:%x:%x:%x [m %x:%x:%x:%x:%x:%x] ]\n"
- " [ proto %d [m %x] ]\n"
- " [ src-ip %d.%d.%d.%d [m %d.%d.%d.%d] ]\n"
- " [ dst-ip %d.%d.%d.%d [m %d.%d.%d.%d] ]\n"
- " [ tos %d [m %x] ]\n"
- " [ l4proto %d [m %x] ]\n"
- " [ src-port %d [m %x] ]\n"
- " [ dst-port %d [m %x] ]\n"
- " [ spi %d [m %x] ]\n"
- " [ vlan-etype %x [m %x] ]\n"
- " [ vlan %x [m %x] ]\n"
- " [ user-def %x [m %x] ]\n"
- " [ action %d ]\n"
- " [ loc %d]]\n" },
- { "-u", "--show-ntuple", MODE_GCLSRULE,
- "Get Rx ntuple filters and actions",
- " [ rule %d ]\n"},
- { "-P", "--show-permaddr", MODE_PERMADDR,
- "Show permanent hardware address" },
- { "-w", "--get-dump", MODE_GET_DUMP,
- "Get dump flag, data",
- " [ data FILENAME ]\n" },
- { "-W", "--set-dump", MODE_SET_DUMP,
- "Set dump flag of the device",
- " N\n"},
- { "-l", "--show-channels", MODE_GCHANNELS, "Query Channels" },
- { "-L", "--set-channels", MODE_SCHANNELS, "Set Channels",
- " [ rx N ]\n"
- " [ tx N ]\n"
- " [ other N ]\n"
- " [ combined N ]\n" },
- { "-h", "--help", MODE_HELP, "Show this help" },
- { NULL, "--version", MODE_VERSION, "Show version number" },
- {}
+ { "-s", "--change", MODE_SSET, "Change generic options",
+ " [ speed %d ]\n"
+ " [ duplex half|full ]\n"
+ " [ port tp|aui|bnc|mii|fibre ]\n"
+ " [ autoneg on|off ]\n"
+ " [ advertise %x ]\n"
+ " [ phyad %d ]\n"
+ " [ xcvr internal|external ]\n"
+ " [ wol p|u|m|b|a|g|s|d... ]\n"
+ " [ sopass %x:%x:%x:%x:%x:%x ]\n"
+ " [ msglvl %d | msglvl type on|off ... ]\n" },
+ { "-a", "--show-pause", MODE_GPAUSE, "Show pause options" },
+ { "-A", "--pause", MODE_SPAUSE, "Set pause options",
+ " [ autoneg on|off ]\n"
+ " [ rx on|off ]\n"
+ " [ tx on|off ]\n" },
+ { "-c", "--show-coalesce", MODE_GCOALESCE, "Show coalesce options" },
+ { "-C", "--coalesce", MODE_SCOALESCE, "Set coalesce options",
+ " [adaptive-rx on|off]\n"
+ " [adaptive-tx on|off]\n"
+ " [rx-usecs N]\n"
+ " [rx-frames N]\n"
+ " [rx-usecs-irq N]\n"
+ " [rx-frames-irq N]\n"
+ " [tx-usecs N]\n"
+ " [tx-frames N]\n"
+ " [tx-usecs-irq N]\n"
+ " [tx-frames-irq N]\n"
+ " [stats-block-usecs N]\n"
+ " [pkt-rate-low N]\n"
+ " [rx-usecs-low N]\n"
+ " [rx-frames-low N]\n"
+ " [tx-usecs-low N]\n"
+ " [tx-frames-low N]\n"
+ " [pkt-rate-high N]\n"
+ " [rx-usecs-high N]\n"
+ " [rx-frames-high N]\n"
+ " [tx-usecs-high N]\n"
+ " [tx-frames-high N]\n"
+ " [sample-interval N]\n" },
+ { "-g", "--show-ring", MODE_GRING, "Query RX/TX ring parameters" },
+ { "-G", "--set-ring", MODE_SRING, "Set RX/TX ring parameters",
+ " [ rx N ]\n"
+ " [ rx-mini N ]\n"
+ " [ rx-jumbo N ]\n"
+ " [ tx N ]\n" },
+ { "-k", "--show-offload", MODE_GOFFLOAD,
+ "Get protocol offload information" },
+ { "-K", "--offload", MODE_SOFFLOAD, "Set protocol offload",
+ " [ rx on|off ]\n"
+ " [ tx on|off ]\n"
+ " [ sg on|off ]\n"
+ " [ tso on|off ]\n"
+ " [ ufo on|off ]\n"
+ " [ gso on|off ]\n"
+ " [ gro on|off ]\n"
+ " [ lro on|off ]\n"
+ " [ rxvlan on|off ]\n"
+ " [ txvlan on|off ]\n"
+ " [ ntuple on|off ]\n"
+ " [ rxhash on|off ]\n"
+ },
+ { "-i", "--driver", MODE_GDRV, "Show driver information" },
+ { "-d", "--register-dump", MODE_GREGS, "Do a register dump",
+ " [ raw on|off ]\n"
+ " [ file FILENAME ]\n" },
+ { "-e", "--eeprom-dump", MODE_GEEPROM, "Do a EEPROM dump",
+ " [ raw on|off ]\n"
+ " [ offset N ]\n"
+ " [ length N ]\n" },
+ { "-E", "--change-eeprom", MODE_SEEPROM,
+ "Change bytes in device EEPROM",
+ " [ magic N ]\n"
+ " [ offset N ]\n"
+ " [ length N ]\n"
+ " [ value N ]\n" },
+ { "-r", "--negotiate", MODE_NWAY_RST, "Restart N-WAY negotiation" },
+ { "-p", "--identify", MODE_PHYS_ID,
+ "Show visible port identification (e.g. blinking)",
+ " [ TIME-IN-SECONDS ]\n" },
+ { "-t", "--test", MODE_TEST, "Execute adapter self test",
+ " [ online | offline | external_lb ]\n" },
+ { "-S", "--statistics", MODE_GSTATS, "Show adapter statistics" },
+ { "-n", "--show-nfc", MODE_GNFC,
+ "Show Rx network flow classification options",
+ " [ rx-flow-hash tcp4|udp4|ah4|esp4|sctp4|"
+ "tcp6|udp6|ah6|esp6|sctp6 ]\n" },
+ { "-f", "--flash", MODE_FLASHDEV,
+ "Flash firmware image from the specified file to a region on the device",
+ " FILENAME [ REGION-NUMBER-TO-FLASH ]\n" },
+ { "-N", "--config-nfc", MODE_SNFC,
+ "Configure Rx network flow classification options",
+ " [ rx-flow-hash tcp4|udp4|ah4|esp4|sctp4|"
+ "tcp6|udp6|ah6|esp6|sctp6 m|v|t|s|d|f|n|r... ]\n" },
+ { "-x", "--show-rxfh-indir", MODE_GRXFHINDIR,
+ "Show Rx flow hash indirection" },
+ { "-X", "--set-rxfh-indir", MODE_SRXFHINDIR,
+ "Set Rx flow hash indirection",
+ " equal N | weight W0 W1 ...\n" },
+ { "-U", "--config-ntuple", MODE_SCLSRULE,
+ "Configure Rx ntuple filters and actions",
+ " [ delete %d ] |\n"
+ " [ flow-type ether|ip4|tcp4|udp4|sctp4|ah4|esp4\n"
+ " [ src %x:%x:%x:%x:%x:%x [m %x:%x:%x:%x:%x:%x] ]\n"
+ " [ dst %x:%x:%x:%x:%x:%x [m %x:%x:%x:%x:%x:%x] ]\n"
+ " [ proto %d [m %x] ]\n"
+ " [ src-ip %d.%d.%d.%d [m %d.%d.%d.%d] ]\n"
+ " [ dst-ip %d.%d.%d.%d [m %d.%d.%d.%d] ]\n"
+ " [ tos %d [m %x] ]\n"
+ " [ l4proto %d [m %x] ]\n"
+ " [ src-port %d [m %x] ]\n"
+ " [ dst-port %d [m %x] ]\n"
+ " [ spi %d [m %x] ]\n"
+ " [ vlan-etype %x [m %x] ]\n"
+ " [ vlan %x [m %x] ]\n"
+ " [ user-def %x [m %x] ]\n"
+ " [ action %d ]\n"
+ " [ loc %d]]\n" },
+ { "-u", "--show-ntuple", MODE_GCLSRULE,
+ "Get Rx ntuple filters and actions",
+ " [ rule %d ]\n"},
+ { "-P", "--show-permaddr", MODE_PERMADDR,
+ "Show permanent hardware address" },
+ { "-w", "--get-dump", MODE_GET_DUMP,
+ "Get dump flag, data",
+ " [ data FILENAME ]\n" },
+ { "-W", "--set-dump", MODE_SET_DUMP,
+ "Set dump flag of the device",
+ " N\n"},
+ { "-l", "--show-channels", MODE_GCHANNELS, "Query Channels" },
+ { "-L", "--set-channels", MODE_SCHANNELS, "Set Channels",
+ " [ rx N ]\n"
+ " [ tx N ]\n"
+ " [ other N ]\n"
+ " [ combined N ]\n" },
+ { "-h", "--help", MODE_HELP, "Show this help" },
+ { NULL, "--version", MODE_VERSION, "Show version number" },
+ {}
};
--
1.7.4.4
--
Ben Hutchings, Staff Engineer, Solarflare
Not speaking for my employer; that's the marketing department's job.
They asked us to note that Solarflare product names are trademarked.
^ permalink raw reply related
* [PATCH ethtool 09/21] Encapsulate command context in a structure
From: Ben Hutchings @ 2011-11-01 23:16 UTC (permalink / raw)
To: netdev; +Cc: linux-net-drivers
In-Reply-To: <1320186901.2758.30.camel@bwh-desktop>
Replace the fd and ifr arguments to each sub-command handler with
struct cmd_context. Change send_ioctl() to take a pointer to
this context and a pointer to the ethtool_cmd or other structure.
Use send_ioctl() consistently.
Signed-off-by: Ben Hutchings <bhutchings@solarflare.com>
---
ethtool.c | 419 +++++++++++++++++++++++++-----------------------------------
internal.h | 16 ++-
rxclass.c | 42 +++----
3 files changed, 204 insertions(+), 273 deletions(-)
diff --git a/ethtool.c b/ethtool.c
index f967f84..b6f535c 100644
--- a/ethtool.c
+++ b/ethtool.c
@@ -67,42 +67,40 @@ enum {
static int parse_wolopts(char *optstr, u32 *data);
static char *unparse_wolopts(int wolopts);
static void get_mac_addr(char *src, unsigned char *dest);
-static int do_gdrv(int fd, struct ifreq *ifr);
-static int do_gset(int fd, struct ifreq *ifr);
-static int do_sset(int fd, struct ifreq *ifr);
-static int do_gregs(int fd, struct ifreq *ifr);
-static int do_nway_rst(int fd, struct ifreq *ifr);
-static int do_geeprom(int fd, struct ifreq *ifr);
-static int do_seeprom(int fd, struct ifreq *ifr);
-static int do_test(int fd, struct ifreq *ifr);
-static int do_phys_id(int fd, struct ifreq *ifr);
-static int do_gpause(int fd, struct ifreq *ifr);
-static int do_spause(int fd, struct ifreq *ifr);
-static int do_gring(int fd, struct ifreq *ifr);
-static int do_sring(int fd, struct ifreq *ifr);
-static int do_schannels(int fd, struct ifreq *ifr);
-static int do_gchannels(int fd, struct ifreq *ifr);
-static int do_gcoalesce(int fd, struct ifreq *ifr);
-static int do_scoalesce(int fd, struct ifreq *ifr);
-static int do_goffload(int fd, struct ifreq *ifr);
-static int do_soffload(int fd, struct ifreq *ifr);
-static int do_gstats(int fd, struct ifreq *ifr);
+static int do_gdrv(struct cmd_context *ctx);
+static int do_gset(struct cmd_context *ctx);
+static int do_sset(struct cmd_context *ctx);
+static int do_gregs(struct cmd_context *ctx);
+static int do_nway_rst(struct cmd_context *ctx);
+static int do_geeprom(struct cmd_context *ctx);
+static int do_seeprom(struct cmd_context *ctx);
+static int do_test(struct cmd_context *ctx);
+static int do_phys_id(struct cmd_context *ctx);
+static int do_gpause(struct cmd_context *ctx);
+static int do_spause(struct cmd_context *ctx);
+static int do_gring(struct cmd_context *ctx);
+static int do_sring(struct cmd_context *ctx);
+static int do_schannels(struct cmd_context *ctx);
+static int do_gchannels(struct cmd_context *ctx);
+static int do_gcoalesce(struct cmd_context *ctx);
+static int do_scoalesce(struct cmd_context *ctx);
+static int do_goffload(struct cmd_context *ctx);
+static int do_soffload(struct cmd_context *ctx);
+static int do_gstats(struct cmd_context *ctx);
static int rxflow_str_to_type(const char *str);
static int parse_rxfhashopts(char *optstr, u32 *data);
static char *unparse_rxfhashopts(u64 opts);
static int dump_rxfhash(int fhash, u64 val);
-static int do_srxclass(int fd, struct ifreq *ifr);
-static int do_grxclass(int fd, struct ifreq *ifr);
-static int do_grxfhindir(int fd, struct ifreq *ifr);
-static int do_srxfhindir(int fd, struct ifreq *ifr);
-static int do_srxclsrule(int fd, struct ifreq *ifr);
-static int do_grxclsrule(int fd, struct ifreq *ifr);
-static int do_flash(int fd, struct ifreq *ifr);
-static int do_permaddr(int fd, struct ifreq *ifr);
-static int do_getfwdump(int fd, struct ifreq *ifr);
-static int do_setfwdump(int fd, struct ifreq *ifr);
-
-static int send_ioctl(int fd, struct ifreq *ifr);
+static int do_srxclass(struct cmd_context *ctx);
+static int do_grxclass(struct cmd_context *ctx);
+static int do_grxfhindir(struct cmd_context *ctx);
+static int do_srxfhindir(struct cmd_context *ctx);
+static int do_srxclsrule(struct cmd_context *ctx);
+static int do_grxclsrule(struct cmd_context *ctx);
+static int do_flash(struct cmd_context *ctx);
+static int do_permaddr(struct cmd_context *ctx);
+static int do_getfwdump(struct cmd_context *ctx);
+static int do_setfwdump(struct cmd_context *ctx);
static enum {
MODE_VERSION = -2,
@@ -1982,94 +1980,92 @@ static int dump_rxfhash(int fhash, u64 val)
static int doit(void)
{
- struct ifreq ifr;
- int fd;
+ struct cmd_context ctx;
/* Setup our control structures. */
- memset(&ifr, 0, sizeof(ifr));
- strcpy(ifr.ifr_name, devname);
+ memset(&ctx.ifr, 0, sizeof(ctx.ifr));
+ strcpy(ctx.ifr.ifr_name, devname);
/* Open control socket. */
- fd = socket(AF_INET, SOCK_DGRAM, 0);
- if (fd < 0) {
+ ctx.fd = socket(AF_INET, SOCK_DGRAM, 0);
+ if (ctx.fd < 0) {
perror("Cannot get control socket");
return 70;
}
/* all of these are expected to populate ifr->ifr_data as needed */
if (mode == MODE_GDRV) {
- return do_gdrv(fd, &ifr);
+ return do_gdrv(&ctx);
} else if (mode == MODE_GSET) {
- return do_gset(fd, &ifr);
+ return do_gset(&ctx);
} else if (mode == MODE_SSET) {
- return do_sset(fd, &ifr);
+ return do_sset(&ctx);
} else if (mode == MODE_GREGS) {
- return do_gregs(fd, &ifr);
+ return do_gregs(&ctx);
} else if (mode == MODE_NWAY_RST) {
- return do_nway_rst(fd, &ifr);
+ return do_nway_rst(&ctx);
} else if (mode == MODE_GEEPROM) {
- return do_geeprom(fd, &ifr);
+ return do_geeprom(&ctx);
} else if (mode == MODE_SEEPROM) {
- return do_seeprom(fd, &ifr);
+ return do_seeprom(&ctx);
} else if (mode == MODE_TEST) {
- return do_test(fd, &ifr);
+ return do_test(&ctx);
} else if (mode == MODE_PHYS_ID) {
- return do_phys_id(fd, &ifr);
+ return do_phys_id(&ctx);
} else if (mode == MODE_GPAUSE) {
- return do_gpause(fd, &ifr);
+ return do_gpause(&ctx);
} else if (mode == MODE_SPAUSE) {
- return do_spause(fd, &ifr);
+ return do_spause(&ctx);
} else if (mode == MODE_GCOALESCE) {
- return do_gcoalesce(fd, &ifr);
+ return do_gcoalesce(&ctx);
} else if (mode == MODE_SCOALESCE) {
- return do_scoalesce(fd, &ifr);
+ return do_scoalesce(&ctx);
} else if (mode == MODE_GRING) {
- return do_gring(fd, &ifr);
+ return do_gring(&ctx);
} else if (mode == MODE_SRING) {
- return do_sring(fd, &ifr);
+ return do_sring(&ctx);
} else if (mode == MODE_GCHANNELS) {
- return do_gchannels(fd, &ifr);
+ return do_gchannels(&ctx);
} else if (mode == MODE_SCHANNELS) {
- return do_schannels(fd, &ifr);
+ return do_schannels(&ctx);
} else if (mode == MODE_GOFFLOAD) {
- return do_goffload(fd, &ifr);
+ return do_goffload(&ctx);
} else if (mode == MODE_SOFFLOAD) {
- return do_soffload(fd, &ifr);
+ return do_soffload(&ctx);
} else if (mode == MODE_GSTATS) {
- return do_gstats(fd, &ifr);
+ return do_gstats(&ctx);
} else if (mode == MODE_GNFC) {
- return do_grxclass(fd, &ifr);
+ return do_grxclass(&ctx);
} else if (mode == MODE_SNFC) {
- return do_srxclass(fd, &ifr);
+ return do_srxclass(&ctx);
} else if (mode == MODE_GRXFHINDIR) {
- return do_grxfhindir(fd, &ifr);
+ return do_grxfhindir(&ctx);
} else if (mode == MODE_SRXFHINDIR) {
- return do_srxfhindir(fd, &ifr);
+ return do_srxfhindir(&ctx);
} else if (mode == MODE_SCLSRULE) {
- return do_srxclsrule(fd, &ifr);
+ return do_srxclsrule(&ctx);
} else if (mode == MODE_GCLSRULE) {
- return do_grxclsrule(fd, &ifr);
+ return do_grxclsrule(&ctx);
} else if (mode == MODE_FLASHDEV) {
- return do_flash(fd, &ifr);
+ return do_flash(&ctx);
} else if (mode == MODE_PERMADDR) {
- return do_permaddr(fd, &ifr);
+ return do_permaddr(&ctx);
} else if (mode == MODE_GET_DUMP) {
- return do_getfwdump(fd, &ifr);
+ return do_getfwdump(&ctx);
} else if (mode == MODE_SET_DUMP) {
- return do_setfwdump(fd, &ifr);
+ return do_setfwdump(&ctx);
}
return 69;
}
-static int do_gdrv(int fd, struct ifreq *ifr)
+static int do_gdrv(struct cmd_context *ctx)
{
int err;
struct ethtool_drvinfo drvinfo;
drvinfo.cmd = ETHTOOL_GDRVINFO;
- ifr->ifr_data = (caddr_t)&drvinfo;
- err = send_ioctl(fd, ifr);
+ err = send_ioctl(ctx, &drvinfo);
if (err < 0) {
perror("Cannot get driver information");
return 71;
@@ -2077,7 +2073,7 @@ static int do_gdrv(int fd, struct ifreq *ifr)
return dump_drvinfo(&drvinfo);
}
-static int do_gpause(int fd, struct ifreq *ifr)
+static int do_gpause(struct cmd_context *ctx)
{
struct ethtool_cmd ecmd;
int err;
@@ -2085,8 +2081,7 @@ static int do_gpause(int fd, struct ifreq *ifr)
fprintf(stdout, "Pause parameters for %s:\n", devname);
epause.cmd = ETHTOOL_GPAUSEPARAM;
- ifr->ifr_data = (caddr_t)&epause;
- err = send_ioctl(fd, ifr);
+ err = send_ioctl(ctx, &epause);
if (err) {
perror("Cannot get device pause settings");
return 76;
@@ -2094,8 +2089,7 @@ static int do_gpause(int fd, struct ifreq *ifr)
if (epause.autoneg) {
ecmd.cmd = ETHTOOL_GSET;
- ifr->ifr_data = (caddr_t)&ecmd;
- err = send_ioctl(fd, ifr);
+ err = send_ioctl(ctx, &ecmd);
if (err) {
perror("Cannot get device settings");
return 1;
@@ -2137,13 +2131,12 @@ static void do_generic_set(struct cmdline_info *info,
do_generic_set1(&info[i], changed_out);
}
-static int do_spause(int fd, struct ifreq *ifr)
+static int do_spause(struct cmd_context *ctx)
{
int err, changed = 0;
epause.cmd = ETHTOOL_GPAUSEPARAM;
- ifr->ifr_data = (caddr_t)&epause;
- err = send_ioctl(fd, ifr);
+ err = send_ioctl(ctx, &epause);
if (err) {
perror("Cannot get device pause settings");
return 77;
@@ -2157,8 +2150,7 @@ static int do_spause(int fd, struct ifreq *ifr)
}
epause.cmd = ETHTOOL_SPAUSEPARAM;
- ifr->ifr_data = (caddr_t)&epause;
- err = send_ioctl(fd, ifr);
+ err = send_ioctl(ctx, &epause);
if (err) {
perror("Cannot set device pause parameters");
return 79;
@@ -2167,13 +2159,12 @@ static int do_spause(int fd, struct ifreq *ifr)
return 0;
}
-static int do_sring(int fd, struct ifreq *ifr)
+static int do_sring(struct cmd_context *ctx)
{
int err, changed = 0;
ering.cmd = ETHTOOL_GRINGPARAM;
- ifr->ifr_data = (caddr_t)&ering;
- err = send_ioctl(fd, ifr);
+ err = send_ioctl(ctx, &ering);
if (err) {
perror("Cannot get device ring settings");
return 76;
@@ -2187,8 +2178,7 @@ static int do_sring(int fd, struct ifreq *ifr)
}
ering.cmd = ETHTOOL_SRINGPARAM;
- ifr->ifr_data = (caddr_t)&ering;
- err = send_ioctl(fd, ifr);
+ err = send_ioctl(ctx, &ering);
if (err) {
perror("Cannot set device ring parameters");
return 81;
@@ -2197,15 +2187,14 @@ static int do_sring(int fd, struct ifreq *ifr)
return 0;
}
-static int do_gring(int fd, struct ifreq *ifr)
+static int do_gring(struct cmd_context *ctx)
{
int err;
fprintf(stdout, "Ring parameters for %s:\n", devname);
ering.cmd = ETHTOOL_GRINGPARAM;
- ifr->ifr_data = (caddr_t)&ering;
- err = send_ioctl(fd, ifr);
+ err = send_ioctl(ctx, &ering);
if (err == 0) {
err = dump_ring();
if (err)
@@ -2218,13 +2207,12 @@ static int do_gring(int fd, struct ifreq *ifr)
return 0;
}
-static int do_schannels(int fd, struct ifreq *ifr)
+static int do_schannels(struct cmd_context *ctx)
{
int err, changed = 0;
echannels.cmd = ETHTOOL_GCHANNELS;
- ifr->ifr_data = (caddr_t)&echannels;
- err = send_ioctl(fd, ifr);
+ err = send_ioctl(ctx, &echannels);
if (err) {
perror("Cannot get device channel parameters");
return 1;
@@ -2243,8 +2231,7 @@ static int do_schannels(int fd, struct ifreq *ifr)
}
echannels.cmd = ETHTOOL_SCHANNELS;
- ifr->ifr_data = (caddr_t)&echannels;
- err = send_ioctl(fd, ifr);
+ err = send_ioctl(ctx, &echannels);
if (err) {
perror("Cannot set device channel parameters");
return 1;
@@ -2253,15 +2240,14 @@ static int do_schannels(int fd, struct ifreq *ifr)
return 0;
}
-static int do_gchannels(int fd, struct ifreq *ifr)
+static int do_gchannels(struct cmd_context *ctx)
{
int err;
fprintf(stdout, "Channel parameters for %s:\n", devname);
echannels.cmd = ETHTOOL_GCHANNELS;
- ifr->ifr_data = (caddr_t)&echannels;
- err = send_ioctl(fd, ifr);
+ err = send_ioctl(ctx, &echannels);
if (err == 0) {
err = dump_channels();
if (err)
@@ -2274,15 +2260,14 @@ static int do_gchannels(int fd, struct ifreq *ifr)
}
-static int do_gcoalesce(int fd, struct ifreq *ifr)
+static int do_gcoalesce(struct cmd_context *ctx)
{
int err;
fprintf(stdout, "Coalesce parameters for %s:\n", devname);
ecoal.cmd = ETHTOOL_GCOALESCE;
- ifr->ifr_data = (caddr_t)&ecoal;
- err = send_ioctl(fd, ifr);
+ err = send_ioctl(ctx, &ecoal);
if (err == 0) {
err = dump_coalesce();
if (err)
@@ -2295,13 +2280,12 @@ static int do_gcoalesce(int fd, struct ifreq *ifr)
return 0;
}
-static int do_scoalesce(int fd, struct ifreq *ifr)
+static int do_scoalesce(struct cmd_context *ctx)
{
int err, changed = 0;
ecoal.cmd = ETHTOOL_GCOALESCE;
- ifr->ifr_data = (caddr_t)&ecoal;
- err = send_ioctl(fd, ifr);
+ err = send_ioctl(ctx, &ecoal);
if (err) {
perror("Cannot get device coalesce settings");
return 76;
@@ -2316,8 +2300,7 @@ static int do_scoalesce(int fd, struct ifreq *ifr)
}
ecoal.cmd = ETHTOOL_SCOALESCE;
- ifr->ifr_data = (caddr_t)&ecoal;
- err = send_ioctl(fd, ifr);
+ err = send_ioctl(ctx, &ecoal);
if (err) {
perror("Cannot set device coalesce parameters");
return 81;
@@ -2326,7 +2309,7 @@ static int do_scoalesce(int fd, struct ifreq *ifr)
return 0;
}
-static int do_goffload(int fd, struct ifreq *ifr)
+static int do_goffload(struct cmd_context *ctx)
{
struct ethtool_value eval;
int err, allfail = 1, rx = 0, tx = 0, sg = 0;
@@ -2336,8 +2319,7 @@ static int do_goffload(int fd, struct ifreq *ifr)
fprintf(stdout, "Offload parameters for %s:\n", devname);
eval.cmd = ETHTOOL_GRXCSUM;
- ifr->ifr_data = (caddr_t)&eval;
- err = send_ioctl(fd, ifr);
+ err = send_ioctl(ctx, &eval);
if (err)
perror("Cannot get device rx csum settings");
else {
@@ -2346,8 +2328,7 @@ static int do_goffload(int fd, struct ifreq *ifr)
}
eval.cmd = ETHTOOL_GTXCSUM;
- ifr->ifr_data = (caddr_t)&eval;
- err = send_ioctl(fd, ifr);
+ err = send_ioctl(ctx, &eval);
if (err)
perror("Cannot get device tx csum settings");
else {
@@ -2356,8 +2337,7 @@ static int do_goffload(int fd, struct ifreq *ifr)
}
eval.cmd = ETHTOOL_GSG;
- ifr->ifr_data = (caddr_t)&eval;
- err = send_ioctl(fd, ifr);
+ err = send_ioctl(ctx, &eval);
if (err)
perror("Cannot get device scatter-gather settings");
else {
@@ -2366,8 +2346,7 @@ static int do_goffload(int fd, struct ifreq *ifr)
}
eval.cmd = ETHTOOL_GTSO;
- ifr->ifr_data = (caddr_t)&eval;
- err = send_ioctl(fd, ifr);
+ err = send_ioctl(ctx, &eval);
if (err)
perror("Cannot get device tcp segmentation offload settings");
else {
@@ -2376,8 +2355,7 @@ static int do_goffload(int fd, struct ifreq *ifr)
}
eval.cmd = ETHTOOL_GUFO;
- ifr->ifr_data = (caddr_t)&eval;
- err = ioctl(fd, SIOCETHTOOL, ifr);
+ err = send_ioctl(ctx, &eval);
if (err)
perror("Cannot get device udp large send offload settings");
else {
@@ -2386,8 +2364,7 @@ static int do_goffload(int fd, struct ifreq *ifr)
}
eval.cmd = ETHTOOL_GGSO;
- ifr->ifr_data = (caddr_t)&eval;
- err = ioctl(fd, SIOCETHTOOL, ifr);
+ err = send_ioctl(ctx, &eval);
if (err)
perror("Cannot get device generic segmentation offload settings");
else {
@@ -2396,8 +2373,7 @@ static int do_goffload(int fd, struct ifreq *ifr)
}
eval.cmd = ETHTOOL_GFLAGS;
- ifr->ifr_data = (caddr_t)&eval;
- err = ioctl(fd, SIOCETHTOOL, ifr);
+ err = send_ioctl(ctx, &eval);
if (err) {
perror("Cannot get device flags");
} else {
@@ -2410,8 +2386,7 @@ static int do_goffload(int fd, struct ifreq *ifr)
}
eval.cmd = ETHTOOL_GGRO;
- ifr->ifr_data = (caddr_t)&eval;
- err = ioctl(fd, SIOCETHTOOL, ifr);
+ err = send_ioctl(ctx, &eval);
if (err)
perror("Cannot get device GRO settings");
else {
@@ -2428,7 +2403,7 @@ static int do_goffload(int fd, struct ifreq *ifr)
ntuple, rxhash);
}
-static int do_soffload(int fd, struct ifreq *ifr)
+static int do_soffload(struct cmd_context *ctx)
{
struct ethtool_value eval;
int err, changed = 0;
@@ -2437,8 +2412,7 @@ static int do_soffload(int fd, struct ifreq *ifr)
changed = 1;
eval.cmd = ETHTOOL_SRXCSUM;
eval.data = (off_csum_rx_wanted == 1);
- ifr->ifr_data = (caddr_t)&eval;
- err = send_ioctl(fd, ifr);
+ err = send_ioctl(ctx, &eval);
if (err) {
perror("Cannot set device rx csum settings");
return 84;
@@ -2449,8 +2423,7 @@ static int do_soffload(int fd, struct ifreq *ifr)
changed = 1;
eval.cmd = ETHTOOL_STXCSUM;
eval.data = (off_csum_tx_wanted == 1);
- ifr->ifr_data = (caddr_t)&eval;
- err = send_ioctl(fd, ifr);
+ err = send_ioctl(ctx, &eval);
if (err) {
perror("Cannot set device tx csum settings");
return 85;
@@ -2461,8 +2434,7 @@ static int do_soffload(int fd, struct ifreq *ifr)
changed = 1;
eval.cmd = ETHTOOL_SSG;
eval.data = (off_sg_wanted == 1);
- ifr->ifr_data = (caddr_t)&eval;
- err = send_ioctl(fd, ifr);
+ err = send_ioctl(ctx, &eval);
if (err) {
perror("Cannot set device scatter-gather settings");
return 86;
@@ -2473,8 +2445,7 @@ static int do_soffload(int fd, struct ifreq *ifr)
changed = 1;
eval.cmd = ETHTOOL_STSO;
eval.data = (off_tso_wanted == 1);
- ifr->ifr_data = (caddr_t)&eval;
- err = send_ioctl(fd, ifr);
+ err = send_ioctl(ctx, &eval);
if (err) {
perror("Cannot set device tcp segmentation offload settings");
return 88;
@@ -2484,8 +2455,7 @@ static int do_soffload(int fd, struct ifreq *ifr)
changed = 1;
eval.cmd = ETHTOOL_SUFO;
eval.data = (off_ufo_wanted == 1);
- ifr->ifr_data = (caddr_t)&eval;
- err = ioctl(fd, SIOCETHTOOL, ifr);
+ err = send_ioctl(ctx, &eval);
if (err) {
perror("Cannot set device udp large send offload settings");
return 89;
@@ -2495,8 +2465,7 @@ static int do_soffload(int fd, struct ifreq *ifr)
changed = 1;
eval.cmd = ETHTOOL_SGSO;
eval.data = (off_gso_wanted == 1);
- ifr->ifr_data = (caddr_t)&eval;
- err = ioctl(fd, SIOCETHTOOL, ifr);
+ err = send_ioctl(ctx, &eval);
if (err) {
perror("Cannot set device generic segmentation offload settings");
return 90;
@@ -2506,8 +2475,7 @@ static int do_soffload(int fd, struct ifreq *ifr)
changed = 1;
eval.cmd = ETHTOOL_GFLAGS;
eval.data = 0;
- ifr->ifr_data = (caddr_t)&eval;
- err = ioctl(fd, SIOCETHTOOL, ifr);
+ err = send_ioctl(ctx, &eval);
if (err) {
perror("Cannot get device flag settings");
return 91;
@@ -2517,7 +2485,7 @@ static int do_soffload(int fd, struct ifreq *ifr)
eval.data = ((eval.data & ~off_flags_mask) |
off_flags_wanted);
- err = ioctl(fd, SIOCETHTOOL, ifr);
+ err = send_ioctl(ctx, &eval);
if (err) {
perror("Cannot set device flag settings");
return 92;
@@ -2527,8 +2495,7 @@ static int do_soffload(int fd, struct ifreq *ifr)
changed = 1;
eval.cmd = ETHTOOL_SGRO;
eval.data = (off_gro_wanted == 1);
- ifr->ifr_data = (caddr_t)&eval;
- err = ioctl(fd, SIOCETHTOOL, ifr);
+ err = send_ioctl(ctx, &eval);
if (err) {
perror("Cannot set device GRO settings");
return 93;
@@ -2542,7 +2509,7 @@ static int do_soffload(int fd, struct ifreq *ifr)
return 0;
}
-static int do_gset(int fd, struct ifreq *ifr)
+static int do_gset(struct cmd_context *ctx)
{
int err;
struct ethtool_cmd ecmd;
@@ -2553,8 +2520,7 @@ static int do_gset(int fd, struct ifreq *ifr)
fprintf(stdout, "Settings for %s:\n", devname);
ecmd.cmd = ETHTOOL_GSET;
- ifr->ifr_data = (caddr_t)&ecmd;
- err = send_ioctl(fd, ifr);
+ err = send_ioctl(ctx, &ecmd);
if (err == 0) {
err = dump_ecmd(&ecmd);
if (err)
@@ -2565,8 +2531,7 @@ static int do_gset(int fd, struct ifreq *ifr)
}
wolinfo.cmd = ETHTOOL_GWOL;
- ifr->ifr_data = (caddr_t)&wolinfo;
- err = send_ioctl(fd, ifr);
+ err = send_ioctl(ctx, &wolinfo);
if (err == 0) {
err = dump_wol(&wolinfo);
if (err)
@@ -2577,8 +2542,7 @@ static int do_gset(int fd, struct ifreq *ifr)
}
edata.cmd = ETHTOOL_GMSGLVL;
- ifr->ifr_data = (caddr_t)&edata;
- err = send_ioctl(fd, ifr);
+ err = send_ioctl(ctx, &edata);
if (err == 0) {
fprintf(stdout, " Current message level: 0x%08x (%d)\n"
" ",
@@ -2592,8 +2556,7 @@ static int do_gset(int fd, struct ifreq *ifr)
}
edata.cmd = ETHTOOL_GLINK;
- ifr->ifr_data = (caddr_t)&edata;
- err = send_ioctl(fd, ifr);
+ err = send_ioctl(ctx, &edata);
if (err == 0) {
fprintf(stdout, " Link detected: %s\n",
edata.data ? "yes":"no");
@@ -2609,7 +2572,7 @@ static int do_gset(int fd, struct ifreq *ifr)
return 0;
}
-static int do_sset(int fd, struct ifreq *ifr)
+static int do_sset(struct cmd_context *ctx)
{
int err;
@@ -2617,8 +2580,7 @@ static int do_sset(int fd, struct ifreq *ifr)
struct ethtool_cmd ecmd;
ecmd.cmd = ETHTOOL_GSET;
- ifr->ifr_data = (caddr_t)&ecmd;
- err = send_ioctl(fd, ifr);
+ err = send_ioctl(ctx, &ecmd);
if (err < 0) {
perror("Cannot get current device settings");
} else {
@@ -2671,8 +2633,7 @@ static int do_sset(int fd, struct ifreq *ifr)
/* Try to perform the update. */
ecmd.cmd = ETHTOOL_SSET;
- ifr->ifr_data = (caddr_t)&ecmd;
- err = send_ioctl(fd, ifr);
+ err = send_ioctl(ctx, &ecmd);
if (err < 0)
perror("Cannot set new settings");
}
@@ -2696,8 +2657,7 @@ static int do_sset(int fd, struct ifreq *ifr)
struct ethtool_wolinfo wol;
wol.cmd = ETHTOOL_GWOL;
- ifr->ifr_data = (caddr_t)&wol;
- err = send_ioctl(fd, ifr);
+ err = send_ioctl(ctx, &wol);
if (err < 0) {
perror("Cannot get current wake-on-lan settings");
} else {
@@ -2714,8 +2674,7 @@ static int do_sset(int fd, struct ifreq *ifr)
/* Try to perform the update. */
wol.cmd = ETHTOOL_SWOL;
- ifr->ifr_data = (caddr_t)&wol;
- err = send_ioctl(fd, ifr);
+ err = send_ioctl(ctx, &wol);
if (err < 0)
perror("Cannot set new wake-on-lan settings");
}
@@ -2731,16 +2690,14 @@ static int do_sset(int fd, struct ifreq *ifr)
struct ethtool_value edata;
edata.cmd = ETHTOOL_GMSGLVL;
- ifr->ifr_data = (caddr_t)&edata;
- err = send_ioctl(fd, ifr);
+ err = send_ioctl(ctx, &edata);
if (err < 0) {
perror("Cannot get msglvl");
} else {
edata.cmd = ETHTOOL_SMSGLVL;
edata.data = ((edata.data & ~msglvl_mask) |
msglvl_wanted);
- ifr->ifr_data = (caddr_t)&edata;
- err = send_ioctl(fd, ifr);
+ err = send_ioctl(ctx, &edata);
if (err < 0)
perror("Cannot set new msglvl");
}
@@ -2749,15 +2706,14 @@ static int do_sset(int fd, struct ifreq *ifr)
return 0;
}
-static int do_gregs(int fd, struct ifreq *ifr)
+static int do_gregs(struct cmd_context *ctx)
{
int err;
struct ethtool_drvinfo drvinfo;
struct ethtool_regs *regs;
drvinfo.cmd = ETHTOOL_GDRVINFO;
- ifr->ifr_data = (caddr_t)&drvinfo;
- err = send_ioctl(fd, ifr);
+ err = send_ioctl(ctx, &drvinfo);
if (err < 0) {
perror("Cannot get driver information");
return 72;
@@ -2770,8 +2726,7 @@ static int do_gregs(int fd, struct ifreq *ifr)
}
regs->cmd = ETHTOOL_GREGS;
regs->len = drvinfo.regdump_len;
- ifr->ifr_data = (caddr_t)regs;
- err = send_ioctl(fd, ifr);
+ err = send_ioctl(ctx, regs);
if (err < 0) {
perror("Cannot get register dump");
free(regs);
@@ -2787,29 +2742,27 @@ static int do_gregs(int fd, struct ifreq *ifr)
return 0;
}
-static int do_nway_rst(int fd, struct ifreq *ifr)
+static int do_nway_rst(struct cmd_context *ctx)
{
struct ethtool_value edata;
int err;
edata.cmd = ETHTOOL_NWAY_RST;
- ifr->ifr_data = (caddr_t)&edata;
- err = send_ioctl(fd, ifr);
+ err = send_ioctl(ctx, &edata);
if (err < 0)
perror("Cannot restart autonegotiation");
return err;
}
-static int do_geeprom(int fd, struct ifreq *ifr)
+static int do_geeprom(struct cmd_context *ctx)
{
int err;
struct ethtool_drvinfo drvinfo;
struct ethtool_eeprom *eeprom;
drvinfo.cmd = ETHTOOL_GDRVINFO;
- ifr->ifr_data = (caddr_t)&drvinfo;
- err = send_ioctl(fd, ifr);
+ err = send_ioctl(ctx, &drvinfo);
if (err < 0) {
perror("Cannot get driver information");
return 74;
@@ -2829,8 +2782,7 @@ static int do_geeprom(int fd, struct ifreq *ifr)
eeprom->cmd = ETHTOOL_GEEPROM;
eeprom->len = geeprom_length;
eeprom->offset = geeprom_offset;
- ifr->ifr_data = (caddr_t)eeprom;
- err = send_ioctl(fd, ifr);
+ err = send_ioctl(ctx, eeprom);
if (err < 0) {
perror("Cannot get EEPROM data");
free(eeprom);
@@ -2842,15 +2794,14 @@ static int do_geeprom(int fd, struct ifreq *ifr)
return err;
}
-static int do_seeprom(int fd, struct ifreq *ifr)
+static int do_seeprom(struct cmd_context *ctx)
{
int err;
struct ethtool_drvinfo drvinfo;
struct ethtool_eeprom *eeprom;
drvinfo.cmd = ETHTOOL_GDRVINFO;
- ifr->ifr_data = (caddr_t)&drvinfo;
- err = send_ioctl(fd, ifr);
+ err = send_ioctl(ctx, &drvinfo);
if (err < 0) {
perror("Cannot get driver information");
return 74;
@@ -2881,8 +2832,7 @@ static int do_seeprom(int fd, struct ifreq *ifr)
if (!seeprom_value_seen)
eeprom->len = fread(eeprom->data, 1, eeprom->len, stdin);
- ifr->ifr_data = (caddr_t)eeprom;
- err = send_ioctl(fd, ifr);
+ err = send_ioctl(ctx, eeprom);
if (err < 0) {
perror("Cannot set EEPROM data");
err = 87;
@@ -2892,7 +2842,7 @@ static int do_seeprom(int fd, struct ifreq *ifr)
return err;
}
-static int do_test(int fd, struct ifreq *ifr)
+static int do_test(struct cmd_context *ctx)
{
int err;
struct ethtool_drvinfo drvinfo;
@@ -2900,8 +2850,7 @@ static int do_test(int fd, struct ifreq *ifr)
struct ethtool_gstrings *strings;
drvinfo.cmd = ETHTOOL_GDRVINFO;
- ifr->ifr_data = (caddr_t)&drvinfo;
- err = send_ioctl(fd, ifr);
+ err = send_ioctl(ctx, &drvinfo);
if (err < 0) {
perror("Cannot get driver information");
return 72;
@@ -2921,8 +2870,7 @@ static int do_test(int fd, struct ifreq *ifr)
test->flags = ETH_TEST_FL_OFFLINE;
else
test->flags = 0;
- ifr->ifr_data = (caddr_t)test;
- err = send_ioctl(fd, ifr);
+ err = send_ioctl(ctx, test);
if (err < 0) {
perror("Cannot test");
free (test);
@@ -2940,8 +2888,7 @@ static int do_test(int fd, struct ifreq *ifr)
strings->cmd = ETHTOOL_GSTRINGS;
strings->string_set = ETH_SS_TEST;
strings->len = drvinfo.testinfo_len;
- ifr->ifr_data = (caddr_t)strings;
- err = send_ioctl(fd, ifr);
+ err = send_ioctl(ctx, strings);
if (err < 0) {
perror("Cannot get strings");
free (test);
@@ -2955,22 +2902,21 @@ static int do_test(int fd, struct ifreq *ifr)
return err;
}
-static int do_phys_id(int fd, struct ifreq *ifr)
+static int do_phys_id(struct cmd_context *ctx)
{
int err;
struct ethtool_value edata;
edata.cmd = ETHTOOL_PHYS_ID;
edata.data = phys_id_time;
- ifr->ifr_data = (caddr_t)&edata;
- err = send_ioctl(fd, ifr);
+ err = send_ioctl(ctx, &edata);
if (err < 0)
perror("Cannot identify NIC");
return err;
}
-static int do_gstats(int fd, struct ifreq *ifr)
+static int do_gstats(struct cmd_context *ctx)
{
struct ethtool_drvinfo drvinfo;
struct ethtool_gstrings *strings;
@@ -2979,8 +2925,7 @@ static int do_gstats(int fd, struct ifreq *ifr)
int err;
drvinfo.cmd = ETHTOOL_GDRVINFO;
- ifr->ifr_data = (caddr_t)&drvinfo;
- err = send_ioctl(fd, ifr);
+ err = send_ioctl(ctx, &drvinfo);
if (err < 0) {
perror("Cannot get driver information");
return 71;
@@ -3005,8 +2950,7 @@ static int do_gstats(int fd, struct ifreq *ifr)
strings->cmd = ETHTOOL_GSTRINGS;
strings->string_set = ETH_SS_STATS;
strings->len = n_stats;
- ifr->ifr_data = (caddr_t) strings;
- err = send_ioctl(fd, ifr);
+ err = send_ioctl(ctx, strings);
if (err < 0) {
perror("Cannot get stats strings information");
free(strings);
@@ -3016,8 +2960,7 @@ static int do_gstats(int fd, struct ifreq *ifr)
stats->cmd = ETHTOOL_GSTATS;
stats->n_stats = n_stats;
- ifr->ifr_data = (caddr_t) stats;
- err = send_ioctl(fd, ifr);
+ err = send_ioctl(ctx, stats);
if (err < 0) {
perror("Cannot get stats information");
free(strings);
@@ -3040,7 +2983,7 @@ static int do_gstats(int fd, struct ifreq *ifr)
}
-static int do_srxclass(int fd, struct ifreq *ifr)
+static int do_srxclass(struct cmd_context *ctx)
{
int err;
@@ -3051,8 +2994,7 @@ static int do_srxclass(int fd, struct ifreq *ifr)
nfccmd.flow_type = rx_fhash_set;
nfccmd.data = rx_fhash_val;
- ifr->ifr_data = (caddr_t)&nfccmd;
- err = ioctl(fd, SIOCETHTOOL, ifr);
+ err = send_ioctl(ctx, &nfccmd);
if (err < 0)
perror("Cannot change RX network flow hashing options");
@@ -3061,7 +3003,7 @@ static int do_srxclass(int fd, struct ifreq *ifr)
return 0;
}
-static int do_grxclass(int fd, struct ifreq *ifr)
+static int do_grxclass(struct cmd_context *ctx)
{
int err;
@@ -3070,8 +3012,7 @@ static int do_grxclass(int fd, struct ifreq *ifr)
nfccmd.cmd = ETHTOOL_GRXFH;
nfccmd.flow_type = rx_fhash_get;
- ifr->ifr_data = (caddr_t)&nfccmd;
- err = ioctl(fd, SIOCETHTOOL, ifr);
+ err = send_ioctl(ctx, &nfccmd);
if (err < 0)
perror("Cannot get RX network flow hashing options");
else
@@ -3081,7 +3022,7 @@ static int do_grxclass(int fd, struct ifreq *ifr)
return 0;
}
-static int do_grxfhindir(int fd, struct ifreq *ifr)
+static int do_grxfhindir(struct cmd_context *ctx)
{
struct ethtool_rxnfc ring_count;
struct ethtool_rxfh_indir indir_head;
@@ -3090,8 +3031,7 @@ static int do_grxfhindir(int fd, struct ifreq *ifr)
int err;
ring_count.cmd = ETHTOOL_GRXRINGS;
- ifr->ifr_data = (caddr_t) &ring_count;
- err = send_ioctl(fd, ifr);
+ err = send_ioctl(ctx, &ring_count);
if (err < 0) {
perror("Cannot get RX ring count");
return 102;
@@ -3099,8 +3039,7 @@ static int do_grxfhindir(int fd, struct ifreq *ifr)
indir_head.cmd = ETHTOOL_GRXFHINDIR;
indir_head.size = 0;
- ifr->ifr_data = (caddr_t) &indir_head;
- err = send_ioctl(fd, ifr);
+ err = send_ioctl(ctx, &indir_head);
if (err < 0) {
perror("Cannot get RX flow hash indirection table size");
return 103;
@@ -3110,8 +3049,7 @@ static int do_grxfhindir(int fd, struct ifreq *ifr)
indir_head.size * sizeof(*indir->ring_index));
indir->cmd = ETHTOOL_GRXFHINDIR;
indir->size = indir_head.size;
- ifr->ifr_data = (caddr_t) indir;
- err = send_ioctl(fd, ifr);
+ err = send_ioctl(ctx, indir);
if (err < 0) {
perror("Cannot get RX flow hash indirection table");
return 103;
@@ -3129,7 +3067,7 @@ static int do_grxfhindir(int fd, struct ifreq *ifr)
return 0;
}
-static int do_srxfhindir(int fd, struct ifreq *ifr)
+static int do_srxfhindir(struct cmd_context *ctx)
{
struct ethtool_rxfh_indir indir_head;
struct ethtool_rxfh_indir *indir;
@@ -3141,8 +3079,7 @@ static int do_srxfhindir(int fd, struct ifreq *ifr)
indir_head.cmd = ETHTOOL_GRXFHINDIR;
indir_head.size = 0;
- ifr->ifr_data = (caddr_t) &indir_head;
- err = send_ioctl(fd, ifr);
+ err = send_ioctl(ctx, &indir_head);
if (err < 0) {
perror("Cannot get RX flow hash indirection table size");
return 104;
@@ -3188,8 +3125,7 @@ static int do_srxfhindir(int fd, struct ifreq *ifr)
}
}
- ifr->ifr_data = (caddr_t) indir;
- err = send_ioctl(fd, ifr);
+ err = send_ioctl(ctx, indir);
if (err < 0) {
perror("Cannot set RX flow hash indirection table");
return 105;
@@ -3198,7 +3134,7 @@ static int do_srxfhindir(int fd, struct ifreq *ifr)
return 0;
}
-static int do_flash(int fd, struct ifreq *ifr)
+static int do_flash(struct cmd_context *ctx)
{
struct ethtool_flash efl;
int err;
@@ -3222,15 +3158,14 @@ static int do_flash(int fd, struct ifreq *ifr)
else
efl.region = flash_region;
- ifr->ifr_data = (caddr_t)&efl;
- err = send_ioctl(fd, ifr);
+ err = send_ioctl(ctx, &efl);
if (err < 0)
perror("Flashing failed");
return err;
}
-static int do_permaddr(int fd, struct ifreq *ifr)
+static int do_permaddr(struct cmd_context *ctx)
{
int i, err;
struct ethtool_perm_addr *epaddr;
@@ -3238,9 +3173,8 @@ static int do_permaddr(int fd, struct ifreq *ifr)
epaddr = malloc(sizeof(struct ethtool_perm_addr) + MAX_ADDR_LEN);
epaddr->cmd = ETHTOOL_GPERMADDR;
epaddr->size = MAX_ADDR_LEN;
- ifr->ifr_data = (caddr_t)epaddr;
- err = send_ioctl(fd, ifr);
+ err = send_ioctl(ctx, epaddr);
if (err < 0)
perror("Cannot read permanent address");
else {
@@ -3332,7 +3266,7 @@ static int flow_spec_to_ntuple(struct ethtool_rx_flow_spec *fsp,
return 0;
}
-static int do_srxntuple(int fd, struct ifreq *ifr)
+static int do_srxntuple(struct cmd_context *ctx)
{
struct ethtool_rx_ntuple ntuplecmd;
struct ethtool_value eval;
@@ -3349,15 +3283,13 @@ static int do_srxntuple(int fd, struct ifreq *ifr)
* flag not being set on the device
*/
eval.cmd = ETHTOOL_GFLAGS;
- ifr->ifr_data = (caddr_t)&eval;
- err = ioctl(fd, SIOCETHTOOL, ifr);
+ err = send_ioctl(ctx, &eval);
if (err || !(eval.data & ETH_FLAG_NTUPLE))
return -1;
/* send rule via N-tuple */
ntuplecmd.cmd = ETHTOOL_SRXNTUPLE;
- ifr->ifr_data = (caddr_t)&ntuplecmd;
- err = ioctl(fd, SIOCETHTOOL, ifr);
+ err = send_ioctl(ctx, &ntuplecmd);
/*
* Display error only if reponse is something other than op not
@@ -3373,25 +3305,25 @@ static int do_srxntuple(int fd, struct ifreq *ifr)
return 0;
}
-static int do_srxclsrule(int fd, struct ifreq *ifr)
+static int do_srxclsrule(struct cmd_context *ctx)
{
int err;
if (rx_class_rule_added) {
/* attempt to add rule via N-tuple specifier */
- err = do_srxntuple(fd, ifr);
+ err = do_srxntuple(ctx);
if (!err)
return 0;
/* attempt to add rule via network flow classifier */
- err = rxclass_rule_ins(fd, ifr, &rx_rule_fs);
+ err = rxclass_rule_ins(ctx, &rx_rule_fs);
if (err < 0) {
fprintf(stderr, "Cannot insert"
" classification rule\n");
return 1;
}
} else if (rx_class_rule_del >= 0) {
- err = rxclass_rule_del(fd, ifr, rx_class_rule_del);
+ err = rxclass_rule_del(ctx, rx_class_rule_del);
if (err < 0) {
fprintf(stderr, "Cannot delete"
@@ -3405,28 +3337,27 @@ static int do_srxclsrule(int fd, struct ifreq *ifr)
return 0;
}
-static int do_grxclsrule(int fd, struct ifreq *ifr)
+static int do_grxclsrule(struct cmd_context *ctx)
{
struct ethtool_rxnfc nfccmd;
int err;
if (rx_class_rule_get >= 0) {
- err = rxclass_rule_get(fd, ifr, rx_class_rule_get);
+ err = rxclass_rule_get(ctx, rx_class_rule_get);
if (err < 0)
fprintf(stderr, "Cannot get RX classification rule\n");
return err ? 1 : 0;
}
nfccmd.cmd = ETHTOOL_GRXRINGS;
- ifr->ifr_data = (caddr_t)&nfccmd;
- err = ioctl(fd, SIOCETHTOOL, ifr);
+ err = send_ioctl(ctx, &nfccmd);
if (err < 0)
perror("Cannot get RX rings");
else
fprintf(stdout, "%d RX rings available\n",
(int)nfccmd.data);
- err = rxclass_rule_getall(fd, ifr);
+ err = rxclass_rule_getall(ctx);
if (err < 0)
fprintf(stderr, "RX classification rule retrieval failed\n");
@@ -3459,7 +3390,7 @@ static int do_writefwdump(struct ethtool_dump *dump)
return err;
}
-static int do_getfwdump(int fd, struct ifreq *ifr)
+static int do_getfwdump(struct cmd_context *ctx)
{
int err;
struct ethtool_dump edata;
@@ -3467,8 +3398,7 @@ static int do_getfwdump(int fd, struct ifreq *ifr)
edata.cmd = ETHTOOL_GET_DUMP_FLAG;
- ifr->ifr_data = (caddr_t) &edata;
- err = send_ioctl(fd, ifr);
+ err = send_ioctl(ctx, &edata);
if (err < 0) {
perror("Can not get dump level\n");
return 1;
@@ -3485,8 +3415,7 @@ static int do_getfwdump(int fd, struct ifreq *ifr)
}
data->cmd = ETHTOOL_GET_DUMP_DATA;
data->len = edata.len;
- ifr->ifr_data = (caddr_t) data;
- err = send_ioctl(fd, ifr);
+ err = send_ioctl(ctx, data);
if (err < 0) {
perror("Can not get dump data\n");
err = 1;
@@ -3498,15 +3427,14 @@ free:
return err;
}
-static int do_setfwdump(int fd, struct ifreq *ifr)
+static int do_setfwdump(struct cmd_context *ctx)
{
int err;
struct ethtool_dump dump;
dump.cmd = ETHTOOL_SET_DUMP;
dump.flag = dump_flag;
- ifr->ifr_data = (caddr_t)&dump;
- err = send_ioctl(fd, ifr);
+ err = send_ioctl(ctx, &dump);
if (err < 0) {
perror("Can not set dump level\n");
return 1;
@@ -3514,9 +3442,10 @@ static int do_setfwdump(int fd, struct ifreq *ifr)
return 0;
}
-static int send_ioctl(int fd, struct ifreq *ifr)
+int send_ioctl(struct cmd_context *ctx, void *cmd)
{
- return ioctl(fd, SIOCETHTOOL, ifr);
+ ctx->ifr.ifr_data = cmd;
+ return ioctl(ctx->fd, SIOCETHTOOL, &ctx->ifr);
}
int main(int argc, char **argp, char **envp)
diff --git a/internal.h b/internal.h
index 2b6a54a..c2f504a 100644
--- a/internal.h
+++ b/internal.h
@@ -88,6 +88,14 @@ static inline int test_bit(unsigned int nr, const unsigned long *addr)
#define RX_CLS_LOC_UNSPEC 0xffffffffUL
+/* Context for sub-commands */
+struct cmd_context {
+ int fd; /* socket suitable for ethtool ioctl */
+ struct ifreq ifr; /* ifreq suitable for ethtool ioctl */
+};
+
+int send_ioctl(struct cmd_context *ctx, void *cmd);
+
/* National Semiconductor DP83815, DP83816 */
int natsemi_dump_regs(struct ethtool_drvinfo *info, struct ethtool_regs *regs);
int natsemi_dump_eeprom(struct ethtool_drvinfo *info,
@@ -155,10 +163,10 @@ int st_gmac_dump_regs(struct ethtool_drvinfo *info, struct ethtool_regs *regs);
/* Rx flow classification */
int rxclass_parse_ruleopts(char **optstr, int opt_cnt,
struct ethtool_rx_flow_spec *fsp);
-int rxclass_rule_getall(int fd, struct ifreq *ifr);
-int rxclass_rule_get(int fd, struct ifreq *ifr, __u32 loc);
-int rxclass_rule_ins(int fd, struct ifreq *ifr,
+int rxclass_rule_getall(struct cmd_context *ctx);
+int rxclass_rule_get(struct cmd_context *ctx, __u32 loc);
+int rxclass_rule_ins(struct cmd_context *ctx,
struct ethtool_rx_flow_spec *fsp);
-int rxclass_rule_del(int fd, struct ifreq *ifr, __u32 loc);
+int rxclass_rule_del(struct cmd_context *ctx, __u32 loc);
#endif /* ETHTOOL_INTERNAL_H__ */
diff --git a/rxclass.c b/rxclass.c
index 809b073..dec9dd5 100644
--- a/rxclass.c
+++ b/rxclass.c
@@ -203,7 +203,7 @@ static void rxclass_print_rule(struct ethtool_rx_flow_spec *fsp)
}
}
-static int rxclass_get_count(int fd, struct ifreq *ifr, __u32 *count)
+static int rxclass_get_count(struct cmd_context *ctx, __u32 *count)
{
struct ethtool_rxnfc nfccmd;
int err;
@@ -211,8 +211,7 @@ static int rxclass_get_count(int fd, struct ifreq *ifr, __u32 *count)
/* request count and store */
nfccmd.cmd = ETHTOOL_GRXCLSRLCNT;
nfccmd.rule_cnt = 0;
- ifr->ifr_data = (caddr_t)&nfccmd;
- err = ioctl(fd, SIOCETHTOOL, ifr);
+ err = send_ioctl(ctx, &nfccmd);
*count = nfccmd.rule_cnt;
if (err < 0)
perror("rxclass: Cannot get RX class rule count");
@@ -220,7 +219,7 @@ static int rxclass_get_count(int fd, struct ifreq *ifr, __u32 *count)
return err;
}
-int rxclass_rule_get(int fd, struct ifreq *ifr, __u32 loc)
+int rxclass_rule_get(struct cmd_context *ctx, __u32 loc)
{
struct ethtool_rxnfc nfccmd;
int err;
@@ -229,8 +228,7 @@ int rxclass_rule_get(int fd, struct ifreq *ifr, __u32 loc)
nfccmd.cmd = ETHTOOL_GRXCLSRULE;
memset(&nfccmd.fs, 0, sizeof(struct ethtool_rx_flow_spec));
nfccmd.fs.location = loc;
- ifr->ifr_data = (caddr_t)&nfccmd;
- err = ioctl(fd, SIOCETHTOOL, ifr);
+ err = send_ioctl(ctx, &nfccmd);
if (err < 0) {
perror("rxclass: Cannot get RX class rule");
return err;
@@ -241,7 +239,7 @@ int rxclass_rule_get(int fd, struct ifreq *ifr, __u32 loc)
return err;
}
-int rxclass_rule_getall(int fd, struct ifreq *ifr)
+int rxclass_rule_getall(struct cmd_context *ctx)
{
struct ethtool_rxnfc *nfccmd;
__u32 *rule_locs;
@@ -249,7 +247,7 @@ int rxclass_rule_getall(int fd, struct ifreq *ifr)
__u32 count;
/* determine rule count */
- err = rxclass_get_count(fd, ifr, &count);
+ err = rxclass_get_count(ctx, &count);
if (err < 0)
return err;
@@ -266,8 +264,7 @@ int rxclass_rule_getall(int fd, struct ifreq *ifr)
/* request location list */
nfccmd->cmd = ETHTOOL_GRXCLSRLALL;
nfccmd->rule_cnt = count;
- ifr->ifr_data = (caddr_t)nfccmd;
- err = ioctl(fd, SIOCETHTOOL, ifr);
+ err = send_ioctl(ctx, nfccmd);
if (err < 0) {
perror("rxclass: Cannot get RX class rules");
free(nfccmd);
@@ -277,7 +274,7 @@ int rxclass_rule_getall(int fd, struct ifreq *ifr)
/* write locations to bitmap */
rule_locs = nfccmd->rule_locs;
for (i = 0; i < count; i++) {
- err = rxclass_rule_get(fd, ifr, rule_locs[i]);
+ err = rxclass_rule_get(ctx, rule_locs[i]);
if (err < 0)
break;
}
@@ -372,7 +369,7 @@ static int rmgr_find_empty_slot(struct ethtool_rx_flow_spec *fsp)
return -1;
}
-static int rmgr_init(int fd, struct ifreq *ifr)
+static int rmgr_init(struct cmd_context *ctx)
{
struct ethtool_rxnfc *nfccmd;
int err, i;
@@ -385,7 +382,7 @@ static int rmgr_init(int fd, struct ifreq *ifr)
memset(&rmgr, 0, sizeof(struct rmgr_ctrl));
/* request count and store in rmgr.n_rules */
- err = rxclass_get_count(fd, ifr, &rmgr.n_rules);
+ err = rxclass_get_count(ctx, &rmgr.n_rules);
if (err < 0)
return err;
@@ -400,8 +397,7 @@ static int rmgr_init(int fd, struct ifreq *ifr)
/* request location list */
nfccmd->cmd = ETHTOOL_GRXCLSRLALL;
nfccmd->rule_cnt = rmgr.n_rules;
- ifr->ifr_data = (caddr_t)nfccmd;
- err = ioctl(fd, SIOCETHTOOL, ifr);
+ err = send_ioctl(ctx, nfccmd);
if (err < 0) {
perror("rmgr: Cannot get RX class rules");
free(nfccmd);
@@ -449,13 +445,13 @@ static void rmgr_cleanup(void)
rmgr.size = 0;
}
-static int rmgr_set_location(int fd, struct ifreq *ifr,
+static int rmgr_set_location(struct cmd_context *ctx,
struct ethtool_rx_flow_spec *fsp)
{
int err;
/* init table of available rules */
- err = rmgr_init(fd, ifr);
+ err = rmgr_init(ctx);
if (err < 0)
return err;
@@ -468,7 +464,7 @@ static int rmgr_set_location(int fd, struct ifreq *ifr,
return err;
}
-int rxclass_rule_ins(int fd, struct ifreq *ifr,
+int rxclass_rule_ins(struct cmd_context *ctx,
struct ethtool_rx_flow_spec *fsp)
{
struct ethtool_rxnfc nfccmd;
@@ -480,7 +476,7 @@ int rxclass_rule_ins(int fd, struct ifreq *ifr,
* and allocate a free rule for our use
*/
if (loc == RX_CLS_LOC_UNSPEC) {
- err = rmgr_set_location(fd, ifr, fsp);
+ err = rmgr_set_location(ctx, fsp);
if (err < 0)
return err;
}
@@ -488,8 +484,7 @@ int rxclass_rule_ins(int fd, struct ifreq *ifr,
/* notify netdev of new rule */
nfccmd.cmd = ETHTOOL_SRXCLSRLINS;
nfccmd.fs = *fsp;
- ifr->ifr_data = (caddr_t)&nfccmd;
- err = ioctl(fd, SIOCETHTOOL, ifr);
+ err = send_ioctl(ctx, &nfccmd);
if (err < 0)
perror("rmgr: Cannot insert RX class rule");
else if (loc == RX_CLS_LOC_UNSPEC)
@@ -498,7 +493,7 @@ int rxclass_rule_ins(int fd, struct ifreq *ifr,
return 0;
}
-int rxclass_rule_del(int fd, struct ifreq *ifr, __u32 loc)
+int rxclass_rule_del(struct cmd_context *ctx, __u32 loc)
{
struct ethtool_rxnfc nfccmd;
int err;
@@ -506,8 +501,7 @@ int rxclass_rule_del(int fd, struct ifreq *ifr, __u32 loc)
/* notify netdev of rule removal */
nfccmd.cmd = ETHTOOL_SRXCLSRLDEL;
nfccmd.fs.location = loc;
- ifr->ifr_data = (caddr_t)&nfccmd;
- err = ioctl(fd, SIOCETHTOOL, ifr);
+ err = send_ioctl(ctx, &nfccmd);
if (err < 0)
perror("rmgr: Cannot delete RX class rule");
--
1.7.4.4
--
Ben Hutchings, Staff Engineer, Solarflare
Not speaking for my employer; that's the marketing department's job.
They asked us to note that Solarflare product names are trademarked.
^ permalink raw reply related
* [PATCH ethtool 10/21] Add test cases for command-line parsing
From: Ben Hutchings @ 2011-11-01 23:17 UTC (permalink / raw)
To: netdev; +Cc: linux-net-drivers
In-Reply-To: <1320186901.2758.30.camel@bwh-desktop>
Preparation for refactoring command-line parsing.
All these test cases pass.
Signed-off-by: Ben Hutchings <bhutchings@solarflare.com>
---
Makefile.am | 7 ++
configure.ac | 1 +
ethtool.c | 5 ++
internal.h | 4 +
test-cmdline.c | 206 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++
test-common.c | 92 +++++++++++++++++++++++++
6 files changed, 315 insertions(+), 0 deletions(-)
create mode 100644 test-cmdline.c
create mode 100644 test-common.c
diff --git a/Makefile.am b/Makefile.am
index 1e05640..4b0eb17 100644
--- a/Makefile.am
+++ b/Makefile.am
@@ -11,6 +11,13 @@ ethtool_SOURCES = ethtool.c ethtool-copy.h internal.h \
smsc911x.c at76c50x-usb.c sfc.c stmmac.c \
rxclass.c
+TESTS = test-cmdline
+check_PROGRAMS = test-cmdline test-one-cmdline
+test_cmdline_SOURCES = test-cmdline.c test-common.c
+test_cmdline_CFLAGS = -DTEST_ETHTOOL
+test_one_cmdline_SOURCES = $(ethtool_SOURCES)
+test_one_cmdline_CFLAGS = -DTEST_ETHTOOL
+
dist-hook:
cp $(top_srcdir)/ethtool.spec $(distdir)
diff --git a/configure.ac b/configure.ac
index 8bc8a56..ac5142b 100644
--- a/configure.ac
+++ b/configure.ac
@@ -10,6 +10,7 @@ AM_MAINTAINER_MODE
dnl Checks for programs.
AC_PROG_CC
AC_PROG_GCC_TRADITIONAL
+AM_PROG_CC_C_O
dnl Checks for libraries.
diff --git a/ethtool.c b/ethtool.c
index b6f535c..7a26043 100644
--- a/ethtool.c
+++ b/ethtool.c
@@ -3444,8 +3444,13 @@ static int do_setfwdump(struct cmd_context *ctx)
int send_ioctl(struct cmd_context *ctx, void *cmd)
{
+#ifndef TEST_ETHTOOL
ctx->ifr.ifr_data = cmd;
return ioctl(ctx->fd, SIOCETHTOOL, &ctx->ifr);
+#else
+ /* If we get this far then parsing succeeded */
+ exit(0);
+#endif
}
int main(int argc, char **argp, char **envp)
diff --git a/internal.h b/internal.h
index c2f504a..ba7d719 100644
--- a/internal.h
+++ b/internal.h
@@ -94,6 +94,10 @@ struct cmd_context {
struct ifreq ifr; /* ifreq suitable for ethtool ioctl */
};
+#ifdef TEST_ETHTOOL
+int test_cmdline(const char *args);
+#endif
+
int send_ioctl(struct cmd_context *ctx, void *cmd);
/* National Semiconductor DP83815, DP83816 */
diff --git a/test-cmdline.c b/test-cmdline.c
new file mode 100644
index 0000000..88591df
--- /dev/null
+++ b/test-cmdline.c
@@ -0,0 +1,206 @@
+/****************************************************************************
+ * Test cases for ethtool command-line parsing
+ * Copyright 2011 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.
+ */
+
+#include <stdio.h>
+#include <stdlib.h>
+#include "internal.h"
+
+static struct test_case {
+ int rc;
+ const char *args;
+} test_cases[] = {
+ { 1, "" },
+ { 0, "devname" },
+ { 0, "15_char_devname" },
+ { 1, "16_char_devname!" },
+ /* Argument parsing for -s is specialised */
+ { 0, "-s devname" },
+ { 0, "--change devname speed 100 duplex half" },
+ { 1, "-s devname speed foo" },
+ { 1, "--change devname speed" },
+ { 0, "-s devname duplex half" },
+ { 1, "--change devname duplex foo" },
+ { 1, "-s devname duplex" },
+ { 0, "--change devname port tp" },
+ { 1, "-s devname port foo" },
+ { 1, "--change devname port" },
+ { 0, "-s devname autoneg on" },
+ { 1, "--change devname autoneg foo" },
+ { 1, "-s devname autoneg" },
+ { 0, "--change devname advertise 0x1" },
+ { 1, "-s devname advertise foo" },
+ { 1, "--change devname advertise" },
+ { 0, "-s devname phyad 1" },
+ { 1, "--change devname phyad foo" },
+ { 1, "-s devname phyad" },
+ { 0, "--change devname xcvr external" },
+ { 1, "-s devname xcvr foo" },
+ { 1, "--change devname xcvr" },
+ { 0, "-s devname wol p" },
+ { 1, "--change devname wol" },
+ { 0, "-s devname sopass 01:23:45:67:89:ab" },
+ { 1, "--change devname sopass 01:23:45:67:89:" },
+ { 1, "-s devname sopass 01:23:45:67:89" },
+ { 1, "--change devname sopass" },
+ { 0, "-s devname msglvl 1" },
+ { 1, "--change devname msglvl" },
+ { 0, "-s devname msglvl hw on rx_status off" },
+ { 1, "--change devname msglvl hw foo" },
+ { 1, "-s devname msglvl hw" },
+ { 0, "--change devname speed 100 duplex half port tp autoneg on advertise 0x1 phyad 1 xcvr external wol p sopass 01:23:45:67:89:ab msglvl 1" },
+ { 1, "-s devname foo" },
+ { 0, "-a devname" },
+ { 0, "--show-pause devname" },
+ /* Many other sub-commands use parse_generic_cmdline() and
+ * don't need to be check in that much detail. */
+ { 0, "-A devname autoneg on" },
+ { 1, "--pause devname autoneg foo" },
+ { 1, "-A devname autoneg" },
+ { 0, "--pause devname rx off" },
+ { 0, "-A devname tx on rx on autoneg off" },
+ { 1, "--pause devname foo on" },
+ { 0, "-c devname" },
+ { 0, "--show-coalesce devname" },
+ { 0, "-C devname adaptive-rx on adaptive-tx off rx-usecs 1 rx-frames 2 rx-usecs-irq 3 rx-frames-irq 4 tx-usecs 5 tx-frames 6 tx-usecs-irq 7 tx-frames-irq 8 stats-block-usecs 9 pkt-rate-low 10" },
+ { 0, "--coalesce devname rx-usecs-low 11 rx-frames-low 12 tx-usecs-low 13 tx-frames-low 14 pkt-rate-high 15 rx-usecs-high 16 rx-frames-high 17 tx-usecs-high 18 tx-frames-high 19 sample-interval 20" },
+ { 1, "-C devname adaptive-rx foo" },
+ { 1, "--coalesce devname adaptive-rx" },
+ { 1, "-C devname foo on" },
+ { 0, "-g devname" },
+ { 0, "--show-ring devname" },
+ { 0, "-G devname rx 1 rx-mini 2 rx-jumbo 3 tx 4" },
+ { 0, "--set-ring devname rx 1 rx-mini 2 rx-jumbo 3 tx 4" },
+ { 1, "-G devname rx foo" },
+ { 1, "--set-ring devname rx" },
+ { 1, "-G devname foo 1" },
+ { 0, "-k devname" },
+ { 0, "--show-offload devname" },
+ { 0, "-K devname rx on tx off sg on tso off ufo on gso off gro on" },
+ { 0, "--offload devname lro off rxvlan on txvlan off ntuple on rxhash off" },
+ { 1, "-K devname rx foo" },
+ { 1, "--offload devname rx" },
+ { 1, "-K devname foo on" },
+ { 0, "-i devname" },
+ { 0, "--driver devname" },
+ { 0, "-d devname" },
+ { 0, "--register-dump devname raw on file foo" },
+ { 1, "-d devname raw foo" },
+ { 1, "--register-dump devname file" },
+ { 1, "-d devname foo" },
+ { 0, "-e devname" },
+ { 0, "--eeprom-dump devname raw on offset 1 length 2" },
+ { 1, "-e devname raw foo" },
+ { 1, "--eeprom-dump devname offset foo" },
+ { 1, "-e devname length" },
+ { 1, "--eeprom-dump devname foo" },
+ { 0, "-E devname" },
+ { 0, "--change-eeprom devname magic 0x87654321 offset 0 value 1" },
+ { 0, "-E devname magic 0x87654321 offset 0 length 2" },
+ { 0, "-r devname" },
+ { 0, "--negotiate devname" },
+ { 0, "-p devname" },
+ { 0, "--identify devname 1" },
+ { 1, "-p devname 1 foo" },
+ { 1, "--identify devname foo" },
+ /* Argument parsing for -t is specialised */
+ { 0, "-t devname" },
+ { 0, "--test devname online" },
+ { 1, "-t devname foo" },
+ { 1, "--test devname online foo" },
+ { 0, "-S devname" },
+ { 0, "--statistics devname" },
+ /* Argument parsing for -n is specialised */
+ { 0, "-n devname rx-flow-hash tcp4" },
+ { 0, "--show-nfc devname rx-flow-hash udp6" },
+ { 1, "-n devname rx-flow-hash foo" },
+ { 1, "--show-nfc devname rx-flow-hash" },
+ { 1, "-n devname foo" },
+ /* Argument parsing for -f is specialised */
+ { 1, "-f devname" },
+ { 0, "--flash devname filename" },
+ { 0, "-f devname filename 1" },
+ /* Argument parsing for -N is specialised */
+ { 0, "-N devname rx-flow-hash tcp4 mvtsdfn" },
+ { 0, "--config-nfc devname rx-flow-hash tcp4 r" },
+ { 1, "-N devname rx-flow-hash tcp4" },
+ { 1, "--config-nfc devname rx-flow-hash foo" },
+ { 1, "-N devname rx-flow-hash" },
+ { 1, "--config-nfc devname foo" },
+ { 0, "-x devname" },
+ { 0, "--show-rxfh-indir devname" },
+ /* Argument parsing for -X is specialised */
+ { 0, "-X devname equal 2" },
+ { 0, "--set-rxfh-indir devname equal 256" },
+ { 1, "-X devname equal 0" },
+ { 1, "--set-rxfh-indir devname equal foo" },
+ { 1, "-X devname equal" },
+ { 0, "--set-rxfh-indir devname weight 1 2 3 4" },
+ { 1, "-X devname foo" },
+ /* Argument parsing for -U is specialised */
+ { 0, "-U devname delete 1" },
+ { 1, "--config-ntuple devname delete foo" },
+ { 1, "-U devname delete" },
+ { 0, "--config-ntuple devname flow-type ether src 01:23:45:67:89:ab m cd:ef:01:23:45:67 dst 89:ab:cd:ef:01:23 m 45:67:89:ab:cd:ef proto 0x0123 m 0x4567 vlan 0x89ab m 0xcdef action 0" },
+ { 0, "-U devname flow-type ether src 01:23:45:67:89:ab src-mask cd:ef:01:23:45:67 dst 89:ab:cd:ef:01:23 dst-mask 45:67:89:ab:cd:ef proto 0x0123 proto-mask 0x4567 vlan 0x89ab vlan-mask 0xcdef action 1" },
+ { 1, "--config-ntuple devname flow-type ether src 01:23:45:67:89: action 3" },
+ { 1, "-U devname flow-type ether src 01:23:45:67:89 action 4" },
+ { 0, "--config-ntuple devname flow-type ip4 src-ip 0.123.45.67 m 89.0.123.45 dst-ip 67.89.0.123 m 45.67.89.0 tos 1 m 1 l4proto 0x23 m 0x45 l4data 0xfedcba98 m 76543210 vlan 0x89ab m 0xcdef action 6" },
+ { 0, "-U devname flow-type ip4 src-ip 0.123.45.67 src-ip-mask 89.0.123.45 dst-ip 67.89.0.123 dst-ip-mask 45.67.89.0 tos 1 tos-mask 1 l4proto 0x23 l4proto-mask 0x45 l4data 0xfedcba98 l4data-mask 76543210 vlan 0x89ab vlan-mask 0xcdef action 7" },
+ { 0, "--config-ntuple devname flow-type tcp4 src-ip 0.123.45.67 m 89.0.123.45 dst-ip 67.89.0.123 m 45.67.89.0 tos 1 m 1 src-port 23456 m 7890 dst-port 12345 m 6789 vlan 0x89ab m 0xcdef action 8" },
+ { 0, "-U devname flow-type tcp4 src-ip 0.123.45.67 src-ip-mask 89.0.123.45 dst-ip 67.89.0.123 dst-ip-mask 45.67.89.0 tos 1 tos-mask 1 src-port 23456 src-port-mask 7890 dst-port 12345 dst-port-mask 6789 vlan 0x89ab vlan-mask 0xcdef action 9" },
+ { 0, "--config-ntuple devname flow-type ah4 src-ip 0.123.45.67 m 89.0.123.45 dst-ip 67.89.0.123 m 45.67.89.0 tos 1 m 1 spi 2 m 3 vlan 0x89ab m 0xcdef action 10" },
+ { 0, "-U devname flow-type ah4 src-ip 0.123.45.67 src-ip-mask 89.0.123.45 dst-ip 67.89.0.123 dst-ip-mask 45.67.89.0 tos 1 tos-mask 1 spi 2 spi-mask 3 vlan 0x89ab vlan-mask 0xcdef action 11" },
+ { 1, "--config-ntuple devname flow-type tcp4 action foo" },
+ { 1, "-U devname flow-type foo" },
+ { 1, "--config-ntuple devname flow-type" },
+ { 1, "-U devname foo" },
+ { 0, "-P devname" },
+ { 0, "--show-permaddr devname" },
+ { 0, "-w devname" },
+ { 0, "--get-dump devname data filename" },
+ { 0, "-w devname data filename" },
+ { 1, "--get-dump devname data" },
+ { 1, "-w devname foo" },
+ { 0, "-W devname 1" },
+ { 0, "--set-dump devname 2" },
+ { 1, "-W devname foo" },
+ { 0, "-l devname" },
+ { 0, "--show-channels devname" },
+ { 0, "-L devname rx 1 tx 2 other 3 combined 4" },
+ { 0, "--set-channels devname rx 1 tx 2 other 3 combined 4" },
+ { 1, "-L devname rx foo" },
+ { 1, "--set-channels devname rx" },
+ { 0, "-L devname" },
+ { 0, "-h" },
+ { 0, "--help" },
+ { 0, "--version" },
+ { 1, "--foo" },
+ { 1, "-foo" },
+ { 1, "-0" },
+};
+
+int main(void)
+{
+ struct test_case *tc;
+ int test_rc;
+ int rc = 0;
+
+ for (tc = test_cases; tc < test_cases + ARRAY_SIZE(test_cases); tc++) {
+ if (getenv("ETHTOOL_TEST_VERBOSE"))
+ printf("I: Test command line: ethtool %s\n", tc->args);
+ test_rc = test_cmdline(tc->args);
+ if (test_rc != tc->rc) {
+ fprintf(stderr, "E: ethtool %s returns %d\n",
+ tc->args, test_rc);
+ rc = 1;
+ }
+ }
+
+ return rc;
+}
diff --git a/test-common.c b/test-common.c
new file mode 100644
index 0000000..4ea84c8
--- /dev/null
+++ b/test-common.c
@@ -0,0 +1,92 @@
+/****************************************************************************
+ * Common test functions for ethtool
+ * Copyright 2011 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.
+ */
+
+#include <stdlib.h>
+#include <string.h>
+#include <sys/fcntl.h>
+#include <sys/wait.h>
+#include <unistd.h>
+#include "internal.h"
+
+int test_cmdline(const char *args)
+{
+ int argc, i;
+ char **argv;
+ const char *arg;
+ size_t len;
+ pid_t pid;
+ int dev_null;
+ int status;
+ int rc;
+
+ /* Convert line to argv */
+ argc = 1;
+ arg = args;
+ for (;;) {
+ len = strcspn(arg, " ");
+ if (len == 0)
+ break;
+ argc++;
+ if (arg[len] == 0)
+ break;
+ arg += len + 1;
+ }
+ argv = calloc(argc + 1, sizeof(argv[0]));
+ argv[0] = strdup("ethtool");
+ arg = args;
+ for (i = 1; i < argc; i++) {
+ len = strcspn(arg, " ");
+ argv[i] = malloc(len + 1);
+ memcpy(argv[i], arg, len);
+ argv[i][len] = 0;
+ arg += len + 1;
+ }
+
+ dev_null = open("/dev/null", O_RDWR);
+ if (dev_null < 0) {
+ perror("open /dev/null");
+ rc = -1;
+ goto out;
+ }
+
+ fflush(NULL);
+ pid = fork();
+
+ /* Child */
+ if (pid == 0) {
+ dup2(dev_null, STDIN_FILENO);
+ if (!getenv("ETHTOOL_TEST_VERBOSE")) {
+ dup2(dev_null, STDOUT_FILENO);
+ dup2(dev_null, STDERR_FILENO);
+ }
+ execv("./test-one-cmdline", argv);
+ _exit(126);
+ }
+
+ /* Parent */
+ if (pid < 0) {
+ perror("fork");
+ close(dev_null);
+ rc = -1;
+ goto out;
+ }
+ close(dev_null);
+ if (waitpid(pid, &status, 0) < 0) {
+ perror("waitpid");
+ rc = -1;
+ goto out;
+ }
+ rc = WIFEXITED(status) ? WEXITSTATUS(status) : -1;
+
+out:
+ for (i = 0; i < argc; i++)
+ free(argv[i]);
+ free(argv);
+ return rc;
+}
--
1.7.4.4
--
Ben Hutchings, Staff Engineer, Solarflare
Not speaking for my employer; that's the marketing department's job.
They asked us to note that Solarflare product names are trademarked.
^ permalink raw reply related
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