* [AX25] inconsistent lock state
From: f6bvp @ 2011-06-16 20:40 UTC (permalink / raw)
To: linux-kernel; +Cc: Linux Netdev List, Ralf Baechle, linux-hams
In-Reply-To: <20100115203654.GA3084@del.dom.local>
Hi,
When unpluging ethernet connector a few seconds I observed the following
kernel message :
Jun 16 12:03:25 f6bvp-9 kernel: e1000e: eth1 NIC Link is Down
Jun 16 12:03:25 f6bvp-9 ifplugd(eth1)[1541]: Link beat lost.
Jun 16 12:03:31 f6bvp-9 ifplugd(eth1)[1541]: Executing
'/etc/ifplugd/ifplugd.action eth1 down'.
Jun 16 12:03:31 f6bvp-9 avahi-daemon[2197]: Withdrawing address record
for 192.168.0.66 on eth1.
Jun 16 12:03:31 f6bvp-9 avahi-daemon[2197]: Leaving mDNS multicast group
on interface eth1.IPv4 with address 192.168.0.66.
Jun 16 12:03:31 f6bvp-9 avahi-daemon[2197]: Interface eth1.IPv4 no
longer relevant for mDNS.
Jun 16 12:03:31 f6bvp-9 avahi-daemon[2197]: Withdrawing address record
for fe80::21c:c0ff:fe36:723e on eth1.
Jun 16 12:03:31 f6bvp-9 vnstatd[2022]: SIGHUP received, flushing data to
disk and reloading config.
Jun 16 12:03:31 f6bvp-9 ifplugd(eth1)[1541]: client: Rechargement de la
configuration de vnstatd : #033[65G[#033[1;32m OK #033[0;39m]#015
Jun 16 12:03:31 f6bvp-9 ifplugd(eth1)[1541]: Program executed successfully.
Jun 16 12:03:31 f6bvp-9 kernel: ADDRCONF(NETDEV_UP): eth1: link is not ready
Jun 16 12:03:34 f6bvp-9 kernel:
Jun 16 12:03:34 f6bvp-9 kernel: =================================
Jun 16 12:03:34 f6bvp-9 kernel: [ INFO: inconsistent lock state ]
Jun 16 12:03:34 f6bvp-9 kernel: 2.6.39.1 #3
Jun 16 12:03:34 f6bvp-9 kernel: ---------------------------------
Jun 16 12:03:34 f6bvp-9 kernel: inconsistent {IN-SOFTIRQ-R} ->
{SOFTIRQ-ON-W} usage.
Jun 16 12:03:34 f6bvp-9 kernel: ax25ipd/2813 [HC0[0]:SC0[0]:HE1:SE1] takes:
Jun 16 12:03:34 f6bvp-9 kernel: (disc_data_lock){+++?.-}, at:
[<ffffffffa018552b>] mkiss_close+0x1b/0x90 [mkiss]
Jun 16 12:03:34 f6bvp-9 kernel: {IN-SOFTIRQ-R} state was registered at:
Jun 16 12:03:34 f6bvp-9 kernel: [<ffffffff8109484e>]
__lock_acquire+0x57e/0x14c0
Jun 16 12:03:34 f6bvp-9 kernel: [<ffffffff81095836>]
lock_acquire+0xa6/0x160
Jun 16 12:03:34 f6bvp-9 kernel: [<ffffffff813f64f4>]
_raw_read_lock+0x34/0x50
Jun 16 12:03:34 f6bvp-9 kernel: [<ffffffffa01850ed>]
mkiss_get+0x1d/0x50 [mkiss]
Jun 16 12:03:34 f6bvp-9 kernel: [<ffffffffa018517e>]
mkiss_write_wakeup+0x1e/0xb0 [mkiss]
Jun 16 12:03:34 f6bvp-9 kernel: [<ffffffff8129457e>] tty_wakeup+0x6e/0x80
Jun 16 12:03:34 f6bvp-9 kernel: [<ffffffff8129f243>] pty_write+0x73/0x80
Jun 16 12:03:34 f6bvp-9 kernel: [<ffffffffa0185d2e>]
ax_xmit+0x27e/0x5e0 [mkiss]
Jun 16 12:03:34 f6bvp-9 kernel: [<ffffffff81339dac>]
dev_hard_start_xmit+0x34c/0x6f0
Jun 16 12:03:34 f6bvp-9 kernel: [<ffffffff81358b4d>]
sch_direct_xmit+0xdd/0x260
Jun 16 12:03:34 f6bvp-9 kernel: [<ffffffff8133cc8f>]
dev_queue_xmit+0x1af/0x8a0
Jun 16 12:03:34 f6bvp-9 kernel: [<ffffffffa0325072>]
ax25_queue_xmit+0x52/0x60 [ax25]
Jun 16 12:03:34 f6bvp-9 kernel: [<ffffffffa032516f>]
ax25_transmit_buffer+0xef/0x130 [ax25]
Jun 16 12:03:34 f6bvp-9 kernel: [<ffffffffa0325238>]
ax25_send_iframe+0x88/0xe0 [ax25]
Jun 16 12:03:34 f6bvp-9 kernel: [<ffffffffa032536e>]
ax25_kick+0xde/0x220 [ax25]
Jun 16 12:03:34 f6bvp-9 kernel: [<ffffffffa0326715>]
ax25_std_frame_in+0x65/0x920 [ax25]
Jun 16 12:03:34 f6bvp-9 kernel: [<ffffffffa03241da>]
ax25_rcv+0x3aa/0x9a0 [ax25]
Jun 16 12:03:34 f6bvp-9 kernel: [<ffffffffa032486f>]
ax25_kiss_rcv+0x9f/0xb0 [ax25]
Jun 16 12:03:34 f6bvp-9 kernel: [<ffffffff8133bba5>]
__netif_receive_skb+0x205/0x6d0
Jun 16 12:03:34 f6bvp-9 kernel: [<ffffffff8133c144>]
process_backlog+0xd4/0x1e0
Jun 16 12:03:34 f6bvp-9 kernel: [<ffffffff8133c995>]
net_rx_action+0x125/0x270
Jun 16 12:03:34 f6bvp-9 kernel: [<ffffffff810618f1>]
__do_softirq+0xc1/0x210
Jun 16 12:03:34 f6bvp-9 kernel: [<ffffffff813ffa9c>] call_softirq+0x1c/0x30
Jun 16 12:03:34 f6bvp-9 kernel: [<ffffffff810627db>]
local_bh_enable_ip+0xeb/0xf0
Jun 16 12:03:34 f6bvp-9 kernel: [<ffffffff813f6594>]
_raw_spin_unlock_bh+0x34/0x40
Jun 16 12:03:34 f6bvp-9 kernel: [<ffffffffa0186522>]
mkiss_receive_buf+0x2e2/0x3dc [mkiss]
Jun 16 12:03:34 f6bvp-9 kernel: [<ffffffff8129e122>]
flush_to_ldisc+0x1b2/0x1d0
Jun 16 12:03:34 f6bvp-9 kernel: [<ffffffff810762c0>]
process_one_work+0x1a0/0x510
Jun 16 12:03:34 f6bvp-9 kernel: [<ffffffff81078ba2>]
worker_thread+0x172/0x400
Jun 16 12:03:34 f6bvp-9 kernel: [<ffffffff8107d816>] kthread+0xb6/0xc0
Jun 16 12:03:34 f6bvp-9 kernel: [<ffffffff813ff9a4>]
kernel_thread_helper+0x4/0x10
Jun 16 12:03:34 f6bvp-9 kernel: irq event stamp: 76635461
Jun 16 12:03:34 f6bvp-9 kernel: hardirqs last enabled at (76635461):
[<ffffffff813f6620>] _raw_spin_unlock_irqrestore+0x40/0x70
Jun 16 12:03:34 f6bvp-9 kernel: hardirqs last disabled at (76635460):
[<ffffffff813f5f1e>] _raw_spin_lock_irqsave+0x2e/0x70
Jun 16 12:03:34 f6bvp-9 kernel: softirqs last enabled at (76635394):
[<ffffffff81329337>] sk_common_release+0x67/0xd0
Jun 16 12:03:34 f6bvp-9 kernel: softirqs last disabled at (76635392):
[<ffffffff813f60f6>] _raw_write_lock_bh+0x16/0x50
Jun 16 12:03:34 f6bvp-9 kernel:
Jun 16 12:03:34 f6bvp-9 kernel: other info that might help us debug this:
Jun 16 12:03:34 f6bvp-9 kernel: 2 locks held by ax25ipd/2813:
Jun 16 12:03:34 f6bvp-9 kernel: #0: (big_tty_mutex){+.+.+.}, at:
[<ffffffff813f67ce>] tty_lock+0x2e/0x4f
Jun 16 12:03:34 f6bvp-9 kernel: #1: (&tty->ldisc_mutex){+.+.+.}, at:
[<ffffffff8129d597>] tty_ldisc_hangup+0xe7/0x250
Jun 16 12:03:34 f6bvp-9 kernel:
Jun 16 12:03:34 f6bvp-9 kernel: stack backtrace:
Jun 16 12:03:34 f6bvp-9 kernel: Pid: 2813, comm: ax25ipd Not tainted
2.6.39.1 #3
Jun 16 12:03:34 f6bvp-9 kernel: Call Trace:
Jun 16 12:03:34 f6bvp-9 kernel: [<ffffffff81092dc0>]
print_usage_bug+0x170/0x180
Jun 16 12:03:34 f6bvp-9 kernel: [<ffffffff81093a81>] mark_lock+0x211/0x3f0
Jun 16 12:03:34 f6bvp-9 kernel: [<ffffffff810948c4>]
__lock_acquire+0x5f4/0x14c0
Jun 16 12:03:34 f6bvp-9 kernel: [<ffffffff81093ccb>] ?
mark_held_locks+0x6b/0xa0
Jun 16 12:03:34 f6bvp-9 kernel: [<ffffffff813f65d0>] ?
_raw_spin_unlock_irq+0x30/0x40
Jun 16 12:03:34 f6bvp-9 kernel: [<ffffffff81093fcd>] ?
trace_hardirqs_on_caller+0x13d/0x180
Jun 16 12:03:34 f6bvp-9 kernel: [<ffffffff81095836>] lock_acquire+0xa6/0x160
Jun 16 12:03:34 f6bvp-9 kernel: [<ffffffffa018552b>] ?
mkiss_close+0x1b/0x90 [mkiss]
Jun 16 12:03:34 f6bvp-9 kernel: [<ffffffff81093ccb>] ?
mark_held_locks+0x6b/0xa0
Jun 16 12:03:34 f6bvp-9 kernel: [<ffffffff813f6221>]
_raw_write_lock+0x31/0x40
Jun 16 12:03:34 f6bvp-9 kernel: [<ffffffffa018552b>] ?
mkiss_close+0x1b/0x90 [mkiss]
Jun 16 12:03:34 f6bvp-9 kernel: [<ffffffff8113775e>] ?
kmem_cache_alloc_trace+0x7e/0x140
Jun 16 12:03:34 f6bvp-9 kernel: [<ffffffffa018552b>]
mkiss_close+0x1b/0x90 [mkiss]
Jun 16 12:03:34 f6bvp-9 kernel: [<ffffffff8129c84b>]
tty_ldisc_close+0x4b/0x70
Jun 16 12:03:34 f6bvp-9 kernel: [<ffffffff8129ce90>]
tty_ldisc_reinit+0x40/0x80
Jun 16 12:03:34 f6bvp-9 kernel: [<ffffffff8129d5b4>]
tty_ldisc_hangup+0x104/0x250
Jun 16 12:03:34 f6bvp-9 kernel: [<ffffffff8129588c>]
__tty_hangup+0x15c/0x3e0
Jun 16 12:03:34 f6bvp-9 kernel: [<ffffffff8109401d>] ?
trace_hardirqs_on+0xd/0x10
Jun 16 12:03:34 f6bvp-9 kernel: [<ffffffff81295b3e>] tty_vhangup+0xe/0x10
Jun 16 12:03:34 f6bvp-9 kernel: [<ffffffff8129f37e>] pty_close+0x10e/0x160
Jun 16 12:03:34 f6bvp-9 kernel: [<ffffffff81295ceb>] tty_release+0x16b/0x640
Jun 16 12:03:34 f6bvp-9 kernel: [<ffffffff8113920a>] ?
kmem_cache_free+0x11a/0x160
Jun 16 12:03:34 f6bvp-9 kernel: [<ffffffff81142f9a>] fput+0xea/0x230
Jun 16 12:03:34 f6bvp-9 kernel: [<ffffffff8113ee03>] filp_close+0x63/0x90
Jun 16 12:03:34 f6bvp-9 kernel: [<ffffffff8105dab1>]
put_files_struct+0x171/0x190
Jun 16 12:03:34 f6bvp-9 kernel: [<ffffffff8105d978>] ?
put_files_struct+0x38/0x190
Jun 16 12:03:34 f6bvp-9 kernel: [<ffffffff8105db22>] exit_files+0x52/0x60
Jun 16 12:03:34 f6bvp-9 kernel: [<ffffffff8105deb9>] do_exit+0x189/0x860
Jun 16 12:03:34 f6bvp-9 kernel: [<ffffffff81142cc0>] ? fget+0xd0/0xd0
Jun 16 12:03:34 f6bvp-9 kernel: [<ffffffff813f69b9>] ?
retint_swapgs+0x13/0x1b
Jun 16 12:03:34 f6bvp-9 kernel: [<ffffffff8105e5eb>] do_group_exit+0x5b/0xd0
Jun 16 12:03:34 f6bvp-9 kernel: [<ffffffff8105e677>]
sys_exit_group+0x17/0x20
Jun 16 12:03:34 f6bvp-9 kernel: [<ffffffff813fe812>]
system_call_fastpath+0x16/0x1b
Kernel is 2.6.39.1
Is there something wrong in AX25 code or (more unlikely) is this
operation not permitted ?
Thanks for help.
Bernard Pidoux
--
To unsubscribe from this list: send the line "unsubscribe linux-hams" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at http://vger.kernel.org/majordomo-info.html
^ permalink raw reply
* [PATCH net-next 4/7] qlcnic: fix initial number of msix entries in adapter.
From: Anirban Chakraborty @ 2011-06-16 20:37 UTC (permalink / raw)
To: netdev; +Cc: David Miller, Sucheta Chakraborty
In-Reply-To: <1308256659-19895-1-git-send-email-anirban.chakraborty@qlogic.com>
From: Sucheta Chakraborty <sucheta.chakraborty@qlogic.com>
Calculation of number of MSI-X vectors was wrong on uniprocessor
systems.
Signed-off-by: Sucheta Chakraborty <sucheta.chakraborty@qlogic.com>
Signed-off-by: Anirban Chakraborty <anirban.chakraborty@qlogic.com>
---
drivers/net/qlcnic/qlcnic.h | 1 -
drivers/net/qlcnic/qlcnic_main.c | 6 ++----
2 files changed, 2 insertions(+), 5 deletions(-)
diff --git a/drivers/net/qlcnic/qlcnic.h b/drivers/net/qlcnic/qlcnic.h
index e5bb332..58d7616 100644
--- a/drivers/net/qlcnic/qlcnic.h
+++ b/drivers/net/qlcnic/qlcnic.h
@@ -900,7 +900,6 @@ struct qlcnic_ipaddr {
((adapter)->flags & (QLCNIC_MSI_ENABLED | QLCNIC_MSIX_ENABLED))
#define QLCNIC_DEF_NUM_STS_DESC_RINGS 4
-#define QLCNIC_MIN_NUM_RSS_RINGS 2
#define QLCNIC_MSIX_TBL_SPACE 8192
#define QLCNIC_PCI_REG_MSIX_TBL 0x44
#define QLCNIC_MSIX_TBL_PGSIZE 4096
diff --git a/drivers/net/qlcnic/qlcnic_main.c b/drivers/net/qlcnic/qlcnic_main.c
index aa94e86..8c07c4e 100644
--- a/drivers/net/qlcnic/qlcnic_main.c
+++ b/drivers/net/qlcnic/qlcnic_main.c
@@ -418,10 +418,8 @@ qlcnic_setup_intr(struct qlcnic_adapter *adapter)
int num_msix;
if (adapter->msix_supported) {
- num_msix = (num_online_cpus() >=
- QLCNIC_DEF_NUM_STS_DESC_RINGS) ?
- QLCNIC_DEF_NUM_STS_DESC_RINGS :
- QLCNIC_MIN_NUM_RSS_RINGS;
+ num_msix = rounddown_pow_of_two(min_t(int, num_online_cpus(),
+ QLCNIC_DEF_NUM_STS_DESC_RINGS));
} else
num_msix = 1;
--
1.7.4.1
^ permalink raw reply related
* [PATCH net-next 5/7] qlcnic: fix default operating state of interface
From: Anirban Chakraborty @ 2011-06-16 20:37 UTC (permalink / raw)
To: netdev; +Cc: David Miller, Amit Kumar Salecha
In-Reply-To: <1308256659-19895-1-git-send-email-anirban.chakraborty@qlogic.com>
From: Amit Kumar Salecha <amit.salecha@qlogic.com>
Currently interface shows status as RUNNING, even if there is no link.
To fix this, netif_carrier_off should be called after register_netdev().
netif_carrier_off calls linkwatch_fire_event(dev); only if netdev is registered,
otherwise it skips. linkwatch_fire_event set default state of nic interface.
Signed-off-by: Amit Kumar Salecha <amit.salecha@qlogic.com>
Signed-off-by: Anirban Chakraborty <anirban.chakraborty@qlogic.com>
---
drivers/net/qlcnic/qlcnic_main.c | 4 ++--
1 files changed, 2 insertions(+), 2 deletions(-)
diff --git a/drivers/net/qlcnic/qlcnic_main.c b/drivers/net/qlcnic/qlcnic_main.c
index 8c07c4e..5348dba 100644
--- a/drivers/net/qlcnic/qlcnic_main.c
+++ b/drivers/net/qlcnic/qlcnic_main.c
@@ -1485,14 +1485,14 @@ qlcnic_setup_netdev(struct qlcnic_adapter *adapter,
netdev->irq = adapter->msix_entries[0].vector;
- netif_carrier_off(netdev);
-
err = register_netdev(netdev);
if (err) {
dev_err(&pdev->dev, "failed to register net device\n");
return err;
}
+ netif_carrier_off(netdev);
+
return 0;
}
--
1.7.4.1
^ permalink raw reply related
* [PATCH net-next 1/7] qlcnic: Add capability to take FW dump deterministically
From: Anirban Chakraborty @ 2011-06-16 20:37 UTC (permalink / raw)
To: netdev; +Cc: David Miller, Sritej Velaga
From: Sritej Velaga <sritej.velaga@qlogic.com>
In presence of multiple functions, current driver implementation does not
guarantee that the FW dump is taken by the same function that forces it.
Change it by adding a fw reset owner flag that could be changed in the device
reset path and only when a function determines that it needs to reset it.
Signed-off-by: Sritej Velaga <sritej.velaga@qlogic.com>
Signed-off-by: Anirban Chakraborty <anirban.chakraborty@qlogic.com>
---
drivers/net/qlcnic/qlcnic.h | 1 +
drivers/net/qlcnic/qlcnic_ctx.c | 4 ++--
drivers/net/qlcnic/qlcnic_main.c | 32 ++++++++++++++++++++++++--------
3 files changed, 27 insertions(+), 10 deletions(-)
diff --git a/drivers/net/qlcnic/qlcnic.h b/drivers/net/qlcnic/qlcnic.h
index 480ef5c..194376e 100644
--- a/drivers/net/qlcnic/qlcnic.h
+++ b/drivers/net/qlcnic/qlcnic.h
@@ -895,6 +895,7 @@ struct qlcnic_ipaddr {
#define QLCNIC_MAC_OVERRIDE_DISABLED 0x400
#define QLCNIC_PROMISC_DISABLED 0x800
#define QLCNIC_NEED_FLR 0x1000
+#define QLCNIC_FW_RESET_OWNER 0x2000
#define QLCNIC_IS_MSI_FAMILY(adapter) \
((adapter)->flags & (QLCNIC_MSI_ENABLED | QLCNIC_MSIX_ENABLED))
diff --git a/drivers/net/qlcnic/qlcnic_ctx.c b/drivers/net/qlcnic/qlcnic_ctx.c
index bab041a..0ca514a 100644
--- a/drivers/net/qlcnic/qlcnic_ctx.c
+++ b/drivers/net/qlcnic/qlcnic_ctx.c
@@ -95,8 +95,8 @@ int qlcnic_fw_cmd_get_minidump_temp(struct qlcnic_adapter *adapter)
QLCNIC_CDRP_CMD_TEMP_SIZE);
if (err != QLCNIC_RCODE_SUCCESS) {
err = QLCRD32(adapter, QLCNIC_ARG1_CRB_OFFSET);
- dev_err(&adapter->pdev->dev,
- "Failed to get template size %d\n", err);
+ dev_info(&adapter->pdev->dev,
+ "Can't get template size %d\n", err);
err = -EIO;
return err;
}
diff --git a/drivers/net/qlcnic/qlcnic_main.c b/drivers/net/qlcnic/qlcnic_main.c
index 0f6af5c..cd8e5c1 100644
--- a/drivers/net/qlcnic/qlcnic_main.c
+++ b/drivers/net/qlcnic/qlcnic_main.c
@@ -1590,10 +1590,6 @@ qlcnic_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
/* This will be reset for mezz cards */
adapter->portnum = adapter->ahw->pci_func;
- /* Get FW dump template and store it */
- if (adapter->op_mode != QLCNIC_NON_PRIV_FUNC)
- qlcnic_fw_cmd_get_minidump_temp(adapter);
-
err = qlcnic_get_board_info(adapter);
if (err) {
dev_err(&pdev->dev, "Error getting board config info.\n");
@@ -1612,6 +1608,12 @@ qlcnic_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
goto err_out_decr_ref;
}
+ /* Get FW dump template and store it */
+ if (adapter->op_mode != QLCNIC_NON_PRIV_FUNC)
+ if (!qlcnic_fw_cmd_get_minidump_temp(adapter))
+ dev_info(&pdev->dev,
+ "Supports FW dump capability\n");
+
if (qlcnic_read_mac_addr(adapter))
dev_warn(&pdev->dev, "failed to read mac addr\n");
@@ -2683,11 +2685,16 @@ err:
static int
qlcnic_check_drv_state(struct qlcnic_adapter *adapter)
{
- int act, state;
+ int act, state, active_mask;
state = QLCRD32(adapter, QLCNIC_CRB_DRV_STATE);
act = QLCRD32(adapter, QLCNIC_CRB_DRV_ACTIVE);
+ if (adapter->flags & QLCNIC_FW_RESET_OWNER) {
+ active_mask = (~(1 << (adapter->ahw->pci_func * 4)));
+ act = act & active_mask;
+ }
+
if (((state & 0x11111111) == (act & 0x11111111)) ||
((act & 0x11111111) == ((state >> 1) & 0x11111111)))
return 0;
@@ -2826,6 +2833,11 @@ qlcnic_fwinit_work(struct work_struct *work)
if (!qlcnic_check_drv_state(adapter)) {
skip_ack_check:
+ if (!(adapter->flags & QLCNIC_FW_RESET_OWNER)) {
+ qlcnic_api_unlock(adapter);
+ goto wait_npar;
+ }
+
dev_state = QLCRD32(adapter, QLCNIC_CRB_DEV_STATE);
if (dev_state == QLCNIC_DEV_NEED_RESET) {
@@ -2836,6 +2848,7 @@ skip_ack_check:
qlcnic_idc_debug_info(adapter, 0);
QLCDB(adapter, DRV, "Take FW dump\n");
qlcnic_dump_fw(adapter);
+ adapter->flags &= ~QLCNIC_FW_RESET_OWNER;
}
qlcnic_api_unlock(adapter);
@@ -2900,9 +2913,11 @@ qlcnic_detach_work(struct work_struct *work)
if (adapter->temp == QLCNIC_TEMP_PANIC)
goto err_ret;
-
- if (qlcnic_set_drv_state(adapter, adapter->dev_state))
- goto err_ret;
+ /* Dont ack if this instance is the reset owner */
+ if (!(adapter->flags & QLCNIC_FW_RESET_OWNER)) {
+ if (qlcnic_set_drv_state(adapter, adapter->dev_state))
+ goto err_ret;
+ }
adapter->fw_wait_cnt = 0;
@@ -2947,6 +2962,7 @@ qlcnic_dev_request_reset(struct qlcnic_adapter *adapter)
if (state == QLCNIC_DEV_READY) {
QLCWR32(adapter, QLCNIC_CRB_DEV_STATE, QLCNIC_DEV_NEED_RESET);
+ adapter->flags |= QLCNIC_FW_RESET_OWNER;
QLCDB(adapter, DRV, "NEED_RESET state set\n");
qlcnic_idc_debug_info(adapter, 0);
}
--
1.7.4.1
^ permalink raw reply related
* [PATCH net-next 2/7] qlcnic: Remove holding api lock while taking the dump
From: Anirban Chakraborty @ 2011-06-16 20:37 UTC (permalink / raw)
To: netdev; +Cc: David Miller, Anirban Chakraborty
In-Reply-To: <1308256659-19895-1-git-send-email-anirban.chakraborty@qlogic.com>
With the change in logic for taking FW dump across multiple drivers,
there is no need to hold onto the api lock anymore in the fw dump path.
Instead use rtnl_lock() to synchronize the access to FW dump data structs.
Signed-off-by: Anirban Chakraborty <anirban.chakraborty@qlogic.com>
---
drivers/net/qlcnic/qlcnic_ethtool.c | 6 ------
drivers/net/qlcnic/qlcnic_main.c | 10 +++++++---
2 files changed, 7 insertions(+), 9 deletions(-)
diff --git a/drivers/net/qlcnic/qlcnic_ethtool.c b/drivers/net/qlcnic/qlcnic_ethtool.c
index 9efc690..3e79c20 100644
--- a/drivers/net/qlcnic/qlcnic_ethtool.c
+++ b/drivers/net/qlcnic/qlcnic_ethtool.c
@@ -986,8 +986,6 @@ qlcnic_get_dump_data(struct net_device *netdev, struct ethtool_dump *dump,
struct qlcnic_adapter *adapter = netdev_priv(netdev);
struct qlcnic_fw_dump *fw_dump = &adapter->ahw->fw_dump;
- if (qlcnic_api_lock(adapter))
- return -EIO;
if (!fw_dump->clr) {
netdev_info(netdev, "Dump not available\n");
qlcnic_api_unlock(adapter);
@@ -1009,7 +1007,6 @@ qlcnic_get_dump_data(struct net_device *netdev, struct ethtool_dump *dump,
vfree(fw_dump->data);
fw_dump->data = NULL;
fw_dump->clr = 0;
- qlcnic_api_unlock(adapter);
return 0;
}
@@ -1032,10 +1029,7 @@ qlcnic_set_dump(struct net_device *netdev, struct ethtool_dump *val)
ret = -EINVAL;
goto out;
}
- if (qlcnic_api_lock(adapter))
- return -EIO;
fw_dump->tmpl_hdr->drv_cap_mask = val->flag & 0xff;
- qlcnic_api_unlock(adapter);
netdev_info(netdev, "Driver mask changed to: 0x%x\n",
fw_dump->tmpl_hdr->drv_cap_mask);
}
diff --git a/drivers/net/qlcnic/qlcnic_main.c b/drivers/net/qlcnic/qlcnic_main.c
index cd8e5c1..aa94e86 100644
--- a/drivers/net/qlcnic/qlcnic_main.c
+++ b/drivers/net/qlcnic/qlcnic_main.c
@@ -2846,13 +2846,17 @@ skip_ack_check:
set_bit(__QLCNIC_START_FW, &adapter->state);
QLCDB(adapter, DRV, "Restarting fw\n");
qlcnic_idc_debug_info(adapter, 0);
- QLCDB(adapter, DRV, "Take FW dump\n");
- qlcnic_dump_fw(adapter);
- adapter->flags &= ~QLCNIC_FW_RESET_OWNER;
}
qlcnic_api_unlock(adapter);
+ rtnl_lock();
+ if (adapter->ahw->fw_dump.enable) {
+ QLCDB(adapter, DRV, "Take FW dump\n");
+ qlcnic_dump_fw(adapter);
+ adapter->flags &= ~QLCNIC_FW_RESET_OWNER;
+ }
+ rtnl_unlock();
if (!adapter->nic_ops->start_firmware(adapter)) {
qlcnic_schedule_work(adapter, qlcnic_attach_work, 0);
adapter->fw_wait_cnt = 0;
--
1.7.4.1
^ permalink raw reply related
* [PATCH net-next 7/7] qlcnic: multi protocol internal loopback support added.
From: Anirban Chakraborty @ 2011-06-16 20:37 UTC (permalink / raw)
To: netdev; +Cc: David Miller, Sucheta Chakraborty
In-Reply-To: <1308256659-19895-1-git-send-email-anirban.chakraborty@qlogic.com>
From: Sucheta Chakraborty <sucheta.chakraborty@qlogic.com>
Driver will generate loopback traffic pattern and do the test. And
returns result of the test to application.
Updated driver version to 5.0.19.
Signed-off-by: Sucheta Chakraborty <sucheta.chakraborty@qlogic.com>
Signed-off-by: Anirban Chakraborty <anirban.chakraborty@qlogic.com>
---
drivers/net/qlcnic/qlcnic.h | 22 ++++++-
drivers/net/qlcnic/qlcnic_ethtool.c | 123 +++++++++++++++++++++++++++++++++-
drivers/net/qlcnic/qlcnic_hw.c | 50 ++++++++++++++
drivers/net/qlcnic/qlcnic_init.c | 126 ++++++++++++++++++++++++++++++++++-
drivers/net/qlcnic/qlcnic_main.c | 6 ++
5 files changed, 322 insertions(+), 5 deletions(-)
diff --git a/drivers/net/qlcnic/qlcnic.h b/drivers/net/qlcnic/qlcnic.h
index 0be84bd..e545450 100644
--- a/drivers/net/qlcnic/qlcnic.h
+++ b/drivers/net/qlcnic/qlcnic.h
@@ -36,8 +36,8 @@
#define _QLCNIC_LINUX_MAJOR 5
#define _QLCNIC_LINUX_MINOR 0
-#define _QLCNIC_LINUX_SUBVERSION 18
-#define QLCNIC_LINUX_VERSIONID "5.0.18"
+#define _QLCNIC_LINUX_SUBVERSION 19
+#define QLCNIC_LINUX_VERSIONID "5.0.19"
#define QLCNIC_DRV_IDC_VER 0x01
#define QLCNIC_DRIVER_VERSION ((_QLCNIC_LINUX_MAJOR << 16) |\
(_QLCNIC_LINUX_MINOR << 8) | (_QLCNIC_LINUX_SUBVERSION))
@@ -451,6 +451,7 @@ struct qlcnic_hardware_context {
u8 revision_id;
u8 pci_func;
u8 linkup;
+ u8 loopback_state;
u16 port_type;
u16 board_type;
@@ -780,6 +781,13 @@ struct qlcnic_mac_list_s {
#define QLCNIC_IP_UP 2
#define QLCNIC_IP_DOWN 3
+#define QLCNIC_ILB_MODE 0x1
+
+#define QLCNIC_LINKEVENT 0x1
+#define QLCNIC_LB_RESPONSE 0x2
+#define QLCNIC_IS_LB_CONFIGURED(VAL) \
+ (VAL == (QLCNIC_LINKEVENT | QLCNIC_LB_RESPONSE))
+
/*
* Driver --> Firmware
*/
@@ -789,13 +797,17 @@ struct qlcnic_mac_list_s {
#define QLCNIC_H2C_OPCODE_LRO_REQUEST 0x7
#define QLCNIC_H2C_OPCODE_SET_MAC_RECEIVE_MODE 0xc
#define QLCNIC_H2C_OPCODE_CONFIG_IPADDR 0x12
+
#define QLCNIC_H2C_OPCODE_GET_LINKEVENT 0x15
#define QLCNIC_H2C_OPCODE_CONFIG_BRIDGING 0x17
#define QLCNIC_H2C_OPCODE_CONFIG_HW_LRO 0x18
+#define QLCNIC_H2C_OPCODE_CONFIG_LOOPBACK 0x13
+
/*
* Firmware --> Driver
*/
+#define QLCNIC_C2H_OPCODE_CONFIG_LOOPBACK 0x8f
#define QLCNIC_C2H_OPCODE_GET_LINKEVENT_RESPONSE 141
#define VPORT_MISS_MODE_DROP 0 /* drop all unmatched */
@@ -1430,6 +1442,12 @@ int qlcnic_send_lro_cleanup(struct qlcnic_adapter *adapter);
void qlcnic_update_cmd_producer(struct qlcnic_adapter *adapter,
struct qlcnic_host_tx_ring *tx_ring);
void qlcnic_fetch_mac(struct qlcnic_adapter *, u32, u32, u8, u8 *);
+void qlcnic_process_rcv_ring_diag(struct qlcnic_host_sds_ring *sds_ring);
+void qlcnic_clear_lb_mode(struct qlcnic_adapter *adapter);
+int qlcnic_set_lb_mode(struct qlcnic_adapter *adapter, u8 mode);
+
+/* Functions from qlcnic_ethtool.c */
+int qlcnic_check_loopback_buff(unsigned char *data, u8 mac[]);
/* Functions from qlcnic_main.c */
int qlcnic_reset_context(struct qlcnic_adapter *);
diff --git a/drivers/net/qlcnic/qlcnic_ethtool.c b/drivers/net/qlcnic/qlcnic_ethtool.c
index a7f16a6..c2128a4 100644
--- a/drivers/net/qlcnic/qlcnic_ethtool.c
+++ b/drivers/net/qlcnic/qlcnic_ethtool.c
@@ -84,7 +84,8 @@ static const char qlcnic_device_gstrings_stats[][ETH_GSTRING_LEN] = {
static const char qlcnic_gstrings_test[][ETH_GSTRING_LEN] = {
"Register_Test_on_offline",
"Link_Test_on_offline",
- "Interrupt_Test_offline"
+ "Interrupt_Test_offline",
+ "Loopback_Test_offline"
};
#define QLCNIC_TEST_LEN ARRAY_SIZE(qlcnic_gstrings_test)
@@ -685,6 +686,123 @@ clear_it:
return ret;
}
+#define QLCNIC_ILB_PKT_SIZE 64
+#define QLCNIC_NUM_ILB_PKT 16
+#define QLCNIC_ILB_MAX_RCV_LOOP 10
+
+static void qlcnic_create_loopback_buff(unsigned char *data, u8 mac[])
+{
+ unsigned char random_data[] = {0xa8, 0x06, 0x45, 0x00};
+
+ memset(data, 0x4e, QLCNIC_ILB_PKT_SIZE);
+
+ memcpy(data, mac, ETH_ALEN);
+ memcpy(data + ETH_ALEN, mac, ETH_ALEN);
+
+ memcpy(data + 2 * ETH_ALEN, random_data, sizeof(random_data));
+}
+
+int qlcnic_check_loopback_buff(unsigned char *data, u8 mac[])
+{
+ unsigned char buff[QLCNIC_ILB_PKT_SIZE];
+ qlcnic_create_loopback_buff(buff, mac);
+ return memcmp(data, buff, QLCNIC_ILB_PKT_SIZE);
+}
+
+static int qlcnic_do_ilb_test(struct qlcnic_adapter *adapter)
+{
+ struct qlcnic_recv_context *recv_ctx = adapter->recv_ctx;
+ struct qlcnic_host_sds_ring *sds_ring = &recv_ctx->sds_rings[0];
+ struct sk_buff *skb;
+ int i, loop, cnt = 0;
+
+ for (i = 0; i < QLCNIC_NUM_ILB_PKT; i++) {
+ skb = dev_alloc_skb(QLCNIC_ILB_PKT_SIZE);
+ qlcnic_create_loopback_buff(skb->data, adapter->mac_addr);
+ skb_put(skb, QLCNIC_ILB_PKT_SIZE);
+
+ adapter->diag_cnt = 0;
+ qlcnic_xmit_frame(skb, adapter->netdev);
+
+ loop = 0;
+ do {
+ msleep(1);
+ qlcnic_process_rcv_ring_diag(sds_ring);
+ if (loop++ > QLCNIC_ILB_MAX_RCV_LOOP)
+ break;
+ } while (!adapter->diag_cnt);
+
+ dev_kfree_skb_any(skb);
+
+ if (!adapter->diag_cnt)
+ dev_warn(&adapter->pdev->dev, "ILB Test: %dth packet"
+ " not recevied\n", i + 1);
+ else
+ cnt++;
+ }
+ if (cnt != i) {
+ dev_warn(&adapter->pdev->dev, "ILB Test failed\n");
+ return -1;
+ }
+ return 0;
+}
+
+static int qlcnic_iloopback_test(struct net_device *netdev)
+{
+ struct qlcnic_adapter *adapter = netdev_priv(netdev);
+ int max_sds_rings = adapter->max_sds_rings;
+ struct qlcnic_host_sds_ring *sds_ring;
+ int loop = 0;
+ int ret;
+
+ netdev_info(netdev, "%s: in progress\n", __func__);
+ if (adapter->op_mode == QLCNIC_NON_PRIV_FUNC) {
+ netdev_warn(netdev, "Loopback test not supported for non "
+ "privilege function\n");
+ return 0;
+ }
+
+ if (test_and_set_bit(__QLCNIC_RESETTING, &adapter->state))
+ return -EIO;
+
+
+ ret = qlcnic_diag_alloc_res(netdev, QLCNIC_LOOPBACK_TEST);
+ if (ret)
+ goto clear_it;
+
+ sds_ring = &adapter->recv_ctx->sds_rings[0];
+
+ ret = qlcnic_set_lb_mode(adapter, QLCNIC_ILB_MODE);
+ if (ret)
+ goto free_res;
+
+ do {
+ msleep(500);
+ qlcnic_process_rcv_ring_diag(sds_ring);
+ if (loop++ > QLCNIC_ILB_MAX_RCV_LOOP)
+ break;
+ } while (!QLCNIC_IS_LB_CONFIGURED(adapter->ahw->loopback_state));
+
+ if (!QLCNIC_IS_LB_CONFIGURED(adapter->ahw->loopback_state)) {
+ netdev_info(netdev, "firmware didnt respond to loopback "
+ "configure request\n");
+ ret = adapter->ahw->loopback_state;
+ goto free_res;
+ }
+
+ ret = qlcnic_do_ilb_test(adapter);
+
+ qlcnic_clear_lb_mode(adapter);
+
+ free_res:
+ qlcnic_diag_free_res(netdev, max_sds_rings);
+
+ clear_it:
+ adapter->max_sds_rings = max_sds_rings;
+ clear_bit(__QLCNIC_RESETTING, &adapter->state);
+ return ret;
+}
+
static void
qlcnic_diag_test(struct net_device *dev, struct ethtool_test *eth_test,
u64 *data)
@@ -704,6 +822,9 @@ qlcnic_diag_test(struct net_device *dev, struct ethtool_test *eth_test,
if (data[2])
eth_test->flags |= ETH_TEST_FL_FAILED;
+ data[3] = qlcnic_iloopback_test(dev);
+ if (data[3])
+ eth_test->flags |= ETH_TEST_FL_FAILED;
}
}
diff --git a/drivers/net/qlcnic/qlcnic_hw.c b/drivers/net/qlcnic/qlcnic_hw.c
index a4bcb87..5939c22 100644
--- a/drivers/net/qlcnic/qlcnic_hw.c
+++ b/drivers/net/qlcnic/qlcnic_hw.c
@@ -533,6 +533,56 @@ void qlcnic_delete_lb_filters(struct qlcnic_adapter *adapter)
}
}
+int qlcnic_set_fw_loopback(struct qlcnic_adapter *adapter, u8 flag)
+{
+ struct qlcnic_nic_req req;
+ int rv;
+
+ memset(&req, 0, sizeof(struct qlcnic_nic_req));
+
+ req.qhdr = cpu_to_le64(QLCNIC_HOST_REQUEST << 23);
+ req.req_hdr = cpu_to_le64(QLCNIC_H2C_OPCODE_CONFIG_LOOPBACK |
+ ((u64) adapter->portnum << 16) | ((u64) 0x1 << 32));
+
+ req.words[0] = cpu_to_le64(flag);
+
+ rv = qlcnic_send_cmd_descs(adapter, (struct cmd_desc_type0 *)&req, 1);
+ if (rv != 0)
+ dev_err(&adapter->pdev->dev, "%sting loopback mode failed\n",
+ flag ? "Set" : "Reset");
+ return rv;
+}
+
+int qlcnic_set_lb_mode(struct qlcnic_adapter *adapter, u8 mode)
+{
+ if (qlcnic_set_fw_loopback(adapter, mode))
+ return -EIO;
+
+ if (qlcnic_nic_set_promisc(adapter, VPORT_MISS_MODE_ACCEPT_ALL)) {
+ qlcnic_set_fw_loopback(adapter, mode);
+ return -EIO;
+ }
+
+ msleep(1000);
+ return 0;
+}
+
+void qlcnic_clear_lb_mode(struct qlcnic_adapter *adapter)
+{
+ int mode = VPORT_MISS_MODE_DROP;
+ struct net_device *netdev = adapter->netdev;
+
+ qlcnic_set_fw_loopback(adapter, 0);
+
+ if (netdev->flags & IFF_PROMISC)
+ mode = VPORT_MISS_MODE_ACCEPT_ALL;
+ else if (netdev->flags & IFF_ALLMULTI)
+ mode = VPORT_MISS_MODE_ACCEPT_MULTI;
+
+ qlcnic_nic_set_promisc(adapter, mode);
+ msleep(1000);
+}
+
/*
* Send the interrupt coalescing parameter set by ethtool to the card.
*/
diff --git a/drivers/net/qlcnic/qlcnic_init.c b/drivers/net/qlcnic/qlcnic_init.c
index 5b8bbcf..9d5bee0 100644
--- a/drivers/net/qlcnic/qlcnic_init.c
+++ b/drivers/net/qlcnic/qlcnic_init.c
@@ -1281,6 +1281,7 @@ qlcnic_handle_linkevent(struct qlcnic_adapter *adapter,
u16 cable_len;
u16 link_speed;
u8 link_status, module, duplex, autoneg;
+ u8 lb_status = 0;
struct net_device *netdev = adapter->netdev;
adapter->has_link_events = 1;
@@ -1292,6 +1293,7 @@ qlcnic_handle_linkevent(struct qlcnic_adapter *adapter,
link_status = msg->body[2] & 0xff;
duplex = (msg->body[2] >> 16) & 0xff;
autoneg = (msg->body[2] >> 24) & 0xff;
+ lb_status = (msg->body[2] >> 32) & 0x3;
module = (msg->body[2] >> 8) & 0xff;
if (module == LINKEVENT_MODULE_TWINAX_UNSUPPORTED_CABLE)
@@ -1301,6 +1303,9 @@ qlcnic_handle_linkevent(struct qlcnic_adapter *adapter,
dev_info(&netdev->dev, "unsupported cable length %d\n",
cable_len);
+ if (!link_status && (lb_status == 1))
+ adapter->ahw->loopback_state |= QLCNIC_LINKEVENT;
+
qlcnic_advert_link_change(adapter, link_status);
if (duplex == LINKEVENT_FULL_DUPLEX)
@@ -1319,7 +1324,9 @@ qlcnic_handle_fw_message(int desc_cnt, int index,
{
struct qlcnic_fw_msg msg;
struct status_desc *desc;
- int i = 0, opcode;
+ struct qlcnic_adapter *adapter;
+ struct device *dev;
+ int i = 0, opcode, ret;
while (desc_cnt > 0 && i < 8) {
desc = &sds_ring->desc_head[index];
@@ -1330,10 +1337,28 @@ qlcnic_handle_fw_message(int desc_cnt, int index,
desc_cnt--;
}
+ adapter = sds_ring->adapter;
+ dev = &adapter->pdev->dev;
opcode = qlcnic_get_nic_msg_opcode(msg.body[0]);
+
switch (opcode) {
case QLCNIC_C2H_OPCODE_GET_LINKEVENT_RESPONSE:
- qlcnic_handle_linkevent(sds_ring->adapter, &msg);
+ qlcnic_handle_linkevent(adapter, &msg);
+ break;
+ case QLCNIC_C2H_OPCODE_CONFIG_LOOPBACK:
+ ret = (u32)(msg.body[1]);
+ switch (ret) {
+ case 0:
+ adapter->ahw->loopback_state |= QLCNIC_LB_RESPONSE;
+ break;
+ case 1:
+ dev_info(dev, "loopback already in progress\n");
+ break;
+ default:
+ dev_info(dev, "loopback configure request failed,"
+ " ret %x\n", ret);
+ break;
+ }
break;
default:
break;
@@ -1746,6 +1771,103 @@ qlcnic_post_rx_buffers_nodb(struct qlcnic_adapter *adapter,
spin_unlock(&rds_ring->lock);
}
+static void dump_skb(struct sk_buff *skb)
+{
+ int i;
+ unsigned char *data = skb->data;
+
+ printk(KERN_INFO "\n");
+ for (i = 0; i < skb->len; i++) {
+ printk(KERN_INFO "%02x ", data[i]);
+ if ((i & 0x0f) == 8)
+ printk(KERN_INFO "\n");
+ }
+}
+
+void qlcnic_process_rcv_diag(struct qlcnic_adapter *adapter,
+ struct qlcnic_host_sds_ring *sds_ring,
+ int ring, u64 sts_data0)
+{
+ struct qlcnic_recv_context *recv_ctx = adapter->recv_ctx;
+ struct sk_buff *skb;
+ struct qlcnic_host_rds_ring *rds_ring;
+ int index, length, cksum, pkt_offset;
+
+ if (unlikely(ring >= adapter->max_rds_rings))
+ return;
+
+ rds_ring = &recv_ctx->rds_rings[ring];
+
+ index = qlcnic_get_sts_refhandle(sts_data0);
+ length = qlcnic_get_sts_totallength(sts_data0);
+ if (unlikely(index >= rds_ring->num_desc))
+ return;
+
+ cksum = qlcnic_get_sts_status(sts_data0);
+ pkt_offset = qlcnic_get_sts_pkt_offset(sts_data0);
+
+ skb = qlcnic_process_rxbuf(adapter, rds_ring, index, cksum);
+ if (!skb)
+ return;
+
+ if (length > rds_ring->skb_size)
+ skb_put(skb, rds_ring->skb_size);
+ else
+ skb_put(skb, length);
+
+ if (pkt_offset)
+ skb_pull(skb, pkt_offset);
+
+ if (!qlcnic_check_loopback_buff(skb->data, adapter->mac_addr))
+ adapter->diag_cnt++;
+ else
+ dump_skb(skb);
+
+ dev_kfree_skb_any(skb);
+ adapter->stats.rx_pkts++;
+ adapter->stats.rxbytes += length;
+
+ return;
+}
+
+void
+qlcnic_process_rcv_ring_diag(struct qlcnic_host_sds_ring *sds_ring)
+{
+ struct qlcnic_adapter *adapter = sds_ring->adapter;
+ struct status_desc *desc;
+ u64 sts_data0;
+ int ring, opcode, desc_cnt;
+
+ u32 consumer = sds_ring->consumer;
+
+ desc = &sds_ring->desc_head[consumer];
+ sts_data0 = le64_to_cpu(desc->status_desc_data[0]);
+
+ if (!(sts_data0 & STATUS_OWNER_HOST))
+ return;
+
+ desc_cnt = qlcnic_get_sts_desc_cnt(sts_data0);
+ opcode = qlcnic_get_sts_opcode(sts_data0);
+ switch (opcode) {
+ case QLCNIC_RESPONSE_DESC:
+ qlcnic_handle_fw_message(desc_cnt, consumer, sds_ring);
+ break;
+ default:
+ ring = qlcnic_get_sts_type(sts_data0);
+ qlcnic_process_rcv_diag(adapter, sds_ring, ring, sts_data0);
+ break;
+ }
+
+ for (; desc_cnt > 0; desc_cnt--) {
+ desc = &sds_ring->desc_head[consumer];
+ desc->status_desc_data[0] = cpu_to_le64(STATUS_OWNER_PHANTOM);
+ consumer = get_next_index(consumer, sds_ring->num_desc);
+ }
+
+ sds_ring->consumer = consumer;
+ writel(consumer, sds_ring->crb_sts_consumer);
+}
+
void
qlcnic_fetch_mac(struct qlcnic_adapter *adapter, u32 off1, u32 off2,
u8 alt_mac, u8 *mac)
diff --git a/drivers/net/qlcnic/qlcnic_main.c b/drivers/net/qlcnic/qlcnic_main.c
index 5348dba..26ac5c6 100644
--- a/drivers/net/qlcnic/qlcnic_main.c
+++ b/drivers/net/qlcnic/qlcnic_main.c
@@ -1391,6 +1391,12 @@ int qlcnic_diag_alloc_res(struct net_device *netdev, int test)
qlcnic_enable_int(sds_ring);
}
}
+
+ if (adapter->diag_test == QLCNIC_LOOPBACK_TEST) {
+ adapter->ahw->loopback_state = 0;
+ qlcnic_linkevent_request(adapter, 1);
+ }
+
set_bit(__QLCNIC_DEV_UP, &adapter->state);
return 0;
--
1.7.4.1
^ permalink raw reply related
* [PATCH net-next 3/7] qlcnic: Add code to tune FW dump
From: Anirban Chakraborty @ 2011-06-16 20:37 UTC (permalink / raw)
To: netdev; +Cc: David Miller, Anirban Chakraborty
In-Reply-To: <1308256659-19895-1-git-send-email-anirban.chakraborty@qlogic.com>
To accommodate change in FW dump template, it is required to modify the
FW dump routine that captures cache data. Also, the default mask is changed
to capture a dump that would cover all the protocols that this FW supports.
Signed-off-by: Anirban Chakraborty <anirban.chakraborty@qlogic.com>
---
drivers/net/qlcnic/qlcnic.h | 5 ++---
drivers/net/qlcnic/qlcnic_hw.c | 14 +++++++++++---
2 files changed, 13 insertions(+), 6 deletions(-)
diff --git a/drivers/net/qlcnic/qlcnic.h b/drivers/net/qlcnic/qlcnic.h
index 194376e..e5bb332 100644
--- a/drivers/net/qlcnic/qlcnic.h
+++ b/drivers/net/qlcnic/qlcnic.h
@@ -1220,8 +1220,7 @@ struct __ctrl {
struct __cache {
__le32 addr;
- u8 stride;
- u8 rsvd;
+ __le16 stride;
__le16 init_tag_val;
__le32 size;
__le32 no_ops;
@@ -1319,7 +1318,7 @@ enum op_codes {
#define QLCNIC_DUMP_SKIP BIT_7
#define QLCNIC_DUMP_MASK_MIN 3
-#define QLCNIC_DUMP_MASK_DEF 0x0f
+#define QLCNIC_DUMP_MASK_DEF 0x7f
#define QLCNIC_DUMP_MASK_MAX 0xff
#define QLCNIC_FORCE_FW_DUMP_KEY 0xdeadfeed
diff --git a/drivers/net/qlcnic/qlcnic_hw.c b/drivers/net/qlcnic/qlcnic_hw.c
index a5d9fbf..a4bcb87 100644
--- a/drivers/net/qlcnic/qlcnic_hw.c
+++ b/drivers/net/qlcnic/qlcnic_hw.c
@@ -1509,18 +1509,26 @@ qlcnic_dump_l2_cache(struct qlcnic_adapter *adapter,
for (i = 0; i < l2->no_ops; i++) {
QLCNIC_WR_DUMP_REG(l2->addr, base, val);
- do {
+ if (LSW(l2->ctrl_val))
QLCNIC_WR_DUMP_REG(l2->ctrl_addr, base,
LSW(l2->ctrl_val));
+ if (!poll_mask)
+ goto skip_poll;
+ do {
QLCNIC_RD_DUMP_REG(l2->ctrl_addr, base, &data);
if (!(data & poll_mask))
break;
msleep(1);
time_out++;
} while (time_out <= poll_to);
- if (time_out > poll_to)
- return -EINVAL;
+ if (time_out > poll_to) {
+ dev_err(&adapter->pdev->dev,
+ "Timeout exceeded in %s, aborting dump\n",
+ __func__);
+ return -EINVAL;
+ }
+skip_poll:
addr = l2->read_addr;
cnt = l2->read_addr_num;
while (cnt) {
--
1.7.4.1
^ permalink raw reply related
* [PATCH net-next 0/7] qlcnic: Misc. fixes and loopback support
From: Anirban Chakraborty @ 2011-06-16 20:37 UTC (permalink / raw)
To: netdev; +Cc: David Miller, Anirban Chakraborty
In-Reply-To: <1308256659-19895-1-git-send-email-anirban.chakraborty@qlogic.com>
Please apply the series to net-next. Thanks.
-Anirban
^ permalink raw reply
* [PATCH net-next 6/7] qlcnic: Add support to enable/disable FW dump capability
From: Anirban Chakraborty @ 2011-06-16 20:37 UTC (permalink / raw)
To: netdev; +Cc: David Miller, Anirban Chakraborty
In-Reply-To: <1308256659-19895-1-git-send-email-anirban.chakraborty@qlogic.com>
In certain situations, it may be required to not enable FW dump
capability. Add support to turn off/on FW dump capability.
Signed-off-by: Anirban Chakraborty <anirban.chakraborty@qlogic.com>
---
drivers/net/qlcnic/qlcnic.h | 3 +++
drivers/net/qlcnic/qlcnic_ctx.c | 1 +
drivers/net/qlcnic/qlcnic_ethtool.c | 19 +++++++++++++++++++
3 files changed, 23 insertions(+), 0 deletions(-)
diff --git a/drivers/net/qlcnic/qlcnic.h b/drivers/net/qlcnic/qlcnic.h
index 58d7616..0be84bd 100644
--- a/drivers/net/qlcnic/qlcnic.h
+++ b/drivers/net/qlcnic/qlcnic.h
@@ -429,6 +429,7 @@ struct qlcnic_dump_template_hdr {
struct qlcnic_fw_dump {
u8 clr; /* flag to indicate if dump is cleared */
+ u8 enable; /* enable/disable dump */
u32 size; /* total size of the dump */
void *data; /* dump data area */
struct qlcnic_dump_template_hdr *tmpl_hdr;
@@ -1320,6 +1321,8 @@ enum op_codes {
#define QLCNIC_DUMP_MASK_DEF 0x7f
#define QLCNIC_DUMP_MASK_MAX 0xff
#define QLCNIC_FORCE_FW_DUMP_KEY 0xdeadfeed
+#define QLCNIC_ENABLE_FW_DUMP 0xaddfeed
+#define QLCNIC_DISABLE_FW_DUMP 0xbadfeed
struct qlcnic_dump_operations {
enum op_codes opcode;
diff --git a/drivers/net/qlcnic/qlcnic_ctx.c b/drivers/net/qlcnic/qlcnic_ctx.c
index 0ca514a..b6769c7 100644
--- a/drivers/net/qlcnic/qlcnic_ctx.c
+++ b/drivers/net/qlcnic/qlcnic_ctx.c
@@ -150,6 +150,7 @@ int qlcnic_fw_cmd_get_minidump_temp(struct qlcnic_adapter *adapter)
tmpl_hdr->drv_cap_mask = tmpl_hdr->cap_mask;
else
tmpl_hdr->drv_cap_mask = QLCNIC_DUMP_MASK_DEF;
+ ahw->fw_dump.enable = 1;
error:
dma_free_coherent(&adapter->pdev->dev, temp_size, tmp_addr, tmp_addr_t);
return err;
diff --git a/drivers/net/qlcnic/qlcnic_ethtool.c b/drivers/net/qlcnic/qlcnic_ethtool.c
index 3e79c20..a7f16a6 100644
--- a/drivers/net/qlcnic/qlcnic_ethtool.c
+++ b/drivers/net/qlcnic/qlcnic_ethtool.c
@@ -1019,8 +1019,27 @@ qlcnic_set_dump(struct net_device *netdev, struct ethtool_dump *val)
struct qlcnic_fw_dump *fw_dump = &adapter->ahw->fw_dump;
if (val->flag == QLCNIC_FORCE_FW_DUMP_KEY) {
+ if (!fw_dump->enable) {
+ netdev_info(netdev, "FW dump not enabled\n");
+ return ret;
+ }
+ if (fw_dump->clr) {
+ dev_info(&adapter->pdev->dev,
+ "Previous dump not cleared, not forcing dump\n");
+ return ret;
+ }
netdev_info(netdev, "Forcing a FW dump\n");
qlcnic_dev_request_reset(adapter);
+ } else if (val->flag == QLCNIC_DISABLE_FW_DUMP) {
+ if (fw_dump->enable) {
+ netdev_info(netdev, "Disabling FW dump\n");
+ fw_dump->enable = 0;
+ }
+ } else if (val->flag == QLCNIC_ENABLE_FW_DUMP) {
+ if (!fw_dump->enable && fw_dump->tmpl_hdr) {
+ netdev_info(netdev, "Enabling FW dump\n");
+ fw_dump->enable = 1;
+ }
} else {
if (val->flag > QLCNIC_DUMP_MASK_MAX ||
val->flag < QLCNIC_DUMP_MASK_MIN) {
--
1.7.4.1
^ permalink raw reply related
* [PATCH 001/001] vlan: don't call ndo_vlan_rx_register on hardware that doesn't have vlan support
From: Antoine Reversat @ 2011-06-16 20:47 UTC (permalink / raw)
To: netdev
This patch removes the call to ndo_vlan_rx_register if the underlying
device doesn't have hardware support for VLAN.
Signed-off-by: Antoine Reversat <a.reversat@gmail.com>
---
--- linux-2.6.39/net/8021q/vlan.c 2011-05-19 00:06:34.000000000 -0400
+++ linux-2.6.39-fixed/net/8021q/vlan.c 2011-06-16 16:39:25.933742004 -0400
@@ -211,7 +211,7 @@ int register_vlan_dev(struct net_device
grp->nr_vlans++;
if (ngrp) {
- if (ops->ndo_vlan_rx_register)
+ if (ops->ndo_vlan_rx_register && (real_dev->features & NETIF_F_HW_VLAN_RX))
ops->ndo_vlan_rx_register(real_dev, ngrp);
rcu_assign_pointer(real_dev->vlgrp, ngrp);
}
^ permalink raw reply
* [PATCH net-next] net: remove mm.h inclusion from netdevice.h
From: Alexey Dobriyan @ 2011-06-16 21:01 UTC (permalink / raw)
To: davem; +Cc: netdev, linux-kernel, fujita.tomonori, linux-arch
Remove linux/mm.h inclusion from netdevice.h -- it's unused (I've checked manually).
To prevent mm.h inclusion via other channels also extract "enum dma_data_direction"
definition into separate header. This tiny piece is what gluing netdevice.h with mm.h
via "netdevice.h => dmaengine.h => dma-mapping.h => scatterlist.h => mm.h".
Removal of mm.h from scatterlist.h was tried and was found not feasible
on most archs, so the link was cutoff earlier.
Hope people are OK with tiny include file.
Note, that mm_types.h is still dragged in, but it is a separate story.
Signed-off-by: Alexey Dobriyan <adobriyan@gmail.com>
---
arch/arm/mach-davinci/board-mityomapl138.c | 1 +
arch/arm/mach-davinci/dm646x.c | 1 +
arch/arm/mach-davinci/pm.c | 1 +
arch/arm/mach-imx/dma-v1.c | 1 +
arch/arm/mach-imx/mach-mx31_3ds.c | 1 +
arch/arm/mach-iop13xx/setup.c | 1 +
arch/arm/mach-mxs/devices/platform-auart.c | 1 +
arch/arm/mach-mxs/devices/platform-dma.c | 1 +
arch/arm/mach-mxs/devices/platform-fec.c | 1 +
arch/arm/plat-mxc/devices/platform-fec.c | 1 +
arch/arm/plat-mxc/devices/platform-fsl-usb2-udc.c | 1 +
arch/arm/plat-mxc/devices/platform-imx-fb.c | 1 +
arch/arm/plat-mxc/devices/platform-ipu-core.c | 1 +
arch/arm/plat-mxc/devices/platform-mxc-ehci.c | 1 +
arch/arm/plat-mxc/devices/platform-mxc-mmc.c | 1 +
arch/arm/plat-nomadik/include/plat/ste_dma40.h | 1 +
arch/x86/kernel/tboot.c | 1 +
crypto/async_tx/raid6test.c | 1 +
drivers/dma/coh901318.c | 1 +
drivers/dma/dmaengine.c | 1 +
drivers/dma/dmatest.c | 1 +
drivers/dma/ipu/ipu_idmac.c | 1 +
drivers/dma/ste_dma40.c | 1 +
drivers/media/dvb/mantis/mantis_ca.c | 1 +
drivers/media/dvb/mantis/mantis_evm.c | 1 +
drivers/media/dvb/mantis/mantis_hif.c | 1 +
drivers/media/dvb/mantis/mantis_ioc.c | 1 +
drivers/media/dvb/mantis/mantis_pcmcia.c | 1 +
drivers/media/dvb/mantis/mantis_uart.c | 1 +
drivers/media/dvb/mantis/mantis_vp1034.c | 1 +
drivers/mmc/host/tmio_mmc_dma.c | 1 +
drivers/mtd/nand/atmel_nand.c | 1 +
drivers/net/arm/ks8695net.c | 1 +
drivers/net/can/janz-ican3.c | 1 +
drivers/net/can/softing/softing_fw.c | 1 +
drivers/net/can/softing/softing_main.c | 1 +
drivers/net/ethoc.c | 1 +
drivers/net/fec_mpc52xx.c | 1 +
drivers/net/greth.c | 1 +
drivers/net/irda/pxaficp_ir.c | 1 +
drivers/net/ks8851_mll.c | 1 +
drivers/net/sgiseeq.c | 1 +
drivers/net/stmmac/dwmac1000_core.c | 1 +
drivers/net/stmmac/dwmac1000_dma.c | 1 +
drivers/net/stmmac/dwmac100_core.c | 1 +
drivers/net/stmmac/dwmac100_dma.c | 1 +
drivers/net/stmmac/stmmac_ethtool.c | 1 +
drivers/net/stmmac/stmmac_mdio.c | 1 +
drivers/net/usb/cdc-phonet.c | 1 +
drivers/net/vxge/vxge-config.h | 1 +
drivers/net/wireless/ath/ath5k/base.c | 1 +
drivers/net/wireless/ath/ath9k/beacon.c | 1 +
drivers/net/wireless/ath/ath9k/init.c | 1 +
drivers/net/wireless/ath/ath9k/recv.c | 1 +
drivers/net/wireless/ath/ath9k/xmit.c | 1 +
drivers/tty/serial/ifx6x60.c | 1 +
drivers/usb/gadget/f_phonet.c | 1 +
include/crypto/if_alg.h | 1 +
include/linux/dma-direction.h | 13 +++++++++++++
include/linux/dma-mapping.h | 10 +---------
include/linux/dmaengine.h | 4 +++-
include/linux/netdevice.h | 1 -
net/sched/sch_netem.c | 1 +
security/apparmor/lib.c | 1 +
64 files changed, 77 insertions(+), 11 deletions(-)
--- a/arch/arm/mach-davinci/board-mityomapl138.c
+++ b/arch/arm/mach-davinci/board-mityomapl138.c
@@ -20,6 +20,7 @@
#include <linux/spi/spi.h>
#include <linux/spi/flash.h>
+#include <asm/io.h>
#include <asm/mach-types.h>
#include <asm/mach/arch.h>
#include <mach/common.h>
--- a/arch/arm/mach-davinci/dm646x.c
+++ b/arch/arm/mach-davinci/dm646x.c
@@ -8,6 +8,7 @@
* is licensed "as is" without any warranty of any kind, whether express
* or implied.
*/
+#include <linux/dma-mapping.h>
#include <linux/init.h>
#include <linux/clk.h>
#include <linux/serial_8250.h>
--- a/arch/arm/mach-davinci/pm.c
+++ b/arch/arm/mach-davinci/pm.c
@@ -17,6 +17,7 @@
#include <asm/cacheflush.h>
#include <asm/delay.h>
+#include <asm/io.h>
#include <mach/da8xx.h>
#include <mach/sram.h>
--- a/arch/arm/mach-imx/dma-v1.c
+++ b/arch/arm/mach-imx/dma-v1.c
@@ -26,6 +26,7 @@
#include <linux/init.h>
#include <linux/kernel.h>
#include <linux/interrupt.h>
+#include <linux/err.h>
#include <linux/errno.h>
#include <linux/clk.h>
#include <linux/scatterlist.h>
--- a/arch/arm/mach-imx/mach-mx31_3ds.c
+++ b/arch/arm/mach-imx/mach-mx31_3ds.c
@@ -13,6 +13,7 @@
*/
#include <linux/delay.h>
+#include <linux/dma-mapping.h>
#include <linux/types.h>
#include <linux/init.h>
#include <linux/clk.h>
--- a/arch/arm/mach-iop13xx/setup.c
+++ b/arch/arm/mach-iop13xx/setup.c
@@ -17,6 +17,7 @@
*
*/
+#include <linux/dma-mapping.h>
#include <linux/serial_8250.h>
#include <linux/io.h>
#ifdef CONFIG_MTD_PHYSMAP
--- a/arch/arm/mach-mxs/devices/platform-auart.c
+++ b/arch/arm/mach-mxs/devices/platform-auart.c
@@ -6,6 +6,7 @@
* the terms of the GNU General Public License version 2 as published by the
* Free Software Foundation.
*/
+#include <linux/dma-mapping.h>
#include <asm/sizes.h>
#include <mach/mx23.h>
#include <mach/mx28.h>
--- a/arch/arm/mach-mxs/devices/platform-dma.c
+++ b/arch/arm/mach-mxs/devices/platform-dma.c
@@ -6,6 +6,7 @@
* Free Software Foundation.
*/
#include <linux/compiler.h>
+#include <linux/dma-mapping.h>
#include <linux/err.h>
#include <linux/init.h>
--- a/arch/arm/mach-mxs/devices/platform-fec.c
+++ b/arch/arm/mach-mxs/devices/platform-fec.c
@@ -6,6 +6,7 @@
* the terms of the GNU General Public License version 2 as published by the
* Free Software Foundation.
*/
+#include <linux/dma-mapping.h>
#include <asm/sizes.h>
#include <mach/mx28.h>
#include <mach/devices-common.h>
--- a/arch/arm/plat-mxc/devices/platform-fec.c
+++ b/arch/arm/plat-mxc/devices/platform-fec.c
@@ -6,6 +6,7 @@
* the terms of the GNU General Public License version 2 as published by the
* Free Software Foundation.
*/
+#include <linux/dma-mapping.h>
#include <asm/sizes.h>
#include <mach/hardware.h>
#include <mach/devices-common.h>
--- a/arch/arm/plat-mxc/devices/platform-fsl-usb2-udc.c
+++ b/arch/arm/plat-mxc/devices/platform-fsl-usb2-udc.c
@@ -6,6 +6,7 @@
* the terms of the GNU General Public License version 2 as published by the
* Free Software Foundation.
*/
+#include <linux/dma-mapping.h>
#include <mach/hardware.h>
#include <mach/devices-common.h>
--- a/arch/arm/plat-mxc/devices/platform-imx-fb.c
+++ b/arch/arm/plat-mxc/devices/platform-imx-fb.c
@@ -6,6 +6,7 @@
* the terms of the GNU General Public License version 2 as published by the
* Free Software Foundation.
*/
+#include <linux/dma-mapping.h>
#include <mach/hardware.h>
#include <mach/devices-common.h>
--- a/arch/arm/plat-mxc/devices/platform-ipu-core.c
+++ b/arch/arm/plat-mxc/devices/platform-ipu-core.c
@@ -6,6 +6,7 @@
* the terms of the GNU General Public License version 2 as published by the
* Free Software Foundation.
*/
+#include <linux/dma-mapping.h>
#include <mach/hardware.h>
#include <mach/devices-common.h>
--- a/arch/arm/plat-mxc/devices/platform-mxc-ehci.c
+++ b/arch/arm/plat-mxc/devices/platform-mxc-ehci.c
@@ -6,6 +6,7 @@
* the terms of the GNU General Public License version 2 as published by the
* Free Software Foundation.
*/
+#include <linux/dma-mapping.h>
#include <mach/hardware.h>
#include <mach/devices-common.h>
--- a/arch/arm/plat-mxc/devices/platform-mxc-mmc.c
+++ b/arch/arm/plat-mxc/devices/platform-mxc-mmc.c
@@ -6,6 +6,7 @@
* the terms of the GNU General Public License version 2 as published by the
* Free Software Foundation.
*/
+#include <linux/dma-mapping.h>
#include <mach/hardware.h>
#include <mach/devices-common.h>
--- a/arch/arm/plat-nomadik/include/plat/ste_dma40.h
+++ b/arch/arm/plat-nomadik/include/plat/ste_dma40.h
@@ -10,6 +10,7 @@
#define STE_DMA40_H
#include <linux/dmaengine.h>
+#include <linux/scatterlist.h>
#include <linux/workqueue.h>
#include <linux/interrupt.h>
--- a/arch/x86/kernel/tboot.c
+++ b/arch/x86/kernel/tboot.c
@@ -36,6 +36,7 @@
#include <asm/bootparam.h>
#include <asm/pgtable.h>
#include <asm/pgalloc.h>
+#include <asm/swiotlb.h>
#include <asm/fixmap.h>
#include <asm/proto.h>
#include <asm/setup.h>
--- a/crypto/async_tx/raid6test.c
+++ b/crypto/async_tx/raid6test.c
@@ -21,6 +21,7 @@
*/
#include <linux/async_tx.h>
#include <linux/gfp.h>
+#include <linux/mm.h>
#include <linux/random.h>
#undef pr
--- a/drivers/dma/coh901318.c
+++ b/drivers/dma/coh901318.c
@@ -11,6 +11,7 @@
#include <linux/module.h>
#include <linux/kernel.h> /* printk() */
#include <linux/fs.h> /* everything... */
+#include <linux/scatterlist.h>
#include <linux/slab.h> /* kmalloc() */
#include <linux/dmaengine.h>
#include <linux/platform_device.h>
--- a/drivers/dma/dmaengine.c
+++ b/drivers/dma/dmaengine.c
@@ -45,6 +45,7 @@
* See Documentation/dmaengine.txt for more details
*/
+#include <linux/dma-mapping.h>
#include <linux/init.h>
#include <linux/module.h>
#include <linux/mm.h>
--- a/drivers/dma/dmatest.c
+++ b/drivers/dma/dmatest.c
@@ -8,6 +8,7 @@
* published by the Free Software Foundation.
*/
#include <linux/delay.h>
+#include <linux/dma-mapping.h>
#include <linux/dmaengine.h>
#include <linux/init.h>
#include <linux/kthread.h>
--- a/drivers/dma/ipu/ipu_idmac.c
+++ b/drivers/dma/ipu/ipu_idmac.c
@@ -9,6 +9,7 @@
* published by the Free Software Foundation.
*/
+#include <linux/dma-mapping.h>
#include <linux/init.h>
#include <linux/platform_device.h>
#include <linux/err.h>
--- a/drivers/dma/ste_dma40.c
+++ b/drivers/dma/ste_dma40.c
@@ -6,6 +6,7 @@
* License terms: GNU General Public License (GPL) version 2
*/
+#include <linux/dma-mapping.h>
#include <linux/kernel.h>
#include <linux/slab.h>
#include <linux/dmaengine.h>
--- a/drivers/media/dvb/mantis/mantis_ca.c
+++ b/drivers/media/dvb/mantis/mantis_ca.c
@@ -22,6 +22,7 @@
#include <linux/slab.h>
#include <linux/sched.h>
#include <linux/interrupt.h>
+#include <asm/io.h>
#include "dmxdev.h"
#include "dvbdev.h"
--- a/drivers/media/dvb/mantis/mantis_evm.c
+++ b/drivers/media/dvb/mantis/mantis_evm.c
@@ -23,6 +23,7 @@
#include <linux/signal.h>
#include <linux/sched.h>
#include <linux/interrupt.h>
+#include <asm/io.h>
#include "dmxdev.h"
#include "dvbdev.h"
--- a/drivers/media/dvb/mantis/mantis_hif.c
+++ b/drivers/media/dvb/mantis/mantis_hif.c
@@ -23,6 +23,7 @@
#include <linux/sched.h>
#include <linux/interrupt.h>
+#include <asm/io.h>
#include "dmxdev.h"
#include "dvbdev.h"
--- a/drivers/media/dvb/mantis/mantis_ioc.c
+++ b/drivers/media/dvb/mantis/mantis_ioc.c
@@ -24,6 +24,7 @@
#include <linux/signal.h>
#include <linux/sched.h>
#include <linux/interrupt.h>
+#include <asm/io.h>
#include "dmxdev.h"
#include "dvbdev.h"
--- a/drivers/media/dvb/mantis/mantis_pcmcia.c
+++ b/drivers/media/dvb/mantis/mantis_pcmcia.c
@@ -23,6 +23,7 @@
#include <linux/signal.h>
#include <linux/sched.h>
#include <linux/interrupt.h>
+#include <asm/io.h>
#include "dmxdev.h"
#include "dvbdev.h"
--- a/drivers/media/dvb/mantis/mantis_uart.c
+++ b/drivers/media/dvb/mantis/mantis_uart.c
@@ -20,6 +20,7 @@
#include <linux/kernel.h>
#include <linux/spinlock.h>
+#include <asm/io.h>
#include <linux/signal.h>
#include <linux/sched.h>
--- a/drivers/media/dvb/mantis/mantis_vp1034.c
+++ b/drivers/media/dvb/mantis/mantis_vp1034.c
@@ -21,6 +21,7 @@
#include <linux/signal.h>
#include <linux/sched.h>
#include <linux/interrupt.h>
+#include <asm/io.h>
#include "dmxdev.h"
#include "dvbdev.h"
--- a/drivers/mmc/host/tmio_mmc_dma.c
+++ b/drivers/mmc/host/tmio_mmc_dma.c
@@ -11,6 +11,7 @@
*/
#include <linux/device.h>
+#include <linux/dma-mapping.h>
#include <linux/dmaengine.h>
#include <linux/mfd/tmio.h>
#include <linux/mmc/host.h>
--- a/drivers/mtd/nand/atmel_nand.c
+++ b/drivers/mtd/nand/atmel_nand.c
@@ -22,6 +22,7 @@
*
*/
+#include <linux/dma-mapping.h>
#include <linux/slab.h>
#include <linux/module.h>
#include <linux/moduleparam.h>
--- a/drivers/net/arm/ks8695net.c
+++ b/drivers/net/arm/ks8695net.c
@@ -16,6 +16,7 @@
* Vincent Sanders <vince@simtec.co.uk>
*/
+#include <linux/dma-mapping.h>
#include <linux/module.h>
#include <linux/ioport.h>
#include <linux/netdevice.h>
--- a/drivers/net/can/janz-ican3.c
+++ b/drivers/net/can/janz-ican3.c
@@ -22,6 +22,7 @@
#include <linux/can/error.h>
#include <linux/mfd/janz.h>
+#include <asm/io.h>
/* the DPM has 64k of memory, organized into 256x 256 byte pages */
#define DPM_NUM_PAGES 256
--- a/drivers/net/can/softing/softing_fw.c
+++ b/drivers/net/can/softing/softing_fw.c
@@ -20,6 +20,7 @@
#include <linux/firmware.h>
#include <linux/sched.h>
#include <asm/div64.h>
+#include <asm/io.h>
#include "softing.h"
--- a/drivers/net/can/softing/softing_main.c
+++ b/drivers/net/can/softing/softing_main.c
@@ -21,6 +21,7 @@
#include <linux/module.h>
#include <linux/init.h>
#include <linux/interrupt.h>
+#include <asm/io.h>
#include "softing.h"
--- a/drivers/net/ethoc.c
+++ b/drivers/net/ethoc.c
@@ -11,6 +11,7 @@
* Written by Thierry Reding <thierry.reding@avionic-design.de>
*/
+#include <linux/dma-mapping.h>
#include <linux/etherdevice.h>
#include <linux/crc32.h>
#include <linux/interrupt.h>
--- a/drivers/net/fec_mpc52xx.c
+++ b/drivers/net/fec_mpc52xx.c
@@ -14,6 +14,7 @@
*
*/
+#include <linux/dma-mapping.h>
#include <linux/module.h>
#include <linux/kernel.h>
--- a/drivers/net/greth.c
+++ b/drivers/net/greth.c
@@ -22,6 +22,7 @@
* Marko Isomaki
*/
+#include <linux/dma-mapping.h>
#include <linux/module.h>
#include <linux/uaccess.h>
#include <linux/init.h>
--- a/drivers/net/irda/pxaficp_ir.c
+++ b/drivers/net/irda/pxaficp_ir.c
@@ -12,6 +12,7 @@
* Infra-red driver (SIR/FIR) for the PXA2xx embedded microprocessor
*
*/
+#include <linux/dma-mapping.h>
#include <linux/interrupt.h>
#include <linux/module.h>
#include <linux/netdevice.h>
--- a/drivers/net/ks8851_mll.c
+++ b/drivers/net/ks8851_mll.c
@@ -35,6 +35,7 @@
#include <linux/platform_device.h>
#include <linux/delay.h>
#include <linux/slab.h>
+#include <asm/io.h>
#define DRV_NAME "ks8851_mll"
--- a/drivers/net/sgiseeq.c
+++ b/drivers/net/sgiseeq.c
@@ -6,6 +6,7 @@
#undef DEBUG
+#include <linux/dma-mapping.h>
#include <linux/kernel.h>
#include <linux/module.h>
#include <linux/slab.h>
--- a/drivers/net/stmmac/dwmac1000_core.c
+++ b/drivers/net/stmmac/dwmac1000_core.c
@@ -28,6 +28,7 @@
#include <linux/crc32.h>
#include <linux/slab.h>
+#include <asm/io.h>
#include "dwmac1000.h"
static void dwmac1000_core_init(void __iomem *ioaddr)
--- a/drivers/net/stmmac/dwmac1000_dma.c
+++ b/drivers/net/stmmac/dwmac1000_dma.c
@@ -26,6 +26,7 @@
Author: Giuseppe Cavallaro <peppe.cavallaro@st.com>
*******************************************************************************/
+#include <asm/io.h>
#include "dwmac1000.h"
#include "dwmac_dma.h"
--- a/drivers/net/stmmac/dwmac100_core.c
+++ b/drivers/net/stmmac/dwmac100_core.c
@@ -29,6 +29,7 @@
*******************************************************************************/
#include <linux/crc32.h>
+#include <asm/io.h>
#include "dwmac100.h"
static void dwmac100_core_init(void __iomem *ioaddr)
--- a/drivers/net/stmmac/dwmac100_dma.c
+++ b/drivers/net/stmmac/dwmac100_dma.c
@@ -28,6 +28,7 @@
Author: Giuseppe Cavallaro <peppe.cavallaro@st.com>
*******************************************************************************/
+#include <asm/io.h>
#include "dwmac100.h"
#include "dwmac_dma.h"
--- a/drivers/net/stmmac/stmmac_ethtool.c
+++ b/drivers/net/stmmac/stmmac_ethtool.c
@@ -27,6 +27,7 @@
#include <linux/interrupt.h>
#include <linux/mii.h>
#include <linux/phy.h>
+#include <asm/io.h>
#include "stmmac.h"
#include "dwmac_dma.h"
--- a/drivers/net/stmmac/stmmac_mdio.c
+++ b/drivers/net/stmmac/stmmac_mdio.c
@@ -27,6 +27,7 @@
#include <linux/mii.h>
#include <linux/phy.h>
#include <linux/slab.h>
+#include <asm/io.h>
#include "stmmac.h"
--- a/drivers/net/usb/cdc-phonet.c
+++ b/drivers/net/usb/cdc-phonet.c
@@ -21,6 +21,7 @@
*/
#include <linux/kernel.h>
+#include <linux/mm.h>
#include <linux/module.h>
#include <linux/gfp.h>
#include <linux/usb.h>
--- a/drivers/net/vxge/vxge-config.h
+++ b/drivers/net/vxge/vxge-config.h
@@ -16,6 +16,7 @@
#include <linux/hardirq.h>
#include <linux/list.h>
#include <linux/slab.h>
+#include <asm/io.h>
#ifndef VXGE_CACHE_LINE_SIZE
#define VXGE_CACHE_LINE_SIZE 128
--- a/drivers/net/wireless/ath/ath5k/base.c
+++ b/drivers/net/wireless/ath/ath5k/base.c
@@ -42,6 +42,7 @@
#include <linux/module.h>
#include <linux/delay.h>
+#include <linux/dma-mapping.h>
#include <linux/hardirq.h>
#include <linux/if.h>
#include <linux/io.h>
--- a/drivers/net/wireless/ath/ath9k/beacon.c
+++ b/drivers/net/wireless/ath/ath9k/beacon.c
@@ -14,6 +14,7 @@
* OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*/
+#include <linux/dma-mapping.h>
#include "ath9k.h"
#define FUDGE 2
--- a/drivers/net/wireless/ath/ath9k/init.c
+++ b/drivers/net/wireless/ath/ath9k/init.c
@@ -14,6 +14,7 @@
* OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*/
+#include <linux/dma-mapping.h>
#include <linux/slab.h>
#include <linux/ath9k_platform.h>
--- a/drivers/net/wireless/ath/ath9k/recv.c
+++ b/drivers/net/wireless/ath/ath9k/recv.c
@@ -14,6 +14,7 @@
* OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*/
+#include <linux/dma-mapping.h>
#include "ath9k.h"
#include "ar9003_mac.h"
--- a/drivers/net/wireless/ath/ath9k/xmit.c
+++ b/drivers/net/wireless/ath/ath9k/xmit.c
@@ -14,6 +14,7 @@
* OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*/
+#include <linux/dma-mapping.h>
#include "ath9k.h"
#include "ar9003_mac.h"
--- a/drivers/tty/serial/ifx6x60.c
+++ b/drivers/tty/serial/ifx6x60.c
@@ -36,6 +36,7 @@
* you need to use this driver for another platform.
*
*****************************************************************************/
+#include <linux/dma-mapping.h>
#include <linux/module.h>
#include <linux/termios.h>
#include <linux/tty.h>
--- a/drivers/usb/gadget/f_phonet.c
+++ b/drivers/usb/gadget/f_phonet.c
@@ -20,6 +20,7 @@
* 02110-1301 USA
*/
+#include <linux/mm.h>
#include <linux/slab.h>
#include <linux/kernel.h>
#include <linux/device.h>
--- a/include/crypto/if_alg.h
+++ b/include/crypto/if_alg.h
@@ -16,6 +16,7 @@
#include <linux/compiler.h>
#include <linux/completion.h>
#include <linux/if_alg.h>
+#include <linux/scatterlist.h>
#include <linux/types.h>
#include <net/sock.h>
new file mode 100644
--- /dev/null
+++ b/include/linux/dma-direction.h
@@ -0,0 +1,13 @@
+#ifndef _LINUX_DMA_DIRECTION_H
+#define _LINUX_DMA_DIRECTION_H
+/*
+ * These definitions mirror those in pci.h, so they can be used
+ * interchangeably with their PCI_ counterparts.
+ */
+enum dma_data_direction {
+ DMA_BIDIRECTIONAL = 0,
+ DMA_TO_DEVICE = 1,
+ DMA_FROM_DEVICE = 2,
+ DMA_NONE = 3,
+};
+#endif
--- a/include/linux/dma-mapping.h
+++ b/include/linux/dma-mapping.h
@@ -4,17 +4,9 @@
#include <linux/device.h>
#include <linux/err.h>
#include <linux/dma-attrs.h>
+#include <linux/dma-direction.h>
#include <linux/scatterlist.h>
-/* These definitions mirror those in pci.h, so they can be used
- * interchangeably with their PCI_ counterparts */
-enum dma_data_direction {
- DMA_BIDIRECTIONAL = 0,
- DMA_TO_DEVICE = 1,
- DMA_FROM_DEVICE = 2,
- DMA_NONE = 3,
-};
-
struct dma_map_ops {
void* (*alloc_coherent)(struct device *dev, size_t size,
dma_addr_t *dma_handle, gfp_t gfp);
--- a/include/linux/dmaengine.h
+++ b/include/linux/dmaengine.h
@@ -23,7 +23,9 @@
#include <linux/device.h>
#include <linux/uio.h>
-#include <linux/dma-mapping.h>
+#include <linux/dma-direction.h>
+
+struct scatterlist;
/**
* typedef dma_cookie_t - an opaque DMA cookie
--- a/include/linux/netdevice.h
+++ b/include/linux/netdevice.h
@@ -34,7 +34,6 @@
#include <linux/pm_qos_params.h>
#include <linux/timer.h>
#include <linux/delay.h>
-#include <linux/mm.h>
#include <asm/atomic.h>
#include <asm/cache.h>
#include <asm/byteorder.h>
--- a/net/sched/sch_netem.c
+++ b/net/sched/sch_netem.c
@@ -13,6 +13,7 @@
* Catalin(ux aka Dino) BOIE <catab at umbrella dot ro>
*/
+#include <linux/mm.h>
#include <linux/module.h>
#include <linux/slab.h>
#include <linux/types.h>
--- a/security/apparmor/lib.c
+++ b/security/apparmor/lib.c
@@ -12,6 +12,7 @@
* License.
*/
+#include <linux/mm.h>
#include <linux/slab.h>
#include <linux/string.h>
#include <linux/vmalloc.h>
^ permalink raw reply
* Re: [PATCH net-next 8/24] bnx2x: dump FW memory when appropriate msglvl is raised
From: Ben Hutchings @ 2011-06-16 21:08 UTC (permalink / raw)
To: Vlad Zolotarov
Cc: Dave Miller, netdev@vger.kernel.org, Eilon Greenstein,
Dmitry Kravkov, Yaniv Rosner
In-Reply-To: <201106141433.25717.vladz@broadcom.com>
The firmware dump functionality should be connected up to the new
ethtool operations added by:
commit 29dd54b72ba8c5ad0dd6dd33584449b5953f700b
Author: Anirban Chakraborty <anirban.chakraborty@qlogic.com>
Date: Thu May 12 12:48:32 2011 +0000
ethtool: Added support for FW dump
Ben.
--
Ben Hutchings, Senior Software 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: Netconf2011 slides...
From: David Miller @ 2011-06-16 21:11 UTC (permalink / raw)
To: seenutn; +Cc: netdev
In-Reply-To: <4DF9D644.708@linux.vnet.ibm.com>
From: Srinivasa T N <seenutn@linux.vnet.ibm.com>
Date: Thu, 16 Jun 2011 15:39:08 +0530
> Were there some interesting topics which is useful for the community?
> (Few lines on each such topic would do).
There is a topic description for each presentation, plus the
slides themselves on the web site.
I can't think of anything more significant that could be
provided.
^ permalink raw reply
* Re: Netconf2011 slides...
From: Ben Hutchings @ 2011-06-16 21:32 UTC (permalink / raw)
To: David Miller; +Cc: seenutn, netdev
In-Reply-To: <20110616.171110.2293322834897062244.davem@davemloft.net>
On Thu, 2011-06-16 at 17:11 -0400, David Miller wrote:
> From: Srinivasa T N <seenutn@linux.vnet.ibm.com>
> Date: Thu, 16 Jun 2011 15:39:08 +0530
>
> > Were there some interesting topics which is useful for the community?
> > (Few lines on each such topic would do).
>
> There is a topic description for each presentation, plus the
> slides themselves on the web site.
>
> I can't think of anything more significant that could be
> provided.
It would be nice to have some record of significant questions and
answers; and any conclusions or consensus from discussions.
I can provide the notes I took regarding my own topics.
Ben.
--
Ben Hutchings, Senior Software 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] vmxnet3: fix starving rx ring when alloc_skb fails
From: Scott J. Goldman @ 2011-06-16 22:02 UTC (permalink / raw)
To: netdev, pv-drivers; +Cc: Scott J. Goldman
if the rx ring is completely empty, then the device may never fire an rx
interrupt. unfortunately, the rx interrupt is what triggers populating
the rx ring with fresh buffers, so this will cause networking to lock
up.
this patch recycles the last skb that we were about to indicate up to
the network stack (only if the rx ring is completely starved of skbs)
so the ring will never be completely empty. If we fail to allocate a
secondary page buffer, we just indicate a 0 length buffer to the device.
Signed-off-by: Scott J. Goldman <scottjg@vmware.com>
---
drivers/net/vmxnet3/vmxnet3_drv.c | 98 +++++++++++++++++++++++++-----------
drivers/net/vmxnet3/vmxnet3_int.h | 5 +-
2 files changed, 70 insertions(+), 33 deletions(-)
diff --git a/drivers/net/vmxnet3/vmxnet3_drv.c b/drivers/net/vmxnet3/vmxnet3_drv.c
index 33097ec..cfa9ff7 100644
--- a/drivers/net/vmxnet3/vmxnet3_drv.c
+++ b/drivers/net/vmxnet3/vmxnet3_drv.c
@@ -558,6 +558,17 @@ vmxnet3_tq_cleanup_all(struct vmxnet3_adapter *adapter)
vmxnet3_tq_cleanup(&adapter->tx_queue[i], adapter);
}
+static bool
+vmxnet3_rq_empty(const struct vmxnet3_rx_queue *rq, u32 ring_idx)
+{
+ const struct vmxnet3_cmd_ring *ring = &rq->rx_ring[ring_idx];
+ u32 i = ring->next2comp;
+ while (rq->buf_info[ring_idx][i].buf_type != VMXNET3_RX_BUF_SKB)
+ VMXNET3_INC_RING_IDX_ONLY(i, ring->size);
+
+ return (i == ring->next2fill);
+}
+
/*
* starting from ring->next2fill, allocate rx buffers for the given ring
* of the rx queue and update the rx desc. stop after @num_to_alloc buffers
@@ -571,9 +582,12 @@ vmxnet3_rq_alloc_rx_buf(struct vmxnet3_rx_queue *rq, u32 ring_idx,
int num_allocated = 0;
struct vmxnet3_rx_buf_info *rbi_base = rq->buf_info[ring_idx];
struct vmxnet3_cmd_ring *ring = &rq->rx_ring[ring_idx];
+ struct vmxnet3_rx_ctx *ctx = &rq->rx_ctx;
+ bool alloc_skb_failed = false;
u32 val;
+ u32 len;
- while (num_allocated < num_to_alloc) {
+ while (num_allocated < num_to_alloc && !alloc_skb_failed) {
struct vmxnet3_rx_buf_info *rbi;
union Vmxnet3_GenericDesc *gd;
@@ -586,7 +600,27 @@ vmxnet3_rq_alloc_rx_buf(struct vmxnet3_rx_queue *rq, u32 ring_idx,
NET_IP_ALIGN);
if (unlikely(rbi->skb == NULL)) {
rq->stats.rx_buf_alloc_failure++;
- break;
+ alloc_skb_failed = true;
+ /*
+ * if allocation failed and ring is
+ * empty, we recycle the last skb we
+ * rx'ed so that we don't starve the
+ * rx ring
+ */
+ if (ctx->skb &&
+ vmxnet3_rq_empty(rq, ring_idx)) {
+ rbi->skb = ctx->skb;
+ ctx->skb = NULL;
+ skb_recycle_check(rbi->skb,
+ rbi->len +
+ NET_IP_ALIGN);
+ /*
+ * free any frags chained to
+ * the skb
+ */
+ __pskb_trim(rbi->skb, 0);
+ } else
+ break;
}
rbi->skb->dev = adapter->netdev;
@@ -594,8 +628,10 @@ vmxnet3_rq_alloc_rx_buf(struct vmxnet3_rx_queue *rq, u32 ring_idx,
rbi->dma_addr = pci_map_single(adapter->pdev,
rbi->skb->data, rbi->len,
PCI_DMA_FROMDEVICE);
+ len = rbi->len;
} else {
/* rx buffer skipped by the device */
+ len = rbi->len;
}
val = VMXNET3_RXD_BTYPE_HEAD << VMXNET3_RXD_BTYPE_SHIFT;
} else {
@@ -606,13 +642,18 @@ vmxnet3_rq_alloc_rx_buf(struct vmxnet3_rx_queue *rq, u32 ring_idx,
rbi->page = alloc_page(GFP_ATOMIC);
if (unlikely(rbi->page == NULL)) {
rq->stats.rx_buf_alloc_failure++;
- break;
+ len = 0;
+ } else {
+ rbi->dma_addr = pci_map_page(
+ adapter->pdev,
+ rbi->page, 0,
+ PAGE_SIZE,
+ PCI_DMA_FROMDEVICE);
+ len = rbi->len;
}
- rbi->dma_addr = pci_map_page(adapter->pdev,
- rbi->page, 0, PAGE_SIZE,
- PCI_DMA_FROMDEVICE);
} else {
/* rx buffers skipped by the device */
+ len = rbi->len;
}
val = VMXNET3_RXD_BTYPE_BODY << VMXNET3_RXD_BTYPE_SHIFT;
}
@@ -620,7 +661,7 @@ vmxnet3_rq_alloc_rx_buf(struct vmxnet3_rx_queue *rq, u32 ring_idx,
BUG_ON(rbi->dma_addr == 0);
gd->rxd.addr = cpu_to_le64(rbi->dma_addr);
gd->dword[2] = cpu_to_le32((ring->gen << VMXNET3_RXD_GEN_SHIFT)
- | val | rbi->len);
+ | val | len);
num_allocated++;
vmxnet3_cmd_ring_adv_next2fill(ring);
@@ -1148,7 +1189,6 @@ vmxnet3_rq_rx_complete(struct vmxnet3_rx_queue *rq,
&rxComp);
while (rcd->gen == rq->comp_ring.gen) {
struct vmxnet3_rx_buf_info *rbi;
- struct sk_buff *skb;
int num_to_alloc;
struct Vmxnet3_RxDesc *rxd;
u32 idx, ring_idx;
@@ -1168,7 +1208,7 @@ vmxnet3_rq_rx_complete(struct vmxnet3_rx_queue *rq,
rbi = rq->buf_info[ring_idx] + idx;
BUG_ON(rxd->addr != rbi->dma_addr ||
- rxd->len != rbi->len);
+ (rxd->len != rbi->len && rbi->len != 0));
if (unlikely(rcd->eop && rcd->err)) {
vmxnet3_rx_error(rq, rcd, ctx, adapter);
@@ -1198,8 +1238,7 @@ vmxnet3_rq_rx_complete(struct vmxnet3_rx_queue *rq,
PCI_DMA_FROMDEVICE);
skb_put(ctx->skb, rcd->len);
- } else {
- BUG_ON(ctx->skb == NULL);
+ } else if (ctx->skb) {
/* non SOP buffer must be type 1 in most cases */
if (rbi->buf_type == VMXNET3_RX_BUF_PAGE) {
BUG_ON(rxd->btype != VMXNET3_RXD_BTYPE_BODY);
@@ -1222,25 +1261,6 @@ vmxnet3_rq_rx_complete(struct vmxnet3_rx_queue *rq,
}
}
- skb = ctx->skb;
- if (rcd->eop) {
- skb->len += skb->data_len;
- skb->truesize += skb->data_len;
-
- vmxnet3_rx_csum(adapter, skb,
- (union Vmxnet3_GenericDesc *)rcd);
- skb->protocol = eth_type_trans(skb, adapter->netdev);
-
- if (unlikely(adapter->vlan_grp && rcd->ts)) {
- vlan_hwaccel_receive_skb(skb,
- adapter->vlan_grp, rcd->tci);
- } else {
- netif_receive_skb(skb);
- }
-
- ctx->skb = NULL;
- }
-
rcd_done:
/* device may skip some rx descs */
rq->rx_ring[ring_idx].next2comp = idx;
@@ -1264,6 +1284,24 @@ rcd_done:
}
}
+ if (rcd->eop && ctx->skb) {
+ ctx->skb->len += ctx->skb->data_len;
+ ctx->skb->truesize += ctx->skb->data_len;
+
+ vmxnet3_rx_csum(adapter, ctx->skb,
+ (union Vmxnet3_GenericDesc *)rcd);
+ ctx->skb->protocol = eth_type_trans(ctx->skb,
+ adapter->netdev);
+ if (unlikely(adapter->vlan_grp && rcd->ts)) {
+ vlan_hwaccel_receive_skb(ctx->skb,
+ adapter->vlan_grp,
+ rcd->tci);
+ } else {
+ netif_receive_skb(ctx->skb);
+ }
+ ctx->skb = NULL;
+ }
+
vmxnet3_comp_ring_adv_next2proc(&rq->comp_ring);
vmxnet3_getRxComp(rcd,
&rq->comp_ring.base[rq->comp_ring.next2proc].rcd, &rxComp);
diff --git a/drivers/net/vmxnet3/vmxnet3_int.h b/drivers/net/vmxnet3/vmxnet3_int.h
index 0e567c24..cb13ed7 100644
--- a/drivers/net/vmxnet3/vmxnet3_int.h
+++ b/drivers/net/vmxnet3/vmxnet3_int.h
@@ -68,10 +68,10 @@
/*
* Version numbers
*/
-#define VMXNET3_DRIVER_VERSION_STRING "1.1.9.0-k"
+#define VMXNET3_DRIVER_VERSION_STRING "1.1.10.0-k"
/* a 32-bit int, each byte encode a verion number in VMXNET3_DRIVER_VERSION */
-#define VMXNET3_DRIVER_VERSION_NUM 0x01010900
+#define VMXNET3_DRIVER_VERSION_NUM 0x01010A00
#if defined(CONFIG_PCI_MSI)
/* RSS only makes sense if MSI-X is supported. */
@@ -255,7 +255,6 @@ struct vmxnet3_rx_buf_info {
struct vmxnet3_rx_ctx {
struct sk_buff *skb;
- u32 sop_idx;
};
struct vmxnet3_rq_driver_stats {
--
1.7.4.1
^ permalink raw reply related
* Re: [GIT PULL nf-2.6] IPVS
From: Simon Horman @ 2011-06-16 22:06 UTC (permalink / raw)
To: Patrick McHardy
Cc: lvs-devel, netdev, netfilter-devel, netfilter, Wensong Zhang,
Julian Anastasov, Pablo Neira Ayuso
In-Reply-To: <4DFA1D0E.5070908@trash.net>
On Thu, Jun 16, 2011 at 05:11:10PM +0200, Patrick McHardy wrote:
> On 13.06.2011 10:47, Simon Horman wrote:
> > Hi Pablo,
> >
> > please consider pulling
> > git://git.kernel.org/pub/scm/linux/kernel/git/horms/ipvs-2.6.git master
> > to get the following fix from Hans.
> >
> > I believe this change should be considered for -stable.
>
> Just send it to the stable people once it hits upstream. I'll
> send it to Dave tonight.
Understood, will do.
^ permalink raw reply
* Re: Netconf2011 slides...
From: Eric Dumazet @ 2011-06-16 22:13 UTC (permalink / raw)
To: David Miller; +Cc: seenutn, netdev
In-Reply-To: <20110616.171110.2293322834897062244.davem@davemloft.net>
Le jeudi 16 juin 2011 à 17:11 -0400, David Miller a écrit :
> From: Srinivasa T N <seenutn@linux.vnet.ibm.com>
> Date: Thu, 16 Jun 2011 15:39:08 +0530
>
> > Were there some interesting topics which is useful for the community?
> > (Few lines on each such topic would do).
>
> There is a topic description for each presentation, plus the
> slides themselves on the web site.
>
> I can't think of anything more significant that could be
> provided.
Hmm, well, to be honest the real interesting stuff were the flash
animations from Jamal !
^ permalink raw reply
* rionet: NULL pointer dereference
From: Jesper Juhl @ 2011-06-16 22:06 UTC (permalink / raw)
To: linux-kernel; +Cc: Matt Porter, netdev, David S. Miller
Hi
Just noticed that drivers/net/rionet.c::rionet_remove() can cause a NULL
deref when it calls unregister_netdev().
It initializes local variable 'ndev' to NULL and nothing changes this
before the call to unregister_netdev(ndev) - that functions then calls:
unregister_netdevice > unregister_netdevice_queue > list_move_tail >
__list_del_entry which dereferences the pointer (which, being NULL, will
end in tears).
I won't claim to know this code nor what the proper fix is; just thought
i'd report it so someone else with more knowledge of this could perhaps
come up with a fix.
Have a nice day.
--
Jesper Juhl <jj@chaosbits.net> http://www.chaosbits.net/
Don't top-post http://www.catb.org/jargon/html/T/top-post.html
Plain text mails only, please.
^ permalink raw reply
* [PATCH] netdev: bfin_mac: fix memory leak when freeing dma descriptors
From: Mike Frysinger @ 2011-06-16 22:31 UTC (permalink / raw)
To: netdev, David S. Miller; +Cc: uclinux-dist-devel, Sonic Zhang
From: Sonic Zhang <sonic.zhang@analog.com>
The size of the desc array is not the size of the desc structure, so
when we try to free up things, we leak some parts.
Reported-by: Regis Dargent <rdargent@edevice.com>
Signed-off-by: Sonic Zhang <sonic.zhang@analog.com>
Signed-off-by: Mike Frysinger <vapier@gentoo.org>
---
drivers/net/bfin_mac.c | 20 ++++++++++----------
1 files changed, 10 insertions(+), 10 deletions(-)
diff --git a/drivers/net/bfin_mac.c b/drivers/net/bfin_mac.c
index 68d45ba..6c019e1 100644
--- a/drivers/net/bfin_mac.c
+++ b/drivers/net/bfin_mac.c
@@ -52,13 +52,13 @@ MODULE_DESCRIPTION(DRV_DESC);
MODULE_ALIAS("platform:bfin_mac");
#if defined(CONFIG_BFIN_MAC_USE_L1)
-# define bfin_mac_alloc(dma_handle, size) l1_data_sram_zalloc(size)
-# define bfin_mac_free(dma_handle, ptr) l1_data_sram_free(ptr)
+# define bfin_mac_alloc(dma_handle, size, num) l1_data_sram_zalloc(size*num)
+# define bfin_mac_free(dma_handle, ptr, num) l1_data_sram_free(ptr)
#else
-# define bfin_mac_alloc(dma_handle, size) \
- dma_alloc_coherent(NULL, size, dma_handle, GFP_KERNEL)
-# define bfin_mac_free(dma_handle, ptr) \
- dma_free_coherent(NULL, sizeof(*ptr), ptr, dma_handle)
+# define bfin_mac_alloc(dma_handle, size, num) \
+ dma_alloc_coherent(NULL, size*num, dma_handle, GFP_KERNEL)
+# define bfin_mac_free(dma_handle, ptr, num) \
+ dma_free_coherent(NULL, sizeof(*ptr)*num, ptr, dma_handle)
#endif
#define PKT_BUF_SZ 1580
@@ -95,7 +95,7 @@ static void desc_list_free(void)
t = t->next;
}
}
- bfin_mac_free(dma_handle, tx_desc);
+ bfin_mac_free(dma_handle, tx_desc, CONFIG_BFIN_TX_DESC_NUM);
}
if (rx_desc) {
@@ -109,7 +109,7 @@ static void desc_list_free(void)
r = r->next;
}
}
- bfin_mac_free(dma_handle, rx_desc);
+ bfin_mac_free(dma_handle, rx_desc, CONFIG_BFIN_RX_DESC_NUM);
}
}
@@ -126,13 +126,13 @@ static int desc_list_init(void)
#endif
tx_desc = bfin_mac_alloc(&dma_handle,
- sizeof(struct net_dma_desc_tx) *
+ sizeof(struct net_dma_desc_tx),
CONFIG_BFIN_TX_DESC_NUM);
if (tx_desc == NULL)
goto init_error;
rx_desc = bfin_mac_alloc(&dma_handle,
- sizeof(struct net_dma_desc_rx) *
+ sizeof(struct net_dma_desc_rx),
CONFIG_BFIN_RX_DESC_NUM);
if (rx_desc == NULL)
goto init_error;
--
1.7.5.3
^ permalink raw reply related
* Re: rionet: NULL pointer dereference
From: Connor Hansen @ 2011-06-16 22:53 UTC (permalink / raw)
To: Jesper Juhl; +Cc: linux-kernel, Matt Porter, netdev, David S. Miller
In-Reply-To: <alpine.LNX.2.00.1106162359560.8140@swampdragon.chaosbits.net>
On Thu, Jun 16, 2011 at 3:06 PM, Jesper Juhl <jj@chaosbits.net> wrote:
> Hi
>
> Just noticed that drivers/net/rionet.c::rionet_remove() can cause a NULL
> deref when it calls unregister_netdev().
> It initializes local variable 'ndev' to NULL and nothing changes this
> before the call to unregister_netdev(ndev) - that functions then calls:
> unregister_netdevice > unregister_netdevice_queue > list_move_tail >
> __list_del_entry which dereferences the pointer (which, being NULL, will
> end in tears).
unregister_netdevice(struct net_device *dev)
{
unregister_netdevice_queue(dev, NULL);
}
so unregister_netdevice_queue is being called with NULL,NULL
void unregister_netdevice_queue(struct net_device *dev, struct list_head *head)
{
ASSERT_RTNL();
if (head) {
list_move_tail(&dev->unreg_list, head);
} else {
rollback_registered(dev);
/* Finish processing unregister after unlock */
net_set_todo(dev);
}
}
if head is null, which it is from the call, then we call
rollback_registered, and not list_move_tail()
the else calls rollback_registered(NULL) then net_set_todo(NULL)
both of which dereference null when passed, so yes there is a null
dereference, just not in the code branch you thought.
static void rollback_registered(struct net_device *dev)
{
LIST_HEAD(single);
list_add(&dev->unreg_list, &single); null dereference
rollback_registered_many(&single);
list_del(&single);
}
static void net_set_todo(struct net_device *dev)
{
list_add_tail(&dev->todo_list, &net_todo_list); null dereference
}
Connor
>
> I won't claim to know this code nor what the proper fix is; just thought
> i'd report it so someone else with more knowledge of this could perhaps
> come up with a fix.
>
> Have a nice day.
>
> --
> Jesper Juhl <jj@chaosbits.net> http://www.chaosbits.net/
> Don't top-post http://www.catb.org/jargon/html/T/top-post.html
> Plain text mails only, please.
>
> --
> To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
> the body of a message to majordomo@vger.kernel.org
> More majordomo info at http://vger.kernel.org/majordomo-info.html
> Please read the FAQ at http://www.tux.org/lkml/
>
^ permalink raw reply
* RE: [Pv-drivers] [PATCH] vmxnet3: fix starving rx ring when alloc_skb fails
From: Bhavesh Davda @ 2011-06-16 22:56 UTC (permalink / raw)
To: Scott Goldman, netdev@vger.kernel.org, pv-drivers@vmware.com
In-Reply-To: <1308261747-17702-1-git-send-email-scottjg@vmware.com>
LGTM.
Signed-off-by: Bhavesh Davda <bhavesh@vmware.com>
> -----Original Message-----
> From: pv-drivers-bounces@vmware.com [mailto:pv-drivers-bounces@vmware.com] On
> Behalf Of Scott J. Goldman
> Sent: Thursday, June 16, 2011 3:02 PM
> To: netdev@vger.kernel.org; pv-drivers@vmware.com
> Subject: [Pv-drivers] [PATCH] vmxnet3: fix starving rx ring when alloc_skb
> fails
>
> if the rx ring is completely empty, then the device may never fire an rx
> interrupt. unfortunately, the rx interrupt is what triggers populating
> the rx ring with fresh buffers, so this will cause networking to lock
> up.
>
> this patch recycles the last skb that we were about to indicate up to
> the network stack (only if the rx ring is completely starved of skbs)
> so the ring will never be completely empty. If we fail to allocate a
> secondary page buffer, we just indicate a 0 length buffer to the device.
>
> Signed-off-by: Scott J. Goldman <scottjg@vmware.com>
> ---
> drivers/net/vmxnet3/vmxnet3_drv.c | 98 +++++++++++++++++++++++++-----------
> drivers/net/vmxnet3/vmxnet3_int.h | 5 +-
> 2 files changed, 70 insertions(+), 33 deletions(-)
>
> diff --git a/drivers/net/vmxnet3/vmxnet3_drv.c
> b/drivers/net/vmxnet3/vmxnet3_drv.c
> index 33097ec..cfa9ff7 100644
> --- a/drivers/net/vmxnet3/vmxnet3_drv.c
> +++ b/drivers/net/vmxnet3/vmxnet3_drv.c
> @@ -558,6 +558,17 @@ vmxnet3_tq_cleanup_all(struct vmxnet3_adapter *adapter)
> vmxnet3_tq_cleanup(&adapter->tx_queue[i], adapter);
> }
>
> +static bool
> +vmxnet3_rq_empty(const struct vmxnet3_rx_queue *rq, u32 ring_idx)
> +{
> + const struct vmxnet3_cmd_ring *ring = &rq->rx_ring[ring_idx];
> + u32 i = ring->next2comp;
> + while (rq->buf_info[ring_idx][i].buf_type != VMXNET3_RX_BUF_SKB)
> + VMXNET3_INC_RING_IDX_ONLY(i, ring->size);
> +
> + return (i == ring->next2fill);
> +}
> +
> /*
> * starting from ring->next2fill, allocate rx buffers for the given ring
> * of the rx queue and update the rx desc. stop after @num_to_alloc
> buffers
> @@ -571,9 +582,12 @@ vmxnet3_rq_alloc_rx_buf(struct vmxnet3_rx_queue *rq, u32
> ring_idx,
> int num_allocated = 0;
> struct vmxnet3_rx_buf_info *rbi_base = rq->buf_info[ring_idx];
> struct vmxnet3_cmd_ring *ring = &rq->rx_ring[ring_idx];
> + struct vmxnet3_rx_ctx *ctx = &rq->rx_ctx;
> + bool alloc_skb_failed = false;
> u32 val;
> + u32 len;
>
> - while (num_allocated < num_to_alloc) {
> + while (num_allocated < num_to_alloc && !alloc_skb_failed) {
> struct vmxnet3_rx_buf_info *rbi;
> union Vmxnet3_GenericDesc *gd;
>
> @@ -586,7 +600,27 @@ vmxnet3_rq_alloc_rx_buf(struct vmxnet3_rx_queue *rq, u32
> ring_idx,
> NET_IP_ALIGN);
> if (unlikely(rbi->skb == NULL)) {
> rq->stats.rx_buf_alloc_failure++;
> - break;
> + alloc_skb_failed = true;
> + /*
> + * if allocation failed and ring is
> + * empty, we recycle the last skb we
> + * rx'ed so that we don't starve the
> + * rx ring
> + */
> + if (ctx->skb &&
> + vmxnet3_rq_empty(rq, ring_idx)) {
> + rbi->skb = ctx->skb;
> + ctx->skb = NULL;
> + skb_recycle_check(rbi->skb,
> + rbi->len +
> + NET_IP_ALIGN);
> + /*
> + * free any frags chained to
> + * the skb
> + */
> + __pskb_trim(rbi->skb, 0);
> + } else
> + break;
> }
> rbi->skb->dev = adapter->netdev;
>
> @@ -594,8 +628,10 @@ vmxnet3_rq_alloc_rx_buf(struct vmxnet3_rx_queue *rq, u32
> ring_idx,
> rbi->dma_addr = pci_map_single(adapter->pdev,
> rbi->skb->data, rbi->len,
> PCI_DMA_FROMDEVICE);
> + len = rbi->len;
> } else {
> /* rx buffer skipped by the device */
> + len = rbi->len;
> }
> val = VMXNET3_RXD_BTYPE_HEAD << VMXNET3_RXD_BTYPE_SHIFT;
> } else {
> @@ -606,13 +642,18 @@ vmxnet3_rq_alloc_rx_buf(struct vmxnet3_rx_queue *rq, u32
> ring_idx,
> rbi->page = alloc_page(GFP_ATOMIC);
> if (unlikely(rbi->page == NULL)) {
> rq->stats.rx_buf_alloc_failure++;
> - break;
> + len = 0;
> + } else {
> + rbi->dma_addr = pci_map_page(
> + adapter->pdev,
> + rbi->page, 0,
> + PAGE_SIZE,
> + PCI_DMA_FROMDEVICE);
> + len = rbi->len;
> }
> - rbi->dma_addr = pci_map_page(adapter->pdev,
> - rbi->page, 0, PAGE_SIZE,
> - PCI_DMA_FROMDEVICE);
> } else {
> /* rx buffers skipped by the device */
> + len = rbi->len;
> }
> val = VMXNET3_RXD_BTYPE_BODY << VMXNET3_RXD_BTYPE_SHIFT;
> }
> @@ -620,7 +661,7 @@ vmxnet3_rq_alloc_rx_buf(struct vmxnet3_rx_queue *rq, u32
> ring_idx,
> BUG_ON(rbi->dma_addr == 0);
> gd->rxd.addr = cpu_to_le64(rbi->dma_addr);
> gd->dword[2] = cpu_to_le32((ring->gen << VMXNET3_RXD_GEN_SHIFT)
> - | val | rbi->len);
> + | val | len);
>
> num_allocated++;
> vmxnet3_cmd_ring_adv_next2fill(ring);
> @@ -1148,7 +1189,6 @@ vmxnet3_rq_rx_complete(struct vmxnet3_rx_queue *rq,
> &rxComp);
> while (rcd->gen == rq->comp_ring.gen) {
> struct vmxnet3_rx_buf_info *rbi;
> - struct sk_buff *skb;
> int num_to_alloc;
> struct Vmxnet3_RxDesc *rxd;
> u32 idx, ring_idx;
> @@ -1168,7 +1208,7 @@ vmxnet3_rq_rx_complete(struct vmxnet3_rx_queue *rq,
> rbi = rq->buf_info[ring_idx] + idx;
>
> BUG_ON(rxd->addr != rbi->dma_addr ||
> - rxd->len != rbi->len);
> + (rxd->len != rbi->len && rbi->len != 0));
>
> if (unlikely(rcd->eop && rcd->err)) {
> vmxnet3_rx_error(rq, rcd, ctx, adapter);
> @@ -1198,8 +1238,7 @@ vmxnet3_rq_rx_complete(struct vmxnet3_rx_queue *rq,
> PCI_DMA_FROMDEVICE);
>
> skb_put(ctx->skb, rcd->len);
> - } else {
> - BUG_ON(ctx->skb == NULL);
> + } else if (ctx->skb) {
> /* non SOP buffer must be type 1 in most cases */
> if (rbi->buf_type == VMXNET3_RX_BUF_PAGE) {
> BUG_ON(rxd->btype != VMXNET3_RXD_BTYPE_BODY);
> @@ -1222,25 +1261,6 @@ vmxnet3_rq_rx_complete(struct vmxnet3_rx_queue *rq,
> }
> }
>
> - skb = ctx->skb;
> - if (rcd->eop) {
> - skb->len += skb->data_len;
> - skb->truesize += skb->data_len;
> -
> - vmxnet3_rx_csum(adapter, skb,
> - (union Vmxnet3_GenericDesc *)rcd);
> - skb->protocol = eth_type_trans(skb, adapter->netdev);
> -
> - if (unlikely(adapter->vlan_grp && rcd->ts)) {
> - vlan_hwaccel_receive_skb(skb,
> - adapter->vlan_grp, rcd->tci);
> - } else {
> - netif_receive_skb(skb);
> - }
> -
> - ctx->skb = NULL;
> - }
> -
> rcd_done:
> /* device may skip some rx descs */
> rq->rx_ring[ring_idx].next2comp = idx;
> @@ -1264,6 +1284,24 @@ rcd_done:
> }
> }
>
> + if (rcd->eop && ctx->skb) {
> + ctx->skb->len += ctx->skb->data_len;
> + ctx->skb->truesize += ctx->skb->data_len;
> +
> + vmxnet3_rx_csum(adapter, ctx->skb,
> + (union Vmxnet3_GenericDesc *)rcd);
> + ctx->skb->protocol = eth_type_trans(ctx->skb,
> + adapter->netdev);
> + if (unlikely(adapter->vlan_grp && rcd->ts)) {
> + vlan_hwaccel_receive_skb(ctx->skb,
> + adapter->vlan_grp,
> + rcd->tci);
> + } else {
> + netif_receive_skb(ctx->skb);
> + }
> + ctx->skb = NULL;
> + }
> +
> vmxnet3_comp_ring_adv_next2proc(&rq->comp_ring);
> vmxnet3_getRxComp(rcd,
> &rq->comp_ring.base[rq->comp_ring.next2proc].rcd, &rxComp);
> diff --git a/drivers/net/vmxnet3/vmxnet3_int.h
> b/drivers/net/vmxnet3/vmxnet3_int.h
> index 0e567c24..cb13ed7 100644
> --- a/drivers/net/vmxnet3/vmxnet3_int.h
> +++ b/drivers/net/vmxnet3/vmxnet3_int.h
> @@ -68,10 +68,10 @@
> /*
> * Version numbers
> */
> -#define VMXNET3_DRIVER_VERSION_STRING "1.1.9.0-k"
> +#define VMXNET3_DRIVER_VERSION_STRING "1.1.10.0-k"
>
> /* a 32-bit int, each byte encode a verion number in VMXNET3_DRIVER_VERSION
> */
> -#define VMXNET3_DRIVER_VERSION_NUM 0x01010900
> +#define VMXNET3_DRIVER_VERSION_NUM 0x01010A00
>
> #if defined(CONFIG_PCI_MSI)
> /* RSS only makes sense if MSI-X is supported. */
> @@ -255,7 +255,6 @@ struct vmxnet3_rx_buf_info {
>
> struct vmxnet3_rx_ctx {
> struct sk_buff *skb;
> - u32 sop_idx;
> };
>
> struct vmxnet3_rq_driver_stats {
> --
> 1.7.4.1
>
> _______________________________________________
> Pv-drivers mailing list
> Pv-drivers@vmware.com
> http://mailman2.vmware.com/mailman/listinfo/pv-drivers
^ permalink raw reply
* Re: rionet: NULL pointer dereference
From: Jesper Juhl @ 2011-06-16 22:51 UTC (permalink / raw)
To: Connor Hansen; +Cc: linux-kernel, Matt Porter, netdev, David S. Miller
In-Reply-To: <BANLkTimwzbB9ZwbG3u=oRNAHSECioEJ3dQ@mail.gmail.com>
[-- Attachment #1: Type: TEXT/PLAIN, Size: 1813 bytes --]
On Thu, 16 Jun 2011, Connor Hansen wrote:
> On Thu, Jun 16, 2011 at 3:06 PM, Jesper Juhl <jj@chaosbits.net> wrote:
> > Hi
> >
> > Just noticed that drivers/net/rionet.c::rionet_remove() can cause a NULL
> > deref when it calls unregister_netdev().
> > It initializes local variable 'ndev' to NULL and nothing changes this
> > before the call to unregister_netdev(ndev) - that functions then calls:
> > unregister_netdevice > unregister_netdevice_queue > list_move_tail >
> > __list_del_entry which dereferences the pointer (which, being NULL, will
> > end in tears).
>
> unregister_netdevice(struct net_device *dev)
> {
> unregister_netdevice_queue(dev, NULL);
> }
>
> so unregister_netdevice_queue is being called with NULL,NULL
>
> void unregister_netdevice_queue(struct net_device *dev, struct list_head *head)
> {
> ASSERT_RTNL();
>
> if (head) {
> list_move_tail(&dev->unreg_list, head);
> } else {
> rollback_registered(dev);
> /* Finish processing unregister after unlock */
> net_set_todo(dev);
> }
> }
>
> if head is null, which it is from the call, then we call
> rollback_registered, and not list_move_tail()
>
> the else calls rollback_registered(NULL) then net_set_todo(NULL)
>
> both of which dereference null when passed, so yes there is a null
> dereference, just not in the code branch you thought.
>
Ahh crap, you are right. Too much coffee and too late to be reading kernel
code is my only excuse ;-)
Thanks for taking the time to look and correct me.
In any case, there's still a problem that needs to be fixed.
--
Jesper Juhl <jj@chaosbits.net> http://www.chaosbits.net/
Don't top-post http://www.catb.org/jargon/html/T/top-post.html
Plain text mails only, please.
^ permalink raw reply
* Re: [PATCH v2] net/r8169: update the new parser for the new firmware
From: Francois Romieu @ 2011-06-16 22:59 UTC (permalink / raw)
To: Hayes Wang; +Cc: netdev, linux-kernel
In-Reply-To: <1308109531-31698-1-git-send-email-hayeswang@realtek.com>
Hayes Wang <hayeswang@realtek.com> :
> Update the parser for the new firmware which is embedded some information.
I have modified several things :
- s/u32/__le32/ in fw_info
- fix unsigned (size_t) comparisons
- more size checks before dereferencing fw_info
The new firmware format should be the same. The old r8168d-1.fw firmware
proved usable when prefixed with :
0000000: 0000 0000 3031 0000 0000 0000 0000 0000 ....01..........
0000010: 0000 0000 0000 0000 0000 0000 0000 0000 ................
0000020: 0000 0000 3000 0000 7501 0000 a000 0000 ....0...u.......
I realized after testing that netif_err could be abused with non-string
fw_info.version. :o/
Comments ?
diff --git a/drivers/net/r8169.c b/drivers/net/r8169.c
index 7310824..5a0a7c3 100644
--- a/drivers/net/r8169.c
+++ b/drivers/net/r8169.c
@@ -1741,21 +1741,82 @@ static void rtl_writephy_batch(struct rtl8169_private *tp,
#define PHY_DELAY_MS 0xe0000000
#define PHY_WRITE_ERI_WORD 0xf0000000
+struct fw_info {
+ u32 magic;
+ char version[32];
+ __le32 fw_start;
+ __le32 fw_len;
+ u8 chksum;
+} __packed;
+
+struct fw_phy_code {
+ __le32 *code;
+ size_t size;
+};
+
+#define FW_OPCODE_SIZE sizeof(typeof(*((struct fw_phy_code *)0)->code))
+
+static bool rtl_fw_format_ok(struct rtl8169_private *tp, struct net_device *dev,
+ const struct firmware *fw, struct fw_phy_code *pc)
+{
+ struct fw_info *fw_info = (struct fw_info *)fw->data;
+ bool rc = false;
+
+ if (fw->size < FW_OPCODE_SIZE)
+ goto out;
+
+ if (fw_info->magic == 0) {
+ size_t i, size, start;
+ u8 checksum = 0;
+
+ if (fw->size < sizeof(*fw_info))
+ goto out;
+
+ for (i = 0; i < fw->size; i++)
+ checksum += fw->data[i];
+ if (checksum != 0)
+ goto out;
+
+ start = le32_to_cpu(fw_info->fw_start);
+ if (start > fw->size)
+ goto out;
+
+ size = le32_to_cpu(fw_info->fw_len);
+ if (size > (fw->size - start) / FW_OPCODE_SIZE)
+ goto out;
+
+ netif_info(tp, probe, dev, "firmware: %s\n", fw_info->version);
+ pc->code = (__le32 *)(fw->data + start);
+ pc->size = size;
+ } else {
+ if (fw->size % FW_OPCODE_SIZE)
+ goto out;
+
+ netif_info(tp, probe, dev, "legacy firmware format detected\n");
+ pc->code = (__le32 *)fw->data;
+ pc->size = fw->size / FW_OPCODE_SIZE;
+ }
+
+ rc = true;
+out:
+ return rc;
+}
+
static void
rtl_phy_write_fw(struct rtl8169_private *tp, const struct firmware *fw)
{
- __le32 *phytable = (__le32 *)fw->data;
struct net_device *dev = tp->dev;
- size_t index, fw_size = fw->size / sizeof(*phytable);
+ struct fw_phy_code phytable;
u32 predata, count;
+ size_t i;
- if (fw->size % sizeof(*phytable)) {
- netif_err(tp, probe, dev, "odd sized firmware %zd\n", fw->size);
+ if (!rtl_fw_format_ok(tp, dev, fw, &phytable)) {
+ netif_err(tp, probe, dev, "invalid firwmare\n");
return;
}
- for (index = 0; index < fw_size; index++) {
- u32 action = le32_to_cpu(phytable[index]);
+ for (i = 0; i < phytable.size; i++) {
+ u32 action = le32_to_cpu(phytable.code[i]);
u32 regno = (action & 0x0fff0000) >> 16;
switch(action & 0xf0000000) {
@@ -1770,14 +1831,14 @@ rtl_phy_write_fw(struct rtl8169_private *tp, const struct firmware *fw)
break;
case PHY_BJMPN:
- if (regno > index) {
+ if (regno > i) {
netif_err(tp, probe, tp->dev,
"Out of range of firmware\n");
return;
}
break;
case PHY_READCOUNT_EQ_SKIP:
- if (index + 2 >= fw_size) {
+ if (i + 2 >= phytable.size) {
netif_err(tp, probe, tp->dev,
"Out of range of firmware\n");
return;
@@ -1786,7 +1847,7 @@ rtl_phy_write_fw(struct rtl8169_private *tp, const struct firmware *fw)
case PHY_COMP_EQ_SKIPN:
case PHY_COMP_NEQ_SKIPN:
case PHY_SKIPN:
- if (index + 1 + regno >= fw_size) {
+ if (i + 1 + regno >= phytable.size) {
netif_err(tp, probe, tp->dev,
"Out of range of firmware\n");
return;
@@ -1806,8 +1867,8 @@ rtl_phy_write_fw(struct rtl8169_private *tp, const struct firmware *fw)
predata = 0;
count = 0;
- for (index = 0; index < fw_size; ) {
- u32 action = le32_to_cpu(phytable[index]);
+ for (i = 0; i < phytable.size; ) {
+ u32 action = le32_to_cpu(phytable.code[i]);
u32 data = action & 0x0000ffff;
u32 regno = (action & 0x0fff0000) >> 16;
@@ -1818,54 +1879,54 @@ rtl_phy_write_fw(struct rtl8169_private *tp, const struct firmware *fw)
case PHY_READ:
predata = rtl_readphy(tp, regno);
count++;
- index++;
+ i++;
break;
case PHY_DATA_OR:
predata |= data;
- index++;
+ i++;
break;
case PHY_DATA_AND:
predata &= data;
- index++;
+ i++;
break;
case PHY_BJMPN:
- index -= regno;
+ i -= regno;
break;
case PHY_READ_EFUSE:
predata = rtl8168d_efuse_read(tp->mmio_addr, regno);
- index++;
+ i++;
break;
case PHY_CLEAR_READCOUNT:
count = 0;
- index++;
+ i++;
break;
case PHY_WRITE:
rtl_writephy(tp, regno, data);
- index++;
+ i++;
break;
case PHY_READCOUNT_EQ_SKIP:
- index += (count == data) ? 2 : 1;
+ i += (count == data) ? 2 : 1;
break;
case PHY_COMP_EQ_SKIPN:
if (predata == data)
- index += regno;
- index++;
+ i += regno;
+ i++;
break;
case PHY_COMP_NEQ_SKIPN:
if (predata != data)
- index += regno;
- index++;
+ i += regno;
+ i++;
break;
case PHY_WRITE_PREVIOUS:
rtl_writephy(tp, regno, predata);
- index++;
+ i++;
break;
case PHY_SKIPN:
- index += regno + 1;
+ i += regno + 1;
break;
case PHY_DELAY_MS:
mdelay(data);
- index++;
+ i++;
break;
case PHY_READ_MAC_BYTE:
^ permalink raw reply related
* Re: [PATCH net-next-2.6] net: rfs: enable RFS before first data packet is received
From: Ben Hutchings @ 2011-06-16 23:50 UTC (permalink / raw)
To: Eric Dumazet; +Cc: Tom Herbert, David Miller, netdev, jamal
In-Reply-To: <1308104128.4578.10.camel@edumazet-laptop>
On Wed, 2011-06-15 at 04:15 +0200, Eric Dumazet wrote:
> First packet received on a passive tcp flow is not correctly RFS
> steered.
>
> One sock_rps_record_flow() call is missing in inet_accept()
>
> But before that, we also must record rxhash when child socket is setup.
>
> Signed-off-by: Eric Dumazet <eric.dumazet@gmail.com>
> CC: Tom Herbert <therbert@google.com>
> CC: Ben Hutchings <bhutchings@solarflare.com>
> CC: Jamal Hadi Salim <hadi@cyberus.ca>
> ---
> Netconf2011 workshop ;)
>
> net/ipv4/af_inet.c | 1 +
> net/ipv4/tcp_ipv4.c | 1 +
> 2 files changed, 2 insertions(+)
>
> diff --git a/net/ipv4/af_inet.c b/net/ipv4/af_inet.c
> index 83673d2..0600f0f 100644
> --- a/net/ipv4/af_inet.c
> +++ b/net/ipv4/af_inet.c
> @@ -676,6 +676,7 @@ int inet_accept(struct socket *sock, struct socket *newsock, int flags)
>
> lock_sock(sk2);
>
> + sock_rps_record_flow(sk2);
> WARN_ON(!((1 << sk2->sk_state) &
> (TCPF_ESTABLISHED | TCPF_CLOSE_WAIT | TCPF_CLOSE)));
>
> diff --git a/net/ipv4/tcp_ipv4.c b/net/ipv4/tcp_ipv4.c
> index 617dee3..955b8e6 100644
> --- a/net/ipv4/tcp_ipv4.c
> +++ b/net/ipv4/tcp_ipv4.c
> @@ -1594,6 +1594,7 @@ int tcp_v4_do_rcv(struct sock *sk, struct sk_buff *skb)
> goto discard;
>
> if (nsk != sk) {
> + sock_rps_save_rxhash(nsk, skb->rxhash);
> if (tcp_child_process(sk, nsk, skb)) {
> rsk = nsk;
> goto reset;
>
I haven't tried this, but it looks reasonable to me.
What about IPv6? The logic in tcp_v6_do_rcv() looks very similar.
Ben.
--
Ben Hutchings, Senior Software 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: [RFC 2/2] ethtool: Add support for DMA Coalescing feature config to ethtool.
From: Ben Hutchings @ 2011-06-16 23:53 UTC (permalink / raw)
To: Wyborny, Carolyn; +Cc: netdev@vger.kernel.org
In-Reply-To: <EDC0E76513226749BFBC9C3FB031318F016C7DEB5B@orsmsx508.amr.corp.intel.com>
On Tue, 2011-06-14 at 13:19 -0700, Wyborny, Carolyn wrote:
[...]
> Ok, will send up update with the suggested changes and an
> implementation as an example. I have one, but will wait to synch it
> with the updated patch. Do you want another RFC or a regular patch
> submission?
That's really for you to decide.
Ben.
--
Ben Hutchings, Senior Software 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
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