* Re: [ethtool PATCH] ethtool: Support n-tuple filter programming
From: Jeff Garzik @ 2010-02-26 21:05 UTC (permalink / raw)
To: Ben Hutchings, Waskiewicz Jr, Peter P, Kirsher, Jeffrey T
Cc: davem, netdev@vger.kernel.org, gospo@redhat.com
In-Reply-To: <1267214397.2098.17.camel@achroite.uk.solarflarecom.com>
On 02/26/2010 02:59 PM, Ben Hutchings wrote:
> On Thu, 2010-02-25 at 21:26 -0500, Jeff Garzik wrote:
>> On 02/25/2010 08:49 PM, Waskiewicz Jr, Peter P wrote:
> [...]
>>> This will require a small kernel change. Will something like this be
>>> pulled in at this point, given that 2.6.33 just released?
>>
>> The n-tuple stuff is not in 2.6.33's ethtool interface, so it hasn't
>> actually made it into a released kernel at this point.
>>
>> It seems reasonable for 2.6.34 to either add ETHTOOL_GSTRINGS_COUNT or
>> update drvinfo. Even if net-next has already been pulled into
>> post-2.6.33 merge window, that would IMO qualify as a reasonable
>> interface bugfix to get upstream. The ethtool n-tuple ABI is not locked
>> into stone until 2.6.34 is released by Linus.
>
> Given that, I would really like to see the tuple strings replaced with
> binary structures. Setting them in binary format and retrieving them in
> text format is inelegant. Also we should not assume that ethtool is the
> only user of the ethtool API. If someone wanted to write a GUI to
> manage the filter tuples, or a tool that would programmatically
> reconfigure filters, they would have to parse the strings.
>
> Even the lookup of number of strings seems to be completely
> misconceived. It's delegated to the driver thus:
>
> ret = ops->get_sset_count(dev, gstrings.string_set);
> if (ret< 0)
> return ret;
>
> What if gstrings.string_set != ETH_SS_NTUPLE_FILTERS? Why is that even
> a parameter to the operation?
>
> Further, each filter can be formatted as multiple strings. So is the
> driver supposed to know how many strings the ethtool core might
> generate?
Speaking _generally_, not specifically about n-tuple filters, text
strings are much more flexible across varied types of hardware. For
example, the "private flags" ethtool interface is intended to be used as
a generic means for a driver to export a set of hardware-specific
boolean knobs.
For example, e1000e's SmartPowerDownEnable need not be a module-wide
parameter applying to all e1000e devices in the system. ethtool's
private-flags interface could enable per-net_device runtime setting of
this Intel-specific feature, simply by exporting a string
"SmartPowerDownEnable" as a private flag.
Thus, text strings isolate the problem of hardware-specific settings,
features and structures entirely in the kernel driver itself.
Getting back to n-tuple filters, the question becomes: how
hardware-specific are the filter formats?
Using binary structures is generally more efficient... but efficiency
is not really a primary goal. Working across a broad spectrum of
hardware, future-proof-edness, is more important. Binary structures may
lock ethtool users into a very specific filter specification -- one that
might not be as easily applicable to other vendors' hardware, or even
future hardware from the same vendor.
procfs and sysfs exist in their current, ASCII-friendly form in part
because Linus has often observed that text strings are often easier and
more resilient kernel<->userspace interfaces than binary interfaces.
All that said, I cannot argue that there are elements of the current
Intel implementation that are quite inelegant, and binary structures may
simply be easier.
Like everything else in life, it's a balance... ;-)
Jeff
^ permalink raw reply
* Re: [PATCH] Delete isa-skeleton net driver
From: David Miller @ 2010-02-26 20:49 UTC (permalink / raw)
To: jeff; +Cc: netdev
In-Reply-To: <20100226202048.GA908@havoc.gtf.org>
From: Jeff Garzik <jeff@garzik.org>
Date: Fri, 26 Feb 2010 15:20:48 -0500
>
> The ISA skeleton net driver has been obsolete and unmaintained for many
> years. Any hardware remotely like ISA will use the platform API and
> look much more like a PCI driver, and make much better use of netdev
> APIs such as NAPI.
>
> Signed-off-by: Jeff Garzik <jgarzik@redhat.com>
Fair enough, applied.
^ permalink raw reply
* Re: [PATCH v2 5/7] pci: Add helper to search for VPD keywords
From: Ben Hutchings @ 2010-02-26 20:49 UTC (permalink / raw)
To: Matt Carlson; +Cc: jbarnes, linux-pci, netdev, andy, Michael Chan
In-Reply-To: <1267216838-19459-6-git-send-email-mcarlson@broadcom.com>
On Fri, 2010-02-26 at 12:40 -0800, Matt Carlson wrote:
> This patch adds the pci_vpd_find_info_keyword() helper function to
> find information field keywords within read-only and read-write large
> resource data type sections.
[...]
> +/**
> + * pci_vpd_find_info_keyword - Locates an information field keyword in the VPD
> + * @buf: Pointer to buffered vpd data
> + * @off: The offset into the buffer at which to begin the search
> + * @len: The length of the buffer area, relative to off, in which to search
> + * @kw: The keyword to search for
> + *
> + * Returns the index where the information field keyword was found or
> + * -ENOENT otherwise.
> + */
> +int pci_vpd_find_info_keyword(u8 *buf, unsigned int off,
> + unsigned int len, char *kw);
[...]
The kw pointer should be const-qualified. The buf pointers could also
be const-qualified though this is less important.
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: [net-next-2.6 PATCH v2 0/3] Support for MPC512x FEC
From: David Miller @ 2010-02-26 20:48 UTC (permalink / raw)
To: agust; +Cc: netdev, linuxppc-dev, grant.likely, dzu, wd, jcrigby
In-Reply-To: <20100226211808.37931258@wker>
From: Anatolij Gustschin <agust@denx.de>
Date: Fri, 26 Feb 2010 21:18:08 +0100
> Hi David,
>
> On Mon, 22 Feb 2010 03:44:52 -0800 (PST)
> David Miller <davem@davemloft.net> wrote:
>
>> From: Anatolij Gustschin <agust@denx.de>
>> Date: Mon, 22 Feb 2010 12:37:24 +0100
>>
>> > Could you please comment on this patch series.
>>
>> It's in the net-next-2.6 tree.
>>
>> If you need to make any more changes, they need to be relative
>> to what went into my tree.
>
> I've pulled your net-next-2.6 tree again and I don't see them
> in net-next-2.6 tree. Could you please check it again. Thanks!
Strange, please resubmit your patches.
Thanks.
^ permalink raw reply
* [PATCH v2 7/7] tg3: Remove now useless VPD code
From: Matt Carlson @ 2010-02-26 20:40 UTC (permalink / raw)
To: jbarnes; +Cc: linux-pci, netdev, andy, mcarlson
Now that the VPD searching code is abstracted away, the outer loop used
to detect the read-only large resource data type section is useless.
Signed-off-by: Matt Carlson <mcarlson@broadcom.com>
---
drivers/net/tg3.c | 52 +++++++++++++++++++++++-----------------------------
1 files changed, 23 insertions(+), 29 deletions(-)
diff --git a/drivers/net/tg3.c b/drivers/net/tg3.c
index 731ba67..6e5feb6 100644
--- a/drivers/net/tg3.c
+++ b/drivers/net/tg3.c
@@ -12440,7 +12440,8 @@ skip_phy_reset:
static void __devinit tg3_read_partno(struct tg3 *tp)
{
unsigned char vpd_data[TG3_NVM_VPD_LEN]; /* in little-endian format */
- int i;
+ unsigned int block_end, rosize, len;
+ int i = 0;
u32 magic;
if ((tp->tg3_flags3 & TG3_FLG3_NO_NVRAM) ||
@@ -12462,7 +12463,7 @@ static void __devinit tg3_read_partno(struct tg3 *tp)
}
} else {
ssize_t cnt;
- unsigned int pos = 0, i = 0;
+ unsigned int pos = 0;
for (; pos < TG3_NVM_VPD_LEN && i < 3; i++, pos += cnt) {
cnt = pci_read_vpd(tp->pdev, pos,
@@ -12477,40 +12478,33 @@ static void __devinit tg3_read_partno(struct tg3 *tp)
goto out_not_found;
}
- /* Now parse and find the part number. */
- for (i = 0; i < TG3_NVM_VPD_LEN - 2; ) {
- unsigned int block_end, rosize;
+ i = pci_vpd_find_tag(vpd_data, 0, TG3_NVM_VPD_LEN,
+ PCI_VPD_LRDT_RO_DATA);
+ if (i < 0)
+ goto out_not_found;
- i = pci_vpd_find_tag(vpd_data, i, TG3_NVM_VPD_LEN,
- PCI_VPD_LRDT_RO_DATA);
- if (i < 0)
- break;
+ rosize = pci_vpd_lrdt_size(&vpd_data[i]);
+ block_end = i + PCI_VPD_LRDT_TAG_SIZE + rosize;
+ i += PCI_VPD_LRDT_TAG_SIZE;
- rosize = pci_vpd_lrdt_size(&vpd_data[i]);
- block_end = i + PCI_VPD_LRDT_TAG_SIZE + rosize;
- i += PCI_VPD_LRDT_TAG_SIZE;
+ if (block_end > TG3_NVM_VPD_LEN)
+ goto out_not_found;
- if (block_end > TG3_NVM_VPD_LEN)
- goto out_not_found;
+ i = pci_vpd_find_info_keyword(vpd_data, i, rosize,
+ PCI_VPD_RO_KEYWORD_PARTNO);
+ if (i < 0)
+ goto out_not_found;
- i = pci_vpd_find_info_keyword(vpd_data, i, rosize,
- PCI_VPD_RO_KEYWORD_PARTNO);
- if (i > 0) {
- u8 len = pci_vpd_info_field_size(&vpd_data[i]);
+ len = pci_vpd_info_field_size(&vpd_data[i]);
- i += PCI_VPD_INFO_FLD_HDR_SIZE;
- if (len > TG3_BPN_SIZE ||
- (len + i) > TG3_NVM_VPD_LEN)
- break;
-
- memcpy(tp->board_part_number, &vpd_data[i], len);
+ i += PCI_VPD_INFO_FLD_HDR_SIZE;
+ if (len > TG3_BPN_SIZE ||
+ (len + i) > TG3_NVM_VPD_LEN)
+ goto out_not_found;
- return;
- }
+ memcpy(tp->board_part_number, &vpd_data[i], len);
- /* Part number not found. */
- goto out_not_found;
- }
+ return;
out_not_found:
if (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5906)
--
1.6.4.4
^ permalink raw reply related
* [PATCH v2 6/7] bnx2: Remove now useless VPD code
From: Matt Carlson @ 2010-02-26 20:40 UTC (permalink / raw)
To: jbarnes; +Cc: linux-pci, netdev, andy, mcarlson
Now that the VPD searching code is abstracted away, the outer loop used
to detect the read-only large resource data type section is useless.
Signed-off-by: Matt Carlson <mcarlson@broadcom.com>
---
drivers/net/bnx2.c | 74 ++++++++++++++++++++-------------------------------
1 files changed, 29 insertions(+), 45 deletions(-)
diff --git a/drivers/net/bnx2.c b/drivers/net/bnx2.c
index 9feab11..24e9c21 100644
--- a/drivers/net/bnx2.c
+++ b/drivers/net/bnx2.c
@@ -7733,10 +7733,9 @@ bnx2_get_pci_speed(struct bnx2 *bp)
static void __devinit
bnx2_read_vpd_fw_ver(struct bnx2 *bp)
{
- int rc, i, v0_len = 0;
+ int rc, i, j;
u8 *data;
- u8 *v0_str = NULL;
- bool mn_match = false;
+ unsigned int block_end, rosize, len;
#define BNX2_VPD_NVRAM_OFFSET 0x300
#define BNX2_VPD_LEN 128
@@ -7758,57 +7757,42 @@ bnx2_read_vpd_fw_ver(struct bnx2 *bp)
data[i + 3] = data[i + BNX2_VPD_LEN];
}
- for (i = 0; i <= BNX2_VPD_LEN - 3; ) {
- int j;
- unsigned int block_end, rosize;
-
- i = pci_vpd_find_tag(data, i, BNX2_VPD_LEN,
- PCI_VPD_LRDT_RO_DATA);
- if (i < 0)
- break;
-
- rosize = pci_vpd_lrdt_size(&data[i]);
- block_end = i + PCI_VPD_LRDT_TAG_SIZE + rosize;
- i += PCI_VPD_LRDT_TAG_SIZE;
-
- if (block_end > BNX2_VPD_LEN)
- goto vpd_done;
+ i = pci_vpd_find_tag(data, 0, BNX2_VPD_LEN, PCI_VPD_LRDT_RO_DATA);
+ if (i < 0)
+ goto vpd_done;
- j = pci_vpd_find_info_keyword(data, i, rosize,
- PCI_VPD_RO_KEYWORD_MFR_ID);
- if (j > 0) {
- int len = pci_vpd_info_field_size(&data[j]);
+ rosize = pci_vpd_lrdt_size(&data[i]);
+ i += PCI_VPD_LRDT_TAG_SIZE;
+ block_end = i + rosize;
- if (j + PCI_VPD_INFO_FLD_HDR_SIZE + len > block_end ||
- len != 4 ||
- memcmp(&data[j + PCI_VPD_INFO_FLD_HDR_SIZE],
- "1028", 4))
- goto vpd_done;
+ if (block_end > BNX2_VPD_LEN)
+ goto vpd_done;
- mn_match = true;
- }
+ j = pci_vpd_find_info_keyword(data, i, rosize,
+ PCI_VPD_RO_KEYWORD_MFR_ID);
+ if (j < 0)
+ goto vpd_done;
- j = pci_vpd_find_info_keyword(data, i, rosize,
- PCI_VPD_RO_KEYWORD_VENDOR0);
- if (j > 0) {
- int len = pci_vpd_info_field_size(&data[j]);
+ len = pci_vpd_info_field_size(&data[j]);
- j += PCI_VPD_INFO_FLD_HDR_SIZE;
- if (j + len > block_end || len > BNX2_MAX_VER_SLEN)
- goto vpd_done;
+ j += PCI_VPD_INFO_FLD_HDR_SIZE;
+ if (j + len > block_end || len != 4 ||
+ memcmp(&data[j], "1028", 4))
+ goto vpd_done;
- v0_len = len;
- v0_str = &data[j];
- }
+ j = pci_vpd_find_info_keyword(data, i, rosize,
+ PCI_VPD_RO_KEYWORD_VENDOR0);
+ if (j < 0)
+ goto vpd_done;
- if (mn_match && v0_str) {
- memcpy(bp->fw_version, v0_str, v0_len);
- bp->fw_version[v0_len] = ' ';
- goto vpd_done;
- }
+ len = pci_vpd_info_field_size(&data[j]);
+ j += PCI_VPD_INFO_FLD_HDR_SIZE;
+ if (j + len > block_end || len > BNX2_MAX_VER_SLEN)
goto vpd_done;
- }
+
+ memcpy(bp->fw_version, &data[j], len);
+ bp->fw_version[len] = ' ';
vpd_done:
kfree(data);
--
1.6.4.4
^ permalink raw reply related
* [PATCH v2 5/7] pci: Add helper to search for VPD keywords
From: Matt Carlson @ 2010-02-26 20:40 UTC (permalink / raw)
To: jbarnes; +Cc: linux-pci, netdev, andy, mcarlson, Michael Chan
This patch adds the pci_vpd_find_info_keyword() helper function to
find information field keywords within read-only and read-write large
resource data type sections.
Signed-off-by: Matt Carlson <mcarlson@broadcom.com>
Signed-off-by: Michael Chan <mchan@broadcom.com>
---
drivers/net/bnx2.c | 54 ++++++++++++++++++++++++++++----------------------
drivers/net/tg3.c | 32 ++++++++++++-----------------
drivers/pci/vpd.c | 18 +++++++++++++++++
include/linux/pci.h | 17 ++++++++++++++++
4 files changed, 78 insertions(+), 43 deletions(-)
diff --git a/drivers/net/bnx2.c b/drivers/net/bnx2.c
index 5909d1a..9feab11 100644
--- a/drivers/net/bnx2.c
+++ b/drivers/net/bnx2.c
@@ -7759,48 +7759,54 @@ bnx2_read_vpd_fw_ver(struct bnx2 *bp)
}
for (i = 0; i <= BNX2_VPD_LEN - 3; ) {
- unsigned int block_end;
+ int j;
+ unsigned int block_end, rosize;
i = pci_vpd_find_tag(data, i, BNX2_VPD_LEN,
PCI_VPD_LRDT_RO_DATA);
if (i < 0)
break;
- block_end = (i + PCI_VPD_LRDT_TAG_SIZE +
- pci_vpd_lrdt_size(&data[i]));
+ rosize = pci_vpd_lrdt_size(&data[i]);
+ block_end = i + PCI_VPD_LRDT_TAG_SIZE + rosize;
i += PCI_VPD_LRDT_TAG_SIZE;
if (block_end > BNX2_VPD_LEN)
goto vpd_done;
- while (i < (block_end - 2)) {
- int len = pci_vpd_info_field_size(&data[i]);
+ j = pci_vpd_find_info_keyword(data, i, rosize,
+ PCI_VPD_RO_KEYWORD_MFR_ID);
+ if (j > 0) {
+ int len = pci_vpd_info_field_size(&data[j]);
- if (i + PCI_VPD_INFO_FLD_HDR_SIZE + len > block_end)
+ if (j + PCI_VPD_INFO_FLD_HDR_SIZE + len > block_end ||
+ len != 4 ||
+ memcmp(&data[j + PCI_VPD_INFO_FLD_HDR_SIZE],
+ "1028", 4))
goto vpd_done;
- if (data[i] == 'M' && data[i + 1] == 'N') {
- if (len != 4 ||
- memcmp(&data[i + PCI_VPD_INFO_FLD_HDR_SIZE],
- "1028", 4))
- goto vpd_done;
- mn_match = true;
+ mn_match = true;
+ }
- } else if (data[i] == 'V' && data[i + 1] == '0') {
- if (len > BNX2_MAX_VER_SLEN)
- goto vpd_done;
+ j = pci_vpd_find_info_keyword(data, i, rosize,
+ PCI_VPD_RO_KEYWORD_VENDOR0);
+ if (j > 0) {
+ int len = pci_vpd_info_field_size(&data[j]);
- v0_len = len;
- v0_str = &data[i + PCI_VPD_INFO_FLD_HDR_SIZE];
- }
- i += PCI_VPD_INFO_FLD_HDR_SIZE + len;
-
- if (mn_match && v0_str) {
- memcpy(bp->fw_version, v0_str, v0_len);
- bp->fw_version[v0_len] = ' ';
+ j += PCI_VPD_INFO_FLD_HDR_SIZE;
+ if (j + len > block_end || len > BNX2_MAX_VER_SLEN)
goto vpd_done;
- }
+
+ v0_len = len;
+ v0_str = &data[j];
}
+
+ if (mn_match && v0_str) {
+ memcpy(bp->fw_version, v0_str, v0_len);
+ bp->fw_version[v0_len] = ' ';
+ goto vpd_done;
+ }
+
goto vpd_done;
}
diff --git a/drivers/net/tg3.c b/drivers/net/tg3.c
index fc510dc..731ba67 100644
--- a/drivers/net/tg3.c
+++ b/drivers/net/tg3.c
@@ -12479,39 +12479,33 @@ static void __devinit tg3_read_partno(struct tg3 *tp)
/* Now parse and find the part number. */
for (i = 0; i < TG3_NVM_VPD_LEN - 2; ) {
- unsigned int block_end;
+ unsigned int block_end, rosize;
i = pci_vpd_find_tag(vpd_data, i, TG3_NVM_VPD_LEN,
PCI_VPD_LRDT_RO_DATA);
if (i < 0)
break;
- block_end = i + PCI_VPD_LRDT_TAG_SIZE +
- pci_vpd_lrdt_size(&vpd_data[i]);
-
+ rosize = pci_vpd_lrdt_size(&vpd_data[i]);
+ block_end = i + PCI_VPD_LRDT_TAG_SIZE + rosize;
i += PCI_VPD_LRDT_TAG_SIZE;
if (block_end > TG3_NVM_VPD_LEN)
goto out_not_found;
- while (i < (block_end - 2)) {
- if (vpd_data[i + 0] == 'P' &&
- vpd_data[i + 1] == 'N') {
- int partno_len = pci_vpd_info_field_size(&vpd_data[i]);
+ i = pci_vpd_find_info_keyword(vpd_data, i, rosize,
+ PCI_VPD_RO_KEYWORD_PARTNO);
+ if (i > 0) {
+ u8 len = pci_vpd_info_field_size(&vpd_data[i]);
- i += PCI_VPD_INFO_FLD_HDR_SIZE;
- if (partno_len > TG3_BPN_SIZE ||
- (partno_len + i) > TG3_NVM_VPD_LEN)
- goto out_not_found;
+ i += PCI_VPD_INFO_FLD_HDR_SIZE;
+ if (len > TG3_BPN_SIZE ||
+ (len + i) > TG3_NVM_VPD_LEN)
+ break;
- memcpy(tp->board_part_number,
- &vpd_data[i], partno_len);
+ memcpy(tp->board_part_number, &vpd_data[i], len);
- /* Success. */
- return;
- }
- i += PCI_VPD_INFO_FLD_HDR_SIZE +
- pci_vpd_info_field_size(&vpd_data[i]);
+ return;
}
/* Part number not found. */
diff --git a/drivers/pci/vpd.c b/drivers/pci/vpd.c
index 8faef70..d232af1 100644
--- a/drivers/pci/vpd.c
+++ b/drivers/pci/vpd.c
@@ -41,3 +41,21 @@ int pci_vpd_find_tag(u8 *buf, unsigned int off, unsigned int len, u8 rdt)
return -ENOENT;
}
EXPORT_SYMBOL_GPL(pci_vpd_find_tag);
+
+int pci_vpd_find_info_keyword(u8 *buf, unsigned int off,
+ unsigned int len, char *kw)
+{
+ int i;
+
+ for (i = off; i + PCI_VPD_INFO_FLD_HDR_SIZE <= off + len;) {
+ if (buf[i + 0] == kw[0] &&
+ buf[i + 1] == kw[1])
+ return i;
+
+ i += PCI_VPD_INFO_FLD_HDR_SIZE +
+ pci_vpd_info_field_size(&buf[i]);
+ }
+
+ return -ENOENT;
+}
+EXPORT_SYMBOL_GPL(pci_vpd_find_info_keyword);
diff --git a/include/linux/pci.h b/include/linux/pci.h
index 1c86d29..8248141 100644
--- a/include/linux/pci.h
+++ b/include/linux/pci.h
@@ -1364,6 +1364,10 @@ void pci_request_acs(void);
#define PCI_VPD_INFO_FLD_HDR_SIZE 3
+#define PCI_VPD_RO_KEYWORD_PARTNO "PN"
+#define PCI_VPD_RO_KEYWORD_MFR_ID "MN"
+#define PCI_VPD_RO_KEYWORD_VENDOR0 "V0"
+
/**
* pci_vpd_lrdt_size - Extracts the Large Resource Data Type length
* @lrdt: Pointer to the beginning of the Large Resource Data Type tag
@@ -1409,5 +1413,18 @@ static inline u8 pci_vpd_info_field_size(u8 *info_field)
*/
int pci_vpd_find_tag(u8 *buf, unsigned int off, unsigned int len, u8 rdt);
+/**
+ * pci_vpd_find_info_keyword - Locates an information field keyword in the VPD
+ * @buf: Pointer to buffered vpd data
+ * @off: The offset into the buffer at which to begin the search
+ * @len: The length of the buffer area, relative to off, in which to search
+ * @kw: The keyword to search for
+ *
+ * Returns the index where the information field keyword was found or
+ * -ENOENT otherwise.
+ */
+int pci_vpd_find_info_keyword(u8 *buf, unsigned int off,
+ unsigned int len, char *kw);
+
#endif /* __KERNEL__ */
#endif /* LINUX_PCI_H */
--
1.6.4.4
^ permalink raw reply related
* [PATCH v2 4/7] pci: Add VPD information field helper functions
From: Matt Carlson @ 2010-02-26 20:40 UTC (permalink / raw)
To: jbarnes; +Cc: linux-pci, netdev, andy, mcarlson, Michael Chan
This patch adds a preprocessor constant to describe the PCI VPD
information field header size and an inline function to extract the
size of the information field itself.
Signed-off-by: Matt Carlson <mcarlson@broadcom.com>
Signed-off-by: Michael Chan <mchan@broadcom.com>
---
drivers/net/bnx2.c | 11 ++++++-----
drivers/net/tg3.c | 7 ++++---
include/linux/pci.h | 13 +++++++++++++
3 files changed, 23 insertions(+), 8 deletions(-)
diff --git a/drivers/net/bnx2.c b/drivers/net/bnx2.c
index 02809da..5909d1a 100644
--- a/drivers/net/bnx2.c
+++ b/drivers/net/bnx2.c
@@ -7774,14 +7774,15 @@ bnx2_read_vpd_fw_ver(struct bnx2 *bp)
goto vpd_done;
while (i < (block_end - 2)) {
- int len = data[i + 2];
+ int len = pci_vpd_info_field_size(&data[i]);
- if (i + 3 + len > block_end)
+ if (i + PCI_VPD_INFO_FLD_HDR_SIZE + len > block_end)
goto vpd_done;
if (data[i] == 'M' && data[i + 1] == 'N') {
if (len != 4 ||
- memcmp(&data[i + 3], "1028", 4))
+ memcmp(&data[i + PCI_VPD_INFO_FLD_HDR_SIZE],
+ "1028", 4))
goto vpd_done;
mn_match = true;
@@ -7790,9 +7791,9 @@ bnx2_read_vpd_fw_ver(struct bnx2 *bp)
goto vpd_done;
v0_len = len;
- v0_str = &data[i + 3];
+ v0_str = &data[i + PCI_VPD_INFO_FLD_HDR_SIZE];
}
- i += 3 + len;
+ i += PCI_VPD_INFO_FLD_HDR_SIZE + len;
if (mn_match && v0_str) {
memcpy(bp->fw_version, v0_str, v0_len);
diff --git a/drivers/net/tg3.c b/drivers/net/tg3.c
index 3e5696b..fc510dc 100644
--- a/drivers/net/tg3.c
+++ b/drivers/net/tg3.c
@@ -12497,9 +12497,9 @@ static void __devinit tg3_read_partno(struct tg3 *tp)
while (i < (block_end - 2)) {
if (vpd_data[i + 0] == 'P' &&
vpd_data[i + 1] == 'N') {
- int partno_len = vpd_data[i + 2];
+ int partno_len = pci_vpd_info_field_size(&vpd_data[i]);
- i += 3;
+ i += PCI_VPD_INFO_FLD_HDR_SIZE;
if (partno_len > TG3_BPN_SIZE ||
(partno_len + i) > TG3_NVM_VPD_LEN)
goto out_not_found;
@@ -12510,7 +12510,8 @@ static void __devinit tg3_read_partno(struct tg3 *tp)
/* Success. */
return;
}
- i += 3 + vpd_data[i + 2];
+ i += PCI_VPD_INFO_FLD_HDR_SIZE +
+ pci_vpd_info_field_size(&vpd_data[i]);
}
/* Part number not found. */
diff --git a/include/linux/pci.h b/include/linux/pci.h
index e158da4..1c86d29 100644
--- a/include/linux/pci.h
+++ b/include/linux/pci.h
@@ -1362,6 +1362,8 @@ void pci_request_acs(void);
#define PCI_VPD_LRDT_TAG_SIZE 3
#define PCI_VPD_SRDT_TAG_SIZE 1
+#define PCI_VPD_INFO_FLD_HDR_SIZE 3
+
/**
* pci_vpd_lrdt_size - Extracts the Large Resource Data Type length
* @lrdt: Pointer to the beginning of the Large Resource Data Type tag
@@ -1385,6 +1387,17 @@ static inline u8 pci_vpd_srdt_size(u8 *srdt)
}
/**
+ * pci_vpd_info_field_size - Extracts the information field length
+ * @lrdt: Pointer to the beginning of an information field header
+ *
+ * Returns the extracted information field length.
+ */
+static inline u8 pci_vpd_info_field_size(u8 *info_field)
+{
+ return info_field[2];
+}
+
+/**
* pci_vpd_find_tag - Locates the Resource Data Type tag provided
* @buf: Pointer to buffered vpd data
* @off: The offset into the buffer at which to begin the search
--
1.6.4.4
^ permalink raw reply related
* [PATCH v2 3/7] pci: Add helper to find a VPD resource data type
From: Matt Carlson @ 2010-02-26 20:40 UTC (permalink / raw)
To: jbarnes; +Cc: linux-pci, netdev, andy, mcarlson, Michael Chan
This patch adds the pci_vpd_find_tag() helper function to find VPD
resource data types in a buffer.
Signed-off-by: Matt Carlson <mcarlson@broadcom.com>
Signed-off-by: Michael Chan <mchan@broadcom.com>
---
drivers/net/bnx2.c | 24 ++++--------------------
drivers/net/tg3.c | 26 +++++---------------------
drivers/pci/Makefile | 2 +-
drivers/pci/vpd.c | 43 +++++++++++++++++++++++++++++++++++++++++++
include/linux/pci.h | 12 ++++++++++++
5 files changed, 65 insertions(+), 42 deletions(-)
create mode 100644 drivers/pci/vpd.c
diff --git a/drivers/net/bnx2.c b/drivers/net/bnx2.c
index 7caa98d..02809da 100644
--- a/drivers/net/bnx2.c
+++ b/drivers/net/bnx2.c
@@ -7759,28 +7759,12 @@ bnx2_read_vpd_fw_ver(struct bnx2 *bp)
}
for (i = 0; i <= BNX2_VPD_LEN - 3; ) {
- unsigned char val = data[i];
unsigned int block_end;
- if (val & PCI_VPD_LRDT) {
- if (i + PCI_VPD_LRDT_TAG_SIZE > BNX2_VPD_LEN)
- break;
-
- if (val != PCI_VPD_LRDT_RO_DATA) {
- i += PCI_VPD_LRDT_TAG_SIZE +
- pci_vpd_lrdt_size(&data[i]);
-
- continue;
- }
- } else {
- if ((val & PCI_VPD_SRDT_TIN_MASK) == PCI_VPD_STIN_END)
- break;
-
- i += PCI_VPD_SRDT_TAG_SIZE +
- pci_vpd_srdt_size(&data[i]);
-
- continue;
- }
+ i = pci_vpd_find_tag(data, i, BNX2_VPD_LEN,
+ PCI_VPD_LRDT_RO_DATA);
+ if (i < 0)
+ break;
block_end = (i + PCI_VPD_LRDT_TAG_SIZE +
pci_vpd_lrdt_size(&data[i]));
diff --git a/drivers/net/tg3.c b/drivers/net/tg3.c
index 4c24998..3e5696b 100644
--- a/drivers/net/tg3.c
+++ b/drivers/net/tg3.c
@@ -12440,7 +12440,7 @@ skip_phy_reset:
static void __devinit tg3_read_partno(struct tg3 *tp)
{
unsigned char vpd_data[TG3_NVM_VPD_LEN]; /* in little-endian format */
- unsigned int i;
+ int i;
u32 magic;
if ((tp->tg3_flags3 & TG3_FLG3_NO_NVRAM) ||
@@ -12479,28 +12479,12 @@ static void __devinit tg3_read_partno(struct tg3 *tp)
/* Now parse and find the part number. */
for (i = 0; i < TG3_NVM_VPD_LEN - 2; ) {
- unsigned char val = vpd_data[i];
unsigned int block_end;
- if (val & PCI_VPD_LRDT) {
- if (i + PCI_VPD_LRDT_TAG_SIZE > TG3_NVM_VPD_LEN)
- break;
-
- if (val != PCI_VPD_LRDT_RO_DATA) {
- i += PCI_VPD_LRDT_TAG_SIZE +
- pci_vpd_lrdt_size(&vpd_data[i]);
-
- continue;
- }
- } else {
- if ((val & PCI_VPD_SRDT_TIN_MASK) == PCI_VPD_STIN_END)
- break;
-
- i += PCI_VPD_SRDT_TAG_SIZE +
- pci_vpd_srdt_size(&vpd_data[i]);
-
- continue;
- }
+ i = pci_vpd_find_tag(vpd_data, i, TG3_NVM_VPD_LEN,
+ PCI_VPD_LRDT_RO_DATA);
+ if (i < 0)
+ break;
block_end = i + PCI_VPD_LRDT_TAG_SIZE +
pci_vpd_lrdt_size(&vpd_data[i]);
diff --git a/drivers/pci/Makefile b/drivers/pci/Makefile
index 4df48d5..b2f6d77 100644
--- a/drivers/pci/Makefile
+++ b/drivers/pci/Makefile
@@ -4,7 +4,7 @@
obj-y += access.o bus.o probe.o remove.o pci.o quirks.o \
pci-driver.o search.o pci-sysfs.o rom.o setup-res.o \
- irq.o
+ irq.o vpd.o
obj-$(CONFIG_PROC_FS) += proc.o
obj-$(CONFIG_SYSFS) += slot.o
diff --git a/drivers/pci/vpd.c b/drivers/pci/vpd.c
new file mode 100644
index 0000000..8faef70
--- /dev/null
+++ b/drivers/pci/vpd.c
@@ -0,0 +1,43 @@
+/*
+ * File: vpd.c
+ * Purpose: Provide PCI VPD support
+ *
+ * Copyright (C) 2010 Broadcom Corporation.
+ */
+
+#include <linux/pci.h>
+
+int pci_vpd_find_tag(u8 *buf, unsigned int off, unsigned int len, u8 rdt)
+{
+ int i;
+
+ for (i = off; i < len; ) {
+ u8 val = buf[i];
+
+ if (val & PCI_VPD_LRDT) {
+ /* Don't return success of the tag isn't complete */
+ if (i + PCI_VPD_LRDT_TAG_SIZE > len)
+ break;
+
+ if (val == rdt)
+ return i;
+
+ i += PCI_VPD_LRDT_TAG_SIZE +
+ pci_vpd_lrdt_size(&buf[i]);
+ } else {
+ u8 tag = val & ~PCI_VPD_SRDT_LEN_MASK;
+
+ if (tag == rdt)
+ return i;
+
+ if (tag == PCI_VPD_SRDT_END)
+ break;
+
+ i += PCI_VPD_SRDT_TAG_SIZE +
+ pci_vpd_srdt_size(&buf[i]);
+ }
+ }
+
+ return -ENOENT;
+}
+EXPORT_SYMBOL_GPL(pci_vpd_find_tag);
diff --git a/include/linux/pci.h b/include/linux/pci.h
index a14b086..e158da4 100644
--- a/include/linux/pci.h
+++ b/include/linux/pci.h
@@ -1384,5 +1384,17 @@ static inline u8 pci_vpd_srdt_size(u8 *srdt)
return (*srdt) & PCI_VPD_SRDT_LEN_MASK;
}
+/**
+ * pci_vpd_find_tag - Locates the Resource Data Type tag provided
+ * @buf: Pointer to buffered vpd data
+ * @off: The offset into the buffer at which to begin the search
+ * @len: The length of the vpd buffer
+ * @rdt: The Resource Data Type to search for
+ *
+ * Returns the index where the Resource Data Type was found or
+ * -ENOENT otherwise.
+ */
+int pci_vpd_find_tag(u8 *buf, unsigned int off, unsigned int len, u8 rdt);
+
#endif /* __KERNEL__ */
#endif /* LINUX_PCI_H */
--
1.6.4.4
^ permalink raw reply related
* [PATCH v2 2/7] pci: Add large and small resource data type code
From: Matt Carlson @ 2010-02-26 20:40 UTC (permalink / raw)
To: jbarnes; +Cc: linux-pci, netdev, andy, mcarlson, Michael Chan
This patch introduces more VPD preprocessor definitions to identify some
small and large resource data type item names. The patch then continues
to correct how the tg3 and bnx2 drivers search for the "read-only data"
large resource data type.
Signed-off-by: Matt Carlson <mcarlson@broadcom.com>
Signed-off-by: Michael Chan <mchan@broadcom.com>
---
drivers/net/bnx2.c | 23 +++++++++++++++++------
drivers/net/tg3.c | 23 +++++++++++++++++------
include/linux/pci.h | 34 +++++++++++++++++++++++++++++++++-
3 files changed, 67 insertions(+), 13 deletions(-)
diff --git a/drivers/net/bnx2.c b/drivers/net/bnx2.c
index d466208..7caa98d 100644
--- a/drivers/net/bnx2.c
+++ b/drivers/net/bnx2.c
@@ -7762,15 +7762,26 @@ bnx2_read_vpd_fw_ver(struct bnx2 *bp)
unsigned char val = data[i];
unsigned int block_end;
- if (val == 0x82 || val == 0x91) {
- i += PCI_VPD_LRDT_TAG_SIZE +
- pci_vpd_lrdt_size(&data[i]);
+ if (val & PCI_VPD_LRDT) {
+ if (i + PCI_VPD_LRDT_TAG_SIZE > BNX2_VPD_LEN)
+ break;
+
+ if (val != PCI_VPD_LRDT_RO_DATA) {
+ i += PCI_VPD_LRDT_TAG_SIZE +
+ pci_vpd_lrdt_size(&data[i]);
+
+ continue;
+ }
+ } else {
+ if ((val & PCI_VPD_SRDT_TIN_MASK) == PCI_VPD_STIN_END)
+ break;
+
+ i += PCI_VPD_SRDT_TAG_SIZE +
+ pci_vpd_srdt_size(&data[i]);
+
continue;
}
- if (val != 0x90)
- goto vpd_done;
-
block_end = (i + PCI_VPD_LRDT_TAG_SIZE +
pci_vpd_lrdt_size(&data[i]));
i += PCI_VPD_LRDT_TAG_SIZE;
diff --git a/drivers/net/tg3.c b/drivers/net/tg3.c
index d01e133..4c24998 100644
--- a/drivers/net/tg3.c
+++ b/drivers/net/tg3.c
@@ -12482,15 +12482,26 @@ static void __devinit tg3_read_partno(struct tg3 *tp)
unsigned char val = vpd_data[i];
unsigned int block_end;
- if (val == 0x82 || val == 0x91) {
- i += PCI_VPD_LRDT_TAG_SIZE +
- pci_vpd_lrdt_size(&vpd_data[i]);
+ if (val & PCI_VPD_LRDT) {
+ if (i + PCI_VPD_LRDT_TAG_SIZE > TG3_NVM_VPD_LEN)
+ break;
+
+ if (val != PCI_VPD_LRDT_RO_DATA) {
+ i += PCI_VPD_LRDT_TAG_SIZE +
+ pci_vpd_lrdt_size(&vpd_data[i]);
+
+ continue;
+ }
+ } else {
+ if ((val & PCI_VPD_SRDT_TIN_MASK) == PCI_VPD_STIN_END)
+ break;
+
+ i += PCI_VPD_SRDT_TAG_SIZE +
+ pci_vpd_srdt_size(&vpd_data[i]);
+
continue;
}
- if (val != 0x90)
- goto out_not_found;
-
block_end = i + PCI_VPD_LRDT_TAG_SIZE +
pci_vpd_lrdt_size(&vpd_data[i]);
diff --git a/include/linux/pci.h b/include/linux/pci.h
index b46669b..a14b086 100644
--- a/include/linux/pci.h
+++ b/include/linux/pci.h
@@ -1339,7 +1339,28 @@ static inline bool pci_is_pcie(struct pci_dev *dev)
void pci_request_acs(void);
-#define PCI_VPD_LRDT_TAG_SIZE 3
+#define PCI_VPD_LRDT 0x80 /* Large Resource Data Type */
+#define PCI_VPD_LRDT_ID(x) (x | PCI_VPD_LRDT)
+
+/* Large Resource Data Type Tag Item Names */
+#define PCI_VPD_LTIN_ID_STRING 0x02 /* Identifier String */
+#define PCI_VPD_LTIN_RO_DATA 0x10 /* Read-Only Data */
+#define PCI_VPD_LTIN_RW_DATA 0x11 /* Read-Write Data */
+
+#define PCI_VPD_LRDT_ID_STRING PCI_VPD_LRDT_ID(PCI_VPD_LTIN_ID_STRING)
+#define PCI_VPD_LRDT_RO_DATA PCI_VPD_LRDT_ID(PCI_VPD_LTIN_RO_DATA)
+#define PCI_VPD_LRDT_RW_DATA PCI_VPD_LRDT_ID(PCI_VPD_LTIN_RW_DATA)
+
+/* Small Resource Data Type Tag Item Names */
+#define PCI_VPD_STIN_END 0x78 /* End */
+
+#define PCI_VPD_SRDT_END PCI_VPD_STIN_END
+
+#define PCI_VPD_SRDT_TIN_MASK 0x78
+#define PCI_VPD_SRDT_LEN_MASK 0x07
+
+#define PCI_VPD_LRDT_TAG_SIZE 3
+#define PCI_VPD_SRDT_TAG_SIZE 1
/**
* pci_vpd_lrdt_size - Extracts the Large Resource Data Type length
@@ -1352,5 +1373,16 @@ static inline u16 pci_vpd_lrdt_size(u8 *lrdt)
return (u16)lrdt[1] + ((u16)lrdt[2] << 8);
}
+/**
+ * pci_vpd_srdt_size - Extracts the Small Resource Data Type length
+ * @lrdt: Pointer to the beginning of the Small Resource Data Type tag
+ *
+ * Returns the extracted Small Resource Data Type length.
+ */
+static inline u8 pci_vpd_srdt_size(u8 *srdt)
+{
+ return (*srdt) & PCI_VPD_SRDT_LEN_MASK;
+}
+
#endif /* __KERNEL__ */
#endif /* LINUX_PCI_H */
--
1.6.4.4
^ permalink raw reply related
* [PATCH v2 1/7] pci: Add PCI LRDT tag size and section size
From: Matt Carlson @ 2010-02-26 20:40 UTC (permalink / raw)
To: jbarnes; +Cc: linux-pci, netdev, andy, mcarlson, Michael Chan
This patch adds a preprocessor constant to describe the PCI VPD large
resource data type tag size and an inline function to extract the large
resource section size from the large resource data type tag.
Signed-off-by: Matt Carlson <mcarlson@broadcom.com>
Signed-off-by: Michael Chan <mchan@broadcom.com>
---
drivers/net/bnx2.c | 8 +++++---
drivers/net/tg3.c | 13 ++++++-------
include/linux/pci.h | 14 ++++++++++++++
3 files changed, 25 insertions(+), 10 deletions(-)
diff --git a/drivers/net/bnx2.c b/drivers/net/bnx2.c
index 65df1de..d466208 100644
--- a/drivers/net/bnx2.c
+++ b/drivers/net/bnx2.c
@@ -7763,15 +7763,17 @@ bnx2_read_vpd_fw_ver(struct bnx2 *bp)
unsigned int block_end;
if (val == 0x82 || val == 0x91) {
- i = (i + 3 + (data[i + 1] + (data[i + 2] << 8)));
+ i += PCI_VPD_LRDT_TAG_SIZE +
+ pci_vpd_lrdt_size(&data[i]);
continue;
}
if (val != 0x90)
goto vpd_done;
- block_end = (i + 3 + (data[i + 1] + (data[i + 2] << 8)));
- i += 3;
+ block_end = (i + PCI_VPD_LRDT_TAG_SIZE +
+ pci_vpd_lrdt_size(&data[i]));
+ i += PCI_VPD_LRDT_TAG_SIZE;
if (block_end > BNX2_VPD_LEN)
goto vpd_done;
diff --git a/drivers/net/tg3.c b/drivers/net/tg3.c
index 7f82b02..d01e133 100644
--- a/drivers/net/tg3.c
+++ b/drivers/net/tg3.c
@@ -12483,19 +12483,18 @@ static void __devinit tg3_read_partno(struct tg3 *tp)
unsigned int block_end;
if (val == 0x82 || val == 0x91) {
- i = (i + 3 +
- (vpd_data[i + 1] +
- (vpd_data[i + 2] << 8)));
+ i += PCI_VPD_LRDT_TAG_SIZE +
+ pci_vpd_lrdt_size(&vpd_data[i]);
continue;
}
if (val != 0x90)
goto out_not_found;
- block_end = (i + 3 +
- (vpd_data[i + 1] +
- (vpd_data[i + 2] << 8)));
- i += 3;
+ block_end = i + PCI_VPD_LRDT_TAG_SIZE +
+ pci_vpd_lrdt_size(&vpd_data[i]);
+
+ i += PCI_VPD_LRDT_TAG_SIZE;
if (block_end > TG3_NVM_VPD_LEN)
goto out_not_found;
diff --git a/include/linux/pci.h b/include/linux/pci.h
index c1968f4..b46669b 100644
--- a/include/linux/pci.h
+++ b/include/linux/pci.h
@@ -1338,5 +1338,19 @@ static inline bool pci_is_pcie(struct pci_dev *dev)
void pci_request_acs(void);
+
+#define PCI_VPD_LRDT_TAG_SIZE 3
+
+/**
+ * pci_vpd_lrdt_size - Extracts the Large Resource Data Type length
+ * @lrdt: Pointer to the beginning of the Large Resource Data Type tag
+ *
+ * Returns the extracted Large Resource Data Type length.
+ */
+static inline u16 pci_vpd_lrdt_size(u8 *lrdt)
+{
+ return (u16)lrdt[1] + ((u16)lrdt[2] << 8);
+}
+
#endif /* __KERNEL__ */
#endif /* LINUX_PCI_H */
--
1.6.4.4
^ permalink raw reply related
* [PATCH v2 0/7] pci: Add VPD parsing support
From: Matt Carlson @ 2010-02-26 20:40 UTC (permalink / raw)
To: jbarnes; +Cc: linux-pci, netdev, andy, mcarlson
This patch adds code to help parse a device's VPD. The bnx2 and tg3
network drivers are modified as an example on how to use the API. I
believe the bnx2x driver will also use this API in the future.
Changes from v1:
* Renamed pci_vpd_find_tag() and pci_vpd_find_info_keyword() parameter names.
* Added docbook notations for functions and inline functions.
* Moved pci-vpd.h contents to pci.h
^ permalink raw reply
* Re: [RFC][PATCH] ns: Syscalls for better namespace sharing control.
From: Eric W. Biederman @ 2010-02-26 20:35 UTC (permalink / raw)
To: Daniel Lezcano
Cc: hadi, Linux Netdev List, containers,
Netfilter Development Mailinglist, Ben Greear, Daniel Lezcano
In-Reply-To: <m1mxyx0yv7.fsf@fess.ebiederm.org>
> No, the plan is only one namespace at a time.
Looking at this a bit more I am frustrated and relieved.
I was looking at what it would take to join an arbitrary mount
namespace and I realized it is completely non-obvious what fs->root
and fs->pwd should be set to.
If I leave them untouched the new mount namespace is useless,
as all path lookups will give results in a different mount namespace,
so not even mount or umount can be used.
I can not change fs->root to mnt_ns->root as that is rootfs and there
is always something mounted on top so I can not use that.
In comparison an unshare of the mount namespace doesn't have to move
fs->root or fs->pwd at all and only has to update their mounts to
the corresponding mounts in the new mount namespace.
I might be able to find the topmost root filesystem and put at least
root there, but I'm not particularly fond of that option.
Eric
^ permalink raw reply
* [PATCH] Delete isa-skeleton net driver
From: Jeff Garzik @ 2010-02-26 20:20 UTC (permalink / raw)
To: netdev
The ISA skeleton net driver has been obsolete and unmaintained for many
years. Any hardware remotely like ISA will use the platform API and
look much more like a PCI driver, and make much better use of netdev
APIs such as NAPI.
Signed-off-by: Jeff Garzik <jgarzik@redhat.com>
---
drivers/net/isa-skeleton.c | 718 ---------------------------------------------
1 file changed, 718 deletions(-)
diff --git a/drivers/net/isa-skeleton.c b/drivers/net/isa-skeleton.c
deleted file mode 100644
index 9e55c30..0000000
--- a/drivers/net/isa-skeleton.c
+++ /dev/null
@@ -1,718 +0,0 @@
-/* isa-skeleton.c: A network driver outline for linux.
- *
- * Written 1993-94 by Donald Becker.
- *
- * Copyright 1993 United States Government as represented by the
- * Director, National Security Agency.
- *
- * This software may be used and distributed according to the terms
- * of the GNU General Public License, incorporated herein by reference.
- *
- * The author may be reached as becker@scyld.com, or C/O
- * Scyld Computing Corporation
- * 410 Severn Ave., Suite 210
- * Annapolis MD 21403
- *
- * This file is an outline for writing a network device driver for the
- * the Linux operating system.
- *
- * To write (or understand) a driver, have a look at the "loopback.c" file to
- * get a feel of what is going on, and then use the code below as a skeleton
- * for the new driver.
- *
- */
-
-static const char *version =
- "isa-skeleton.c:v1.51 9/24/94 Donald Becker (becker@cesdis.gsfc.nasa.gov)\n";
-
-/*
- * Sources:
- * List your sources of programming information to document that
- * the driver is your own creation, and give due credit to others
- * that contributed to the work. Remember that GNU project code
- * cannot use proprietary or trade secret information. Interface
- * definitions are generally considered non-copyrightable to the
- * extent that the same names and structures must be used to be
- * compatible.
- *
- * Finally, keep in mind that the Linux kernel is has an API, not
- * ABI. Proprietary object-code-only distributions are not permitted
- * under the GPL.
- */
-
-#include <linux/module.h>
-#include <linux/kernel.h>
-#include <linux/types.h>
-#include <linux/fcntl.h>
-#include <linux/interrupt.h>
-#include <linux/ioport.h>
-#include <linux/in.h>
-#include <linux/slab.h>
-#include <linux/string.h>
-#include <linux/spinlock.h>
-#include <linux/errno.h>
-#include <linux/init.h>
-#include <linux/netdevice.h>
-#include <linux/etherdevice.h>
-#include <linux/skbuff.h>
-#include <linux/bitops.h>
-
-#include <asm/system.h>
-#include <asm/io.h>
-#include <asm/dma.h>
-
-/*
- * The name of the card. Is used for messages and in the requests for
- * io regions, irqs and dma channels
- */
-static const char* cardname = "netcard";
-
-/* First, a few definitions that the brave might change. */
-
-/* A zero-terminated list of I/O addresses to be probed. */
-static unsigned int netcard_portlist[] __initdata =
- { 0x200, 0x240, 0x280, 0x2C0, 0x300, 0x320, 0x340, 0};
-
-/* use 0 for production, 1 for verification, >2 for debug */
-#ifndef NET_DEBUG
-#define NET_DEBUG 2
-#endif
-static unsigned int net_debug = NET_DEBUG;
-
-/* The number of low I/O ports used by the ethercard. */
-#define NETCARD_IO_EXTENT 32
-
-#define MY_TX_TIMEOUT ((400*HZ)/1000)
-
-/* Information that need to be kept for each board. */
-struct net_local {
- struct net_device_stats stats;
- long open_time; /* Useless example local info. */
-
- /* Tx control lock. This protects the transmit buffer ring
- * state along with the "tx full" state of the driver. This
- * means all netif_queue flow control actions are protected
- * by this lock as well.
- */
- spinlock_t lock;
-};
-
-/* The station (ethernet) address prefix, used for IDing the board. */
-#define SA_ADDR0 0x00
-#define SA_ADDR1 0x42
-#define SA_ADDR2 0x65
-
-/* Index to functions, as function prototypes. */
-
-static int netcard_probe1(struct net_device *dev, int ioaddr);
-static int net_open(struct net_device *dev);
-static int net_send_packet(struct sk_buff *skb, struct net_device *dev);
-static irqreturn_t net_interrupt(int irq, void *dev_id);
-static void net_rx(struct net_device *dev);
-static int net_close(struct net_device *dev);
-static struct net_device_stats *net_get_stats(struct net_device *dev);
-static void set_multicast_list(struct net_device *dev);
-static void net_tx_timeout(struct net_device *dev);
-
-
-/* Example routines you must write ;->. */
-#define tx_done(dev) 1
-static void hardware_send_packet(short ioaddr, char *buf, int length);
-static void chipset_init(struct net_device *dev, int startp);
-
-/*
- * Check for a network adaptor of this type, and return '0' iff one exists.
- * If dev->base_addr == 0, probe all likely locations.
- * If dev->base_addr == 1, always return failure.
- * If dev->base_addr == 2, allocate space for the device and return success
- * (detachable devices only).
- */
-static int __init do_netcard_probe(struct net_device *dev)
-{
- int i;
- int base_addr = dev->base_addr;
- int irq = dev->irq;
-
- if (base_addr > 0x1ff) /* Check a single specified location. */
- return netcard_probe1(dev, base_addr);
- else if (base_addr != 0) /* Don't probe at all. */
- return -ENXIO;
-
- for (i = 0; netcard_portlist[i]; i++) {
- int ioaddr = netcard_portlist[i];
- if (netcard_probe1(dev, ioaddr) == 0)
- return 0;
- dev->irq = irq;
- }
-
- return -ENODEV;
-}
-
-static void cleanup_card(struct net_device *dev)
-{
-#ifdef jumpered_dma
- free_dma(dev->dma);
-#endif
-#ifdef jumpered_interrupts
- free_irq(dev->irq, dev);
-#endif
- release_region(dev->base_addr, NETCARD_IO_EXTENT);
-}
-
-#ifndef MODULE
-struct net_device * __init netcard_probe(int unit)
-{
- struct net_device *dev = alloc_etherdev(sizeof(struct net_local));
- int err;
-
- if (!dev)
- return ERR_PTR(-ENOMEM);
-
- sprintf(dev->name, "eth%d", unit);
- netdev_boot_setup_check(dev);
-
- err = do_netcard_probe(dev);
- if (err)
- goto out;
- return dev;
-out:
- free_netdev(dev);
- return ERR_PTR(err);
-}
-#endif
-
-static const struct net_device_ops netcard_netdev_ops = {
- .ndo_open = net_open,
- .ndo_stop = net_close,
- .ndo_start_xmit = net_send_packet,
- .ndo_get_stats = net_get_stats,
- .ndo_set_multicast_list = set_multicast_list,
- .ndo_tx_timeout = net_tx_timeout,
- .ndo_validate_addr = eth_validate_addr,
- .ndo_set_mac_address = eth_mac_addr,
- .ndo_change_mtu = eth_change_mtu,
-};
-
-/*
- * This is the real probe routine. Linux has a history of friendly device
- * probes on the ISA bus. A good device probes avoids doing writes, and
- * verifies that the correct device exists and functions.
- */
-static int __init netcard_probe1(struct net_device *dev, int ioaddr)
-{
- struct net_local *np;
- static unsigned version_printed;
- int i;
- int err = -ENODEV;
-
- /* Grab the region so that no one else tries to probe our ioports. */
- if (!request_region(ioaddr, NETCARD_IO_EXTENT, cardname))
- return -EBUSY;
-
- /*
- * For ethernet adaptors the first three octets of the station address
- * contains the manufacturer's unique code. That might be a good probe
- * method. Ideally you would add additional checks.
- */
- if (inb(ioaddr + 0) != SA_ADDR0 ||
- inb(ioaddr + 1) != SA_ADDR1 ||
- inb(ioaddr + 2) != SA_ADDR2)
- goto out;
-
- if (net_debug && version_printed++ == 0)
- printk(KERN_DEBUG "%s", version);
-
- printk(KERN_INFO "%s: %s found at %#3x, ", dev->name, cardname, ioaddr);
-
- /* Fill in the 'dev' fields. */
- dev->base_addr = ioaddr;
-
- /* Retrieve and print the ethernet address. */
- for (i = 0; i < 6; i++)
- dev->dev_addr[i] = inb(ioaddr + i);
-
- printk("%pM", dev->dev_addr);
-
- err = -EAGAIN;
-#ifdef jumpered_interrupts
- /*
- * If this board has jumpered interrupts, allocate the interrupt
- * vector now. There is no point in waiting since no other device
- * can use the interrupt, and this marks the irq as busy. Jumpered
- * interrupts are typically not reported by the boards, and we must
- * used autoIRQ to find them.
- */
-
- if (dev->irq == -1)
- ; /* Do nothing: a user-level program will set it. */
- else if (dev->irq < 2) { /* "Auto-IRQ" */
- unsigned long irq_mask = probe_irq_on();
- /* Trigger an interrupt here. */
-
- dev->irq = probe_irq_off(irq_mask);
- if (net_debug >= 2)
- printk(" autoirq is %d", dev->irq);
- } else if (dev->irq == 2)
- /*
- * Fixup for users that don't know that IRQ 2 is really
- * IRQ9, or don't know which one to set.
- */
- dev->irq = 9;
-
- {
- int irqval = request_irq(dev->irq, net_interrupt, 0, cardname, dev);
- if (irqval) {
- printk("%s: unable to get IRQ %d (irqval=%d).\n",
- dev->name, dev->irq, irqval);
- goto out;
- }
- }
-#endif /* jumpered interrupt */
-#ifdef jumpered_dma
- /*
- * If we use a jumpered DMA channel, that should be probed for and
- * allocated here as well. See lance.c for an example.
- */
- if (dev->dma == 0) {
- if (request_dma(dev->dma, cardname)) {
- printk("DMA %d allocation failed.\n", dev->dma);
- goto out1;
- } else
- printk(", assigned DMA %d.\n", dev->dma);
- } else {
- short dma_status, new_dma_status;
-
- /* Read the DMA channel status registers. */
- dma_status = ((inb(DMA1_STAT_REG) >> 4) & 0x0f) |
- (inb(DMA2_STAT_REG) & 0xf0);
- /* Trigger a DMA request, perhaps pause a bit. */
- outw(0x1234, ioaddr + 8);
- /* Re-read the DMA status registers. */
- new_dma_status = ((inb(DMA1_STAT_REG) >> 4) & 0x0f) |
- (inb(DMA2_STAT_REG) & 0xf0);
- /*
- * Eliminate the old and floating requests,
- * and DMA4 the cascade.
- */
- new_dma_status ^= dma_status;
- new_dma_status &= ~0x10;
- for (i = 7; i > 0; i--)
- if (test_bit(i, &new_dma_status)) {
- dev->dma = i;
- break;
- }
- if (i <= 0) {
- printk("DMA probe failed.\n");
- goto out1;
- }
- if (request_dma(dev->dma, cardname)) {
- printk("probed DMA %d allocation failed.\n", dev->dma);
- goto out1;
- }
- }
-#endif /* jumpered DMA */
-
- np = netdev_priv(dev);
- spin_lock_init(&np->lock);
-
- dev->netdev_ops = &netcard_netdev_ops;
- dev->watchdog_timeo = MY_TX_TIMEOUT;
-
- err = register_netdev(dev);
- if (err)
- goto out2;
- return 0;
-out2:
-#ifdef jumpered_dma
- free_dma(dev->dma);
-#endif
-out1:
-#ifdef jumpered_interrupts
- free_irq(dev->irq, dev);
-#endif
-out:
- release_region(base_addr, NETCARD_IO_EXTENT);
- return err;
-}
-
-static void net_tx_timeout(struct net_device *dev)
-{
- struct net_local *np = netdev_priv(dev);
-
- printk(KERN_WARNING "%s: transmit timed out, %s?\n", dev->name,
- tx_done(dev) ? "IRQ conflict" : "network cable problem");
-
- /* Try to restart the adaptor. */
- chipset_init(dev, 1);
-
- np->stats.tx_errors++;
-
- /* If we have space available to accept new transmit
- * requests, wake up the queueing layer. This would
- * be the case if the chipset_init() call above just
- * flushes out the tx queue and empties it.
- *
- * If instead, the tx queue is retained then the
- * netif_wake_queue() call should be placed in the
- * TX completion interrupt handler of the driver instead
- * of here.
- */
- if (!tx_full(dev))
- netif_wake_queue(dev);
-}
-
-/*
- * Open/initialize the board. This is called (in the current kernel)
- * sometime after booting when the 'ifconfig' program is run.
- *
- * This routine should set everything up anew at each open, even
- * registers that "should" only need to be set once at boot, so that
- * there is non-reboot way to recover if something goes wrong.
- */
-static int
-net_open(struct net_device *dev)
-{
- struct net_local *np = netdev_priv(dev);
- int ioaddr = dev->base_addr;
- /*
- * This is used if the interrupt line can turned off (shared).
- * See 3c503.c for an example of selecting the IRQ at config-time.
- */
- if (request_irq(dev->irq, net_interrupt, 0, cardname, dev)) {
- return -EAGAIN;
- }
- /*
- * Always allocate the DMA channel after the IRQ,
- * and clean up on failure.
- */
- if (request_dma(dev->dma, cardname)) {
- free_irq(dev->irq, dev);
- return -EAGAIN;
- }
-
- /* Reset the hardware here. Don't forget to set the station address. */
- chipset_init(dev, 1);
- outb(0x00, ioaddr);
- np->open_time = jiffies;
-
- /* We are now ready to accept transmit requeusts from
- * the queueing layer of the networking.
- */
- netif_start_queue(dev);
-
- return 0;
-}
-
-/* This will only be invoked if your driver is _not_ in XOFF state.
- * What this means is that you need not check it, and that this
- * invariant will hold if you make sure that the netif_*_queue()
- * calls are done at the proper times.
- */
-static int net_send_packet(struct sk_buff *skb, struct net_device *dev)
-{
- struct net_local *np = netdev_priv(dev);
- int ioaddr = dev->base_addr;
- short length = ETH_ZLEN < skb->len ? skb->len : ETH_ZLEN;
- unsigned char *buf = skb->data;
-
- /* If some error occurs while trying to transmit this
- * packet, you should return '1' from this function.
- * In such a case you _may not_ do anything to the
- * SKB, it is still owned by the network queueing
- * layer when an error is returned. This means you
- * may not modify any SKB fields, you may not free
- * the SKB, etc.
- */
-
-#if TX_RING
- /* This is the most common case for modern hardware.
- * The spinlock protects this code from the TX complete
- * hardware interrupt handler. Queue flow control is
- * thus managed under this lock as well.
- */
- unsigned long flags;
- spin_lock_irqsave(&np->lock, flags);
-
- add_to_tx_ring(np, skb, length);
- dev->trans_start = jiffies;
-
- /* If we just used up the very last entry in the
- * TX ring on this device, tell the queueing
- * layer to send no more.
- */
- if (tx_full(dev))
- netif_stop_queue(dev);
-
- /* When the TX completion hw interrupt arrives, this
- * is when the transmit statistics are updated.
- */
-
- spin_unlock_irqrestore(&np->lock, flags);
-#else
- /* This is the case for older hardware which takes
- * a single transmit buffer at a time, and it is
- * just written to the device via PIO.
- *
- * No spin locking is needed since there is no TX complete
- * event. If by chance your card does have a TX complete
- * hardware IRQ then you may need to utilize np->lock here.
- */
- hardware_send_packet(ioaddr, buf, length);
- np->stats.tx_bytes += skb->len;
-
- dev->trans_start = jiffies;
-
- /* You might need to clean up and record Tx statistics here. */
- if (inw(ioaddr) == /*RU*/81)
- np->stats.tx_aborted_errors++;
- dev_kfree_skb (skb);
-#endif
-
- return NETDEV_TX_OK;
-}
-
-#if TX_RING
-/* This handles TX complete events posted by the device
- * via interrupts.
- */
-void net_tx(struct net_device *dev)
-{
- struct net_local *np = netdev_priv(dev);
- int entry;
-
- /* This protects us from concurrent execution of
- * our dev->hard_start_xmit function above.
- */
- spin_lock(&np->lock);
-
- entry = np->tx_old;
- while (tx_entry_is_sent(np, entry)) {
- struct sk_buff *skb = np->skbs[entry];
-
- np->stats.tx_bytes += skb->len;
- dev_kfree_skb_irq (skb);
-
- entry = next_tx_entry(np, entry);
- }
- np->tx_old = entry;
-
- /* If we had stopped the queue due to a "tx full"
- * condition, and space has now been made available,
- * wake up the queue.
- */
- if (netif_queue_stopped(dev) && ! tx_full(dev))
- netif_wake_queue(dev);
-
- spin_unlock(&np->lock);
-}
-#endif
-
-/*
- * The typical workload of the driver:
- * Handle the network interface interrupts.
- */
-static irqreturn_t net_interrupt(int irq, void *dev_id)
-{
- struct net_device *dev = dev_id;
- struct net_local *np;
- int ioaddr, status;
- int handled = 0;
-
- ioaddr = dev->base_addr;
-
- np = netdev_priv(dev);
- status = inw(ioaddr + 0);
-
- if (status == 0)
- goto out;
- handled = 1;
-
- if (status & RX_INTR) {
- /* Got a packet(s). */
- net_rx(dev);
- }
-#if TX_RING
- if (status & TX_INTR) {
- /* Transmit complete. */
- net_tx(dev);
- np->stats.tx_packets++;
- }
-#endif
- if (status & COUNTERS_INTR) {
- /* Increment the appropriate 'localstats' field. */
- np->stats.tx_window_errors++;
- }
-out:
- return IRQ_RETVAL(handled);
-}
-
-/* We have a good packet(s), get it/them out of the buffers. */
-static void
-net_rx(struct net_device *dev)
-{
- struct net_local *lp = netdev_priv(dev);
- int ioaddr = dev->base_addr;
- int boguscount = 10;
-
- do {
- int status = inw(ioaddr);
- int pkt_len = inw(ioaddr);
-
- if (pkt_len == 0) /* Read all the frames? */
- break; /* Done for now */
-
- if (status & 0x40) { /* There was an error. */
- lp->stats.rx_errors++;
- if (status & 0x20) lp->stats.rx_frame_errors++;
- if (status & 0x10) lp->stats.rx_over_errors++;
- if (status & 0x08) lp->stats.rx_crc_errors++;
- if (status & 0x04) lp->stats.rx_fifo_errors++;
- } else {
- /* Malloc up new buffer. */
- struct sk_buff *skb;
-
- lp->stats.rx_bytes+=pkt_len;
-
- skb = dev_alloc_skb(pkt_len);
- if (skb == NULL) {
- printk(KERN_NOTICE "%s: Memory squeeze, dropping packet.\n",
- dev->name);
- lp->stats.rx_dropped++;
- break;
- }
- skb->dev = dev;
-
- /* 'skb->data' points to the start of sk_buff data area. */
- memcpy(skb_put(skb,pkt_len), (void*)dev->rmem_start,
- pkt_len);
- /* or */
- insw(ioaddr, skb->data, (pkt_len + 1) >> 1);
-
- netif_rx(skb);
- lp->stats.rx_packets++;
- lp->stats.rx_bytes += pkt_len;
- }
- } while (--boguscount);
-
- return;
-}
-
-/* The inverse routine to net_open(). */
-static int
-net_close(struct net_device *dev)
-{
- struct net_local *lp = netdev_priv(dev);
- int ioaddr = dev->base_addr;
-
- lp->open_time = 0;
-
- netif_stop_queue(dev);
-
- /* Flush the Tx and disable Rx here. */
-
- disable_dma(dev->dma);
-
- /* If not IRQ or DMA jumpered, free up the line. */
- outw(0x00, ioaddr+0); /* Release the physical interrupt line. */
-
- free_irq(dev->irq, dev);
- free_dma(dev->dma);
-
- /* Update the statistics here. */
-
- return 0;
-
-}
-
-/*
- * Get the current statistics.
- * This may be called with the card open or closed.
- */
-static struct net_device_stats *net_get_stats(struct net_device *dev)
-{
- struct net_local *lp = netdev_priv(dev);
- short ioaddr = dev->base_addr;
-
- /* Update the statistics from the device registers. */
- lp->stats.rx_missed_errors = inw(ioaddr+1);
- return &lp->stats;
-}
-
-/*
- * Set or clear the multicast filter for this adaptor.
- * num_addrs == -1 Promiscuous mode, receive all packets
- * num_addrs == 0 Normal mode, clear multicast list
- * num_addrs > 0 Multicast mode, receive normal and MC packets,
- * and do best-effort filtering.
- */
-static void
-set_multicast_list(struct net_device *dev)
-{
- short ioaddr = dev->base_addr;
- if (dev->flags&IFF_PROMISC)
- {
- /* Enable promiscuous mode */
- outw(MULTICAST|PROMISC, ioaddr);
- }
- else if ((dev->flags&IFF_ALLMULTI) ||
- netdev_mc_count(dev) > HW_MAX_ADDRS)
- {
- /* Disable promiscuous mode, use normal mode. */
- hardware_set_filter(NULL);
-
- outw(MULTICAST, ioaddr);
- }
- else if (!netdev_mc_empty(dev))
- {
- /* Walk the address list, and load the filter */
- hardware_set_filter(dev);
-
- outw(MULTICAST, ioaddr);
- }
- else
- outw(0, ioaddr);
-}
-
-#ifdef MODULE
-
-static struct net_device *this_device;
-static int io = 0x300;
-static int irq;
-static int dma;
-static int mem;
-MODULE_LICENSE("GPL");
-
-int init_module(void)
-{
- struct net_device *dev;
- int result;
-
- if (io == 0)
- printk(KERN_WARNING "%s: You shouldn't use auto-probing with insmod!\n",
- cardname);
- dev = alloc_etherdev(sizeof(struct net_local));
- if (!dev)
- return -ENOMEM;
-
- /* Copy the parameters from insmod into the device structure. */
- dev->base_addr = io;
- dev->irq = irq;
- dev->dma = dma;
- dev->mem_start = mem;
- if (do_netcard_probe(dev) == 0) {
- this_device = dev;
- return 0;
- }
- free_netdev(dev);
- return -ENXIO;
-}
-
-void
-cleanup_module(void)
-{
- unregister_netdev(this_device);
- cleanup_card(this_device);
- free_netdev(this_device);
-}
-
-#endif /* MODULE */
^ permalink raw reply related
* Re: [net-next-2.6 PATCH v2 0/3] Support for MPC512x FEC
From: Anatolij Gustschin @ 2010-02-26 20:18 UTC (permalink / raw)
To: David Miller; +Cc: netdev, linuxppc-dev, grant.likely, dzu, wd, jcrigby
In-Reply-To: <20100222.034452.193720264.davem@davemloft.net>
Hi David,
On Mon, 22 Feb 2010 03:44:52 -0800 (PST)
David Miller <davem@davemloft.net> wrote:
> From: Anatolij Gustschin <agust@denx.de>
> Date: Mon, 22 Feb 2010 12:37:24 +0100
>
> > Could you please comment on this patch series.
>
> It's in the net-next-2.6 tree.
>
> If you need to make any more changes, they need to be relative
> to what went into my tree.
I've pulled your net-next-2.6 tree again and I don't see them
in net-next-2.6 tree. Could you please check it again. Thanks!
Anatolij
^ permalink raw reply
* Re: [net-next-2.6 PATCH] ethtool: Add n-tuple string length to drvinfo and return it
From: Peter P Waskiewicz Jr @ 2010-02-26 20:08 UTC (permalink / raw)
To: David Miller
Cc: jeff@garzik.org, Kirsher, Jeffrey T, netdev@vger.kernel.org,
gospo@redhat.com
In-Reply-To: <20100226.051145.01410157.davem@davemloft.net>
On Fri, 2010-02-26 at 05:11 -0800, David Miller wrote:
> From: Jeff Garzik <jeff@garzik.org>
> Date: Fri, 26 Feb 2010 08:05:19 -0500
>
> > NAK. Did you even read the patch?
>
> I did, brain doesn't work sometimes :-)
>
> > We don't increase the size of struct ethtool_drvinfo, _especially_ by
> > sticking struct members into the middle of the struct.
> >
Brain lapse. When you mentioned ABI not being locked down until 2.6.34
is dropped, I didn't think.
I'm testing your proposed change, and once I have it working, I'll give
it to Jeff K. to get pushed along with a new userspace patch.
> > What do you think 'reserved' is for???
>
> Right, I'll revert, thanks.
^ permalink raw reply
* Re: [ethtool PATCH] ethtool: Support n-tuple filter programming
From: Ben Hutchings @ 2010-02-26 19:59 UTC (permalink / raw)
To: Jeff Garzik
Cc: Waskiewicz Jr, Peter P, davem, Kirsher, Jeffrey T,
netdev@vger.kernel.org, gospo@redhat.com
In-Reply-To: <4B87315E.4080905@garzik.org>
On Thu, 2010-02-25 at 21:26 -0500, Jeff Garzik wrote:
> On 02/25/2010 08:49 PM, Waskiewicz Jr, Peter P wrote:
[...]
> > This will require a small kernel change. Will something like this be
> > pulled in at this point, given that 2.6.33 just released?
>
> The n-tuple stuff is not in 2.6.33's ethtool interface, so it hasn't
> actually made it into a released kernel at this point.
>
> It seems reasonable for 2.6.34 to either add ETHTOOL_GSTRINGS_COUNT or
> update drvinfo. Even if net-next has already been pulled into
> post-2.6.33 merge window, that would IMO qualify as a reasonable
> interface bugfix to get upstream. The ethtool n-tuple ABI is not locked
> into stone until 2.6.34 is released by Linus.
Given that, I would really like to see the tuple strings replaced with
binary structures. Setting them in binary format and retrieving them in
text format is inelegant. Also we should not assume that ethtool is the
only user of the ethtool API. If someone wanted to write a GUI to
manage the filter tuples, or a tool that would programmatically
reconfigure filters, they would have to parse the strings.
Even the lookup of number of strings seems to be completely
misconceived. It's delegated to the driver thus:
ret = ops->get_sset_count(dev, gstrings.string_set);
if (ret < 0)
return ret;
What if gstrings.string_set != ETH_SS_NTUPLE_FILTERS? Why is that even
a parameter to the operation?
Further, each filter can be formatted as multiple strings. So is the
driver supposed to know how many strings the ethtool core might
generate?
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: [PATCH net-next 3/6] cnic: Fix panic in cnic_iscsi_nl_msg_recv() when device is down.
From: Paul E. McKenney @ 2010-02-26 19:33 UTC (permalink / raw)
To: Michael Chan
Cc: 'Simon Horman', davem@davemloft.net,
netdev@vger.kernel.org
In-Reply-To: <1267211469.19491.8.camel@nseg_linux_HP1.broadcom.com>
On Fri, Feb 26, 2010 at 11:11:09AM -0800, Michael Chan wrote:
>
> On Fri, 2010-02-26 at 10:40 -0800, Paul E. McKenney wrote:
> > On Thu, Feb 25, 2010 at 11:01:59PM -0800, Michael Chan wrote:
> > > Simon Horman wrote:
> > >
> > > > On Wed, Feb 24, 2010 at 04:42:06PM -0800, Michael Chan wrote:
> > > > > Some data structures are freed when the device is down and it will
> > > > > crash if an ISCSI netlink message is received. Add RCU protection
> > > > > to prevent this. In the shutdown path, ulp_ops[CNIC_ULP_L4] is
> > > > > assigned NULL and rcu_synchronized before freeing the data
> > > > > structures.
> > > >
> > > > Is rcu_assign_pointer() unnecessary in cnic_cm_open()?
> > > > It doesn't seem to be followed by rcu_synchronized() and the pointer
> > > > doesn't seem to be accessible anywhere else at that time.
> > >
> > > We assign a valid pointer in cnic_cm_open() so that it can be used
> > > during run-time (in service_kcqes() for example). During shutdown in
> > > cnic_stop_hw(), we assign NULL followed by rcu_synchronize().
> >
> > So you are saying that when the pointer is assigned in cnic_cm_open(),
> > there cannot possibly be any concurrent reading threads?
>
> Right. The hardware has not been started yet so there will be no events
> to process from the hardware. The pointer is read when processing these
> hardware events.
>
> >
> > Use of an explicit rcu_assign_pointer() would be better if so.
>
> Yes, we use rcu_assign_pointer in cnic_cm_open() when assigning the
> valid pointer in cnic_cm_open(). Thanks.
Sounds very good, thank you!
Thanx, Paul
^ permalink raw reply
* Re: [PATCH net-next 3/6] cnic: Fix panic in cnic_iscsi_nl_msg_recv() when device is down.
From: Michael Chan @ 2010-02-26 19:11 UTC (permalink / raw)
To: paulmck@linux.vnet.ibm.com
Cc: 'Simon Horman', davem@davemloft.net,
netdev@vger.kernel.org
In-Reply-To: <20100226184001.GJ6733@linux.vnet.ibm.com>
On Fri, 2010-02-26 at 10:40 -0800, Paul E. McKenney wrote:
> On Thu, Feb 25, 2010 at 11:01:59PM -0800, Michael Chan wrote:
> > Simon Horman wrote:
> >
> > > On Wed, Feb 24, 2010 at 04:42:06PM -0800, Michael Chan wrote:
> > > > Some data structures are freed when the device is down and it will
> > > > crash if an ISCSI netlink message is received. Add RCU protection
> > > > to prevent this. In the shutdown path, ulp_ops[CNIC_ULP_L4] is
> > > > assigned NULL and rcu_synchronized before freeing the data
> > > > structures.
> > >
> > > Is rcu_assign_pointer() unnecessary in cnic_cm_open()?
> > > It doesn't seem to be followed by rcu_synchronized() and the pointer
> > > doesn't seem to be accessible anywhere else at that time.
> >
> > We assign a valid pointer in cnic_cm_open() so that it can be used
> > during run-time (in service_kcqes() for example). During shutdown in
> > cnic_stop_hw(), we assign NULL followed by rcu_synchronize().
>
> So you are saying that when the pointer is assigned in cnic_cm_open(),
> there cannot possibly be any concurrent reading threads?
Right. The hardware has not been started yet so there will be no events
to process from the hardware. The pointer is read when processing these
hardware events.
>
> Use of an explicit rcu_assign_pointer() would be better if so.
Yes, we use rcu_assign_pointer in cnic_cm_open() when assigning the
valid pointer in cnic_cm_open(). Thanks.
^ permalink raw reply
* Re: [RFC 0/5] bridge - introduce via_phys_dev feature
From: David Miller @ 2010-02-26 19:01 UTC (permalink / raw)
To: shemminger; +Cc: xemul, gorcunov, bridge, netdev, den
In-Reply-To: <20100226103003.097c39ec@nehalam>
From: Stephen Hemminger <shemminger@linux-foundation.org>
Date: Fri, 26 Feb 2010 10:30:03 -0800
> On Fri, 26 Feb 2010 10:08:00 -0800 (PST)
> David Miller <davem@davemloft.net> wrote:
>
>> From: Stephen Hemminger <shemminger@linux-foundation.org>
>> Date: Fri, 26 Feb 2010 10:01:02 -0800
>>
>> > TCP connections are never really bound to device. TCP routing is
>> > flexible; if packets can get through, it doesn't care.
>>
>> I think he might be talking about SO_BINDTODEVICE
>
> What application does that with TCP?
Any application that would like to, it's been supported from day one.
In fact I bet there are more TCP applications that support
SO_BINDTODEVICE than UDP ones.
^ permalink raw reply
* Re: [RFC 0/5] bridge - introduce via_phys_dev feature
From: Cyrill Gorcunov @ 2010-02-26 18:55 UTC (permalink / raw)
To: Stephen Hemminger; +Cc: David Miller, xemul, bridge, netdev, den
In-Reply-To: <20100226103003.097c39ec@nehalam>
On Fri, Feb 26, 2010 at 10:30:03AM -0800, Stephen Hemminger wrote:
> On Fri, 26 Feb 2010 10:08:00 -0800 (PST)
> David Miller <davem@davemloft.net> wrote:
>
> > From: Stephen Hemminger <shemminger@linux-foundation.org>
> > Date: Fri, 26 Feb 2010 10:01:02 -0800
> >
> > > TCP connections are never really bound to device. TCP routing is
> > > flexible; if packets can get through, it doesn't care.
> >
> > I think he might be talking about SO_BINDTODEVICE
>
> What application does that with TCP?
>
Seems g500i uses it http://goo.gl/5lIi (function open_tcp_socket),
which is either router firmware or kind of modile device.
But frankly -- this seems to be unrelated to a bridge.
-- Cyrill
^ permalink raw reply
* Re: [RFC 0/5] bridge - introduce via_phys_dev feature
From: Stephen Hemminger @ 2010-02-26 18:49 UTC (permalink / raw)
To: Ben Greear; +Cc: David Miller, xemul, gorcunov, bridge, netdev, den
In-Reply-To: <4B8815AE.1090909@candelatech.com>
On Fri, 26 Feb 2010 10:40:46 -0800
Ben Greear <greearb@candelatech.com> wrote:
> On 02/26/2010 10:30 AM, Stephen Hemminger wrote:
> > On Fri, 26 Feb 2010 10:08:00 -0800 (PST)
> > David Miller<davem@davemloft.net> wrote:
> >
> >> From: Stephen Hemminger<shemminger@linux-foundation.org>
> >> Date: Fri, 26 Feb 2010 10:01:02 -0800
> >>
> >>> TCP connections are never really bound to device. TCP routing is
> >>> flexible; if packets can get through, it doesn't care.
> >>
> >> I think he might be talking about SO_BINDTODEVICE
> >
> > What application does that with TCP?
>
> I use it..helps with using multiple interfaces on the same system,
> especially when sending-to-self.
>
That is a special case which is not related to the discussion.
We are talking about being able to setup a bridge and migrate the
associated state from the ethernet device to the bridge.
^ permalink raw reply
* Re: [RFC 0/5] bridge - introduce via_phys_dev feature
From: Ben Greear @ 2010-02-26 18:40 UTC (permalink / raw)
To: Stephen Hemminger; +Cc: bridge, netdev, gorcunov, den, David Miller, xemul
In-Reply-To: <20100226103003.097c39ec@nehalam>
On 02/26/2010 10:30 AM, Stephen Hemminger wrote:
> On Fri, 26 Feb 2010 10:08:00 -0800 (PST)
> David Miller<davem@davemloft.net> wrote:
>
>> From: Stephen Hemminger<shemminger@linux-foundation.org>
>> Date: Fri, 26 Feb 2010 10:01:02 -0800
>>
>>> TCP connections are never really bound to device. TCP routing is
>>> flexible; if packets can get through, it doesn't care.
>>
>> I think he might be talking about SO_BINDTODEVICE
>
> What application does that with TCP?
I use it..helps with using multiple interfaces on the same system,
especially when sending-to-self.
Thanks,
Ben
--
Ben Greear <greearb@candelatech.com>
Candela Technologies Inc http://www.candelatech.com
^ permalink raw reply
* Re: [PATCH net-next 3/6] cnic: Fix panic in cnic_iscsi_nl_msg_recv() when device is down.
From: Paul E. McKenney @ 2010-02-26 18:40 UTC (permalink / raw)
To: Michael Chan
Cc: 'Simon Horman', davem@davemloft.net,
netdev@vger.kernel.org
In-Reply-To: <C27F8246C663564A84BB7AB34397724218312F8FD0@IRVEXCHCCR01.corp.ad.broadcom.com>
On Thu, Feb 25, 2010 at 11:01:59PM -0800, Michael Chan wrote:
> Simon Horman wrote:
>
> > On Wed, Feb 24, 2010 at 04:42:06PM -0800, Michael Chan wrote:
> > > Some data structures are freed when the device is down and it will
> > > crash if an ISCSI netlink message is received. Add RCU protection
> > > to prevent this. In the shutdown path, ulp_ops[CNIC_ULP_L4] is
> > > assigned NULL and rcu_synchronized before freeing the data
> > > structures.
> >
> > Is rcu_assign_pointer() unnecessary in cnic_cm_open()?
> > It doesn't seem to be followed by rcu_synchronized() and the pointer
> > doesn't seem to be accessible anywhere else at that time.
>
> We assign a valid pointer in cnic_cm_open() so that it can be used
> during run-time (in service_kcqes() for example). During shutdown in
> cnic_stop_hw(), we assign NULL followed by rcu_synchronize().
So you are saying that when the pointer is assigned in cnic_cm_open(),
there cannot possibly be any concurrent reading threads?
Use of an explicit rcu_assign_pointer() would be better if so.
Thanx, Paul
^ permalink raw reply
* Re: [RFC 0/5] bridge - introduce via_phys_dev feature
From: Stephen Hemminger @ 2010-02-26 18:30 UTC (permalink / raw)
To: David Miller; +Cc: xemul, gorcunov, bridge, netdev, den
In-Reply-To: <20100226.100800.116618587.davem@davemloft.net>
On Fri, 26 Feb 2010 10:08:00 -0800 (PST)
David Miller <davem@davemloft.net> wrote:
> From: Stephen Hemminger <shemminger@linux-foundation.org>
> Date: Fri, 26 Feb 2010 10:01:02 -0800
>
> > TCP connections are never really bound to device. TCP routing is
> > flexible; if packets can get through, it doesn't care.
>
> I think he might be talking about SO_BINDTODEVICE
What application does that with TCP?
^ 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