* Re: PATCH: Network Device Naming mechanism and policy
From: Kay Sievers @ 2009-10-10 18:35 UTC (permalink / raw)
To: Bill Fink
Cc: Greg KH, Matt Domsch, Stephen Hemminger, netdev, linux-hotplug,
Narendra_K, jordan_hargrave
In-Reply-To: <20091010141124.82d226b8.billfink@mindspring.com>
On Sat, Oct 10, 2009 at 20:11, Bill Fink <billfink@mindspring.com> wrote:
> No comment on the specific implementation decision, but I am in the
> process of setting up a large number of test systems with identical
> hardware configurations, and using a master disk image to clone all the
> test systems. The biggest pain in this process is identiying the MAC
> addresses for each of the six or more network interfaces in each test
> system (we want eth0...ethN to always reference the same physical port
> on the test systems), and then having to modify the 70-persistent-net.rules
> udev file and the HWADDR entry for all the ifcfg-ethX files to reflect
> the correct MAC addresses. It would be fantastic if there were some
> mechanism for making this part of the process unnecessary.
Udev creates the persistent rules only if no other rule set a name.
Adding something like:
SUBSYSTEM=="net", KERNEL==""eth*", NAME="eth%n"
in any earlier rules file before the udev generated one will skip all
off the automatic udev rule creation.
Kay
^ permalink raw reply
* Re: PATCH: Network Device Naming mechanism and policy
From: Ben Hutchings @ 2009-10-10 19:00 UTC (permalink / raw)
To: Greg KH
Cc: Sujit K M, Matt Domsch, Stephen Hemminger, netdev, linux-hotplug,
Narendra_K, jordan_hargrave
In-Reply-To: <20091010162703.GB30354@kroah.com>
On Sat, 2009-10-10 at 09:27 -0700, Greg KH wrote:
> On Sat, Oct 10, 2009 at 01:47:39PM +0530, Sujit K M wrote:
> > Greg,
> >
> >
> > > No, the hardware changes the enumeration order, it places _no_
> > > guarantees on what order stuff will be found in. ?So this is not the
> > > kernel changing, just to be clear.
> > > Again, I have a machine here that likes to reorder PCI devices every 4th
> > > or so boot times, and that's fine according to the PCI spec. ?Yeah, it's
> > > a crappy BIOS, but the manufacturer rightly pointed out that it is not
> > > in violation of anything.
> > >
> >
> > I think the open call should be implemented then. By the patch very little
> > knowledge is being shared on type of network implementation it is trying to
> > do.
>
> What would open() accomplish? What good would the file descriptor be?
> What could you use it for?
Currently all net device ioctls are carried out through arbitrary
sockets and identify the device by name (aside from one to look up the
name by ifindex). Ever since it became possible to rename net devices,
it has been possible for a sequence of ioctls intended for one device to
race with renaming of that device. Adding open() and ioctl() to the
character device (which seems reasonably easy) would provide a way to
avoid this.
On the other hand, the netlink configuration APIs already use ifindex so
it may be better just to say that the device ioctls are deprecated and
applications should use netlink.
> > Also it is messing with core datastructure and procedures. This seems
> > to be simplified by changing implementing the other operations like poll().
>
> I don't understand.
>
> > > That is why all distros name network devices based on the only
> > > deterministic thing they have today, the MAC address. ?I still fail to
> > > see why you do not like this solution, it is honestly the only way to
> > > properly name network devices in a sane manner.
> >
> > This is feature that needs to be implemented. As per the rules followed.
>
> This feature is already implemented today, all distros have it.
No, see below.
> > > All distros also provide a way to easily rename the network devices, to
> > > place a specific name on a specific MAC address, so again, this should
> > > all be solved already.
> > >
> > > No matter how badly your BIOS teams mess up the PCI enumeration order :)
> >
> > This is an problem, But I think this can be solved by implementing some of the
> > routines in the network device.
>
> I don't, see the rules that your distro ships today for persistant
> network devices, it's already there, no need to change the kernel at
> all.
The udev persistent net rules work tolerably well for a single system
with a stable set of net devices.
They do not solve the problem Matt's talking about, which is lack of
consistency between multiple systems, because the initial enumeration
order is not predictable.
They also result in name changes when a NIC (or motherboard) is swapped.
For some users, that's fine; for others, it's not.
The ability to specify NICs by port name or PCI address should solve
these problems.
Ben.
--
Ben Hutchings, Senior Software Engineer, Solarflare Communications
Not speaking for my employer; that's the marketing department's job.
They asked us to note that Solarflare product names are trademarked.
^ permalink raw reply
* Re: [Bonding-devel] [PATCH] net, bonding: Add return statement in bond_create_proc_entry.
From: Nicolas de Pesloüan @ 2009-10-10 19:19 UTC (permalink / raw)
To: Rakib Mullick
Cc: Jay Vosburgh, netdev, linux-kernel, Andrew Morton, bonding-devel
In-Reply-To: <b9df5fa10910091910u1b6bf14bg2781cb12c58b21f9@mail.gmail.com>
Rakib Mullick wrote:
> The function bond_create_proc_entry supposed to return int instead of void.
> And fixes the following compilation warning.
>
> drivers/net/bonding/bond_main.c: In function `bond_create_proc_entry':
> drivers/net/bonding/bond_main.c:3393: warning: control reaches end of
> non-void function
>
> ---
> Signed-off-by: Rakib Mullick <rakib.mullick@gmail.com>
>
> --- linus/drivers/net/bonding/bond_main.c 2009-10-09 17:38:35.000000000 +0600
> +++ rakib/drivers/net/bonding/bond_main.c 2009-10-09 17:47:46.000000000 +0600
> @@ -3391,6 +3391,7 @@ static void bond_destroy_proc_dir(void)
>
> static int bond_create_proc_entry(struct bonding *bond)
> {
> + return 0;
> }
This empty function is defined inside the else branch of an ifdef. The corresponding non-empty
function always return 0 and no caller of this function use the returned value.
So I suggest to change the return type of this function from int to void, instead of adding a return
0 into the empty one.
Nicolas.
^ permalink raw reply
* [net-next PATCH 0/8] qlge: Cleanup and additions for qlge.
From: Ron Mercer @ 2009-10-10 19:35 UTC (permalink / raw)
To: davem; +Cc: netdev, ron.mercer
Cleanup and a couple of small performance tweeks for qlge.
^ permalink raw reply
* [net-next PATCH 1/8] qlge: Remove explicit setting of PCI Dev CTL reg.
From: Ron Mercer @ 2009-10-10 19:35 UTC (permalink / raw)
To: davem; +Cc: netdev, ron.mercer, root
In-Reply-To: <1255203310-18114-1-git-send-email-ron.mercer@qlogic.com>
From: root <root@localhost.localdomain>
Remove explicit setting of error reporting bits.
Signed-off-by: root <root@localhost.localdomain>
Signed-off-by: Ron Mercer <ron.mercer@qlogic.com>
---
drivers/net/qlge/qlge_main.c | 16 +---------------
1 files changed, 1 insertions(+), 15 deletions(-)
diff --git a/drivers/net/qlge/qlge_main.c b/drivers/net/qlge/qlge_main.c
index 48b45df..7a9dca8 100644
--- a/drivers/net/qlge/qlge_main.c
+++ b/drivers/net/qlge/qlge_main.c
@@ -3868,8 +3868,7 @@ static int __devinit ql_init_device(struct pci_dev *pdev,
struct net_device *ndev, int cards_found)
{
struct ql_adapter *qdev = netdev_priv(ndev);
- int pos, err = 0;
- u16 val16;
+ int err = 0;
memset((void *)qdev, 0, sizeof(*qdev));
err = pci_enable_device(pdev);
@@ -3881,19 +3880,6 @@ static int __devinit ql_init_device(struct pci_dev *pdev,
qdev->ndev = ndev;
qdev->pdev = pdev;
pci_set_drvdata(pdev, ndev);
- pos = pci_find_capability(pdev, PCI_CAP_ID_EXP);
- if (pos <= 0) {
- dev_err(&pdev->dev, PFX "Cannot find PCI Express capability, "
- "aborting.\n");
- return pos;
- } else {
- pci_read_config_word(pdev, pos + PCI_EXP_DEVCTL, &val16);
- val16 &= ~PCI_EXP_DEVCTL_NOSNOOP_EN;
- val16 |= (PCI_EXP_DEVCTL_CERE |
- PCI_EXP_DEVCTL_NFERE |
- PCI_EXP_DEVCTL_FERE | PCI_EXP_DEVCTL_URRE);
- pci_write_config_word(pdev, pos + PCI_EXP_DEVCTL, val16);
- }
err = pci_request_regions(pdev, DRV_NAME);
if (err) {
--
1.6.0.2
^ permalink raw reply related
* [net-next PATCH 2/8] qlge: Set PCIE max read request size.
From: Ron Mercer @ 2009-10-10 19:35 UTC (permalink / raw)
To: davem; +Cc: netdev, ron.mercer, root
In-Reply-To: <1255203310-18114-1-git-send-email-ron.mercer@qlogic.com>
From: root <root@localhost.localdomain>
Signed-off-by: root <root@localhost.localdomain>
Signed-off-by: Ron Mercer <ron.mercer@qlogic.com>
---
drivers/net/qlge/qlge_main.c | 7 +++++++
1 files changed, 7 insertions(+), 0 deletions(-)
diff --git a/drivers/net/qlge/qlge_main.c b/drivers/net/qlge/qlge_main.c
index 7a9dca8..aeb0104 100644
--- a/drivers/net/qlge/qlge_main.c
+++ b/drivers/net/qlge/qlge_main.c
@@ -3881,6 +3881,13 @@ static int __devinit ql_init_device(struct pci_dev *pdev,
qdev->pdev = pdev;
pci_set_drvdata(pdev, ndev);
+ /* Set PCIe read request size */
+ err = pcie_set_readrq(pdev, 4096);
+ if (err) {
+ dev_err(&pdev->dev, "Set readrq failed.\n");
+ goto err_out;
+ }
+
err = pci_request_regions(pdev, DRV_NAME);
if (err) {
dev_err(&pdev->dev, "PCI region request failed.\n");
--
1.6.0.2
^ permalink raw reply related
* [net-next PATCH 3/8] qlge: Add handler for DCBX firmware event.
From: Ron Mercer @ 2009-10-10 19:35 UTC (permalink / raw)
To: davem; +Cc: netdev, ron.mercer
In-Reply-To: <1255203310-18114-1-git-send-email-ron.mercer@qlogic.com>
The driver has nothing to do, but this marker prevents the event from
showing up 'not handled'.
Signed-off-by: Ron Mercer <ron.mercer@qlogic.com>
---
drivers/net/qlge/qlge_mpi.c | 3 +++
1 files changed, 3 insertions(+), 0 deletions(-)
diff --git a/drivers/net/qlge/qlge_mpi.c b/drivers/net/qlge/qlge_mpi.c
index 99e58e3..2e83c4b 100644
--- a/drivers/net/qlge/qlge_mpi.c
+++ b/drivers/net/qlge/qlge_mpi.c
@@ -446,6 +446,9 @@ static int ql_mpi_handler(struct ql_adapter *qdev, struct mbox_params *mbcp)
ql_aen_lost(qdev, mbcp);
break;
+ case AEN_DCBX_CHG:
+ /* Need to support AEN 8110 */
+ break;
default:
QPRINTK(qdev, DRV, ERR,
"Unsupported AE %.08x.\n", mbcp->mbox_out[0]);
--
1.6.0.2
^ permalink raw reply related
* [net-next PATCH 4/8] qlge: Store firmware revision as early as possible.
From: Ron Mercer @ 2009-10-10 19:35 UTC (permalink / raw)
To: davem; +Cc: netdev, ron.mercer
In-Reply-To: <1255203310-18114-1-git-send-email-ron.mercer@qlogic.com>
Signed-off-by: Ron Mercer <ron.mercer@qlogic.com>
---
drivers/net/qlge/qlge_mpi.c | 1 +
1 files changed, 1 insertions(+), 0 deletions(-)
diff --git a/drivers/net/qlge/qlge_mpi.c b/drivers/net/qlge/qlge_mpi.c
index 2e83c4b..9c0dfe0 100644
--- a/drivers/net/qlge/qlge_mpi.c
+++ b/drivers/net/qlge/qlge_mpi.c
@@ -317,6 +317,7 @@ static void ql_init_fw_done(struct ql_adapter *qdev, struct mbox_params *mbcp)
} else {
QPRINTK(qdev, DRV, ERR, "Firmware Revision = 0x%.08x.\n",
mbcp->mbox_out[1]);
+ qdev->fw_rev_id = mbcp->mbox_out[1];
status = ql_cam_route_initialize(qdev);
if (status)
QPRINTK(qdev, IFUP, ERR,
--
1.6.0.2
^ permalink raw reply related
* [net-next PATCH 5/8] qlge: Remove inline math for small rx buf mapping.
From: Ron Mercer @ 2009-10-10 19:35 UTC (permalink / raw)
To: davem; +Cc: netdev, ron.mercer
In-Reply-To: <1255203310-18114-1-git-send-email-ron.mercer@qlogic.com>
rx_ring->sbq_buf_len now holds the length of the mapped portion of the
buffer rather than the overall length.
Signed-off-by: Ron Mercer <ron.mercer@qlogic.com>
---
drivers/net/qlge/qlge.h | 3 ++-
drivers/net/qlge/qlge_main.c | 14 +++++++-------
2 files changed, 9 insertions(+), 8 deletions(-)
diff --git a/drivers/net/qlge/qlge.h b/drivers/net/qlge/qlge.h
index e7285f0..633fcd1 100644
--- a/drivers/net/qlge/qlge.h
+++ b/drivers/net/qlge/qlge.h
@@ -54,7 +54,8 @@
#define RX_RING_SHADOW_SPACE (sizeof(u64) + \
MAX_DB_PAGES_PER_BQ(NUM_SMALL_BUFFERS) * sizeof(u64) + \
MAX_DB_PAGES_PER_BQ(NUM_LARGE_BUFFERS) * sizeof(u64))
-#define SMALL_BUFFER_SIZE 256
+#define SMALL_BUFFER_SIZE 512
+#define SMALL_BUF_MAP_SIZE (SMALL_BUFFER_SIZE / 2)
#define LARGE_BUFFER_SIZE PAGE_SIZE
#define MAX_SPLIT_SIZE 1023
#define QLGE_SB_PAD 32
diff --git a/drivers/net/qlge/qlge_main.c b/drivers/net/qlge/qlge_main.c
index aeb0104..09247ab 100644
--- a/drivers/net/qlge/qlge_main.c
+++ b/drivers/net/qlge/qlge_main.c
@@ -1147,7 +1147,7 @@ static void ql_update_sbq(struct ql_adapter *qdev, struct rx_ring *rx_ring)
sbq_desc->index);
sbq_desc->p.skb =
netdev_alloc_skb(qdev->ndev,
- rx_ring->sbq_buf_size);
+ SMALL_BUFFER_SIZE);
if (sbq_desc->p.skb == NULL) {
QPRINTK(qdev, PROBE, ERR,
"Couldn't get an skb.\n");
@@ -1157,8 +1157,8 @@ static void ql_update_sbq(struct ql_adapter *qdev, struct rx_ring *rx_ring)
skb_reserve(sbq_desc->p.skb, QLGE_SB_PAD);
map = pci_map_single(qdev->pdev,
sbq_desc->p.skb->data,
- rx_ring->sbq_buf_size /
- 2, PCI_DMA_FROMDEVICE);
+ rx_ring->sbq_buf_size,
+ PCI_DMA_FROMDEVICE);
if (pci_dma_mapping_error(qdev->pdev, map)) {
QPRINTK(qdev, IFUP, ERR, "PCI mapping failed.\n");
rx_ring->sbq_clean_idx = clean_idx;
@@ -1168,7 +1168,7 @@ static void ql_update_sbq(struct ql_adapter *qdev, struct rx_ring *rx_ring)
}
pci_unmap_addr_set(sbq_desc, mapaddr, map);
pci_unmap_len_set(sbq_desc, maplen,
- rx_ring->sbq_buf_size / 2);
+ rx_ring->sbq_buf_size);
*sbq_desc->addr = cpu_to_le64(map);
}
@@ -2692,7 +2692,7 @@ static int ql_start_rx_ring(struct ql_adapter *qdev, struct rx_ring *rx_ring)
cqicb->sbq_addr =
cpu_to_le64(rx_ring->sbq_base_indirect_dma);
cqicb->sbq_buf_size =
- cpu_to_le16((u16)(rx_ring->sbq_buf_size/2));
+ cpu_to_le16((u16)(rx_ring->sbq_buf_size));
bq_len = (rx_ring->sbq_len == 65536) ? 0 :
(u16) rx_ring->sbq_len;
cqicb->sbq_len = cpu_to_le16(bq_len);
@@ -3268,7 +3268,7 @@ static int ql_adapter_initialize(struct ql_adapter *qdev)
ql_write32(qdev, FSC, mask | value);
ql_write32(qdev, SPLT_HDR, SPLT_HDR_EP |
- min(SMALL_BUFFER_SIZE, MAX_SPLIT_SIZE));
+ min(SMALL_BUF_MAP_SIZE, MAX_SPLIT_SIZE));
/* Set RX packet routing to use port/pci function on which the
* packet arrived on in addition to usual frame routing.
@@ -3548,7 +3548,7 @@ static int ql_configure_rings(struct ql_adapter *qdev)
rx_ring->sbq_len = NUM_SMALL_BUFFERS;
rx_ring->sbq_size =
rx_ring->sbq_len * sizeof(__le64);
- rx_ring->sbq_buf_size = SMALL_BUFFER_SIZE * 2;
+ rx_ring->sbq_buf_size = SMALL_BUF_MAP_SIZE;
rx_ring->type = RX_Q;
} else {
/*
--
1.6.0.2
^ permalink raw reply related
* [net-next PATCH 6/8] qlge: Get rid of firmware handler debug code.
From: Ron Mercer @ 2009-10-10 19:35 UTC (permalink / raw)
To: davem; +Cc: netdev, ron.mercer
In-Reply-To: <1255203310-18114-1-git-send-email-ron.mercer@qlogic.com>
Signed-off-by: Ron Mercer <ron.mercer@qlogic.com>
---
drivers/net/qlge/qlge_mpi.c | 21 ---------------------
1 files changed, 0 insertions(+), 21 deletions(-)
diff --git a/drivers/net/qlge/qlge_mpi.c b/drivers/net/qlge/qlge_mpi.c
index 9c0dfe0..e497eac 100644
--- a/drivers/net/qlge/qlge_mpi.c
+++ b/drivers/net/qlge/qlge_mpi.c
@@ -1,25 +1,5 @@
#include "qlge.h"
-static void ql_display_mb_sts(struct ql_adapter *qdev,
- struct mbox_params *mbcp)
-{
- int i;
- static char *err_sts[] = {
- "Command Complete",
- "Command Not Supported",
- "Host Interface Error",
- "Checksum Error",
- "Unused Completion Status",
- "Test Failed",
- "Command Parameter Error"};
-
- QPRINTK(qdev, DRV, DEBUG, "%s.\n",
- err_sts[mbcp->mbox_out[0] & 0x0000000f]);
- for (i = 0; i < mbcp->out_count; i++)
- QPRINTK(qdev, DRV, DEBUG, "mbox_out[%d] = 0x%.08x.\n",
- i, mbcp->mbox_out[i]);
-}
-
int ql_read_mpi_reg(struct ql_adapter *qdev, u32 reg, u32 *data)
{
int status;
@@ -540,7 +520,6 @@ static int ql_mailbox_command(struct ql_adapter *qdev, struct mbox_params *mbcp)
MB_CMD_STS_GOOD) &&
((mbcp->mbox_out[0] & 0x0000f000) !=
MB_CMD_STS_INTRMDT)) {
- ql_display_mb_sts(qdev, mbcp);
status = -EIO;
}
end:
--
1.6.0.2
^ permalink raw reply related
* [net-next PATCH 7/8] qlge: Don't fail open when port is not initialized.
From: Ron Mercer @ 2009-10-10 19:35 UTC (permalink / raw)
To: davem; +Cc: netdev, ron.mercer
In-Reply-To: <1255203310-18114-1-git-send-email-ron.mercer@qlogic.com>
Signed-off-by: Ron Mercer <ron.mercer@qlogic.com>
---
drivers/net/qlge/qlge_main.c | 6 ++----
1 files changed, 2 insertions(+), 4 deletions(-)
diff --git a/drivers/net/qlge/qlge_main.c b/drivers/net/qlge/qlge_main.c
index 09247ab..9eefb11 100644
--- a/drivers/net/qlge/qlge_main.c
+++ b/drivers/net/qlge/qlge_main.c
@@ -3310,10 +3310,8 @@ static int ql_adapter_initialize(struct ql_adapter *qdev)
/* Initialize the port and set the max framesize. */
status = qdev->nic_ops->port_initialize(qdev);
- if (status) {
- QPRINTK(qdev, IFUP, ERR, "Failed to start port.\n");
- return status;
- }
+ if (status)
+ QPRINTK(qdev, IFUP, ERR, "Failed to start port.\n");
/* Set up the MAC address and frame routing filter. */
status = ql_cam_route_initialize(qdev);
--
1.6.0.2
^ permalink raw reply related
* [net-next PATCH 8/8] qlge: Add CBFC pause frame counters to ethtool stats.
From: Ron Mercer @ 2009-10-10 19:35 UTC (permalink / raw)
To: davem; +Cc: netdev, ron.mercer
In-Reply-To: <1255203310-18114-1-git-send-email-ron.mercer@qlogic.com>
Signed-off-by: Ron Mercer <ron.mercer@qlogic.com>
---
drivers/net/qlge/qlge.h | 21 ++++++++++++
drivers/net/qlge/qlge_ethtool.c | 69 +++++++++++++++++++++++++++++++++++++++
2 files changed, 90 insertions(+), 0 deletions(-)
diff --git a/drivers/net/qlge/qlge.h b/drivers/net/qlge/qlge.h
index 633fcd1..fd47691 100644
--- a/drivers/net/qlge/qlge.h
+++ b/drivers/net/qlge/qlge.h
@@ -1363,6 +1363,27 @@ struct nic_stats {
u64 rx_1024_to_1518_pkts;
u64 rx_1519_to_max_pkts;
u64 rx_len_err_pkts;
+ /*
+ * These stats come from offset 500h to 5C8h
+ * in the XGMAC register.
+ */
+ u64 tx_cbfc_pause_frames0;
+ u64 tx_cbfc_pause_frames1;
+ u64 tx_cbfc_pause_frames2;
+ u64 tx_cbfc_pause_frames3;
+ u64 tx_cbfc_pause_frames4;
+ u64 tx_cbfc_pause_frames5;
+ u64 tx_cbfc_pause_frames6;
+ u64 tx_cbfc_pause_frames7;
+ u64 rx_cbfc_pause_frames0;
+ u64 rx_cbfc_pause_frames1;
+ u64 rx_cbfc_pause_frames2;
+ u64 rx_cbfc_pause_frames3;
+ u64 rx_cbfc_pause_frames4;
+ u64 rx_cbfc_pause_frames5;
+ u64 rx_cbfc_pause_frames6;
+ u64 rx_cbfc_pause_frames7;
+ u64 rx_nic_fifo_drop;
};
/*
diff --git a/drivers/net/qlge/qlge_ethtool.c b/drivers/net/qlge/qlge_ethtool.c
index 5207394..aac6c6f 100644
--- a/drivers/net/qlge/qlge_ethtool.c
+++ b/drivers/net/qlge/qlge_ethtool.c
@@ -132,6 +132,41 @@ static void ql_update_stats(struct ql_adapter *qdev)
iter++;
}
+ /*
+ * Get Per-priority TX pause frame counter statistics.
+ */
+ for (i = 0x500; i < 0x540; i += 8) {
+ if (ql_read_xgmac_reg64(qdev, i, &data)) {
+ QPRINTK(qdev, DRV, ERR,
+ "Error reading status register 0x%.04x.\n", i);
+ goto end;
+ } else
+ *iter = data;
+ iter++;
+ }
+
+ /*
+ * Get Per-priority RX pause frame counter statistics.
+ */
+ for (i = 0x568; i < 0x5a8; i += 8) {
+ if (ql_read_xgmac_reg64(qdev, i, &data)) {
+ QPRINTK(qdev, DRV, ERR,
+ "Error reading status register 0x%.04x.\n", i);
+ goto end;
+ } else
+ *iter = data;
+ iter++;
+ }
+
+ /*
+ * Get RX NIC FIFO DROP statistics.
+ */
+ if (ql_read_xgmac_reg64(qdev, 0x5b8, &data)) {
+ QPRINTK(qdev, DRV, ERR,
+ "Error reading status register 0x%.04x.\n", i);
+ goto end;
+ } else
+ *iter = data;
end:
ql_sem_unlock(qdev, qdev->xg_sem_mask);
quit:
@@ -185,6 +220,23 @@ static char ql_stats_str_arr[][ETH_GSTRING_LEN] = {
{"rx_1024_to_1518_pkts"},
{"rx_1519_to_max_pkts"},
{"rx_len_err_pkts"},
+ {"tx_cbfc_pause_frames0"},
+ {"tx_cbfc_pause_frames1"},
+ {"tx_cbfc_pause_frames2"},
+ {"tx_cbfc_pause_frames3"},
+ {"tx_cbfc_pause_frames4"},
+ {"tx_cbfc_pause_frames5"},
+ {"tx_cbfc_pause_frames6"},
+ {"tx_cbfc_pause_frames7"},
+ {"rx_cbfc_pause_frames0"},
+ {"rx_cbfc_pause_frames1"},
+ {"rx_cbfc_pause_frames2"},
+ {"rx_cbfc_pause_frames3"},
+ {"rx_cbfc_pause_frames4"},
+ {"rx_cbfc_pause_frames5"},
+ {"rx_cbfc_pause_frames6"},
+ {"rx_cbfc_pause_frames7"},
+ {"rx_nic_fifo_drop"},
};
static void ql_get_strings(struct net_device *dev, u32 stringset, u8 *buf)
@@ -257,6 +309,23 @@ ql_get_ethtool_stats(struct net_device *ndev,
*data++ = s->rx_1024_to_1518_pkts;
*data++ = s->rx_1519_to_max_pkts;
*data++ = s->rx_len_err_pkts;
+ *data++ = s->tx_cbfc_pause_frames0;
+ *data++ = s->tx_cbfc_pause_frames1;
+ *data++ = s->tx_cbfc_pause_frames2;
+ *data++ = s->tx_cbfc_pause_frames3;
+ *data++ = s->tx_cbfc_pause_frames4;
+ *data++ = s->tx_cbfc_pause_frames5;
+ *data++ = s->tx_cbfc_pause_frames6;
+ *data++ = s->tx_cbfc_pause_frames7;
+ *data++ = s->rx_cbfc_pause_frames0;
+ *data++ = s->rx_cbfc_pause_frames1;
+ *data++ = s->rx_cbfc_pause_frames2;
+ *data++ = s->rx_cbfc_pause_frames3;
+ *data++ = s->rx_cbfc_pause_frames4;
+ *data++ = s->rx_cbfc_pause_frames5;
+ *data++ = s->rx_cbfc_pause_frames6;
+ *data++ = s->rx_cbfc_pause_frames7;
+ *data++ = s->rx_nic_fifo_drop;
}
static int ql_get_settings(struct net_device *ndev,
--
1.6.0.2
^ permalink raw reply related
* [PATCH netnext-2.6] bonding: change bond_create_proc_entry() to return void
From: Nicolas de Pesloüan @ 2009-10-10 20:41 UTC (permalink / raw)
To: fubar, davem, netdev, bonding-devel, rakib.mullick
Cc: Nicolas de Pesloüan
In-Reply-To: <b9df5fa10910091910u1b6bf14bg2781cb12c58b21f9@mail.gmail.com>
The function bond_create_proc_entry is currently of type int.
Two versions of this function exist:
The one in the ifdef CONFIG_PROC_FS branch always return 0.
The one in the else branch (which is empty) return nothing.
When CONFIG_PROC_FS is undef, this cause the following warning:
drivers/net/bonding/bond_main.c: In function `bond_create_proc_entry':
drivers/net/bonding/bond_main.c:3393: warning: control reaches end of
non-void function
No caller of this function use the returned value.
So change the returned type from int to void and remove the
useless return 0; .
Signed-off-by: Nicolas de Pesloüan <nicolas.2p.debian@free.fr>
Reported-by: Rakib Mullick <rakib.mullick@gmail.com>
---
drivers/net/bonding/bond_main.c | 6 ++----
1 files changed, 2 insertions(+), 4 deletions(-)
diff --git a/drivers/net/bonding/bond_main.c b/drivers/net/bonding/bond_main.c
index ef6af1c..feb03ad 100644
--- a/drivers/net/bonding/bond_main.c
+++ b/drivers/net/bonding/bond_main.c
@@ -3375,7 +3375,7 @@ static const struct file_operations bond_info_fops = {
.release = seq_release,
};
-static int bond_create_proc_entry(struct bonding *bond)
+static void bond_create_proc_entry(struct bonding *bond)
{
struct net_device *bond_dev = bond->dev;
@@ -3390,8 +3390,6 @@ static int bond_create_proc_entry(struct bonding *bond)
else
memcpy(bond->proc_file_name, bond_dev->name, IFNAMSIZ);
}
-
- return 0;
}
static void bond_remove_proc_entry(struct bonding *bond)
@@ -3430,7 +3428,7 @@ static void bond_destroy_proc_dir(void)
#else /* !CONFIG_PROC_FS */
-static int bond_create_proc_entry(struct bonding *bond)
+static void bond_create_proc_entry(struct bonding *bond)
{
}
--
1.6.3.3
^ permalink raw reply related
* Re: PATCH: Network Device Naming mechanism and policy
From: Greg KH @ 2009-10-10 21:06 UTC (permalink / raw)
To: Stephen Hemminger
Cc: Matt Domsch, netdev, linux-hotplug, Narendra_K, jordan_hargrave
In-Reply-To: <20091010113219.3136fb8b@s6510>
On Sat, Oct 10, 2009 at 11:32:19AM -0700, Stephen Hemminger wrote:
>
> BTW, for our distro, we are looking into device renaming based on PCI slot
> because that is what router OS's do. Customers expect if they replace the card
> in slot 0, it will come back with the same name. This is not what server
> customers expect.
If your bios exposes the PCI slots to userspace (through the proper ACPI
namespace), doing this type of naming should be trivial with some simple
udev rules, no additional kernel infrastructure is needed.
thanks,
greg k-h
^ permalink raw reply
* Re: [PATCH 00/31] Swap over NFS -v20
From: Pavel Machek @ 2009-10-10 21:10 UTC (permalink / raw)
To: Peter Zijlstra
Cc: Christoph Hellwig, Suresh Jayaraman, Linus Torvalds,
Andrew Morton, linux-kernel, linux-mm, netdev, Neil Brown,
Miklos Szeredi, Wouter Verhelst, trond.myklebust
In-Reply-To: <1255177421.11081.0.camel@twins>
On Sat 2009-10-10 14:23:41, Peter Zijlstra wrote:
> On Sat, 2009-10-10 at 14:06 +0200, Pavel Machek wrote:
> > Hi!
> >
> > > > One of them
> > > > would be the whole VM/net work to just make swap over nbd/iscsi safe.
> > >
> > > Getting those two 'fixed' is going to be tons of interesting work
> > > because they involve interaction with userspace daemons.
> > >
> > > NBD has fairly simple userspace, but iSCSI has a rather large userspace
> > > footprint and a rather complicated user/kernel interaction which will be
> > > mighty interesting to get allocation safe.
> > >
> > > Ideally the swap-over-$foo bits have no userspace component.
> > >
> > > That said, Wouter is the NBD userspace maintainer and has expressed
> > > interest into looking at making that work, but its sure going to be
> > > non-trivial, esp. since exposing PF_MEMALLOC to userspace is a, not over
> > > my dead-bodym like thing.
> >
> > Well, as long as nbd-server is on separate machine (with real swap),
> > safe swapping over network should be ok, without PF_MEMALLOC for
> > userspace or similar nightmares, right?
>
> Nope, as soon as the nbd-client looses its connection you're up shit
> creek.
Oops, right. Putting reconnect logic into the kernel would make sense.
I misunderstood your proposal. I thought you'd want to put
nbd-_server_ into the kernel too. I guess we violently agree that
that's unneccessary.
Pavel
--
(english) http://www.livejournal.com/~pavelmachek
(cesky, pictures) http://atrey.karlin.mff.cuni.cz/~pavel/picture/horses/blog.html
--
To unsubscribe, send a message with 'unsubscribe linux-mm' in
the body to majordomo@kvack.org. For more info on Linux MM,
see: http://www.linux-mm.org/ .
Don't email: <a href=mailto:"dont@kvack.org"> email@kvack.org </a>
^ permalink raw reply
* Re: PATCH: Network Device Naming mechanism and policy
From: Greg KH @ 2009-10-10 21:10 UTC (permalink / raw)
To: Ben Hutchings
Cc: Sujit K M, Matt Domsch, Stephen Hemminger, netdev, linux-hotplug,
Narendra_K, jordan_hargrave
In-Reply-To: <1255201230.25061.60.camel@localhost>
On Sat, Oct 10, 2009 at 08:00:30PM +0100, Ben Hutchings wrote:
> On the other hand, the netlink configuration APIs already use ifindex so
> it may be better just to say that the device ioctls are deprecated and
> applications should use netlink.
I thought that is what was already encouraged to happen.
> > > > That is why all distros name network devices based on the only
> > > > deterministic thing they have today, the MAC address. ?I still fail to
> > > > see why you do not like this solution, it is honestly the only way to
> > > > properly name network devices in a sane manner.
> > >
> > > This is feature that needs to be implemented. As per the rules followed.
> >
> > This feature is already implemented today, all distros have it.
>
> No, see below.
Yes, if not, file a bug in your distro, all of the infrastructure is
already in place, and the udev rules and scripts are already written.
> > > > All distros also provide a way to easily rename the network devices, to
> > > > place a specific name on a specific MAC address, so again, this should
> > > > all be solved already.
> > > >
> > > > No matter how badly your BIOS teams mess up the PCI enumeration order :)
> > >
> > > This is an problem, But I think this can be solved by implementing some of the
> > > routines in the network device.
> >
> > I don't, see the rules that your distro ships today for persistant
> > network devices, it's already there, no need to change the kernel at
> > all.
>
> The udev persistent net rules work tolerably well for a single system
> with a stable set of net devices.
>
> They do not solve the problem Matt's talking about, which is lack of
> consistency between multiple systems, because the initial enumeration
> order is not predictable.
Again, you name the device as a MAC address. Or something else that the
BIOS exports in a unique manner (PCI slot name, etc.). That is
consistant. If not, then fix the BIOS.
> They also result in name changes when a NIC (or motherboard) is swapped.
> For some users, that's fine; for others, it's not.
>
> The ability to specify NICs by port name or PCI address should solve
> these problems.
That can be done today quite easily. But note that PCI addresses are
not guaranteed to be stable. As lots of machines are known to have
happen.
Again, none of this requires any kernel changes today at all, let alone
adding dummy char devices for network devices.
thanks,
greg k-h
^ permalink raw reply
* Re: PATCH: Network Device Naming mechanism and policy
From: Greg KH @ 2009-10-10 21:13 UTC (permalink / raw)
To: Bryan Kadzban
Cc: Matt Domsch, Stephen Hemminger, netdev, linux-hotplug, Narendra_K,
jordan_hargrave
In-Reply-To: <4AD0C598.4070403@kadzban.is-a-geek.net>
On Sat, Oct 10, 2009 at 10:34:16AM -0700, Bryan Kadzban wrote:
> Greg KH wrote:
> > On Sat, Oct 10, 2009 at 07:47:32AM -0500, Matt Domsch wrote:
> >> On Fri, Oct 09, 2009 at 10:23:08PM -0700, Greg KH wrote:
> >>> On Fri, Oct 09, 2009 at 11:40:57PM -0500, Matt Domsch wrote:
> >>>> The fundamental roadblock to this is that enumeration !=
> >>>> naming, except that it is for network devices, and we keep
> >>>> changing the enumeration order.
> >>> No, the hardware changes the enumeration order, it places _no_
> >>> guarantees on what order stuff will be found in. So this is not
> >>> the kernel changing, just to be clear.
> >> Over time the kernel has changed its enumeration mechanisms, and
> >> introduced parallelism into the process (which is a good thing),
> >> which, from a user perspective, makes names nondeterministic. Yes,
> >> fixing this up by hard-coding MAC addresses after install has been
> >> the traditional mechanism to address this. I think there's a
> >> better way.
> >
> > Ok, but that way can be done in userspace, without the need for this
> > char device, right?
>
> For the record -- when I tried to send a patch that did exactly this
> (provided an option to use by-path persistence for network drivers), it
> was rejected because "that doesn't work for USB".
>
> True, it doesn't. But by-mac (what we have today) doesn't work for
> replacing motherboards in a random home system (that can't override the
> MAC address in the BIOS), either.
If you replace a motherboard, you honestly expect no configuration to be
needed to be changed? If so, then don't use the MAC naming scheme for
your systems.
> > But this code is not a requirement to "solve" the fact that network
> > devices can show up in different order, that problem can be solved as
> > long as the user picks a single way to name the devices, using tools
> > that are already present today in distros.
>
> This code is not a requirement, no. But -- as you say -- it does
> provide a halfway-decent way to assign multiple names to a NIC. And
> that provides admins the choice to use a couple different persistence
> schemes, depending on how they expect their hardware to work.
But the names need to then be resolved back to a "real" kernel name in
order to do anything with that network connection, as the char devices
are not real ones. So that adds an additional layer of complexity on
all of the system configuration tools.
thanks,
greg k-h
^ permalink raw reply
* [PATCH] ax25: unsigned cannot be less than 0 in ax25_ctl_ioctl()
From: Roel Kluin @ 2009-10-10 21:22 UTC (permalink / raw)
To: Joerg Reuter, linux-hams, Andrew Morton, netdev
struct ax25_ctl_struct member `arg' is unsigned and cannot be less
than 0.
Signed-off-by: Roel Kluin <roel.kluin@gmail.com>
---
If the ax25_ctl.arg limit is known to be lower, please suggest
other values.
diff --git a/net/ax25/af_ax25.c b/net/ax25/af_ax25.c
index f454607..0d99704 100644
--- a/net/ax25/af_ax25.c
+++ b/net/ax25/af_ax25.c
@@ -398,14 +398,14 @@ static int ax25_ctl_ioctl(const unsigned int cmd, void __user *arg)
break;
case AX25_T1:
- if (ax25_ctl.arg < 1)
+ if (ax25_ctl.arg < 1 || ax25_ctl.arg * HZ > ULONG_MAX)
goto einval_put;
ax25->rtt = (ax25_ctl.arg * HZ) / 2;
ax25->t1 = ax25_ctl.arg * HZ;
break;
case AX25_T2:
- if (ax25_ctl.arg < 1)
+ if (ax25_ctl.arg < 1 || ax25_ctl.arg * HZ > ULONG_MAX)
goto einval_put;
ax25->t2 = ax25_ctl.arg * HZ;
break;
@@ -418,13 +418,13 @@ static int ax25_ctl_ioctl(const unsigned int cmd, void __user *arg)
break;
case AX25_T3:
- if (ax25_ctl.arg < 0)
+ if (ax25_ctl.arg * HZ > ULONG_MAX)
goto einval_put;
ax25->t3 = ax25_ctl.arg * HZ;
break;
case AX25_IDLE:
- if (ax25_ctl.arg < 0)
+ if (ax25_ctl.arg * 60 * HZ > ULONG_MAX)
goto einval_put;
ax25->idle = ax25_ctl.arg * 60 * HZ;
break;
^ permalink raw reply related
* Re: Very strange issues with ethernet wake on lan
From: Maxim Levitsky @ 2009-10-10 21:37 UTC (permalink / raw)
To: Rafael J. Wysocki
Cc: netdev@vger.kernel.org, linux-pm@lists.linux-foundation.org
In-Reply-To: <200909292228.18200.rjw@sisk.pl>
On Tue, 2009-09-29 at 22:28 +0200, Rafael J. Wysocki wrote:
> On Sunday 16 August 2009, Maxim Levitsky wrote:
> > Hi,
> >
> > I have recently put back the davicom dm9009 ethernet card into my
> > computer.
> >
> > Some long time ago, I have written its suspend/resume routines.
> > Now I see that few things have changed, like I need to enable wake in
> > sysfs or better patch the code to do so, some nice helpers like
> > pci_prepare_to_sleep have arrived, etc.
> >
> >
> > I narrowed the strange issue down to following situation:
> >
> > I reload dmfe.ko (and networkmanager is disabled)
> > I don't ifup the device, thus pretty much no hardware initialization
> > takes place (but this appears not to matter anyway)
> >
> > I then suspend the system, and WOL doesn't work (I have patched the
> > driver to enable WOL automaticly)
> >
> > I then, suspend again. WOL works, and continues to work as long as I
> > don't reload the driver. If I do, same situation repeats.
> >
> > Also, after a boot, WOL works, so a reload cycle triggers that issue.
> >
> > And most importantly, if I don't do a
> >
> > pci_set_power_state(pci_dev, pci_choose_state (pci_dev, state));
> >
> > in .suspend, then WOL always works.
> >
> > and I have even tried to set state manually to PCI_D3hot or PCI_D3cold,
> >
> > I also tried to use pci_save_state
> >
> >
> > I also have 2 copies of this card, and both have this issue.
> > I also tried 2 pci slots.
> >
> > Kernel is vanilla 2.6.31-rc5
>
> Please check if this still happens with 2.6.32-rc1.
It doesn't! (-git as of today tested)
Thanks,
Best regards,
Maxim Levitsky
>
> Best,
> Rafael
> --
> To unsubscribe from this list: send the line "unsubscribe netdev" 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
* Re: Real networking namespace
From: Paul Moore @ 2009-10-10 21:40 UTC (permalink / raw)
To: shemminger; +Cc: sds, linux-security-module, viro, netdev, jmorris
In-Reply-To: <20091009190820.0a0f09c2@nehalam>
------- Original message -------
> From: Stephen Hemminger <shemminger@linux-foundation.org>
> Cc: sds@tycho.nsa.gov, linux-security-module@vger.kernel.org,
> viro@zeniv.linux.org.uk, netdev@vger.kernel.org, jmorris@namei.org
> Sent: 10/9, 22:08
>
> On Fri, 9 Oct 2009 18:12:15 -0400
> Paul Moore <paul.moore@hp.com> wrote:
>
>> On Friday 09 October 2009 12:44:52 pm Stephen Smalley wrote:
>> > On Fri, 2009-10-09 at 12:37 -0400, Stephen Smalley wrote:
>> > > On Fri, 2009-10-09 at 08:38 -0700, Stephen Hemminger wrote:
>> > > > The existing networking namespace model is unattractive for what I
>> > > > want, has anyone investigated better alternatives?
>> > > >
>> > > > I would like to be able to allow access to a network interface and
>> > > > associated objects (routing tables etc), to be controlled by
>> Mandatory
>> > > > Access Control API's. I.e grant access to eth0 and to only certain
>> > > > processes. Some the issues with the existing models are:
>> > > > * eth0 and associated objects don't really exist in filesystem
>> so
>> > > > not subject to LSM style control (SeLinux/SMACK/TOMOYO)
>>
>> As Stephen points out, SELinux does have the ability to assign security
>> labels
>> to network interfaces, check out the 'semanage' command. A while back I
>> wrote
>> up something about the SELinux network "ingress/egress" access controls:
>>
>> * http://paulmoore.livejournal.com/2128.html
>
> I was hoping to be able to not have inaccessible interfaces visible,
> is it possible to not have interfaces show up in commands like:
> ip link show
> or sysfs?
I haven't looked at the code for 'ip' but I'm pretty sure it uses netlink
to configure the kernel, yes? If that is the case, no I don't believe any
of the current LSMs provide that level of granularity (netlink, generic
netlink in particular, is a bit of a problem spot at the moment). As for
sysfs, I don't believe we label the interface related files based on their
semanage labels but I could be wrong - we've got plenty of good people
already working on fs labeling so I spend most of my time worrying about
network labeling.
--
paul moore
linux @ hp
^ permalink raw reply
* Re: Very strange issues with ethernet wake on lan
From: Rafael J. Wysocki @ 2009-10-10 21:45 UTC (permalink / raw)
To: Maxim Levitsky
Cc: netdev@vger.kernel.org, linux-pm@lists.linux-foundation.org
In-Reply-To: <1255210639.4199.0.camel@maxim-laptop>
On Saturday 10 October 2009, Maxim Levitsky wrote:
> On Tue, 2009-09-29 at 22:28 +0200, Rafael J. Wysocki wrote:
> > On Sunday 16 August 2009, Maxim Levitsky wrote:
> > > Hi,
> > >
> > > I have recently put back the davicom dm9009 ethernet card into my
> > > computer.
> > >
> > > Some long time ago, I have written its suspend/resume routines.
> > > Now I see that few things have changed, like I need to enable wake in
> > > sysfs or better patch the code to do so, some nice helpers like
> > > pci_prepare_to_sleep have arrived, etc.
> > >
> > >
> > > I narrowed the strange issue down to following situation:
> > >
> > > I reload dmfe.ko (and networkmanager is disabled)
> > > I don't ifup the device, thus pretty much no hardware initialization
> > > takes place (but this appears not to matter anyway)
> > >
> > > I then suspend the system, and WOL doesn't work (I have patched the
> > > driver to enable WOL automaticly)
> > >
> > > I then, suspend again. WOL works, and continues to work as long as I
> > > don't reload the driver. If I do, same situation repeats.
> > >
> > > Also, after a boot, WOL works, so a reload cycle triggers that issue.
> > >
> > > And most importantly, if I don't do a
> > >
> > > pci_set_power_state(pci_dev, pci_choose_state (pci_dev, state));
> > >
> > > in .suspend, then WOL always works.
> > >
> > > and I have even tried to set state manually to PCI_D3hot or PCI_D3cold,
> > >
> > > I also tried to use pci_save_state
> > >
> > >
> > > I also have 2 copies of this card, and both have this issue.
> > > I also tried 2 pci slots.
> > >
> > > Kernel is vanilla 2.6.31-rc5
> >
> > Please check if this still happens with 2.6.32-rc1.
>
> It doesn't! (-git as of today tested)
Great, thanks for verifying.
Best,
Rafael
^ permalink raw reply
* [PATCH 1/7] bnx2x: Refactor bnx2x_sp_post().
From: Michael Chan @ 2009-10-10 23:46 UTC (permalink / raw)
To: davem; +Cc: netdev, michaelc, shmulikr, eilong, Michael Chan
Some of the SPQ (slow-path queue) operations will be used
by the cnic code in later patches.
Signed-off-by: Shmulik Ravid - Rabinovitz <shmulikr@broadcom.com>
Signed-off-by: Michael Chan <mchan@broadcom.com>
Acked-by: Eilon Greenstein <eilong@broadcom.com>
---
drivers/net/bnx2x_main.c | 62 ++++++++++++++++++++++++++++-----------------
1 files changed, 38 insertions(+), 24 deletions(-)
diff --git a/drivers/net/bnx2x_main.c b/drivers/net/bnx2x_main.c
index c0abfc4..713d669 100644
--- a/drivers/net/bnx2x_main.c
+++ b/drivers/net/bnx2x_main.c
@@ -2638,11 +2638,40 @@ static void bnx2x_dcc_event(struct bnx2x *bp, u32 dcc_event)
bnx2x_fw_command(bp, DRV_MSG_CODE_DCC_OK);
}
+/* must be called under the spq lock */
+static inline struct eth_spe *bnx2x_sp_get_next(struct bnx2x *bp)
+{
+ struct eth_spe *next_spe = bp->spq_prod_bd;
+
+ if (bp->spq_prod_bd == bp->spq_last_bd) {
+ bp->spq_prod_bd = bp->spq;
+ bp->spq_prod_idx = 0;
+ DP(NETIF_MSG_TIMER, "end of spq\n");
+ } else {
+ bp->spq_prod_bd++;
+ bp->spq_prod_idx++;
+ }
+ return next_spe;
+}
+
+/* must be called under the spq lock */
+static inline void bnx2x_sp_prod_update(struct bnx2x *bp)
+{
+ int func = BP_FUNC(bp);
+
+ /* Make sure that BD data is updated before writing the producer */
+ wmb();
+
+ REG_WR(bp, BAR_XSTRORM_INTMEM + XSTORM_SPQ_PROD_OFFSET(func),
+ bp->spq_prod_idx);
+ mmiowb();
+}
+
/* the slow path queue is odd since completions arrive on the fastpath ring */
static int bnx2x_sp_post(struct bnx2x *bp, int command, int cid,
u32 data_hi, u32 data_lo, int common)
{
- int func = BP_FUNC(bp);
+ struct eth_spe *spe;
DP(BNX2X_MSG_SP/*NETIF_MSG_TIMER*/,
"SPQE (%x:%x) command %d hw_cid %x data (%x:%x) left %x\n",
@@ -2664,38 +2693,23 @@ static int bnx2x_sp_post(struct bnx2x *bp, int command, int cid,
return -EBUSY;
}
+ spe = bnx2x_sp_get_next(bp);
+
/* CID needs port number to be encoded int it */
- bp->spq_prod_bd->hdr.conn_and_cmd_data =
+ spe->hdr.conn_and_cmd_data =
cpu_to_le32(((command << SPE_HDR_CMD_ID_SHIFT) |
HW_CID(bp, cid)));
- bp->spq_prod_bd->hdr.type = cpu_to_le16(ETH_CONNECTION_TYPE);
+ spe->hdr.type = cpu_to_le16(ETH_CONNECTION_TYPE);
if (common)
- bp->spq_prod_bd->hdr.type |=
+ spe->hdr.type |=
cpu_to_le16((1 << SPE_HDR_COMMON_RAMROD_SHIFT));
- bp->spq_prod_bd->data.mac_config_addr.hi = cpu_to_le32(data_hi);
- bp->spq_prod_bd->data.mac_config_addr.lo = cpu_to_le32(data_lo);
+ spe->data.mac_config_addr.hi = cpu_to_le32(data_hi);
+ spe->data.mac_config_addr.lo = cpu_to_le32(data_lo);
bp->spq_left--;
- if (bp->spq_prod_bd == bp->spq_last_bd) {
- bp->spq_prod_bd = bp->spq;
- bp->spq_prod_idx = 0;
- DP(NETIF_MSG_TIMER, "end of spq\n");
-
- } else {
- bp->spq_prod_bd++;
- bp->spq_prod_idx++;
- }
-
- /* Make sure that BD data is updated before writing the producer */
- wmb();
-
- REG_WR(bp, BAR_XSTRORM_INTMEM + XSTORM_SPQ_PROD_OFFSET(func),
- bp->spq_prod_idx);
-
- mmiowb();
-
+ bnx2x_sp_prod_update(bp);
spin_unlock_bh(&bp->spq_lock);
return 0;
}
--
1.6.4.GIT
^ permalink raw reply related
* [PATCH 2/7] bnx2x: Refactor MAC address setup code.
From: Michael Chan @ 2009-10-10 23:46 UTC (permalink / raw)
To: davem; +Cc: netdev, michaelc, shmulikr, eilong, Michael Chan
In-Reply-To: <1255218419-17320-1-git-send-email-mchan@broadcom.com>
For iSCSI MAC address setup in later patches.
Signed-off-by: Shmulik Ravid - Rabinovitz <shmulikr@broadcom.com>
Signed-off-by: Michael Chan <mchan@broadcom.com>
Acked-by: Eilon Greenstein <eilong@broadcom.com>
---
drivers/net/bnx2x.h | 4 +-
drivers/net/bnx2x_main.c | 162 ++++++++++++++++++++++++++++++++--------------
2 files changed, 114 insertions(+), 52 deletions(-)
diff --git a/drivers/net/bnx2x.h b/drivers/net/bnx2x.h
index bbf8422..1f07063 100644
--- a/drivers/net/bnx2x.h
+++ b/drivers/net/bnx2x.h
@@ -863,8 +863,8 @@ struct bnx2x {
/* Flags for marking that there is a STAT_QUERY or
SET_MAC ramrod pending */
- u8 stats_pending;
- u8 set_mac_pending;
+ int stats_pending;
+ int set_mac_pending;
/* End of fields used in the performance code paths */
diff --git a/drivers/net/bnx2x_main.c b/drivers/net/bnx2x_main.c
index 713d669..02ce3b3 100644
--- a/drivers/net/bnx2x_main.c
+++ b/drivers/net/bnx2x_main.c
@@ -1026,12 +1026,15 @@ static void bnx2x_sp_event(struct bnx2x_fastpath *fp,
case (RAMROD_CMD_ID_ETH_SET_MAC | BNX2X_STATE_OPEN):
case (RAMROD_CMD_ID_ETH_SET_MAC | BNX2X_STATE_DIAG):
DP(NETIF_MSG_IFUP, "got set mac ramrod\n");
- bp->set_mac_pending = 0;
+ bp->set_mac_pending--;
+ smp_wmb();
break;
case (RAMROD_CMD_ID_ETH_SET_MAC | BNX2X_STATE_CLOSING_WAIT4_HALT):
case (RAMROD_CMD_ID_ETH_SET_MAC | BNX2X_STATE_DISABLED):
DP(NETIF_MSG_IFDOWN, "got (un)set mac ramrod\n");
+ bp->set_mac_pending--;
+ smp_wmb();
break;
default:
@@ -2530,7 +2533,7 @@ u32 bnx2x_fw_command(struct bnx2x *bp, u32 command)
}
static void bnx2x_set_storm_rx_mode(struct bnx2x *bp);
-static void bnx2x_set_mac_addr_e1h(struct bnx2x *bp, int set);
+static void bnx2x_set_eth_mac_addr_e1h(struct bnx2x *bp, int set);
static void bnx2x_set_rx_mode(struct net_device *dev);
static void bnx2x_e1h_disable(struct bnx2x *bp)
@@ -2546,7 +2549,7 @@ static void bnx2x_e1h_disable(struct bnx2x *bp)
REG_WR(bp, NIG_REG_LLH0_FUNC_EN + port*8, 0);
- bnx2x_set_mac_addr_e1h(bp, 0);
+ bnx2x_set_eth_mac_addr_e1h(bp, 0);
for (i = 0; i < MC_HASH_SIZE; i++)
REG_WR(bp, MC_HASH_OFFSET(bp, i), 0);
@@ -2560,7 +2563,7 @@ static void bnx2x_e1h_enable(struct bnx2x *bp)
REG_WR(bp, NIG_REG_LLH0_FUNC_EN + port*8, 1);
- bnx2x_set_mac_addr_e1h(bp, 1);
+ bnx2x_set_eth_mac_addr_e1h(bp, 1);
/* Tx queue should be only reenabled */
netif_tx_wake_all_queues(bp->dev);
@@ -7036,7 +7039,19 @@ static void bnx2x_netif_stop(struct bnx2x *bp, int disable_hw)
* Init service functions
*/
-static void bnx2x_set_mac_addr_e1(struct bnx2x *bp, int set)
+/**
+ * Sets a MAC in a CAM for a few L2 Clients for E1 chip
+ *
+ * @param bp driver descriptor
+ * @param set set or clear an entry (1 or 0)
+ * @param mac pointer to a buffer containing a MAC
+ * @param cl_bit_vec bit vector of clients to register a MAC for
+ * @param cam_offset offset in a CAM to use
+ * @param with_bcast set broadcast MAC as well
+ */
+static void bnx2x_set_mac_addr_e1_gen(struct bnx2x *bp, int set, u8 *mac,
+ u32 cl_bit_vec, u8 cam_offset,
+ u8 with_bcast)
{
struct mac_configuration_cmd *config = bnx2x_sp(bp, mac_config);
int port = BP_PORT(bp);
@@ -7045,25 +7060,25 @@ static void bnx2x_set_mac_addr_e1(struct bnx2x *bp, int set)
* unicasts 0-31:port0 32-63:port1
* multicast 64-127:port0 128-191:port1
*/
- config->hdr.length = 2;
- config->hdr.offset = port ? 32 : 0;
- config->hdr.client_id = bp->fp->cl_id;
+ config->hdr.length = 1 + (with_bcast ? 1 : 0);
+ config->hdr.offset = cam_offset;
+ config->hdr.client_id = 0xff;
config->hdr.reserved1 = 0;
/* primary MAC */
config->config_table[0].cam_entry.msb_mac_addr =
- swab16(*(u16 *)&bp->dev->dev_addr[0]);
+ swab16(*(u16 *)&mac[0]);
config->config_table[0].cam_entry.middle_mac_addr =
- swab16(*(u16 *)&bp->dev->dev_addr[2]);
+ swab16(*(u16 *)&mac[2]);
config->config_table[0].cam_entry.lsb_mac_addr =
- swab16(*(u16 *)&bp->dev->dev_addr[4]);
+ swab16(*(u16 *)&mac[4]);
config->config_table[0].cam_entry.flags = cpu_to_le16(port);
if (set)
config->config_table[0].target_table_entry.flags = 0;
else
CAM_INVALIDATE(config->config_table[0]);
config->config_table[0].target_table_entry.clients_bit_vector =
- cpu_to_le32(1 << BP_L_ID(bp));
+ cpu_to_le32(cl_bit_vec);
config->config_table[0].target_table_entry.vlan_id = 0;
DP(NETIF_MSG_IFUP, "%s MAC (%04x:%04x:%04x)\n",
@@ -7073,47 +7088,58 @@ static void bnx2x_set_mac_addr_e1(struct bnx2x *bp, int set)
config->config_table[0].cam_entry.lsb_mac_addr);
/* broadcast */
- config->config_table[1].cam_entry.msb_mac_addr = cpu_to_le16(0xffff);
- config->config_table[1].cam_entry.middle_mac_addr = cpu_to_le16(0xffff);
- config->config_table[1].cam_entry.lsb_mac_addr = cpu_to_le16(0xffff);
- config->config_table[1].cam_entry.flags = cpu_to_le16(port);
- if (set)
- config->config_table[1].target_table_entry.flags =
- TSTORM_CAM_TARGET_TABLE_ENTRY_BROADCAST;
- else
- CAM_INVALIDATE(config->config_table[1]);
- config->config_table[1].target_table_entry.clients_bit_vector =
- cpu_to_le32(1 << BP_L_ID(bp));
- config->config_table[1].target_table_entry.vlan_id = 0;
+ if (with_bcast) {
+ config->config_table[1].cam_entry.msb_mac_addr =
+ cpu_to_le16(0xffff);
+ config->config_table[1].cam_entry.middle_mac_addr =
+ cpu_to_le16(0xffff);
+ config->config_table[1].cam_entry.lsb_mac_addr =
+ cpu_to_le16(0xffff);
+ config->config_table[1].cam_entry.flags = cpu_to_le16(port);
+ if (set)
+ config->config_table[1].target_table_entry.flags =
+ TSTORM_CAM_TARGET_TABLE_ENTRY_BROADCAST;
+ else
+ CAM_INVALIDATE(config->config_table[1]);
+ config->config_table[1].target_table_entry.clients_bit_vector =
+ cpu_to_le32(cl_bit_vec);
+ config->config_table[1].target_table_entry.vlan_id = 0;
+ }
bnx2x_sp_post(bp, RAMROD_CMD_ID_ETH_SET_MAC, 0,
U64_HI(bnx2x_sp_mapping(bp, mac_config)),
U64_LO(bnx2x_sp_mapping(bp, mac_config)), 0);
}
-static void bnx2x_set_mac_addr_e1h(struct bnx2x *bp, int set)
+/**
+ * Sets a MAC in a CAM for a few L2 Clients for E1H chip
+ *
+ * @param bp driver descriptor
+ * @param set set or clear an entry (1 or 0)
+ * @param mac pointer to a buffer containing a MAC
+ * @param cl_bit_vec bit vector of clients to register a MAC for
+ * @param cam_offset offset in a CAM to use
+ */
+static void bnx2x_set_mac_addr_e1h_gen(struct bnx2x *bp, int set, u8 *mac,
+ u32 cl_bit_vec, u8 cam_offset)
{
struct mac_configuration_cmd_e1h *config =
(struct mac_configuration_cmd_e1h *)bnx2x_sp(bp, mac_config);
- /* CAM allocation for E1H
- * unicasts: by func number
- * multicast: 20+FUNC*20, 20 each
- */
config->hdr.length = 1;
- config->hdr.offset = BP_FUNC(bp);
- config->hdr.client_id = bp->fp->cl_id;
+ config->hdr.offset = cam_offset;
+ config->hdr.client_id = 0xff;
config->hdr.reserved1 = 0;
/* primary MAC */
config->config_table[0].msb_mac_addr =
- swab16(*(u16 *)&bp->dev->dev_addr[0]);
+ swab16(*(u16 *)&mac[0]);
config->config_table[0].middle_mac_addr =
- swab16(*(u16 *)&bp->dev->dev_addr[2]);
+ swab16(*(u16 *)&mac[2]);
config->config_table[0].lsb_mac_addr =
- swab16(*(u16 *)&bp->dev->dev_addr[4]);
+ swab16(*(u16 *)&mac[4]);
config->config_table[0].clients_bit_vector =
- cpu_to_le32(1 << BP_L_ID(bp));
+ cpu_to_le32(cl_bit_vec);
config->config_table[0].vlan_id = 0;
config->config_table[0].e1hov_id = cpu_to_le16(bp->e1hov);
if (set)
@@ -7122,11 +7148,11 @@ static void bnx2x_set_mac_addr_e1h(struct bnx2x *bp, int set)
config->config_table[0].flags =
MAC_CONFIGURATION_ENTRY_E1H_ACTION_TYPE;
- DP(NETIF_MSG_IFUP, "%s MAC (%04x:%04x:%04x) E1HOV %d CLID %d\n",
+ DP(NETIF_MSG_IFUP, "%s MAC (%04x:%04x:%04x) E1HOV %d CLID mask %d\n",
(set ? "setting" : "clearing"),
config->config_table[0].msb_mac_addr,
config->config_table[0].middle_mac_addr,
- config->config_table[0].lsb_mac_addr, bp->e1hov, BP_L_ID(bp));
+ config->config_table[0].lsb_mac_addr, bp->e1hov, cl_bit_vec);
bnx2x_sp_post(bp, RAMROD_CMD_ID_ETH_SET_MAC, 0,
U64_HI(bnx2x_sp_mapping(bp, mac_config)),
@@ -7178,6 +7204,31 @@ static int bnx2x_wait_ramrod(struct bnx2x *bp, int state, int idx,
return -EBUSY;
}
+static void bnx2x_set_eth_mac_addr_e1h(struct bnx2x *bp, int set)
+{
+ bp->set_mac_pending++;
+ smp_wmb();
+
+ bnx2x_set_mac_addr_e1h_gen(bp, set, bp->dev->dev_addr,
+ (1 << bp->fp->cl_id), BP_FUNC(bp));
+
+ /* Wait for a completion */
+ bnx2x_wait_ramrod(bp, 0, 0, &bp->set_mac_pending, set ? 0 : 1);
+}
+
+static void bnx2x_set_eth_mac_addr_e1(struct bnx2x *bp, int set)
+{
+ bp->set_mac_pending++;
+ smp_wmb();
+
+ bnx2x_set_mac_addr_e1_gen(bp, set, bp->dev->dev_addr,
+ (1 << bp->fp->cl_id), (BP_PORT(bp) ? 32 : 0),
+ 1);
+
+ /* Wait for a completion */
+ bnx2x_wait_ramrod(bp, 0, 0, &bp->set_mac_pending, set ? 0 : 1);
+}
+
static int bnx2x_setup_leading(struct bnx2x *bp)
{
int rc;
@@ -7452,9 +7503,9 @@ static int bnx2x_nic_load(struct bnx2x *bp, int load_mode)
}
if (CHIP_IS_E1(bp))
- bnx2x_set_mac_addr_e1(bp, 1);
+ bnx2x_set_eth_mac_addr_e1(bp, 1);
else
- bnx2x_set_mac_addr_e1h(bp, 1);
+ bnx2x_set_eth_mac_addr_e1h(bp, 1);
}
if (bp->port.pmf)
@@ -7717,7 +7768,7 @@ static int bnx2x_nic_unload(struct bnx2x *bp, int unload_mode)
struct mac_configuration_cmd *config =
bnx2x_sp(bp, mcast_config);
- bnx2x_set_mac_addr_e1(bp, 0);
+ bnx2x_set_eth_mac_addr_e1(bp, 0);
for (i = 0; i < config->hdr.length; i++)
CAM_INVALIDATE(config->config_table[i]);
@@ -7730,6 +7781,9 @@ static int bnx2x_nic_unload(struct bnx2x *bp, int unload_mode)
config->hdr.client_id = bp->fp->cl_id;
config->hdr.reserved1 = 0;
+ bp->set_mac_pending++;
+ smp_wmb();
+
bnx2x_sp_post(bp, RAMROD_CMD_ID_ETH_SET_MAC, 0,
U64_HI(bnx2x_sp_mapping(bp, mcast_config)),
U64_LO(bnx2x_sp_mapping(bp, mcast_config)), 0);
@@ -7737,7 +7791,7 @@ static int bnx2x_nic_unload(struct bnx2x *bp, int unload_mode)
} else { /* E1H */
REG_WR(bp, NIG_REG_LLH0_FUNC_EN + port*8, 0);
- bnx2x_set_mac_addr_e1h(bp, 0);
+ bnx2x_set_eth_mac_addr_e1h(bp, 0);
for (i = 0; i < MC_HASH_SIZE; i++)
REG_WR(bp, MC_HASH_OFFSET(bp, i), 0);
@@ -8520,6 +8574,14 @@ static void __devinit bnx2x_link_settings_requested(struct bnx2x *bp)
bp->link_params.req_flow_ctrl, bp->port.advertising);
}
+static void __devinit bnx2x_set_mac_buf(u8 *mac_buf, u32 mac_lo, u16 mac_hi)
+{
+ mac_hi = cpu_to_be16(mac_hi);
+ mac_lo = cpu_to_be32(mac_lo);
+ memcpy(mac_buf, &mac_hi, sizeof(mac_hi));
+ memcpy(mac_buf + sizeof(mac_hi), &mac_lo, sizeof(mac_lo));
+}
+
static void __devinit bnx2x_get_port_hwinfo(struct bnx2x *bp)
{
int port = BP_PORT(bp);
@@ -8601,12 +8663,7 @@ static void __devinit bnx2x_get_port_hwinfo(struct bnx2x *bp)
val2 = SHMEM_RD(bp, dev_info.port_hw_config[port].mac_upper);
val = SHMEM_RD(bp, dev_info.port_hw_config[port].mac_lower);
- bp->dev->dev_addr[0] = (u8)(val2 >> 8 & 0xff);
- bp->dev->dev_addr[1] = (u8)(val2 & 0xff);
- bp->dev->dev_addr[2] = (u8)(val >> 24 & 0xff);
- bp->dev->dev_addr[3] = (u8)(val >> 16 & 0xff);
- bp->dev->dev_addr[4] = (u8)(val >> 8 & 0xff);
- bp->dev->dev_addr[5] = (u8)(val & 0xff);
+ bnx2x_set_mac_buf(bp->dev->dev_addr, val, val2);
memcpy(bp->link_params.mac_addr, bp->dev->dev_addr, ETH_ALEN);
memcpy(bp->dev->perm_addr, bp->dev->dev_addr, ETH_ALEN);
}
@@ -10232,14 +10289,16 @@ static int bnx2x_test_intr(struct bnx2x *bp)
config->hdr.client_id = bp->fp->cl_id;
config->hdr.reserved1 = 0;
+ bp->set_mac_pending++;
+ smp_wmb();
rc = bnx2x_sp_post(bp, RAMROD_CMD_ID_ETH_SET_MAC, 0,
U64_HI(bnx2x_sp_mapping(bp, mac_config)),
U64_LO(bnx2x_sp_mapping(bp, mac_config)), 0);
if (rc == 0) {
- bp->set_mac_pending++;
for (i = 0; i < 10; i++) {
if (!bp->set_mac_pending)
break;
+ smp_rmb();
msleep_interruptible(10);
}
if (i == 10)
@@ -11337,6 +11396,9 @@ static void bnx2x_set_rx_mode(struct net_device *dev)
config->hdr.client_id = bp->fp->cl_id;
config->hdr.reserved1 = 0;
+ bp->set_mac_pending++;
+ smp_wmb();
+
bnx2x_sp_post(bp, RAMROD_CMD_ID_ETH_SET_MAC, 0,
U64_HI(bnx2x_sp_mapping(bp, mcast_config)),
U64_LO(bnx2x_sp_mapping(bp, mcast_config)),
@@ -11386,9 +11448,9 @@ static int bnx2x_change_mac_addr(struct net_device *dev, void *p)
memcpy(dev->dev_addr, addr->sa_data, dev->addr_len);
if (netif_running(dev)) {
if (CHIP_IS_E1(bp))
- bnx2x_set_mac_addr_e1(bp, 1);
+ bnx2x_set_eth_mac_addr_e1(bp, 1);
else
- bnx2x_set_mac_addr_e1h(bp, 1);
+ bnx2x_set_eth_mac_addr_e1h(bp, 1);
}
return 0;
--
1.6.4.GIT
^ permalink raw reply related
* [PATCH 4/7] bnx2x: Add main CNIC interface functions.
From: Michael Chan @ 2009-10-10 23:46 UTC (permalink / raw)
To: davem; +Cc: netdev, michaelc, shmulikr, eilong, Michael Chan
In-Reply-To: <1255218419-17320-1-git-send-email-mchan@broadcom.com>
Add the main CNIC registration, callback, MAC addr. setup functions.
Signed-off-by: Michael Chan <mchan@broadcom.com>
Signed-off-by: Shmulik Ravid - Rabinovitz <shmulikr@broadcom.com>
Acked-by: Eilon Greenstein <eilong@broadcom.com>
---
drivers/net/bnx2x.h | 4 +
drivers/net/bnx2x_main.c | 388 ++++++++++++++++++++++++++++++++++++++++++++++
drivers/net/cnic_if.h | 14 ++-
3 files changed, 404 insertions(+), 2 deletions(-)
diff --git a/drivers/net/bnx2x.h b/drivers/net/bnx2x.h
index e94ce83..60fa14f 100644
--- a/drivers/net/bnx2x.h
+++ b/drivers/net/bnx2x.h
@@ -24,6 +24,10 @@
#define BCM_VLAN 1
#endif
+#if defined(CONFIG_CNIC) || defined(CONFIG_CNIC_MODULE)
+#define BCM_CNIC 1
+#include "cnic_if.h"
+#endif
#define BNX2X_MULTI_QUEUE
diff --git a/drivers/net/bnx2x_main.c b/drivers/net/bnx2x_main.c
index f7b7110..b4e9c6e 100644
--- a/drivers/net/bnx2x_main.c
+++ b/drivers/net/bnx2x_main.c
@@ -969,6 +969,9 @@ static void bnx2x_tx_int(struct bnx2x_fastpath *fp)
}
}
+#ifdef BCM_CNIC
+static void bnx2x_cnic_cfc_comp(struct bnx2x *bp, int cid);
+#endif
static void bnx2x_sp_event(struct bnx2x_fastpath *fp,
union eth_rx_cqe *rr_cqe)
@@ -1025,6 +1028,12 @@ static void bnx2x_sp_event(struct bnx2x_fastpath *fp,
bnx2x_fp(bp, cid, state) = BNX2X_FP_STATE_CLOSED;
break;
+#ifdef BCM_CNIC
+ case (RAMROD_CMD_ID_ETH_CFC_DEL | BNX2X_STATE_OPEN):
+ DP(NETIF_MSG_IFDOWN, "got delete ramrod for CID %d\n", cid);
+ bnx2x_cnic_cfc_comp(bp, cid);
+ break;
+#endif
case (RAMROD_CMD_ID_ETH_SET_MAC | BNX2X_STATE_OPEN):
case (RAMROD_CMD_ID_ETH_SET_MAC | BNX2X_STATE_DIAG):
@@ -1810,6 +1819,20 @@ static irqreturn_t bnx2x_interrupt(int irq, void *dev_instance)
}
}
+#ifdef BCM_CNIC
+ mask = 0x2 << CNIC_SB_ID(bp);
+ if (status & (mask | 0x1)) {
+ struct cnic_ops *c_ops = NULL;
+
+ rcu_read_lock();
+ c_ops = rcu_dereference(bp->cnic_ops);
+ if (c_ops)
+ c_ops->cnic_handler(bp->cnic_data, NULL);
+ rcu_read_unlock();
+
+ status &= ~mask;
+ }
+#endif
if (unlikely(status & 0x1)) {
queue_delayed_work(bnx2x_wq, &bp->sp_task, 0);
@@ -3247,6 +3270,17 @@ static irqreturn_t bnx2x_msix_sp_int(int irq, void *dev_instance)
return IRQ_HANDLED;
#endif
+#ifdef BCM_CNIC
+ {
+ struct cnic_ops *c_ops;
+
+ rcu_read_lock();
+ c_ops = rcu_dereference(bp->cnic_ops);
+ if (c_ops)
+ c_ops->cnic_handler(bp->cnic_data, NULL);
+ rcu_read_unlock();
+ }
+#endif
queue_delayed_work(bnx2x_wq, &bp->sp_task, 0);
return IRQ_HANDLED;
@@ -7291,6 +7325,44 @@ static void bnx2x_set_eth_mac_addr_e1(struct bnx2x *bp, int set)
bnx2x_wait_ramrod(bp, 0, 0, &bp->set_mac_pending, set ? 0 : 1);
}
+#ifdef BCM_CNIC
+/**
+ * Set iSCSI MAC(s) at the next enties in the CAM after the ETH
+ * MAC(s). This function will wait until the ramdord completion
+ * returns.
+ *
+ * @param bp driver handle
+ * @param set set or clear the CAM entry
+ *
+ * @return 0 if cussess, -ENODEV if ramrod doesn't return.
+ */
+static int bnx2x_set_iscsi_eth_mac_addr(struct bnx2x *bp, int set)
+{
+ u32 cl_bit_vec = (1 << BCM_ISCSI_ETH_CL_ID);
+
+ bp->set_mac_pending++;
+ smp_wmb();
+
+ /* Send a SET_MAC ramrod */
+ if (CHIP_IS_E1(bp))
+ bnx2x_set_mac_addr_e1_gen(bp, set, bp->iscsi_mac,
+ cl_bit_vec, (BP_PORT(bp) ? 32 : 0) + 2,
+ 1);
+ else
+ /* CAM allocation for E1H
+ * unicasts: by func number
+ * multicast: 20+FUNC*20, 20 each
+ */
+ bnx2x_set_mac_addr_e1h_gen(bp, set, bp->iscsi_mac,
+ cl_bit_vec, E1H_FUNC_MAX + BP_FUNC(bp));
+
+ /* Wait for a completion when setting */
+ bnx2x_wait_ramrod(bp, 0, 0, &bp->set_mac_pending, set ? 0 : 1);
+
+ return 0;
+}
+#endif
+
static int bnx2x_setup_leading(struct bnx2x *bp)
{
int rc;
@@ -7416,6 +7488,10 @@ static int bnx2x_set_int_mode(struct bnx2x *bp)
return rc;
}
+#ifdef BCM_CNIC
+static int bnx2x_cnic_notify(struct bnx2x *bp, int cmd);
+static void bnx2x_setup_cnic_irq_info(struct bnx2x *bp);
+#endif
/* must be called with rtnl_lock */
static int bnx2x_nic_load(struct bnx2x *bp, int load_mode)
@@ -7576,6 +7652,15 @@ static int bnx2x_nic_load(struct bnx2x *bp, int load_mode)
bnx2x_set_eth_mac_addr_e1(bp, 1);
else
bnx2x_set_eth_mac_addr_e1h(bp, 1);
+#ifdef BCM_CNIC
+ /* Set iSCSI L2 MAC */
+ mutex_lock(&bp->cnic_mutex);
+ if (bp->cnic_eth_dev.drv_state & CNIC_DRV_STATE_REGD) {
+ bnx2x_set_iscsi_eth_mac_addr(bp, 1);
+ bp->cnic_flags |= BNX2X_CNIC_FLAG_MAC_SET;
+ }
+ mutex_unlock(&bp->cnic_mutex);
+#endif
}
if (bp->port.pmf)
@@ -7616,6 +7701,11 @@ static int bnx2x_nic_load(struct bnx2x *bp, int load_mode)
/* start the timer */
mod_timer(&bp->timer, jiffies + bp->current_interval);
+#ifdef BCM_CNIC
+ bnx2x_setup_cnic_irq_info(bp);
+ if (bp->state == BNX2X_STATE_OPEN)
+ bnx2x_cnic_notify(bp, CNIC_CTL_START_CMD);
+#endif
return 0;
@@ -7810,6 +7900,9 @@ static int bnx2x_nic_unload(struct bnx2x *bp, int unload_mode)
u32 reset_code = 0;
int i, cnt, rc;
+#ifdef BCM_CNIC
+ bnx2x_cnic_notify(bp, CNIC_CTL_STOP_CMD);
+#endif
bp->state = BNX2X_STATE_CLOSING_WAIT4_HALT;
/* Set "drop all" */
@@ -7886,6 +7979,15 @@ static int bnx2x_nic_unload(struct bnx2x *bp, int unload_mode)
REG_WR(bp, MISC_REG_E1HMF_MODE, 0);
}
+#ifdef BCM_CNIC
+ /* Clear iSCSI L2 MAC */
+ mutex_lock(&bp->cnic_mutex);
+ if (bp->cnic_flags & BNX2X_CNIC_FLAG_MAC_SET) {
+ bnx2x_set_iscsi_eth_mac_addr(bp, 0);
+ bp->cnic_flags &= ~BNX2X_CNIC_FLAG_MAC_SET;
+ }
+ mutex_unlock(&bp->cnic_mutex);
+#endif
if (unload_mode == UNLOAD_NORMAL)
reset_code = DRV_MSG_CODE_UNLOAD_REQ_WOL_DIS;
@@ -8855,6 +8957,9 @@ static int __devinit bnx2x_init_bp(struct bnx2x *bp)
smp_wmb(); /* Ensure that bp->intr_sem update is SMP-safe */
mutex_init(&bp->port.phy_mutex);
+#ifdef BCM_CNIC
+ mutex_init(&bp->cnic_mutex);
+#endif
INIT_DELAYED_WORK(&bp->sp_task, bnx2x_sp_task);
INIT_WORK(&bp->reset_task, bnx2x_reset_task);
@@ -12448,4 +12553,287 @@ static void __exit bnx2x_cleanup(void)
module_init(bnx2x_init);
module_exit(bnx2x_cleanup);
+#ifdef BCM_CNIC
+
+/* count denotes the number of new completions we have seen */
+static void bnx2x_cnic_sp_post(struct bnx2x *bp, int count)
+{
+ struct eth_spe *spe;
+
+#ifdef BNX2X_STOP_ON_ERROR
+ if (unlikely(bp->panic))
+ return;
+#endif
+
+ spin_lock_bh(&bp->spq_lock);
+ bp->cnic_spq_pending -= count;
+
+ for (; bp->cnic_spq_pending < bp->cnic_eth_dev.max_kwqe_pending;
+ bp->cnic_spq_pending++) {
+
+ if (!bp->cnic_kwq_pending)
+ break;
+
+ spe = bnx2x_sp_get_next(bp);
+ *spe = *bp->cnic_kwq_cons;
+
+ bp->cnic_kwq_pending--;
+
+ DP(NETIF_MSG_TIMER, "pending on SPQ %d, on KWQ %d count %d\n",
+ bp->cnic_spq_pending, bp->cnic_kwq_pending, count);
+
+ if (bp->cnic_kwq_cons == bp->cnic_kwq_last)
+ bp->cnic_kwq_cons = bp->cnic_kwq;
+ else
+ bp->cnic_kwq_cons++;
+ }
+ bnx2x_sp_prod_update(bp);
+ spin_unlock_bh(&bp->spq_lock);
+}
+
+static int bnx2x_cnic_sp_queue(struct net_device *dev,
+ struct kwqe_16 *kwqes[], u32 count)
+{
+ struct bnx2x *bp = netdev_priv(dev);
+ int i;
+
+#ifdef BNX2X_STOP_ON_ERROR
+ if (unlikely(bp->panic))
+ return -EIO;
+#endif
+
+ spin_lock_bh(&bp->spq_lock);
+
+ for (i = 0; i < count; i++) {
+ struct eth_spe *spe = (struct eth_spe *)kwqes[i];
+
+ if (bp->cnic_kwq_pending == MAX_SP_DESC_CNT)
+ break;
+
+ *bp->cnic_kwq_prod = *spe;
+
+ bp->cnic_kwq_pending++;
+
+ DP(NETIF_MSG_TIMER, "L5 SPQE %x %x %x:%x pos %d\n",
+ spe->hdr.conn_and_cmd_data, spe->hdr.type,
+ spe->data.mac_config_addr.hi,
+ spe->data.mac_config_addr.lo,
+ bp->cnic_kwq_pending);
+
+ if (bp->cnic_kwq_prod == bp->cnic_kwq_last)
+ bp->cnic_kwq_prod = bp->cnic_kwq;
+ else
+ bp->cnic_kwq_prod++;
+ }
+
+ spin_unlock_bh(&bp->spq_lock);
+
+ if (bp->cnic_spq_pending < bp->cnic_eth_dev.max_kwqe_pending)
+ bnx2x_cnic_sp_post(bp, 0);
+
+ return i;
+}
+
+static int bnx2x_cnic_ctl_send(struct bnx2x *bp, struct cnic_ctl_info *ctl)
+{
+ struct cnic_ops *c_ops;
+ int rc = 0;
+
+ mutex_lock(&bp->cnic_mutex);
+ c_ops = bp->cnic_ops;
+ if (c_ops)
+ rc = c_ops->cnic_ctl(bp->cnic_data, ctl);
+ mutex_unlock(&bp->cnic_mutex);
+
+ return rc;
+}
+
+static int bnx2x_cnic_ctl_send_bh(struct bnx2x *bp, struct cnic_ctl_info *ctl)
+{
+ struct cnic_ops *c_ops;
+ int rc = 0;
+
+ rcu_read_lock();
+ c_ops = rcu_dereference(bp->cnic_ops);
+ if (c_ops)
+ rc = c_ops->cnic_ctl(bp->cnic_data, ctl);
+ rcu_read_unlock();
+
+ return rc;
+}
+
+/*
+ * for commands that have no data
+ */
+static int bnx2x_cnic_notify(struct bnx2x *bp, int cmd)
+{
+ struct cnic_ctl_info ctl = {0};
+
+ ctl.cmd = cmd;
+
+ return bnx2x_cnic_ctl_send(bp, &ctl);
+}
+
+static void bnx2x_cnic_cfc_comp(struct bnx2x *bp, int cid)
+{
+ struct cnic_ctl_info ctl;
+
+ /* first we tell CNIC and only then we count this as a completion */
+ ctl.cmd = CNIC_CTL_COMPLETION_CMD;
+ ctl.data.comp.cid = cid;
+
+ bnx2x_cnic_ctl_send_bh(bp, &ctl);
+ bnx2x_cnic_sp_post(bp, 1);
+}
+
+static int bnx2x_drv_ctl(struct net_device *dev, struct drv_ctl_info *ctl)
+{
+ struct bnx2x *bp = netdev_priv(dev);
+ int rc = 0;
+
+ switch (ctl->cmd) {
+ case DRV_CTL_CTXTBL_WR_CMD: {
+ u32 index = ctl->data.io.offset;
+ dma_addr_t addr = ctl->data.io.dma_addr;
+
+ bnx2x_ilt_wr(bp, index, addr);
+ break;
+ }
+
+ case DRV_CTL_COMPLETION_CMD: {
+ int count = ctl->data.comp.comp_count;
+
+ bnx2x_cnic_sp_post(bp, count);
+ break;
+ }
+
+ /* rtnl_lock is held. */
+ case DRV_CTL_START_L2_CMD: {
+ u32 cli = ctl->data.ring.client_id;
+
+ bp->rx_mode_cl_mask |= (1 << cli);
+ bnx2x_set_storm_rx_mode(bp);
+ break;
+ }
+
+ /* rtnl_lock is held. */
+ case DRV_CTL_STOP_L2_CMD: {
+ u32 cli = ctl->data.ring.client_id;
+
+ bp->rx_mode_cl_mask &= ~(1 << cli);
+ bnx2x_set_storm_rx_mode(bp);
+ break;
+ }
+
+ default:
+ BNX2X_ERR("unknown command %x\n", ctl->cmd);
+ rc = -EINVAL;
+ }
+
+ return rc;
+}
+
+static void bnx2x_setup_cnic_irq_info(struct bnx2x *bp)
+{
+ struct cnic_eth_dev *cp = &bp->cnic_eth_dev;
+
+ if (bp->flags & USING_MSIX_FLAG) {
+ cp->drv_state |= CNIC_DRV_STATE_USING_MSIX;
+ cp->irq_arr[0].irq_flags |= CNIC_IRQ_FL_MSIX;
+ cp->irq_arr[0].vector = bp->msix_table[1].vector;
+ } else {
+ cp->drv_state &= ~CNIC_DRV_STATE_USING_MSIX;
+ cp->irq_arr[0].irq_flags &= ~CNIC_IRQ_FL_MSIX;
+ }
+ cp->irq_arr[0].status_blk = bp->cnic_sb;
+ cp->irq_arr[0].status_blk_num = CNIC_SB_ID(bp);
+ cp->irq_arr[1].status_blk = bp->def_status_blk;
+ cp->irq_arr[1].status_blk_num = DEF_SB_ID;
+
+ cp->num_irq = 2;
+}
+
+static int bnx2x_register_cnic(struct net_device *dev, struct cnic_ops *ops,
+ void *data)
+{
+ struct bnx2x *bp = netdev_priv(dev);
+ struct cnic_eth_dev *cp = &bp->cnic_eth_dev;
+
+ if (ops == NULL)
+ return -EINVAL;
+
+ if (atomic_read(&bp->intr_sem) != 0)
+ return -EBUSY;
+
+ bp->cnic_kwq = kzalloc(PAGE_SIZE, GFP_KERNEL);
+ if (!bp->cnic_kwq)
+ return -ENOMEM;
+
+ bp->cnic_kwq_cons = bp->cnic_kwq;
+ bp->cnic_kwq_prod = bp->cnic_kwq;
+ bp->cnic_kwq_last = bp->cnic_kwq + MAX_SP_DESC_CNT;
+
+ bp->cnic_spq_pending = 0;
+ bp->cnic_kwq_pending = 0;
+
+ bp->cnic_data = data;
+
+ cp->num_irq = 0;
+ cp->drv_state = CNIC_DRV_STATE_REGD;
+
+ bnx2x_init_sb(bp, bp->cnic_sb, bp->cnic_sb_mapping, CNIC_SB_ID(bp));
+
+ bnx2x_setup_cnic_irq_info(bp);
+ bnx2x_set_iscsi_eth_mac_addr(bp, 1);
+ bp->cnic_flags |= BNX2X_CNIC_FLAG_MAC_SET;
+ rcu_assign_pointer(bp->cnic_ops, ops);
+
+ return 0;
+}
+
+static int bnx2x_unregister_cnic(struct net_device *dev)
+{
+ struct bnx2x *bp = netdev_priv(dev);
+ struct cnic_eth_dev *cp = &bp->cnic_eth_dev;
+
+ mutex_lock(&bp->cnic_mutex);
+ if (bp->cnic_flags & BNX2X_CNIC_FLAG_MAC_SET) {
+ bp->cnic_flags &= ~BNX2X_CNIC_FLAG_MAC_SET;
+ bnx2x_set_iscsi_eth_mac_addr(bp, 0);
+ }
+ cp->drv_state = 0;
+ rcu_assign_pointer(bp->cnic_ops, NULL);
+ mutex_unlock(&bp->cnic_mutex);
+ synchronize_rcu();
+ kfree(bp->cnic_kwq);
+ bp->cnic_kwq = NULL;
+
+ return 0;
+}
+
+struct cnic_eth_dev *bnx2x_cnic_probe(struct net_device *dev)
+{
+ struct bnx2x *bp = netdev_priv(dev);
+ struct cnic_eth_dev *cp = &bp->cnic_eth_dev;
+
+ cp->drv_owner = THIS_MODULE;
+ cp->chip_id = CHIP_ID(bp);
+ cp->pdev = bp->pdev;
+ cp->io_base = bp->regview;
+ cp->io_base2 = bp->doorbells;
+ cp->max_kwqe_pending = 8;
+ cp->ctx_blk_size = CNIC_CTX_PER_ILT * sizeof(union cdu_context);
+ cp->ctx_tbl_offset = FUNC_ILT_BASE(BP_FUNC(bp)) + 1;
+ cp->ctx_tbl_len = CNIC_ILT_LINES;
+ cp->starting_cid = BCM_CNIC_CID_START;
+ cp->drv_submit_kwqes_16 = bnx2x_cnic_sp_queue;
+ cp->drv_ctl = bnx2x_drv_ctl;
+ cp->drv_register_cnic = bnx2x_register_cnic;
+ cp->drv_unregister_cnic = bnx2x_unregister_cnic;
+
+ return cp;
+}
+EXPORT_SYMBOL(bnx2x_cnic_probe);
+
+#endif /* BCM_CNIC */
diff --git a/drivers/net/cnic_if.h b/drivers/net/cnic_if.h
index d8b09ef..8aaf98b 100644
--- a/drivers/net/cnic_if.h
+++ b/drivers/net/cnic_if.h
@@ -12,8 +12,8 @@
#ifndef CNIC_IF_H
#define CNIC_IF_H
-#define CNIC_MODULE_VERSION "2.0.1"
-#define CNIC_MODULE_RELDATE "Oct 01, 2009"
+#define CNIC_MODULE_VERSION "2.1.0"
+#define CNIC_MODULE_RELDATE "Oct 10, 2009"
#define CNIC_ULP_RDMA 0
#define CNIC_ULP_ISCSI 1
@@ -81,6 +81,8 @@ struct kcqe {
#define DRV_CTL_CTX_WR_CMD 0x103
#define DRV_CTL_CTXTBL_WR_CMD 0x104
#define DRV_CTL_COMPLETION_CMD 0x105
+#define DRV_CTL_START_L2_CMD 0x106
+#define DRV_CTL_STOP_L2_CMD 0x107
struct cnic_ctl_completion {
u32 cid;
@@ -105,11 +107,17 @@ struct drv_ctl_io {
dma_addr_t dma_addr;
};
+struct drv_ctl_l2_ring {
+ u32 client_id;
+ u32 cid;
+};
+
struct drv_ctl_info {
int cmd;
union {
struct drv_ctl_completion comp;
struct drv_ctl_io io;
+ struct drv_ctl_l2_ring ring;
char bytes[MAX_DRV_CTL_DATA];
} data;
};
@@ -143,6 +151,7 @@ struct cnic_eth_dev {
u32 max_kwqe_pending;
struct pci_dev *pdev;
void __iomem *io_base;
+ void __iomem *io_base2;
u32 ctx_tbl_offset;
u32 ctx_tbl_len;
@@ -298,5 +307,6 @@ extern int cnic_register_driver(int ulp_type, struct cnic_ulp_ops *ulp_ops);
extern int cnic_unregister_driver(int ulp_type);
extern struct cnic_eth_dev *bnx2_cnic_probe(struct net_device *dev);
+extern struct cnic_eth_dev *bnx2x_cnic_probe(struct net_device *dev);
#endif
--
1.6.4.GIT
^ permalink raw reply related
* [PATCH 5/7] cnic: Refactor some code.
From: Michael Chan @ 2009-10-10 23:46 UTC (permalink / raw)
To: davem; +Cc: netdev, michaelc, shmulikr, eilong, Michael Chan
In-Reply-To: <1255218419-17320-1-git-send-email-mchan@broadcom.com>
Refactor ring init. code for subsequent 10G patches. Also add rtnl_lock()
in cnic_uio_open() to prevent race condition with netdev events.
Signed-off-by: Michael Chan <mchan@broadcom.com>
---
drivers/net/cnic.c | 64 +++++++++++++++++++++++++++++++++++++--------------
1 files changed, 46 insertions(+), 18 deletions(-)
diff --git a/drivers/net/cnic.c b/drivers/net/cnic.c
index 46c87ec..eac68f9 100644
--- a/drivers/net/cnic.c
+++ b/drivers/net/cnic.c
@@ -67,9 +67,8 @@ static struct cnic_ops cnic_bnx2_ops = {
.cnic_ctl = cnic_ctl,
};
-static void cnic_shutdown_bnx2_rx_ring(struct cnic_dev *);
-static void cnic_init_bnx2_tx_ring(struct cnic_dev *);
-static void cnic_init_bnx2_rx_ring(struct cnic_dev *);
+static void cnic_shutdown_rings(struct cnic_dev *);
+static void cnic_init_rings(struct cnic_dev *);
static int cnic_cm_set_pg(struct cnic_sock *);
static int cnic_uio_open(struct uio_info *uinfo, struct inode *inode)
@@ -83,10 +82,16 @@ static int cnic_uio_open(struct uio_info *uinfo, struct inode *inode)
if (cp->uio_dev != -1)
return -EBUSY;
+ rtnl_lock();
+ if (!test_bit(CNIC_F_CNIC_UP, &dev->flags)) {
+ rtnl_unlock();
+ return -ENODEV;
+ }
+
cp->uio_dev = iminor(inode);
- cnic_init_bnx2_tx_ring(dev);
- cnic_init_bnx2_rx_ring(dev);
+ cnic_init_rings(dev);
+ rtnl_unlock();
return 0;
}
@@ -96,7 +101,7 @@ static int cnic_uio_close(struct uio_info *uinfo, struct inode *inode)
struct cnic_dev *dev = uinfo->priv;
struct cnic_local *cp = dev->cnic_priv;
- cnic_shutdown_bnx2_rx_ring(dev);
+ cnic_shutdown_rings(dev);
cp->uio_dev = -1;
return 0;
@@ -675,6 +680,21 @@ error:
return -ENOMEM;
}
+static void cnic_free_context(struct cnic_dev *dev)
+{
+ struct cnic_local *cp = dev->cnic_priv;
+ int i;
+
+ for (i = 0; i < cp->ctx_blks; i++) {
+ if (cp->ctx_arr[i].ctx) {
+ pci_free_consistent(dev->pcidev, cp->ctx_blk_size,
+ cp->ctx_arr[i].ctx,
+ cp->ctx_arr[i].mapping);
+ cp->ctx_arr[i].ctx = NULL;
+ }
+ }
+}
+
static void cnic_free_resc(struct cnic_dev *dev)
{
struct cnic_local *cp = dev->cnic_priv;
@@ -702,14 +722,7 @@ static void cnic_free_resc(struct cnic_dev *dev)
cp->l2_ring = NULL;
}
- for (i = 0; i < cp->ctx_blks; i++) {
- if (cp->ctx_arr[i].ctx) {
- pci_free_consistent(dev->pcidev, cp->ctx_blk_size,
- cp->ctx_arr[i].ctx,
- cp->ctx_arr[i].mapping);
- cp->ctx_arr[i].ctx = NULL;
- }
- }
+ cnic_free_context(dev);
kfree(cp->ctx_arr);
cp->ctx_arr = NULL;
cp->ctx_blks = 0;
@@ -808,8 +821,8 @@ static int cnic_alloc_uio(struct cnic_dev *dev) {
uinfo->mem[0].size = dev->netdev->mem_end - dev->netdev->mem_start;
uinfo->mem[0].memtype = UIO_MEM_PHYS;
- uinfo->mem[1].addr = (unsigned long) cp->status_blk & PAGE_MASK;
if (test_bit(CNIC_F_BNX2_CLASS, &dev->flags)) {
+ uinfo->mem[1].addr = (unsigned long) cp->status_blk & PAGE_MASK;
if (cp->ethdev->drv_state & CNIC_DRV_STATE_USING_MSIX)
uinfo->mem[1].size = BNX2_SBLK_MSIX_ALIGN_SIZE * 9;
else
@@ -1012,7 +1025,7 @@ static int cnic_get_kcqes(struct cnic_dev *dev, u16 hw_prod, u16 *sw_prod)
return last_cnt;
}
-static void cnic_chk_bnx2_pkt_rings(struct cnic_local *cp)
+static void cnic_chk_pkt_rings(struct cnic_local *cp)
{
u16 rx_cons = *cp->rx_cons_ptr;
u16 tx_cons = *cp->tx_cons_ptr;
@@ -1062,7 +1075,7 @@ done:
cp->kcq_prod_idx = sw_prod;
- cnic_chk_bnx2_pkt_rings(cp);
+ cnic_chk_pkt_rings(cp);
return status_idx;
}
@@ -1100,7 +1113,7 @@ done:
CNIC_WR16(dev, cp->kcq_io_addr, sw_prod);
cp->kcq_prod_idx = sw_prod;
- cnic_chk_bnx2_pkt_rings(cp);
+ cnic_chk_pkt_rings(cp);
cp->last_status_idx = status_idx;
CNIC_WR(dev, BNX2_PCICFG_INT_ACK_CMD, cp->int_num |
@@ -2464,6 +2477,21 @@ static int cnic_start_bnx2_hw(struct cnic_dev *dev)
return 0;
}
+static void cnic_init_rings(struct cnic_dev *dev)
+{
+ if (test_bit(CNIC_F_BNX2_CLASS, &dev->flags)) {
+ cnic_init_bnx2_tx_ring(dev);
+ cnic_init_bnx2_rx_ring(dev);
+ }
+}
+
+static void cnic_shutdown_rings(struct cnic_dev *dev)
+{
+ if (test_bit(CNIC_F_BNX2_CLASS, &dev->flags)) {
+ cnic_shutdown_bnx2_rx_ring(dev);
+ }
+}
+
static int cnic_register_netdev(struct cnic_dev *dev)
{
struct cnic_local *cp = dev->cnic_priv;
--
1.6.4.GIT
^ permalink raw reply related
page: next (older) | prev (newer) | latest
- recent:[subjects (threaded)|topics (new)|topics (active)]
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox