* [PATCH] e1000: fix time comparison
From: Asaf Vertz @ 2015-01-07 12:41 UTC (permalink / raw)
To: jeffrey.t.kirsher
Cc: jesse.brandeburg, bruce.w.allan, carolyn.wyborny,
donald.c.skidmore, gregory.v.rose, matthew.vick, john.ronciak,
mitch.a.williams, linux.nics, e1000-devel, netdev, linux-kernel
To be future-proof and for better readability the time comparisons are
modified to use time_after_eq() instead of plain, error-prone math.
Signed-off-by: Asaf Vertz <asaf.vertz@tandemg.com>
---
drivers/net/ethernet/intel/e1000/e1000_ethtool.c | 3 ++-
1 files changed, 2 insertions(+), 1 deletions(-)
diff --git a/drivers/net/ethernet/intel/e1000/e1000_ethtool.c b/drivers/net/ethernet/intel/e1000/e1000_ethtool.c
index b691eb4..4270ad2 100644
--- a/drivers/net/ethernet/intel/e1000/e1000_ethtool.c
+++ b/drivers/net/ethernet/intel/e1000/e1000_ethtool.c
@@ -24,6 +24,7 @@
/* ethtool support for e1000 */
#include "e1000.h"
+#include <linux/jiffies.h>
#include <linux/uaccess.h>
enum {NETDEV_STATS, E1000_STATS};
@@ -1460,7 +1461,7 @@ static int e1000_run_loopback_test(struct e1000_adapter *adapter)
ret_val = 13; /* ret_val is the same as mis-compare */
break;
}
- if (jiffies >= (time + 2)) {
+ if (time_after_eq(jiffies, time + 2)) {
ret_val = 14; /* error code for time out error */
break;
}
--
1.7.0.4
^ permalink raw reply related
* Re: Clarification regarding IFLA_BRPORT_LEARNING_SYNC and aging of fdb entries learnt via br_fdb_external_learn_add()
From: Jiri Pirko @ 2015-01-07 12:53 UTC (permalink / raw)
To: Siva Mannem; +Cc: netdev, sfeldma
In-Reply-To: <CA+CtxLSv6Hg9kOmavqQKs+7y8b8+TBdW1dYwb3ZsTMOh=Ow8Ew@mail.gmail.com>
Tue, Dec 30, 2014 at 07:20:21PM CET, siva.mannem.lnx@gmail.com wrote:
>Hi,
>
>I am trying to understand the ongoing switch device offload effort and
>am following the discussions. I have a question regarding
>IFLA_BRPORT_LEARNING_SYNC flag and how aging happens when this flag is
>enabled on a port that is attached to a bridge that has vlan filtering
>enabled.
>
>If I understand correctly, when IFLA_BRPORT_LEARNING_SYNC is set on a
>bridge port, fdb entries that are learnt externally(may be learnt by
>hardware and driver is notified) are synced to bridges fdb using
>br_fdb_external_learn_add(). The fdb
>entries(fdb->added_by_external_learn set to true) that are learnt via
>this method are also deleted by the aging logic after the aging time
>even though L2 data forwadring happens in hardware. Is there a way
>where aging can be disabled for these entries? and let the entries be
>removed only via br_fdb_external_learn_delete()? or am I missing
>something?
Currently extenaly learned fdb entries are indeed removed during aging
cleanup. I believe that br_fdb_cleanup should check added_by_external_learn
and not remove that fdbs. What do you think Scott?
^ permalink raw reply
* Re: IPsec workshop at netdev01?
From: Florian Westphal @ 2015-01-07 12:55 UTC (permalink / raw)
To: Steffen Klassert
Cc: Florian Westphal, netdev, Jamal Hadi Salim, Herbert Xu,
David Miller
In-Reply-To: <20150107103137.GB13046@secunet.com>
Steffen Klassert <steffen.klassert@secunet.com> wrote:
> On Tue, Jan 06, 2015 at 06:00:26PM +0100, Florian Westphal wrote:
> > Steffen Klassert <steffen.klassert@secunet.com> wrote:
> > > - We still lack a 32/64 bit compatibiltiy layer for IPsec, this issue
> > > comes up from time to time. Some solutions were proposed in the past
> > > but all had problems. The current behaviour is broken if someone tries
> > > to configure IPsec with 32 bit tools on a 64 bit machine. Can we get
> > > this right somehow or is it better to just return an error in this case?
> >
> > FWIW I think
> > http://patchwork.ozlabs.org/patch/49465/
> >
> > came closest to achieving full CONFIG_COMPAT support; since netlink is
> > no longer async now I'm not sure we'd still need additonal 32-compat syscalls
> > to make compat work for all cases.
> >
> > So "its ugly as hell" is probably the only problem that is hard to avoid ;-)
>
> Yeah, and it will be no fun to maintain it...
Not sure, you'd have to make sure that no new attributes introduce need
to add another compat hack.
The best argument against supporting it is that this problem
has existed for so long that there arguably isn't much demand
(else, such patch would have been merged years ago).
i686 userland with x86_64 kernel should be rare nowadays, and
x32 seems to require 8byte aligned 64bit integers so that would work
as-is.
> So the question is still, do we really need/want it or should we
> tell that this is not supported. We just can't leave it as it is.
> We allow to configure with 32 bit tools, but the result is crap.
Perhaps one could add only some of the patches from that series,
i.e. allow xfrm netlink to detect when its dealing with a message
from i686 task (so it can fail right away)?
^ permalink raw reply
* Re: TCP connection issues against Amazon S3
From: Erik Grinaker @ 2015-01-07 13:06 UTC (permalink / raw)
To: Lukas Tribus
Cc: Eric Dumazet, Yuchung Cheng, linux-kernel@vger.kernel.org, netdev
In-Reply-To: <DUB123-W1008C526C7E0FA115A87EED460@phx.gbl>
On 07 Jan 2015, at 01:23, Lukas Tribus <luky-37@hotmail.com> wrote:
>> This still doesn’t explain why it works with older kernels, but not newer ones.
>
> Can you try the different 3.12-rc kernels? The information that this was
> introduced in 3.12-rc1 as opposed to a specific -rc>1 releases may help
> the guys here to pinpoint what exactly caused the behavior change on the
> receiver side.
I can reproduce the problem with 3.12.0-rc1 as well.
I also tried 3.11.10 again, to make sure it did not have the problem even when forcing requests to a non-SACK-enabled loadbalancer, and it works as it should (no hung connections).
^ permalink raw reply
* Re: TCP connection issues against Amazon S3
From: Erik Grinaker @ 2015-01-07 13:31 UTC (permalink / raw)
To: Yuchung Cheng; +Cc: Eric Dumazet, linux-kernel@vger.kernel.org, netdev
In-Reply-To: <CAK6E8=cf7cROQ0SON0BihkbOsBB+-sLAbexxgt4_xD+Auqev3Q@mail.gmail.com>
On 06 Jan 2015, at 22:00, Yuchung Cheng <ycheng@google.com> wrote:
> On Tue, Jan 6, 2015 at 1:04 PM, Erik Grinaker <erik@bengler.no> wrote:
>>
>>> On 06 Jan 2015, at 20:26, Erik Grinaker <erik@bengler.no> wrote:
>> This still doesn’t explain why it works with older kernels, but not newer ones. I’m thinking it’s
> probably some minor change, which gets amplified by the lack of SACKs
> on the loadbalancer. Anyway, I’ll bring it up with Amazon.
> can you post traces with the older kernels?
Here is a dump using 3.11.10 against a non-SACK-enabled loadbalancer:
http://abstrakt.bengler.no/tcp-issues-s3-nosack-3.11.10.pcap.bz2
The transfer shows lots of DUPACKs and retransmits, but this does not seem to have as bad an effect as it did with the failing transfer we saw on newer kernels:
http://abstrakt.bengler.no/tcp-issues-s3-failure.pcap.bz2
One big difference, which Rick touched on earlier, is that the newer kernels keep sending TCP window updates as it’s going through the retransmits. The older kernel does not do this.
^ permalink raw reply
* [PATCH] csiostor:firmware upgrade fix
From: Praveen Madhavan @ 2015-01-07 13:46 UTC (permalink / raw)
To: netdev, linux-scsi; +Cc: davem, JBottomley, hch, hariprasad, praveenm
This patch fixes removes older means of upgrading Firmware using MAJOR version
and adds newer interface version checking mechanism.
Please apply this patch on net-next since it depends on previous commits.
Signed-off-by: Praveen Madhavan <praveenm@chelsio.com>
---
drivers/scsi/csiostor/csio_hw.c | 277 +++++++++++++++++++++++++----------
drivers/scsi/csiostor/csio_hw.h | 5 +-
drivers/scsi/csiostor/csio_hw_chip.h | 47 +++++-
3 files changed, 247 insertions(+), 82 deletions(-)
diff --git a/drivers/scsi/csiostor/csio_hw.c b/drivers/scsi/csiostor/csio_hw.c
index 6602835..b70c15f 100644
--- a/drivers/scsi/csiostor/csio_hw.c
+++ b/drivers/scsi/csiostor/csio_hw.c
@@ -682,43 +682,6 @@ csio_hw_get_tp_version(struct csio_hw *hw, u32 *vers)
}
/*
- * csio_hw_check_fw_version - check if the FW is compatible with
- * this driver
- * @hw: HW module
- *
- * Checks if an adapter's FW is compatible with the driver. Returns 0
- * if there's exact match, a negative error if the version could not be
- * read or there's a major/minor version mismatch/minor.
- */
-static int
-csio_hw_check_fw_version(struct csio_hw *hw)
-{
- int ret, major, minor, micro;
-
- ret = csio_hw_get_fw_version(hw, &hw->fwrev);
- if (!ret)
- ret = csio_hw_get_tp_version(hw, &hw->tp_vers);
- if (ret)
- return ret;
-
- major = FW_HDR_FW_VER_MAJOR_G(hw->fwrev);
- minor = FW_HDR_FW_VER_MINOR_G(hw->fwrev);
- micro = FW_HDR_FW_VER_MICRO_G(hw->fwrev);
-
- if (major != FW_VERSION_MAJOR(hw)) { /* major mismatch - fail */
- csio_err(hw, "card FW has major version %u, driver wants %u\n",
- major, FW_VERSION_MAJOR(hw));
- return -EINVAL;
- }
-
- if (minor == FW_VERSION_MINOR(hw) && micro == FW_VERSION_MICRO(hw))
- return 0; /* perfect match */
-
- /* Minor/micro version mismatch */
- return -EINVAL;
-}
-
-/*
* csio_hw_fw_dload - download firmware.
* @hw: HW module
* @fw_data: firmware image to write.
@@ -1967,6 +1930,170 @@ out:
return rv;
}
+/* Is the given firmware API compatible with the one the driver was compiled
+ * with?
+ */
+static int fw_compatible(const struct fw_hdr *hdr1, const struct fw_hdr *hdr2)
+{
+
+ /* short circuit if it's the exact same firmware version */
+ if (hdr1->chip == hdr2->chip && hdr1->fw_ver == hdr2->fw_ver)
+ return 1;
+
+#define SAME_INTF(x) (hdr1->intfver_##x == hdr2->intfver_##x)
+ if (hdr1->chip == hdr2->chip && SAME_INTF(nic) && SAME_INTF(vnic) &&
+ SAME_INTF(ri) && SAME_INTF(iscsi) && SAME_INTF(fcoe))
+ return 1;
+#undef SAME_INTF
+
+ return 0;
+}
+
+/* The firmware in the filesystem is usable, but should it be installed?
+ * This routine explains itself in detail if it indicates the filesystem
+ * firmware should be installed.
+ */
+static int csio_should_install_fs_fw(struct csio_hw *hw, int card_fw_usable,
+ int k, int c)
+{
+ const char *reason;
+
+ if (!card_fw_usable) {
+ reason = "incompatible or unusable";
+ goto install;
+ }
+
+ if (k > c) {
+ reason = "older than the version supported with this driver";
+ goto install;
+ }
+
+ return 0;
+
+install:
+ csio_err(hw, "firmware on card (%u.%u.%u.%u) is %s, "
+ "installing firmware %u.%u.%u.%u on card.\n",
+ FW_HDR_FW_VER_MAJOR_G(c), FW_HDR_FW_VER_MINOR_G(c),
+ FW_HDR_FW_VER_MICRO_G(c), FW_HDR_FW_VER_BUILD_G(c), reason,
+ FW_HDR_FW_VER_MAJOR_G(k), FW_HDR_FW_VER_MINOR_G(k),
+ FW_HDR_FW_VER_MICRO_G(k), FW_HDR_FW_VER_BUILD_G(k));
+
+ return 1;
+}
+
+static struct fw_info fw_info_array[] = {
+ {
+ .chip = CHELSIO_T5,
+ .fs_name = FW_CFG_NAME_T5,
+ .fw_mod_name = FW_FNAME_T5,
+ .fw_hdr = {
+ .chip = FW_HDR_CHIP_T5,
+ .fw_ver = __cpu_to_be32(FW_VERSION(T5)),
+ .intfver_nic = FW_INTFVER(T5, NIC),
+ .intfver_vnic = FW_INTFVER(T5, VNIC),
+ .intfver_ri = FW_INTFVER(T5, RI),
+ .intfver_iscsi = FW_INTFVER(T5, ISCSI),
+ .intfver_fcoe = FW_INTFVER(T5, FCOE),
+ },
+ }
+};
+
+static struct fw_info *find_fw_info(int chip)
+{
+ int i;
+
+ for (i = 0; i < ARRAY_SIZE(fw_info_array); i++) {
+ if (fw_info_array[i].chip == chip)
+ return &fw_info_array[i];
+ }
+ return NULL;
+}
+
+int csio_hw_prep_fw(struct csio_hw *hw, struct fw_info *fw_info,
+ const u8 *fw_data, unsigned int fw_size,
+ struct fw_hdr *card_fw, enum csio_dev_state state,
+ int *reset)
+{
+ int ret, card_fw_usable, fs_fw_usable;
+ const struct fw_hdr *fs_fw;
+ const struct fw_hdr *drv_fw;
+
+ drv_fw = &fw_info->fw_hdr;
+
+ /* Read the header of the firmware on the card */
+ ret = csio_hw_read_flash(hw, FLASH_FW_START,
+ sizeof(*card_fw) / sizeof(uint32_t),
+ (uint32_t *)card_fw, 1);
+ if (ret == 0) {
+ card_fw_usable = fw_compatible(drv_fw, (const void *)card_fw);
+ } else {
+ csio_err(hw,
+ "Unable to read card's firmware header: %d\n", ret);
+ card_fw_usable = 0;
+ }
+
+ if (fw_data != NULL) {
+ fs_fw = (const void *)fw_data;
+ fs_fw_usable = fw_compatible(drv_fw, fs_fw);
+ } else {
+ fs_fw = NULL;
+ fs_fw_usable = 0;
+ }
+
+ if (card_fw_usable && card_fw->fw_ver == drv_fw->fw_ver &&
+ (!fs_fw_usable || fs_fw->fw_ver == drv_fw->fw_ver)) {
+ /* Common case: the firmware on the card is an exact match and
+ * the filesystem one is an exact match too, or the filesystem
+ * one is absent/incompatible.
+ */
+ } else if (fs_fw_usable && state == CSIO_DEV_STATE_UNINIT &&
+ csio_should_install_fs_fw(hw, card_fw_usable,
+ be32_to_cpu(fs_fw->fw_ver),
+ be32_to_cpu(card_fw->fw_ver))) {
+ ret = csio_hw_fw_upgrade(hw, hw->pfn, fw_data,
+ fw_size, 0);
+ if (ret != 0) {
+ csio_err(hw,
+ "failed to install firmware: %d\n", ret);
+ goto bye;
+ }
+
+ /* Installed successfully, update the cached header too. */
+ memcpy(card_fw, fs_fw, sizeof(*card_fw));
+ card_fw_usable = 1;
+ *reset = 0; /* already reset as part of load_fw */
+ }
+
+ if (!card_fw_usable) {
+ uint32_t d, c, k;
+
+ d = be32_to_cpu(drv_fw->fw_ver);
+ c = be32_to_cpu(card_fw->fw_ver);
+ k = fs_fw ? be32_to_cpu(fs_fw->fw_ver) : 0;
+
+ csio_err(hw, "Cannot find a usable firmware: "
+ "chip state %d, "
+ "driver compiled with %d.%d.%d.%d, "
+ "card has %d.%d.%d.%d, filesystem has %d.%d.%d.%d\n",
+ state,
+ FW_HDR_FW_VER_MAJOR_G(d), FW_HDR_FW_VER_MINOR_G(d),
+ FW_HDR_FW_VER_MICRO_G(d), FW_HDR_FW_VER_BUILD_G(d),
+ FW_HDR_FW_VER_MAJOR_G(c), FW_HDR_FW_VER_MINOR_G(c),
+ FW_HDR_FW_VER_MICRO_G(c), FW_HDR_FW_VER_BUILD_G(c),
+ FW_HDR_FW_VER_MAJOR_G(k), FW_HDR_FW_VER_MINOR_G(k),
+ FW_HDR_FW_VER_MICRO_G(k), FW_HDR_FW_VER_BUILD_G(k));
+ ret = EINVAL;
+ goto bye;
+ }
+
+ /* We're using whatever's on the card and it's known to be good. */
+ hw->fwrev = be32_to_cpu(card_fw->fw_ver);
+ hw->tp_vers = be32_to_cpu(card_fw->tp_microcode_ver);
+
+bye:
+ return ret;
+}
+
/*
* Returns -EINVAL if attempts to flash the firmware failed
* else returns 0,
@@ -1974,14 +2101,27 @@ out:
* latest firmware ECANCELED is returned
*/
static int
-csio_hw_flash_fw(struct csio_hw *hw)
+csio_hw_flash_fw(struct csio_hw *hw, int *reset)
{
int ret = -ECANCELED;
const struct firmware *fw;
- const struct fw_hdr *hdr;
- u32 fw_ver;
+ struct fw_info *fw_info;
+ struct fw_hdr *card_fw;
struct pci_dev *pci_dev = hw->pdev;
struct device *dev = &pci_dev->dev ;
+ const u8 *fw_data = NULL;
+ unsigned int fw_size = 0;
+
+ /* This is the firmware whose headers the driver was compiled
+ * against
+ */
+ fw_info = find_fw_info(CHELSIO_CHIP_VERSION(hw->chip_id));
+ if (fw_info == NULL) {
+ csio_err(hw,
+ "unable to get firmware info for chip %d.\n",
+ CHELSIO_CHIP_VERSION(hw->chip_id));
+ return -EINVAL;
+ }
if (request_firmware(&fw, CSIO_FW_FNAME(hw), dev) < 0) {
csio_err(hw, "could not find firmware image %s, err: %d\n",
@@ -1989,33 +2129,25 @@ csio_hw_flash_fw(struct csio_hw *hw)
return -EINVAL;
}
- hdr = (const struct fw_hdr *)fw->data;
- fw_ver = ntohl(hdr->fw_ver);
- if (FW_HDR_FW_VER_MAJOR_G(fw_ver) != FW_VERSION_MAJOR(hw))
- return -EINVAL; /* wrong major version, won't do */
-
- /*
- * If the flash FW is unusable or we found something newer, load it.
+ /* allocate memory to read the header of the firmware on the
+ * card
*/
- if (FW_HDR_FW_VER_MAJOR_G(hw->fwrev) != FW_VERSION_MAJOR(hw) ||
- fw_ver > hw->fwrev) {
- ret = csio_hw_fw_upgrade(hw, hw->pfn, fw->data, fw->size,
- /*force=*/false);
- if (!ret)
- csio_info(hw,
- "firmware upgraded to version %pI4 from %s\n",
- &hdr->fw_ver, CSIO_FW_FNAME(hw));
- else
- csio_err(hw, "firmware upgrade failed! err=%d\n", ret);
- } else
- ret = -EINVAL;
+ card_fw = kmalloc(sizeof(*card_fw), GFP_KERNEL);
- release_firmware(fw);
+ fw_data = fw->data;
+ fw_size = fw->size;
+ /* upgrade FW logic */
+ ret = csio_hw_prep_fw(hw, fw_info, fw_data, fw_size, card_fw,
+ hw->fw_state, reset);
+
+ /* Cleaning up */
+ if (fw != NULL)
+ release_firmware(fw);
+ kfree(card_fw);
return ret;
}
-
/*
* csio_hw_configure - Configure HW
* @hw - HW module
@@ -2071,25 +2203,18 @@ csio_hw_configure(struct csio_hw *hw)
if (rv != 0)
goto out;
+ csio_hw_get_fw_version(hw, &hw->fwrev);
+ csio_hw_get_tp_version(hw, &hw->tp_vers);
if (csio_is_hw_master(hw) && hw->fw_state != CSIO_DEV_STATE_INIT) {
- rv = csio_hw_check_fw_version(hw);
- if (rv == -EINVAL) {
/* Do firmware update */
- spin_unlock_irq(&hw->lock);
- rv = csio_hw_flash_fw(hw);
- spin_lock_irq(&hw->lock);
+ spin_unlock_irq(&hw->lock);
+ rv = csio_hw_flash_fw(hw, &reset);
+ spin_lock_irq(&hw->lock);
+
+ if (rv != 0)
+ goto out;
- if (rv == 0) {
- reset = 0;
- /*
- * Note that the chip was reset as part of the
- * firmware upgrade so we don't reset it again
- * below and grab the new firmware version.
- */
- rv = csio_hw_check_fw_version(hw);
- }
- }
/*
* If the firmware doesn't support Configuration
* Files, use the old Driver-based, hard-wired
diff --git a/drivers/scsi/csiostor/csio_hw.h b/drivers/scsi/csiostor/csio_hw.h
index bd97204..1fe8fde 100644
--- a/drivers/scsi/csiostor/csio_hw.h
+++ b/drivers/scsi/csiostor/csio_hw.h
@@ -201,9 +201,8 @@ enum {
SF_ERASE_SECTOR = 0xd8, /* erase sector */
FW_START_SEC = 8, /* first flash sector for FW */
- FW_END_SEC = 15, /* last flash sector for FW */
FW_IMG_START = FW_START_SEC * SF_SEC_SIZE,
- FW_MAX_SIZE = (FW_END_SEC - FW_START_SEC + 1) * SF_SEC_SIZE,
+ FW_MAX_SIZE = 16 * SF_SEC_SIZE,
FLASH_CFG_MAX_SIZE = 0x10000 , /* max size of the flash config file*/
FLASH_CFG_OFFSET = 0x1f0000,
@@ -221,7 +220,7 @@ enum {
* Location of firmware image in FLASH.
*/
FLASH_FW_START_SEC = 8,
- FLASH_FW_NSECS = 8,
+ FLASH_FW_NSECS = 16,
FLASH_FW_START = FLASH_START(FLASH_FW_START_SEC),
FLASH_FW_MAX_SIZE = FLASH_MAX_SIZE(FLASH_FW_NSECS),
diff --git a/drivers/scsi/csiostor/csio_hw_chip.h b/drivers/scsi/csiostor/csio_hw_chip.h
index 70c0bdd..eec98f5 100644
--- a/drivers/scsi/csiostor/csio_hw_chip.h
+++ b/drivers/scsi/csiostor/csio_hw_chip.h
@@ -50,6 +50,36 @@
#define FW_CFG_NAME_T4 "cxgb4/t4-config.txt"
#define FW_CFG_NAME_T5 "cxgb4/t5-config.txt"
+#define T4FW_VERSION_MAJOR 0x01
+#define T4FW_VERSION_MINOR 0x0B
+#define T4FW_VERSION_MICRO 0x1B
+#define T4FW_VERSION_BUILD 0x00
+
+#define T5FW_VERSION_MAJOR 0x01
+#define T5FW_VERSION_MINOR 0x0B
+#define T5FW_VERSION_MICRO 0x1B
+#define T5FW_VERSION_BUILD 0x00
+
+#define CHELSIO_CHIP_CODE(version, revision) (((version) << 4) | (revision))
+#define CHELSIO_CHIP_FPGA 0x100
+#define CHELSIO_CHIP_VERSION(code) (((code) >> 12) & 0xf)
+#define CHELSIO_CHIP_RELEASE(code) ((code) & 0xf)
+
+#define CHELSIO_T4 0x4
+#define CHELSIO_T5 0x5
+
+enum chip_type {
+ T4_A1 = CHELSIO_CHIP_CODE(CHELSIO_T4, 1),
+ T4_A2 = CHELSIO_CHIP_CODE(CHELSIO_T4, 2),
+ T4_FIRST_REV = T4_A1,
+ T4_LAST_REV = T4_A2,
+
+ T5_A0 = CHELSIO_CHIP_CODE(CHELSIO_T5, 0),
+ T5_A1 = CHELSIO_CHIP_CODE(CHELSIO_T5, 1),
+ T5_FIRST_REV = T5_A0,
+ T5_LAST_REV = T5_A1,
+};
+
/* Define static functions */
static inline int csio_is_t4(uint16_t chip)
{
@@ -80,10 +110,21 @@ static inline int csio_is_t5(uint16_t chip)
(csio_is_t4(hw->chip_id) ? (PORT_REG(port, XGMAC_PORT_INT_CAUSE_A)) : \
(T5_PORT_REG(port, MAC_PORT_INT_CAUSE_A)))
-#define FW_VERSION_MAJOR(hw) (csio_is_t4(hw->chip_id) ? 1 : 0)
-#define FW_VERSION_MINOR(hw) (csio_is_t4(hw->chip_id) ? 2 : 0)
-#define FW_VERSION_MICRO(hw) (csio_is_t4(hw->chip_id) ? 8 : 0)
+#include "t4fw_api.h"
+#define FW_VERSION(chip) ( \
+ FW_HDR_FW_VER_MAJOR_G(chip##FW_VERSION_MAJOR) | \
+ FW_HDR_FW_VER_MINOR_G(chip##FW_VERSION_MINOR) | \
+ FW_HDR_FW_VER_MICRO_G(chip##FW_VERSION_MICRO) | \
+ FW_HDR_FW_VER_BUILD_G(chip##FW_VERSION_BUILD))
+#define FW_INTFVER(chip, intf) (FW_HDR_INTFVER_##intf)
+
+struct fw_info {
+ u8 chip;
+ char *fs_name;
+ char *fw_mod_name;
+ struct fw_hdr fw_hdr;
+};
#define CSIO_FW_FNAME(hw) \
(csio_is_t4(hw->chip_id) ? FW_FNAME_T4 : FW_FNAME_T5)
--
2.0.2
^ permalink raw reply related
* [PATCH] net: fec: fix NULL pointer dereference in fec_enet_timeout_work
From: Hubert Feurstein @ 2015-01-07 13:48 UTC (permalink / raw)
To: netdev; +Cc: fabio.estevam, frank.li, linux-kernel, davem, Hubert Feurstein
From: Hubert Feurstein <h.feurstein@gmail.com>
This patch initialises the fep->netdev pointer. This pointer was not
initialised at all, but is used in fec_enet_timeout_work and in some
error paths.
Signed-off-by: Hubert Feurstein <h.feurstein@gmail.com>
---
drivers/net/ethernet/freescale/fec_main.c | 1 +
1 file changed, 1 insertion(+)
diff --git a/drivers/net/ethernet/freescale/fec_main.c b/drivers/net/ethernet/freescale/fec_main.c
index 5ebdf8d..dbcab1c 100644
--- a/drivers/net/ethernet/freescale/fec_main.c
+++ b/drivers/net/ethernet/freescale/fec_main.c
@@ -3129,6 +3129,7 @@ fec_probe(struct platform_device *pdev)
pdev->id_entry = of_id->data;
fep->quirks = pdev->id_entry->driver_data;
+ fep->netdev = ndev;
fep->num_rx_queues = num_rx_qs;
fep->num_tx_queues = num_tx_qs;
--
2.2.1
^ permalink raw reply related
* [PATCH v2 0/7] Fix sti drivers whcih mix reg address spaces
From: Peter Griffin @ 2015-01-07 15:04 UTC (permalink / raw)
To: linux-arm-kernel-IAPFreCvJWM7uuMidbF8XUB+6BGkLq7r,
linux-kernel-u79uwXL29TY76Z2rM5mHXA,
srinivas.kandagatla-Re5JQEeQqe8AvxtiuMwx3w,
maxime.coquelin-qxv4g6HH51o, patrice.chotard-qxv4g6HH51o,
peppe.cavallaro-qxv4g6HH51o, kishon-l0cyMroinI0, arnd-r2nGTMty4D4
Cc: peter.griffin-QSEj5FYQhm4dnm+yROfE0A,
lee.jones-QSEj5FYQhm4dnm+yROfE0A,
devicetree-u79uwXL29TY76Z2rM5mHXA, netdev-u79uwXL29TY76Z2rM5mHXA
Hi folks,
A V2 of this old series incorporating Arnd and Lees Feedback form v1.
Following on from Arnds comments about the picophy driver here
https://lkml.org/lkml/2014/11/13/161, this series fixes the
remaining upstreamed drivers for STI, which are mixing address spaces
in the reg property. We do this in a way similar to the keystone
and bcm7445 platforms, by having sysconfig phandle/ offset pair
(where only one register is required). Or phandle / integer array
where multiple offsets in the same bank are needed).
This series breaks DT compatability! But the platform support
is WIP and only being used by the few developers who are upstreaming
support for it. I've made each change to the driver / dt doc / dt
file as a single atomic commit so the kernel will remain bisectable.
This series then also enables the picophy driver, and adds back in
the ehci/ohci dt nodes for stih410 which make use of the picophy.
regards,
Peter.
Changes since v1:
- Add missing space after */ (Lee)
- Change comment to "indexed from" rather than "not indexed from" (Lee)
- Change naming to phy1, phy2 rather than phy@1 phy@2 if there is no reg property (Arnd / Grant)
- Rebased on v3.19-rc3 (me)
- Checkpatch "no space before tabs" warning in stih41*.dtsi (me)
Peter Griffin (7):
phy: phy-stih407-usb: Pass sysconfig register offsets via syscfg
property.
phy: miphy365x: Pass sysconfig register offsets via syscfg dt
property.
ARM: STi: DT: STiH407: Add usb2 picophy dt nodes
ARM: STi: DT: STiH410: Add usb2 picophy dt nodes
ARM: STi: DT: STiH410: Add DT nodes for the ehci and ohci usb
controllers.
ARM: multi_v7_defconfig: Enable stih407 usb picophy
stmmac: dwmac-sti: Pass sysconfig register offset via syscon dt
property.
.../devicetree/bindings/net/sti-dwmac.txt | 14 ++---
.../devicetree/bindings/phy/phy-miphy365x.txt | 15 ++---
.../devicetree/bindings/phy/phy-stih407-usb.txt | 10 +---
arch/arm/boot/dts/stih407-family.dtsi | 9 +++
arch/arm/boot/dts/stih410.dtsi | 70 ++++++++++++++++++++++
arch/arm/boot/dts/stih415.dtsi | 12 ++--
arch/arm/boot/dts/stih416.dtsi | 22 +++----
arch/arm/configs/multi_v7_defconfig | 1 +
drivers/net/ethernet/stmicro/stmmac/dwmac-sti.c | 13 ++--
drivers/phy/phy-miphy365x.c | 29 ++++-----
drivers/phy/phy-stih407-usb.c | 25 ++++----
11 files changed, 143 insertions(+), 77 deletions(-)
--
1.9.1
--
To unsubscribe from this list: send the line "unsubscribe devicetree" in
the body of a message to majordomo-u79uwXL29TY76Z2rM5mHXA@public.gmane.org
More majordomo info at http://vger.kernel.org/majordomo-info.html
^ permalink raw reply
* [PATCH v2 1/7] phy: phy-stih407-usb: Pass sysconfig register offsets via syscfg property.
From: Peter Griffin @ 2015-01-07 15:04 UTC (permalink / raw)
To: linux-arm-kernel-IAPFreCvJWM7uuMidbF8XUB+6BGkLq7r,
linux-kernel-u79uwXL29TY76Z2rM5mHXA,
srinivas.kandagatla-Re5JQEeQqe8AvxtiuMwx3w,
maxime.coquelin-qxv4g6HH51o, patrice.chotard-qxv4g6HH51o,
peppe.cavallaro-qxv4g6HH51o, kishon-l0cyMroinI0, arnd-r2nGTMty4D4
Cc: peter.griffin-QSEj5FYQhm4dnm+yROfE0A,
lee.jones-QSEj5FYQhm4dnm+yROfE0A,
devicetree-u79uwXL29TY76Z2rM5mHXA, netdev-u79uwXL29TY76Z2rM5mHXA
In-Reply-To: <1420643052-4506-1-git-send-email-peter.griffin-QSEj5FYQhm4dnm+yROfE0A@public.gmane.org>
Based on Arnds review comments here https://lkml.org/lkml/2014/11/13/161,
update the phy driver to not use the reg property to access the sysconfig
register offsets.
This is because other phy's (miphy28, miphy365) have a combination of
memory mapped registers and sysconfig control regs, and we shouldn't
be mixing address spaces in the reg property. In addition we would
ideally like the sysconfig offsets to be passed via DT in a uniform way.
This new method will also allow us to support devices which have sysconfig
registers in different banks more easily and it is also analagous to how
keystone and bcm7745 platforms pass there syscon offsets in DT.
This breaks DT compatibility, but this platform is considered WIP, and
is only used by a few developers who are upstreaming support for it.
Signed-off-by: Peter Griffin <peter.griffin-QSEj5FYQhm4dnm+yROfE0A@public.gmane.org>
Reviewed-by: Arnd Bergmann <arnd-r2nGTMty4D4@public.gmane.org>
---
.../devicetree/bindings/phy/phy-stih407-usb.txt | 10 ++-------
drivers/phy/phy-stih407-usb.c | 25 ++++++++++++----------
2 files changed, 16 insertions(+), 19 deletions(-)
diff --git a/Documentation/devicetree/bindings/phy/phy-stih407-usb.txt b/Documentation/devicetree/bindings/phy/phy-stih407-usb.txt
index 1ef8228..de6a706 100644
--- a/Documentation/devicetree/bindings/phy/phy-stih407-usb.txt
+++ b/Documentation/devicetree/bindings/phy/phy-stih407-usb.txt
@@ -5,10 +5,7 @@ host controllers (when controlling usb2/1.1 devices) available on STiH407 SoC fa
Required properties:
- compatible : should be "st,stih407-usb2-phy"
-- reg : contain the offset and length of the system configuration registers
- used as glue logic to control & parameter phy
-- reg-names : the names of the system configuration registers in "reg", should be "param" and "reg"
-- st,syscfg : sysconfig register to manage phy parameter at driver level
+- st,syscfg : phandle of sysconfig bank plus integer array containing phyparam and phyctrl register offsets
- resets : list of phandle and reset specifier pairs. There should be two entries, one
for the whole phy and one for the port
- reset-names : list of reset signal names. Should be "global" and "port"
@@ -19,11 +16,8 @@ Example:
usb2_picophy0: usbpicophy@f8 {
compatible = "st,stih407-usb2-phy";
- reg = <0xf8 0x04>, /* syscfg 5062 */
- <0xf4 0x04>; /* syscfg 5061 */
- reg-names = "param", "ctrl";
#phy-cells = <0>;
- st,syscfg = <&syscfg_core>;
+ st,syscfg = <&syscfg_core 0x100 0xf4>;
resets = <&softreset STIH407_PICOPHY_SOFTRESET>,
<&picophyreset STIH407_PICOPHY0_RESET>;
reset-names = "global", "port";
diff --git a/drivers/phy/phy-stih407-usb.c b/drivers/phy/phy-stih407-usb.c
index 74f0fab..1d5ae5f 100644
--- a/drivers/phy/phy-stih407-usb.c
+++ b/drivers/phy/phy-stih407-usb.c
@@ -22,6 +22,9 @@
#include <linux/mfd/syscon.h>
#include <linux/phy/phy.h>
+#define PHYPARAM_REG 1
+#define PHYCTRL_REG 2
+
/* Default PHY_SEL and REFCLKSEL configuration */
#define STIH407_USB_PICOPHY_CTRL_PORT_CONF 0x6
#define STIH407_USB_PICOPHY_CTRL_PORT_MASK 0x1f
@@ -93,7 +96,7 @@ static int stih407_usb2_picophy_probe(struct platform_device *pdev)
struct device_node *np = dev->of_node;
struct phy_provider *phy_provider;
struct phy *phy;
- struct resource *res;
+ int ret;
phy_dev = devm_kzalloc(dev, sizeof(*phy_dev), GFP_KERNEL);
if (!phy_dev)
@@ -123,19 +126,19 @@ static int stih407_usb2_picophy_probe(struct platform_device *pdev)
return PTR_ERR(phy_dev->regmap);
}
- res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "ctrl");
- if (!res) {
- dev_err(dev, "No ctrl reg found\n");
- return -ENXIO;
+ ret = of_property_read_u32_index(np, "st,syscfg", PHYPARAM_REG,
+ &phy_dev->param);
+ if (ret) {
+ dev_err(dev, "can't get phyparam offset (%d)\n", ret);
+ return ret;
}
- phy_dev->ctrl = res->start;
- res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "param");
- if (!res) {
- dev_err(dev, "No param reg found\n");
- return -ENXIO;
+ ret = of_property_read_u32_index(np, "st,syscfg", PHYCTRL_REG,
+ &phy_dev->ctrl);
+ if (ret) {
+ dev_err(dev, "can't get phyctrl offset (%d)\n", ret);
+ return ret;
}
- phy_dev->param = res->start;
phy = devm_phy_create(dev, NULL, &stih407_usb2_picophy_data);
if (IS_ERR(phy)) {
--
1.9.1
--
To unsubscribe from this list: send the line "unsubscribe devicetree" in
the body of a message to majordomo-u79uwXL29TY76Z2rM5mHXA@public.gmane.org
More majordomo info at http://vger.kernel.org/majordomo-info.html
^ permalink raw reply related
* [PATCH v2 2/7] phy: miphy365x: Pass sysconfig register offsets via syscfg dt property.
From: Peter Griffin @ 2015-01-07 15:04 UTC (permalink / raw)
To: linux-arm-kernel-IAPFreCvJWM7uuMidbF8XUB+6BGkLq7r,
linux-kernel-u79uwXL29TY76Z2rM5mHXA,
srinivas.kandagatla-Re5JQEeQqe8AvxtiuMwx3w,
maxime.coquelin-qxv4g6HH51o, patrice.chotard-qxv4g6HH51o,
peppe.cavallaro-qxv4g6HH51o, kishon-l0cyMroinI0, arnd-r2nGTMty4D4
Cc: peter.griffin-QSEj5FYQhm4dnm+yROfE0A,
lee.jones-QSEj5FYQhm4dnm+yROfE0A,
devicetree-u79uwXL29TY76Z2rM5mHXA, netdev-u79uwXL29TY76Z2rM5mHXA
In-Reply-To: <1420643052-4506-1-git-send-email-peter.griffin-QSEj5FYQhm4dnm+yROfE0A@public.gmane.org>
Based on Arnds review comments here https://lkml.org/lkml/2014/11/13/161,
update the miphy365 phy driver to access sysconfig register offsets via
syscfg dt property.
This is because the reg property should not be mixing address spaces
like it does currently for miphy365. This change then also aligns us
to how other platforms such as keystone and bcm7445 pass there syscon
offsets via DT.
This patch breaks DT compatibility, but this platform is considered WIP,
and is only used by a few developers who are upstreaming support for it.
This change has been done as a single atomic commit to ensure it is
bisectable.
Signed-off-by: Peter Griffin <peter.griffin-QSEj5FYQhm4dnm+yROfE0A@public.gmane.org>
Reviewed-by: Arnd Bergmann <arnd-r2nGTMty4D4@public.gmane.org>
---
.../devicetree/bindings/phy/phy-miphy365x.txt | 15 +++++------
arch/arm/boot/dts/stih416.dtsi | 10 ++++----
drivers/phy/phy-miphy365x.c | 29 ++++++++--------------
3 files changed, 23 insertions(+), 31 deletions(-)
diff --git a/Documentation/devicetree/bindings/phy/phy-miphy365x.txt b/Documentation/devicetree/bindings/phy/phy-miphy365x.txt
index 42c8808..9802d5d 100644
--- a/Documentation/devicetree/bindings/phy/phy-miphy365x.txt
+++ b/Documentation/devicetree/bindings/phy/phy-miphy365x.txt
@@ -6,8 +6,10 @@ for SATA and PCIe.
Required properties (controller (parent) node):
- compatible : Should be "st,miphy365x-phy"
-- st,syscfg : Should be a phandle of the system configuration register group
- which contain the SATA, PCIe mode setting bits
+- st,syscfg : Phandle / integer array property. Phandle of sysconfig group
+ containing the miphy registers and integer array should contain
+ an entry for each port sub-node, specifying the control
+ register offset inside the sysconfig group.
Required nodes : A sub-node is required for each channel the controller
provides. Address range information including the usual
@@ -26,7 +28,6 @@ Required properties (port (child) node):
registers filled in "reg":
- sata: For SATA devices
- pcie: For PCIe devices
- - syscfg: To specify the syscfg based config register
Optional properties (port (child) node):
- st,sata-gen : Generation of locally attached SATA IP. Expected values
@@ -39,20 +40,20 @@ Example:
miphy365x_phy: miphy365x@fe382000 {
compatible = "st,miphy365x-phy";
- st,syscfg = <&syscfg_rear>;
+ st,syscfg = <&syscfg_rear 0x824 0x828>;
#address-cells = <1>;
#size-cells = <1>;
ranges;
phy_port0: port@fe382000 {
- reg = <0xfe382000 0x100>, <0xfe394000 0x100>, <0x824 0x4>;
- reg-names = "sata", "pcie", "syscfg";
+ reg = <0xfe382000 0x100>, <0xfe394000 0x100>;
+ reg-names = "sata", "pcie";
#phy-cells = <1>;
st,sata-gen = <3>;
};
phy_port1: port@fe38a000 {
- reg = <0xfe38a000 0x100>, <0xfe804000 0x100>, <0x828 0x4>;;
+ reg = <0xfe38a000 0x100>, <0xfe804000 0x100>;;
reg-names = "sata", "pcie", "syscfg";
#phy-cells = <1>;
st,pcie-tx-pol-inv;
diff --git a/arch/arm/boot/dts/stih416.dtsi b/arch/arm/boot/dts/stih416.dtsi
index fad9073..85afe01 100644
--- a/arch/arm/boot/dts/stih416.dtsi
+++ b/arch/arm/boot/dts/stih416.dtsi
@@ -283,21 +283,21 @@
miphy365x_phy: phy@fe382000 {
compatible = "st,miphy365x-phy";
- st,syscfg = <&syscfg_rear>;
+ st,syscfg = <&syscfg_rear 0x824 0x828>;
#address-cells = <1>;
#size-cells = <1>;
ranges;
phy_port0: port@fe382000 {
#phy-cells = <1>;
- reg = <0xfe382000 0x100>, <0xfe394000 0x100>, <0x824 0x4>;
- reg-names = "sata", "pcie", "syscfg";
+ reg = <0xfe382000 0x100>, <0xfe394000 0x100>;
+ reg-names = "sata", "pcie";
};
phy_port1: port@fe38a000 {
#phy-cells = <1>;
- reg = <0xfe38a000 0x100>, <0xfe804000 0x100>, <0x828 0x4>;
- reg-names = "sata", "pcie", "syscfg";
+ reg = <0xfe38a000 0x100>, <0xfe804000 0x100>;
+ reg-names = "sata", "pcie";
};
};
diff --git a/drivers/phy/phy-miphy365x.c b/drivers/phy/phy-miphy365x.c
index 6ab43a8..6c80154 100644
--- a/drivers/phy/phy-miphy365x.c
+++ b/drivers/phy/phy-miphy365x.c
@@ -141,7 +141,7 @@ struct miphy365x_phy {
bool pcie_tx_pol_inv;
bool sata_tx_pol_inv;
u32 sata_gen;
- u64 ctrlreg;
+ u32 ctrlreg;
u8 type;
};
@@ -179,7 +179,7 @@ static int miphy365x_set_path(struct miphy365x_phy *miphy_phy,
bool sata = (miphy_phy->type == MIPHY_TYPE_SATA);
return regmap_update_bits(miphy_dev->regmap,
- (unsigned int)miphy_phy->ctrlreg,
+ miphy_phy->ctrlreg,
SYSCFG_SELECT_SATA_MASK,
sata << SYSCFG_SELECT_SATA_POS);
}
@@ -445,7 +445,6 @@ int miphy365x_get_addr(struct device *dev, struct miphy365x_phy *miphy_phy,
{
struct device_node *phynode = miphy_phy->phy->dev.of_node;
const char *name;
- const __be32 *taddr;
int type = miphy_phy->type;
int ret;
@@ -455,22 +454,6 @@ int miphy365x_get_addr(struct device *dev, struct miphy365x_phy *miphy_phy,
return ret;
}
- if (!strncmp(name, "syscfg", 6)) {
- taddr = of_get_address(phynode, index, NULL, NULL);
- if (!taddr) {
- dev_err(dev, "failed to fetch syscfg address\n");
- return -EINVAL;
- }
-
- miphy_phy->ctrlreg = of_translate_address(phynode, taddr);
- if (miphy_phy->ctrlreg == OF_BAD_ADDR) {
- dev_err(dev, "failed to translate syscfg address\n");
- return -EINVAL;
- }
-
- return 0;
- }
-
if (!((!strncmp(name, "sata", 4) && type == MIPHY_TYPE_SATA) ||
(!strncmp(name, "pcie", 4) && type == MIPHY_TYPE_PCIE)))
return 0;
@@ -606,7 +589,15 @@ static int miphy365x_probe(struct platform_device *pdev)
return ret;
phy_set_drvdata(phy, miphy_dev->phys[port]);
+
port++;
+ /* sysconfig offsets are indexed from 1 */
+ ret = of_property_read_u32_index(np, "st,syscfg", port,
+ &miphy_phy->ctrlreg);
+ if (ret) {
+ dev_err(&pdev->dev, "No sysconfig offset found\n");
+ return ret;
+ }
}
provider = devm_of_phy_provider_register(&pdev->dev, miphy365x_xlate);
--
1.9.1
--
To unsubscribe from this list: send the line "unsubscribe devicetree" in
the body of a message to majordomo-u79uwXL29TY76Z2rM5mHXA@public.gmane.org
More majordomo info at http://vger.kernel.org/majordomo-info.html
^ permalink raw reply related
* [PATCH v2 4/7] ARM: STi: DT: STiH410: Add usb2 picophy dt nodes
From: Peter Griffin @ 2015-01-07 15:04 UTC (permalink / raw)
To: linux-arm-kernel-IAPFreCvJWM7uuMidbF8XUB+6BGkLq7r,
linux-kernel-u79uwXL29TY76Z2rM5mHXA,
srinivas.kandagatla-Re5JQEeQqe8AvxtiuMwx3w,
maxime.coquelin-qxv4g6HH51o, patrice.chotard-qxv4g6HH51o,
peppe.cavallaro-qxv4g6HH51o, kishon-l0cyMroinI0, arnd-r2nGTMty4D4
Cc: peter.griffin-QSEj5FYQhm4dnm+yROfE0A,
lee.jones-QSEj5FYQhm4dnm+yROfE0A,
devicetree-u79uwXL29TY76Z2rM5mHXA, netdev-u79uwXL29TY76Z2rM5mHXA
In-Reply-To: <1420643052-4506-1-git-send-email-peter.griffin-QSEj5FYQhm4dnm+yROfE0A@public.gmane.org>
This patch adds the dt nodes for the extra usb2 picophys found on
the stih410.
These two picophys are used in conjunction with the extra ehci/ohci usb
controllers also found on the stih410 SoC.
Signed-off-by: Peter Griffin <peter.griffin-QSEj5FYQhm4dnm+yROfE0A@public.gmane.org>
Reviewed-by: Arnd Bergmann <arnd-r2nGTMty4D4@public.gmane.org>
---
arch/arm/boot/dts/stih410.dtsi | 18 ++++++++++++++++++
1 file changed, 18 insertions(+)
diff --git a/arch/arm/boot/dts/stih410.dtsi b/arch/arm/boot/dts/stih410.dtsi
index c05627e..2e5e9ed 100644
--- a/arch/arm/boot/dts/stih410.dtsi
+++ b/arch/arm/boot/dts/stih410.dtsi
@@ -10,5 +10,23 @@
#include "stih407-family.dtsi"
#include "stih410-pinctrl.dtsi"
/ {
+ soc {
+ usb2_picophy1: phy2 {
+ compatible = "st,stih407-usb2-phy";
+ #phy-cells = <0>;
+ st,syscfg = <&syscfg_core 0xf8 0xf4>;
+ resets = <&softreset STIH407_PICOPHY_SOFTRESET>,
+ <&picophyreset STIH407_PICOPHY0_RESET>;
+ reset-names = "global", "port";
+ };
+ usb2_picophy2: phy3 {
+ compatible = "st,stih407-usb2-phy";
+ #phy-cells = <0>;
+ st,syscfg = <&syscfg_core 0xfc 0xf4>;
+ resets = <&softreset STIH407_PICOPHY_SOFTRESET>,
+ <&picophyreset STIH407_PICOPHY1_RESET>;
+ reset-names = "global", "port";
+ };
+ };
};
--
1.9.1
--
To unsubscribe from this list: send the line "unsubscribe devicetree" in
the body of a message to majordomo-u79uwXL29TY76Z2rM5mHXA@public.gmane.org
More majordomo info at http://vger.kernel.org/majordomo-info.html
^ permalink raw reply related
* [PATCH v2 5/7] ARM: STi: DT: STiH410: Add DT nodes for the ehci and ohci usb controllers.
From: Peter Griffin @ 2015-01-07 15:04 UTC (permalink / raw)
To: linux-arm-kernel, linux-kernel, srinivas.kandagatla,
maxime.coquelin, patrice.chotard, peppe.cavallaro, kishon, arnd
Cc: peter.griffin, devicetree, lee.jones, netdev
In-Reply-To: <1420643052-4506-1-git-send-email-peter.griffin@linaro.org>
This patch adds the DT nodes for the extra ehci and ohci usb controllers
on the stih410 SoC.
Signed-off-by: Peter Griffin <peter.griffin@linaro.org>
Reviewed-by: Arnd Bergmann <arnd@arndb.de>
---
arch/arm/boot/dts/stih410.dtsi | 52 ++++++++++++++++++++++++++++++++++++++++++
1 file changed, 52 insertions(+)
diff --git a/arch/arm/boot/dts/stih410.dtsi b/arch/arm/boot/dts/stih410.dtsi
index 2e5e9ed..37995f4 100644
--- a/arch/arm/boot/dts/stih410.dtsi
+++ b/arch/arm/boot/dts/stih410.dtsi
@@ -28,5 +28,57 @@
<&picophyreset STIH407_PICOPHY1_RESET>;
reset-names = "global", "port";
};
+
+ ohci0: usb@9a03c00 {
+ compatible = "st,st-ohci-300x";
+ reg = <0x9a03c00 0x100>;
+ interrupts = <GIC_SPI 180 IRQ_TYPE_NONE>;
+ clocks = <&clk_s_c0_flexgen CLK_TX_ICN_DISP_0>;
+ resets = <&powerdown STIH407_USB2_PORT0_POWERDOWN>,
+ <&softreset STIH407_USB2_PORT0_SOFTRESET>;
+ reset-names = "power", "softreset";
+ phys = <&usb2_picophy1>;
+ phy-names = "usb";
+ };
+
+ ehci0: usb@9a03e00 {
+ compatible = "st,st-ehci-300x";
+ reg = <0x9a03e00 0x100>;
+ interrupts = <GIC_SPI 151 IRQ_TYPE_NONE>;
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_usb0>;
+ clocks = <&clk_s_c0_flexgen CLK_TX_ICN_DISP_0>;
+ resets = <&powerdown STIH407_USB2_PORT0_POWERDOWN>,
+ <&softreset STIH407_USB2_PORT0_SOFTRESET>;
+ reset-names = "power", "softreset";
+ phys = <&usb2_picophy1>;
+ phy-names = "usb";
+ };
+
+ ohci1: usb@9a83c00 {
+ compatible = "st,st-ohci-300x";
+ reg = <0x9a83c00 0x100>;
+ interrupts = <GIC_SPI 181 IRQ_TYPE_NONE>;
+ clocks = <&clk_s_c0_flexgen CLK_TX_ICN_DISP_0>;
+ resets = <&powerdown STIH407_USB2_PORT1_POWERDOWN>,
+ <&softreset STIH407_USB2_PORT1_SOFTRESET>;
+ reset-names = "power", "softreset";
+ phys = <&usb2_picophy2>;
+ phy-names = "usb";
+ };
+
+ ehci1: usb@9a83e00 {
+ compatible = "st,st-ehci-300x";
+ reg = <0x9a83e00 0x100>;
+ interrupts = <GIC_SPI 153 IRQ_TYPE_NONE>;
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_usb1>;
+ clocks = <&clk_s_c0_flexgen CLK_TX_ICN_DISP_0>;
+ resets = <&powerdown STIH407_USB2_PORT1_POWERDOWN>,
+ <&softreset STIH407_USB2_PORT1_SOFTRESET>;
+ reset-names = "power", "softreset";
+ phys = <&usb2_picophy2>;
+ phy-names = "usb";
+ };
};
};
--
1.9.1
^ permalink raw reply related
* [PATCH v2 6/7] ARM: multi_v7_defconfig: Enable stih407 usb picophy
From: Peter Griffin @ 2015-01-07 15:04 UTC (permalink / raw)
To: linux-arm-kernel, linux-kernel, srinivas.kandagatla,
maxime.coquelin, patrice.chotard, peppe.cavallaro, kishon, arnd
Cc: peter.griffin, lee.jones, devicetree, netdev
In-Reply-To: <1420643052-4506-1-git-send-email-peter.griffin@linaro.org>
This patch enables the picoPHY usb phy which is used by
the usb2 and usb3 host controllers when controlling usb2/1.1
devices. It is found in stih407 family SoC's from STMicroelectronics.
Signed-off-by: Peter Griffin <peter.griffin@linaro.org>
Acked-by: Lee Jones <lee.jones@linaro.org>
Reviewed-by: Arnd Bergmann <arnd@arndb.de>
---
arch/arm/configs/multi_v7_defconfig | 1 +
1 file changed, 1 insertion(+)
diff --git a/arch/arm/configs/multi_v7_defconfig b/arch/arm/configs/multi_v7_defconfig
index bc393b7..444685c 100644
--- a/arch/arm/configs/multi_v7_defconfig
+++ b/arch/arm/configs/multi_v7_defconfig
@@ -456,6 +456,7 @@ CONFIG_OMAP_USB2=y
CONFIG_TI_PIPE3=y
CONFIG_PHY_MIPHY365X=y
CONFIG_PHY_STIH41X_USB=y
+CONFIG_PHY_STIH407_USB=y
CONFIG_PHY_SUN4I_USB=y
CONFIG_EXT4_FS=y
CONFIG_AUTOFS4_FS=y
--
1.9.1
^ permalink raw reply related
* [PATCH v2 7/7] stmmac: dwmac-sti: Pass sysconfig register offset via syscon dt property.
From: Peter Griffin @ 2015-01-07 15:04 UTC (permalink / raw)
To: linux-arm-kernel, linux-kernel, srinivas.kandagatla,
maxime.coquelin, patrice.chotard, peppe.cavallaro, kishon, arnd
Cc: peter.griffin, lee.jones, devicetree, netdev
In-Reply-To: <1420643052-4506-1-git-send-email-peter.griffin@linaro.org>
Based on Arnds review comments here https://lkml.org/lkml/2014/11/13/161,
we should not be mixing address spaces in the reg property like this driver
currently does. This patch updates the driver, dt docs and also the existing
dt nodes to pass the sysconfig offset in the syscon dt property.
This patch breaks DT compatibility! But this platform is considered WIP,
and is only used by a few developers who are upstreaming support for it.
This change has been done as a single atomic commit to ensure it is
bisectable.
Signed-off-by: Peter Griffin <peter.griffin@linaro.org>
Reviewed-by: Arnd Bergmann <arnd@arndb.de>
---
Documentation/devicetree/bindings/net/sti-dwmac.txt | 14 +++++---------
arch/arm/boot/dts/stih415.dtsi | 12 ++++++------
arch/arm/boot/dts/stih416.dtsi | 12 ++++++------
drivers/net/ethernet/stmicro/stmmac/dwmac-sti.c | 13 +++++++------
4 files changed, 24 insertions(+), 27 deletions(-)
diff --git a/Documentation/devicetree/bindings/net/sti-dwmac.txt b/Documentation/devicetree/bindings/net/sti-dwmac.txt
index 6762a6b..d05c1e1 100644
--- a/Documentation/devicetree/bindings/net/sti-dwmac.txt
+++ b/Documentation/devicetree/bindings/net/sti-dwmac.txt
@@ -9,14 +9,10 @@ The device node has following properties.
Required properties:
- compatible : Can be "st,stih415-dwmac", "st,stih416-dwmac",
"st,stih407-dwmac", "st,stid127-dwmac".
- - reg : Offset of the glue configuration register map in system
- configuration regmap pointed by st,syscon property and size.
- - st,syscon : Should be phandle to system configuration node which
- encompases this glue registers.
+ - st,syscon : Should be phandle/offset pair. The phandle to the syscon node which
+ encompases the glue register, and the offset of the control register.
- st,gmac_en: this is to enable the gmac into a dedicated sysctl control
register available on STiH407 SoC.
- - sti-ethconf: this is the gmac glue logic register to enable the GMAC,
- select among the different modes and program the clk retiming.
- pinctrl-0: pin-control for all the MII mode supported.
Optional properties:
@@ -40,10 +36,10 @@ ethernet0: dwmac@9630000 {
device_type = "network";
status = "disabled";
compatible = "st,stih407-dwmac", "snps,dwmac", "snps,dwmac-3.710";
- reg = <0x9630000 0x8000>, <0x80 0x4>;
- reg-names = "stmmaceth", "sti-ethconf";
+ reg = <0x9630000 0x8000>;
+ reg-names = "stmmaceth";
- st,syscon = <&syscfg_sbc_reg>;
+ st,syscon = <&syscfg_sbc_reg 0x80>;
st,gmac_en;
resets = <&softreset STIH407_ETH1_SOFTRESET>;
reset-names = "stmmaceth";
diff --git a/arch/arm/boot/dts/stih415.dtsi b/arch/arm/boot/dts/stih415.dtsi
index 9198c12..19b019b 100644
--- a/arch/arm/boot/dts/stih415.dtsi
+++ b/arch/arm/boot/dts/stih415.dtsi
@@ -153,8 +153,8 @@
compatible = "st,stih415-dwmac", "snps,dwmac", "snps,dwmac-3.610";
status = "disabled";
- reg = <0xfe810000 0x8000>, <0x148 0x4>;
- reg-names = "stmmaceth", "sti-ethconf";
+ reg = <0xfe810000 0x8000>;
+ reg-names = "stmmaceth";
interrupts = <0 147 0>, <0 148 0>, <0 149 0>;
interrupt-names = "macirq", "eth_wake_irq", "eth_lpi";
@@ -165,7 +165,7 @@
snps,mixed-burst;
snps,force_sf_dma_mode;
- st,syscon = <&syscfg_rear>;
+ st,syscon = <&syscfg_rear 0x148>;
pinctrl-names = "default";
pinctrl-0 = <&pinctrl_mii0>;
@@ -177,8 +177,8 @@
device_type = "network";
compatible = "st,stih415-dwmac", "snps,dwmac", "snps,dwmac-3.610";
status = "disabled";
- reg = <0xfef08000 0x8000>, <0x74 0x4>;
- reg-names = "stmmaceth", "sti-ethconf";
+ reg = <0xfef08000 0x8000>;
+ reg-names = "stmmaceth";
interrupts = <0 150 0>, <0 151 0>, <0 152 0>;
interrupt-names = "macirq", "eth_wake_irq", "eth_lpi";
@@ -186,7 +186,7 @@
snps,mixed-burst;
snps,force_sf_dma_mode;
- st,syscon = <&syscfg_sbc>;
+ st,syscon = <&syscfg_sbc 0x74>;
resets = <&softreset STIH415_ETH1_SOFTRESET>;
reset-names = "stmmaceth";
diff --git a/arch/arm/boot/dts/stih416.dtsi b/arch/arm/boot/dts/stih416.dtsi
index 85afe01..ea28eba 100644
--- a/arch/arm/boot/dts/stih416.dtsi
+++ b/arch/arm/boot/dts/stih416.dtsi
@@ -163,8 +163,8 @@
device_type = "network";
compatible = "st,stih416-dwmac", "snps,dwmac", "snps,dwmac-3.710";
status = "disabled";
- reg = <0xfe810000 0x8000>, <0x8bc 0x4>;
- reg-names = "stmmaceth", "sti-ethconf";
+ reg = <0xfe810000 0x8000>;
+ reg-names = "stmmaceth";
interrupts = <0 133 0>, <0 134 0>, <0 135 0>;
interrupt-names = "macirq", "eth_wake_irq", "eth_lpi";
@@ -172,7 +172,7 @@
snps,pbl = <32>;
snps,mixed-burst;
- st,syscon = <&syscfg_rear>;
+ st,syscon = <&syscfg_rear 0x8bc>;
resets = <&softreset STIH416_ETH0_SOFTRESET>;
reset-names = "stmmaceth";
pinctrl-names = "default";
@@ -185,15 +185,15 @@
device_type = "network";
compatible = "st,stih416-dwmac", "snps,dwmac", "snps,dwmac-3.710";
status = "disabled";
- reg = <0xfef08000 0x8000>, <0x7f0 0x4>;
- reg-names = "stmmaceth", "sti-ethconf";
+ reg = <0xfef08000 0x8000>;
+ reg-names = "stmmaceth";
interrupts = <0 136 0>, <0 137 0>, <0 138 0>;
interrupt-names = "macirq", "eth_wake_irq", "eth_lpi";
snps,pbl = <32>;
snps,mixed-burst;
- st,syscon = <&syscfg_sbc>;
+ st,syscon = <&syscfg_sbc 0x7f0>;
resets = <&softreset STIH416_ETH1_SOFTRESET>;
reset-names = "stmmaceth";
diff --git a/drivers/net/ethernet/stmicro/stmmac/dwmac-sti.c b/drivers/net/ethernet/stmicro/stmmac/dwmac-sti.c
index 056b358..bb6e2dc 100644
--- a/drivers/net/ethernet/stmicro/stmmac/dwmac-sti.c
+++ b/drivers/net/ethernet/stmicro/stmmac/dwmac-sti.c
@@ -122,7 +122,7 @@ struct sti_dwmac {
bool ext_phyclk; /* Clock from external PHY */
u32 tx_retime_src; /* TXCLK Retiming*/
struct clk *clk; /* PHY clock */
- int ctrl_reg; /* GMAC glue-logic control register */
+ u32 ctrl_reg; /* GMAC glue-logic control register */
int clk_sel_reg; /* GMAC ext clk selection register */
struct device *dev;
struct regmap *regmap;
@@ -285,11 +285,6 @@ static int sti_dwmac_parse_data(struct sti_dwmac *dwmac,
if (!np)
return -EINVAL;
- res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "sti-ethconf");
- if (!res)
- return -ENODATA;
- dwmac->ctrl_reg = res->start;
-
/* clk selection from extra syscfg register */
dwmac->clk_sel_reg = -ENXIO;
res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "sti-clkconf");
@@ -300,6 +295,12 @@ static int sti_dwmac_parse_data(struct sti_dwmac *dwmac,
if (IS_ERR(regmap))
return PTR_ERR(regmap);
+ err = of_property_read_u32_index(np, "st,syscon", 1, &dwmac->ctrl_reg);
+ if (err) {
+ dev_err(dev, "Can't get sysconfig ctrl offset (%d)\n", err);
+ return err;
+ }
+
dwmac->dev = dev;
dwmac->interface = of_get_phy_mode(np);
dwmac->regmap = regmap;
--
1.9.1
^ permalink raw reply related
* [PATCH v2 3/7] ARM: STi: DT: STiH407: Add usb2 picophy dt nodes
From: Peter Griffin @ 2015-01-07 15:04 UTC (permalink / raw)
To: linux-arm-kernel, linux-kernel, srinivas.kandagatla,
maxime.coquelin, patrice.chotard, peppe.cavallaro, kishon, arnd
Cc: peter.griffin, lee.jones, devicetree, netdev
In-Reply-To: <1420643052-4506-1-git-send-email-peter.griffin@linaro.org>
This patch adds the dt nodes for the usb2 picophy found on the stih407
device family. It is used on stih407 by the dwc3 usb3 controller when
controlling usb2/1.1 devices.
Signed-off-by: Peter Griffin <peter.griffin@linaro.org>
Reviewed-by: Arnd Bergmann <arnd@arndb.de>
---
arch/arm/boot/dts/stih407-family.dtsi | 9 +++++++++
1 file changed, 9 insertions(+)
diff --git a/arch/arm/boot/dts/stih407-family.dtsi b/arch/arm/boot/dts/stih407-family.dtsi
index 3e31d32..d4a8f84 100644
--- a/arch/arm/boot/dts/stih407-family.dtsi
+++ b/arch/arm/boot/dts/stih407-family.dtsi
@@ -274,5 +274,14 @@
status = "disabled";
};
+
+ usb2_picophy0: phy1 {
+ compatible = "st,stih407-usb2-phy";
+ #phy-cells = <0>;
+ st,syscfg = <&syscfg_core 0x100 0xf4>;
+ resets = <&softreset STIH407_PICOPHY_SOFTRESET>,
+ <&picophyreset STIH407_PICOPHY0_RESET>;
+ reset-names = "global", "port";
+ };
};
};
--
1.9.1
^ permalink raw reply related
* Re: [PATCH] vhost/net: length miscalculation
From: Alex Williamson @ 2015-01-07 15:09 UTC (permalink / raw)
To: Michael S. Tsirkin; +Cc: linux-kernel, Greg Kurz, kvm, virtualization, netdev
In-Reply-To: <1420620847-24477-1-git-send-email-mst@redhat.com>
On Wed, 2015-01-07 at 10:55 +0200, Michael S. Tsirkin wrote:
> commit 8b38694a2dc8b18374310df50174f1e4376d6824
> vhost/net: virtio 1.0 byte swap
> had this chunk:
> - heads[headcount - 1].len += datalen;
> + heads[headcount - 1].len = cpu_to_vhost32(vq, len - datalen);
>
> This adds datalen with the wrong sign, causing guest panics.
>
> Fixes: 8b38694a2dc8b18374310df50174f1e4376d6824
> Reported-by: Alex Williamson <alex.williamson@redhat.com>
> Suggested-by: Greg Kurz <gkurz@linux.vnet.ibm.com>
> Signed-off-by: Michael S. Tsirkin <mst@redhat.com>
> ---
>
> Alex, could you please confirm this fixes the crash for you?
Confirmed, this works. Thanks,
Alex
> drivers/vhost/net.c | 2 +-
> 1 file changed, 1 insertion(+), 1 deletion(-)
>
> diff --git a/drivers/vhost/net.c b/drivers/vhost/net.c
> index 14419a8..d415d69 100644
> --- a/drivers/vhost/net.c
> +++ b/drivers/vhost/net.c
> @@ -538,7 +538,7 @@ static int get_rx_bufs(struct vhost_virtqueue *vq,
> ++headcount;
> seg += in;
> }
> - heads[headcount - 1].len = cpu_to_vhost32(vq, len - datalen);
> + heads[headcount - 1].len = cpu_to_vhost32(vq, len + datalen);
> *iovcount = seg;
> if (unlikely(log))
> *log_num = nlogs;
^ permalink raw reply
* Re: [PATCH iproute2 3/3] ip netns: Delete all netns
From: Brian Haley @ 2015-01-07 15:44 UTC (permalink / raw)
To: Vadim Kochan, netdev
In-Reply-To: <1420628662-9930-4-git-send-email-vadim4j@gmail.com>
On 01/07/2015 06:04 AM, Vadim Kochan wrote:
> From: Vadim Kochan <vadim4j@gmail.com>
>
> Allow delete all namespace names by:
>
> $ ip netns del all
So I can still create a namespace called 'all', but can't exec in it or delete
it independently with this change. Perhaps you need to block that as well?
Unless there's some other patch I'm missing?
-Brian
^ permalink raw reply
* Re: [PATCH net-next] net: sched: use pinned timers
From: Eric Dumazet @ 2015-01-07 15:45 UTC (permalink / raw)
To: Cosmin GIRADU; +Cc: netdev
In-Reply-To: <54AD0543.1090806@rcs-rds.ro>
On Wed, 2015-01-07 at 12:06 +0200, Cosmin GIRADU wrote:
> Hi Eric,
>
> I saw that this patch didn't make it's way into the stable branches.
> So I have two questions:
> - Would it be safe to apply to linux-3.12.x stable?
> - If yes, would there be any [noticeable] efects on a [pretty
> complex] HTB setup? (I know, test and I'll see,
> but if theory sais I won't, then there would be no point to
> the test, would there?)
>
It is safe to backport.
If you want to test an equivalent, without kernel patch, you simply can
do :
echo 0 >/proc/sys/kernel/timer_migration
^ permalink raw reply
* Re: TCP connection issues against Amazon S3
From: Eric Dumazet @ 2015-01-07 15:58 UTC (permalink / raw)
To: Erik Grinaker; +Cc: Yuchung Cheng, linux-kernel@vger.kernel.org, netdev
In-Reply-To: <34CE0233-F881-4F40-B119-AA9D8F7D500F@bengler.no>
On Wed, 2015-01-07 at 13:31 +0000, Erik Grinaker wrote:
> On 06 Jan 2015, at 22:00, Yuchung Cheng <ycheng@google.com> wrote:
> > On Tue, Jan 6, 2015 at 1:04 PM, Erik Grinaker <erik@bengler.no> wrote:
> >>
> >>> On 06 Jan 2015, at 20:26, Erik Grinaker <erik@bengler.no> wrote:
> >> This still doesn’t explain why it works with older kernels, but not newer ones. I’m thinking it’s
> > probably some minor change, which gets amplified by the lack of SACKs
> > on the loadbalancer. Anyway, I’ll bring it up with Amazon.
> > can you post traces with the older kernels?
>
> Here is a dump using 3.11.10 against a non-SACK-enabled loadbalancer:
>
> http://abstrakt.bengler.no/tcp-issues-s3-nosack-3.11.10.pcap.bz2
>
> The transfer shows lots of DUPACKs and retransmits, but this does not
> seem to have as bad an effect as it did with the failing transfer we
> saw on newer kernels:
>
> http://abstrakt.bengler.no/tcp-issues-s3-failure.pcap.bz2
>
> One big difference, which Rick touched on earlier, is that the newer
> kernels keep sending TCP window updates as it’s going through the
> retransmits. The older kernel does not do this.
The new kernel is the receiver : It does no retransmits.
Increasing window in ACK packets should not prevent sender into
retransmitting missing packets.
Sender is not a linux host and is very buggy IMO : If receiver
advertises a too big window, sender decides to not retransmit in some
cases.
You can play with /proc/sys/net/ipv4/tcp_rmem and adopt very low values
to work around the sender bug.
( Or use SO_RCVBUF in receiver application)
^ permalink raw reply
* Re: [PATCH v4] can: Convert to runtime_pm
From: Sören Brinkmann @ 2015-01-07 15:58 UTC (permalink / raw)
To: Marc Kleine-Budde
Cc: Kedareswara rao Appana, wg, michal.simek, grant.likely, linux-can,
netdev, linux-kernel, Kedareswara rao Appana
In-Reply-To: <54AD267C.4060004@pengutronix.de>
On Wed, 2015-01-07 at 01:28PM +0100, Marc Kleine-Budde wrote:
> On 12/23/2014 01:25 PM, Kedareswara rao Appana wrote:
> > Instead of enabling/disabling clocks at several locations in the driver,
> > use the runtime_pm framework. This consolidates the actions for
> > runtime PM in the appropriate callbacks and makes the driver more
> > readable and mantainable.
> >
> > Signed-off-by: Soren Brinkmann <soren.brinkmann@xilinx.com>
> > Signed-off-by: Kedareswara rao Appana <appanad@xilinx.com>
> > ---
> > Chnages for v4:
> > - Updated with the review comments.
> > Changes for v3:
> > - Converted the driver to use runtime_pm.
> > Changes for v2:
> > - Removed the struct platform_device* from suspend/resume
> > as suggest by Lothar.
> >
> > drivers/net/can/xilinx_can.c | 123 +++++++++++++++++++++++++-----------------
> > 1 files changed, 74 insertions(+), 49 deletions(-)
> >
> > diff --git a/drivers/net/can/xilinx_can.c b/drivers/net/can/xilinx_can.c
> > index 6c67643..c71f683 100644
> > --- a/drivers/net/can/xilinx_can.c
> > +++ b/drivers/net/can/xilinx_can.c
> > @@ -32,6 +32,7 @@
> > #include <linux/can/dev.h>
> > #include <linux/can/error.h>
> > #include <linux/can/led.h>
> > +#include <linux/pm_runtime.h>
> >
> > #define DRIVER_NAME "xilinx_can"
> >
> > @@ -138,7 +139,7 @@ struct xcan_priv {
> > u32 (*read_reg)(const struct xcan_priv *priv, enum xcan_reg reg);
> > void (*write_reg)(const struct xcan_priv *priv, enum xcan_reg reg,
> > u32 val);
> > - struct net_device *dev;
> > + struct device *dev;
> > void __iomem *reg_base;
> > unsigned long irq_flags;
> > struct clk *bus_clk;
> > @@ -842,6 +843,13 @@ static int xcan_open(struct net_device *ndev)
> > struct xcan_priv *priv = netdev_priv(ndev);
> > int ret;
> >
> > + ret = pm_runtime_get_sync(priv->dev);
> > + if (ret < 0) {
> > + netdev_err(ndev, "%s: pm_runtime_get failed\r(%d)\n\r",
> > + __func__, ret);
> > + return ret;
> > + }
> > +
> > ret = request_irq(ndev->irq, xcan_interrupt, priv->irq_flags,
> > ndev->name, ndev);
> > if (ret < 0) {
> > @@ -849,29 +857,17 @@ static int xcan_open(struct net_device *ndev)
> > goto err;
> > }
> >
> > - ret = clk_prepare_enable(priv->can_clk);
> > - if (ret) {
> > - netdev_err(ndev, "unable to enable device clock\n");
> > - goto err_irq;
> > - }
> > -
> > - ret = clk_prepare_enable(priv->bus_clk);
> > - if (ret) {
> > - netdev_err(ndev, "unable to enable bus clock\n");
> > - goto err_can_clk;
> > - }
> > -
> > /* Set chip into reset mode */
> > ret = set_reset_mode(ndev);
> > if (ret < 0) {
> > netdev_err(ndev, "mode resetting failed!\n");
> > - goto err_bus_clk;
> > + goto err_irq;
> > }
> >
> > /* Common open */
> > ret = open_candev(ndev);
> > if (ret)
> > - goto err_bus_clk;
> > + goto err_irq;
> >
> > ret = xcan_chip_start(ndev);
> > if (ret < 0) {
> > @@ -887,13 +883,11 @@ static int xcan_open(struct net_device *ndev)
> >
> > err_candev:
> > close_candev(ndev);
> > -err_bus_clk:
> > - clk_disable_unprepare(priv->bus_clk);
> > -err_can_clk:
> > - clk_disable_unprepare(priv->can_clk);
> > err_irq:
> > free_irq(ndev->irq, ndev);
> > err:
> > + pm_runtime_put(priv->dev);
> > +
> > return ret;
> > }
> >
> > @@ -910,12 +904,11 @@ static int xcan_close(struct net_device *ndev)
> > netif_stop_queue(ndev);
> > napi_disable(&priv->napi);
> > xcan_chip_stop(ndev);
> > - clk_disable_unprepare(priv->bus_clk);
> > - clk_disable_unprepare(priv->can_clk);
> > free_irq(ndev->irq, ndev);
> > close_candev(ndev);
> >
> > can_led_event(ndev, CAN_LED_EVENT_STOP);
> > + pm_runtime_put(priv->dev);
> >
> > return 0;
> > }
> > @@ -934,27 +927,20 @@ static int xcan_get_berr_counter(const struct net_device *ndev,
> > struct xcan_priv *priv = netdev_priv(ndev);
> > int ret;
> >
> > - ret = clk_prepare_enable(priv->can_clk);
> > - if (ret)
> > - goto err;
> > -
> > - ret = clk_prepare_enable(priv->bus_clk);
> > - if (ret)
> > - goto err_clk;
> > + ret = pm_runtime_get_sync(priv->dev);
> > + if (ret < 0) {
> > + netdev_err(ndev, "%s: pm_runtime_get failed\r(%d)\n\r",
> > + __func__, ret);
>
> Please remove the \r from the error messages.
>
> > + return ret;
> > + }
> >
> > bec->txerr = priv->read_reg(priv, XCAN_ECR_OFFSET) & XCAN_ECR_TEC_MASK;
> > bec->rxerr = ((priv->read_reg(priv, XCAN_ECR_OFFSET) &
> > XCAN_ECR_REC_MASK) >> XCAN_ESR_REC_SHIFT);
> >
> > - clk_disable_unprepare(priv->bus_clk);
> > - clk_disable_unprepare(priv->can_clk);
> > + pm_runtime_put(priv->dev);
> >
> > return 0;
> > -
> > -err_clk:
> > - clk_disable_unprepare(priv->can_clk);
> > -err:
> > - return ret;
> > }
> >
> >
> > @@ -967,15 +953,45 @@ static const struct net_device_ops xcan_netdev_ops = {
> >
> > /**
> > * xcan_suspend - Suspend method for the driver
> > - * @dev: Address of the platform_device structure
> > + * @dev: Address of the device structure
> > *
> > * Put the driver into low power mode.
> > - * Return: 0 always
> > + * Return: 0 on success and failure value on error
> > */
> > static int __maybe_unused xcan_suspend(struct device *dev)
> > {
> > - struct platform_device *pdev = dev_get_drvdata(dev);
> > - struct net_device *ndev = platform_get_drvdata(pdev);
> > + if (!device_may_wakeup(dev))
> > + return pm_runtime_force_suspend(dev);
> > +
> > + return 0;
> > +}
> > +
> > +/**
> > + * xcan_resume - Resume from suspend
> > + * @dev: Address of the device structure
> > + *
> > + * Resume operation after suspend.
> > + * Return: 0 on success and failure value on error
> > + */
> > +static int __maybe_unused xcan_resume(struct device *dev)
> > +{
> > + if (!device_may_wakeup(dev))
> > + return pm_runtime_force_resume(dev);
> > +
> > + return 0;
> > +
> > +}
> > +
> > +/**
> > + * xcan_runtime_suspend - Runtime suspend method for the driver
> > + * @dev: Address of the device structure
> > + *
> > + * Put the driver into low power mode.
> > + * Return: 0 always
> > + */
> > +static int __maybe_unused xcan_runtime_suspend(struct device *dev)
> > +{
> > + struct net_device *ndev = dev_get_drvdata(dev);
> > struct xcan_priv *priv = netdev_priv(ndev);
> >
> > if (netif_running(ndev)) {
> > @@ -993,16 +1009,15 @@ static int __maybe_unused xcan_suspend(struct device *dev)
> > }
> >
> > /**
> > - * xcan_resume - Resume from suspend
> > - * @dev: Address of the platformdevice structure
> > + * xcan_runtime_resume - Runtime resume from suspend
> > + * @dev: Address of the device structure
> > *
> > * Resume operation after suspend.
> > * Return: 0 on success and failure value on error
> > */
> > -static int __maybe_unused xcan_resume(struct device *dev)
> > +static int __maybe_unused xcan_runtime_resume(struct device *dev)
> > {
> > - struct platform_device *pdev = dev_get_drvdata(dev);
> > - struct net_device *ndev = platform_get_drvdata(pdev);
> > + struct net_device *ndev = dev_get_drvdata(dev);
> > struct xcan_priv *priv = netdev_priv(ndev);
> > int ret;
>
> Some more context:
>
> > ret = clk_enable(priv->bus_clk);
> > if (ret) {
> > dev_err(dev, "Cannot enable clock.\n");
> > return ret;
> > }
> > ret = clk_enable(priv->can_clk);
> > if (ret) {
> > dev_err(dev, "Cannot enable clock.\n");
> > clk_disable_unprepare(priv->bus_clk);
>
> This disable_unprepare looks wrong, should be a disable only.
>
> > return ret;
> > }
> >
> > priv->write_reg(priv, XCAN_MSR_OFFSET, 0);
> > priv->write_reg(priv, XCAN_SRR_OFFSET, XCAN_SRR_CEN_MASK);
> >
> > if (netif_running(ndev)) {
> > priv->can.state = CAN_STATE_ERROR_ACTIVE;
>
> What happens if the device was not in ACTIVE state prior to the
> runtime_suspend?
>
> > netif_device_attach(ndev);
> > netif_start_queue(ndev);
> > }
> >
> > return 0;
> > }
>
>
> >
> > @@ -1020,9 +1035,9 @@ static int __maybe_unused xcan_resume(struct device *dev)
> >
> > priv->write_reg(priv, XCAN_MSR_OFFSET, 0);
> > priv->write_reg(priv, XCAN_SRR_OFFSET, XCAN_SRR_CEN_MASK);
> > - priv->can.state = CAN_STATE_ERROR_ACTIVE;
> >
> > if (netif_running(ndev)) {
> > + priv->can.state = CAN_STATE_ERROR_ACTIVE;
> > netif_device_attach(ndev);
> > netif_start_queue(ndev);
> > }
> > @@ -1030,7 +1045,10 @@ static int __maybe_unused xcan_resume(struct device *dev)
> > return 0;
> > }
> >
> > -static SIMPLE_DEV_PM_OPS(xcan_dev_pm_ops, xcan_suspend, xcan_resume);
> > +static const struct dev_pm_ops xcan_dev_pm_ops = {
> > + SET_SYSTEM_SLEEP_PM_OPS(xcan_suspend, xcan_resume)
> > + SET_PM_RUNTIME_PM_OPS(xcan_runtime_suspend, xcan_runtime_resume, NULL)
> > +};
> >
> > /**
> > * xcan_probe - Platform registration call
> > @@ -1071,7 +1089,7 @@ static int xcan_probe(struct platform_device *pdev)
> > return -ENOMEM;
> >
> > priv = netdev_priv(ndev);
> > - priv->dev = ndev;
> > + priv->dev = &pdev->dev;
> > priv->can.bittiming_const = &xcan_bittiming_const;
> > priv->can.do_set_mode = xcan_do_set_mode;
> > priv->can.do_get_berr_counter = xcan_get_berr_counter;
> > @@ -1137,15 +1155,22 @@ static int xcan_probe(struct platform_device *pdev)
> >
> > netif_napi_add(ndev, &priv->napi, xcan_rx_poll, rx_max);
> >
> > + pm_runtime_set_active(&pdev->dev);
> > + pm_runtime_irq_safe(&pdev->dev);
> > + pm_runtime_enable(&pdev->dev);
> > + pm_runtime_get_sync(&pdev->dev);
> Check error values?
> > +
> > ret = register_candev(ndev);
> > if (ret) {
> > dev_err(&pdev->dev, "fail to register failed (err=%d)\n", ret);
> > + pm_runtime_put(priv->dev);
>
> Please move the pm_runtime_put into the common error exit path.
>
> > goto err_unprepare_disable_busclk;
> > }
> >
> > devm_can_led_init(ndev);
> > - clk_disable_unprepare(priv->bus_clk);
> > - clk_disable_unprepare(priv->can_clk);
> > +
> > + pm_runtime_put(&pdev->dev);
> > +
> > netdev_dbg(ndev, "reg_base=0x%p irq=%d clock=%d, tx fifo depth:%d\n",
> > priv->reg_base, ndev->irq, priv->can.clock.freq,
> > priv->tx_max);
> >
>
> I think you have to convert the _remove() function, too. Have a look at
> the gpio-zynq.c driver:
>
> > static int zynq_gpio_remove(struct platform_device *pdev)
> > {
> > struct zynq_gpio *gpio = platform_get_drvdata(pdev);
> >
> > pm_runtime_get_sync(&pdev->dev);
>
> However I don't understand why the get_sync() is here. Maybe Sören can help?
IIRC, the concern was that the remove function may be called while the device is
runtime suspended. Hence the remove function needs to resume the device since the
remove function may access the HW.
Sören
^ permalink raw reply
* Re: [PATCH 2/6] vxlan: Group Policy extension
From: Tom Herbert @ 2015-01-07 16:05 UTC (permalink / raw)
To: Thomas Graf
Cc: David Miller, Jesse Gross, Stephen Hemminger, Pravin B Shelar,
Linux Netdev List, dev@openvswitch.org
In-Reply-To: <2b43c19c47e3702b370054f8fd11233e44179edf.1420594925.git.tgraf@suug.ch>
On Tue, Jan 6, 2015 at 6:05 PM, Thomas Graf <tgraf@suug.ch> wrote:
> Implements supports for the Group Policy VXLAN extension [0] to provide
> a lightweight and simple security label mechanism across network peers
> based on VXLAN. The security context and associated metadata is mapped
> to/from skb->mark. This allows further mapping to a SELinux context
> using SECMARK, to implement ACLs directly with nftables, iptables, OVS,
> tc, etc.
>
> The group membership is defined by the lower 16 bits of skb->mark, the
> upper 16 bits are used for flags.
>
> SELinux allows to manage label to secure local resources. However,
> distributed applications require ACLs to implemented across hosts. This
> is typically achieved by matching on L2-L4 fields to identify the
> original sending host and process on the receiver. On top of that,
> netlabel and specifically CIPSO [1] allow to map security contexts to
> universal labels. However, netlabel and CIPSO are relatively complex.
> This patch provides a lightweight alternative for overlay network
> environments with a trusted underlay. No additional control protocol
> is required.
>
Associating a sixteen bit field with security is worrisome, especially
considering that VXLAN provides no verification for any header fields
and doesn't even advocate use of outer UDP checksum so the field is
susceptible to an undetected single bit flip. The concept of a
"trusted underlay" is weak justification and hardly universal, so the
only way to actually secure this is through IPsec (this is mentioned
in the VXLAN-GPB draft). But if we have the security state of IPsec
then why would we need this field anyway?
Could this same functionality be achieved if we just match the VNI to
a mark in IP tables?
Tom
> Host 1: Host 2:
>
> Group A Group B Group B Group A
> +-----+ +-------------+ +-------+ +-----+
> | lxc | | SELinux CTX | | httpd | | VM |
> +--+--+ +--+----------+ +---+---+ +--+--+
> \---+---/ \----+---/
> | |
> +---+---+ +---+---+
> | vxlan | | vxlan |
> +---+---+ +---+---+
> +------------------------------+
>
> Backwards compatibility:
> A VXLAN-GBP socket can receive standard VXLAN frames and will assign
> the default group 0x0000 to such frames. A Linux VXLAN socket will
> drop VXLAN-GBP frames. The extension is therefore disabled by default
> and needs to be specifically enabled:
>
> ip link add [...] type vxlan [...] gbp
>
> In a mixed environment with VXLAN and VXLAN-GBP sockets, the GBP socket
> must run on a separate port number.
>
> Examples:
> iptables:
> $ iptables -I OUTPUT -p icmp -j MARK --set-mark 0x200
> $ iptables -I INPUT -i br0 -m mark --mark 0x200 -j ACCEPT
>
> OVS (patches provided separately):
> in_port=1, actions=load:0x200->NXM_NX_TUN_GBP_ID[],NORMAL
>
> [0] https://tools.ietf.org/html/draft-smith-vxlan-group-policy
> [1] http://lwn.net/Articles/204905/
>
> Signed-off-by: Thomas Graf <tgraf@suug.ch>
> ---
> drivers/net/vxlan.c | 155 ++++++++++++++++++++++++++++++------------
> include/net/vxlan.h | 80 ++++++++++++++++++++--
> include/uapi/linux/if_link.h | 8 +++
> net/openvswitch/vport-vxlan.c | 9 ++-
> 4 files changed, 197 insertions(+), 55 deletions(-)
>
> diff --git a/drivers/net/vxlan.c b/drivers/net/vxlan.c
> index 4d52aa9..30b7b59 100644
> --- a/drivers/net/vxlan.c
> +++ b/drivers/net/vxlan.c
> @@ -132,6 +132,7 @@ struct vxlan_dev {
> __u8 tos; /* TOS override */
> __u8 ttl;
> u32 flags; /* VXLAN_F_* in vxlan.h */
> + u32 exts; /* Enabled extensions */
>
> struct work_struct sock_work;
> struct work_struct igmp_join;
> @@ -568,7 +569,8 @@ static struct sk_buff **vxlan_gro_receive(struct sk_buff **head, struct sk_buff
> continue;
>
> vh2 = (struct vxlanhdr *)(p->data + off_vx);
> - if (vh->vx_vni != vh2->vx_vni) {
> + if (vh->vx_flags != vh2->vx_flags ||
> + vh->vx_vni != vh2->vx_vni) {
> NAPI_GRO_CB(p)->same_flow = 0;
> continue;
> }
> @@ -1095,6 +1097,7 @@ static int vxlan_udp_encap_recv(struct sock *sk, struct sk_buff *skb)
> {
> struct vxlan_sock *vs;
> struct vxlanhdr *vxh;
> + struct vxlan_metadata md = {0};
>
> /* Need Vxlan and inner Ethernet header to be present */
> if (!pskb_may_pull(skb, VXLAN_HLEN))
> @@ -1113,6 +1116,19 @@ static int vxlan_udp_encap_recv(struct sock *sk, struct sk_buff *skb)
> if (vs->exts) {
> if (!vxh->vni_present)
> goto error_invalid_header;
> +
> + if (vxh->gbp_present) {
> + if (!(vs->exts & VXLAN_EXT_GBP))
> + goto error_invalid_header;
> +
> + md.gbp = ntohs(vxh->gbp.policy_id);
> +
> + if (vxh->gbp.dont_learn)
> + md.gbp |= VXLAN_GBP_DONT_LEARN;
> +
> + if (vxh->gbp.policy_applied)
> + md.gbp |= VXLAN_GBP_POLICY_APPLIED;
> + }
> } else {
> if (vxh->vx_flags != htonl(VXLAN_FLAGS) ||
> (vxh->vx_vni & htonl(0xff)))
> @@ -1122,7 +1138,8 @@ static int vxlan_udp_encap_recv(struct sock *sk, struct sk_buff *skb)
> if (iptunnel_pull_header(skb, VXLAN_HLEN, htons(ETH_P_TEB)))
> goto drop;
>
> - vs->rcv(vs, skb, vxh->vx_vni);
> + md.vni = vxh->vx_vni;
> + vs->rcv(vs, skb, &md);
> return 0;
>
> drop:
> @@ -1138,8 +1155,8 @@ error:
> return 1;
> }
>
> -static void vxlan_rcv(struct vxlan_sock *vs,
> - struct sk_buff *skb, __be32 vx_vni)
> +static void vxlan_rcv(struct vxlan_sock *vs, struct sk_buff *skb,
> + struct vxlan_metadata *md)
> {
> struct iphdr *oip = NULL;
> struct ipv6hdr *oip6 = NULL;
> @@ -1150,7 +1167,7 @@ static void vxlan_rcv(struct vxlan_sock *vs,
> int err = 0;
> union vxlan_addr *remote_ip;
>
> - vni = ntohl(vx_vni) >> 8;
> + vni = ntohl(md->vni) >> 8;
> /* Is this VNI defined? */
> vxlan = vxlan_vs_find_vni(vs, vni);
> if (!vxlan)
> @@ -1184,6 +1201,7 @@ static void vxlan_rcv(struct vxlan_sock *vs,
> goto drop;
>
> skb_reset_network_header(skb);
> + skb->mark = md->gbp;
>
> if (oip6)
> err = IP6_ECN_decapsulate(oip6, skb);
> @@ -1533,15 +1551,54 @@ static bool route_shortcircuit(struct net_device *dev, struct sk_buff *skb)
> return false;
> }
>
> +static int vxlan_build_hdr(struct sk_buff *skb, struct vxlan_sock *vs,
> + int min_headroom, struct vxlan_metadata *md)
> +{
> + struct vxlanhdr *vxh;
> + int err;
> +
> + /* Need space for new headers (invalidates iph ptr) */
> + err = skb_cow_head(skb, min_headroom);
> + if (unlikely(err)) {
> + kfree_skb(skb);
> + return err;
> + }
> +
> + skb = vlan_hwaccel_push_inside(skb);
> + if (WARN_ON(!skb))
> + return -ENOMEM;
> +
> + vxh = (struct vxlanhdr *) __skb_push(skb, sizeof(*vxh));
> + vxh->vx_flags = htonl(VXLAN_FLAGS);
> + vxh->vx_vni = md->vni;
> +
> + if (vs->exts) {
> + if (vs->exts & VXLAN_EXT_GBP) {
> + vxh->gbp_present = 1;
> +
> + if (md->gbp & VXLAN_GBP_DONT_LEARN)
> + vxh->gbp.dont_learn = 1;
> +
> + if (md->gbp & VXLAN_GBP_POLICY_APPLIED)
> + vxh->gbp.policy_applied = 1;
> +
> + vxh->gbp.policy_id = htons(md->gbp & VXLAN_GBP_ID_MASK);
> + }
> + }
> +
> + skb_set_inner_protocol(skb, htons(ETH_P_TEB));
> +
> + return 0;
> +}
> +
> #if IS_ENABLED(CONFIG_IPV6)
> static int vxlan6_xmit_skb(struct vxlan_sock *vs,
> struct dst_entry *dst, struct sk_buff *skb,
> struct net_device *dev, struct in6_addr *saddr,
> struct in6_addr *daddr, __u8 prio, __u8 ttl,
> - __be16 src_port, __be16 dst_port, __be32 vni,
> - bool xnet)
> + __be16 src_port, __be16 dst_port,
> + struct vxlan_metadata *md, bool xnet)
> {
> - struct vxlanhdr *vxh;
> int min_headroom;
> int err;
> bool udp_sum = !udp_get_no_check6_tx(vs->sock->sk);
> @@ -1558,24 +1615,9 @@ static int vxlan6_xmit_skb(struct vxlan_sock *vs,
> + VXLAN_HLEN + sizeof(struct ipv6hdr)
> + (vlan_tx_tag_present(skb) ? VLAN_HLEN : 0);
>
> - /* Need space for new headers (invalidates iph ptr) */
> - err = skb_cow_head(skb, min_headroom);
> - if (unlikely(err)) {
> - kfree_skb(skb);
> - goto err;
> - }
> -
> - skb = vlan_hwaccel_push_inside(skb);
> - if (WARN_ON(!skb)) {
> - err = -ENOMEM;
> + err = vxlan_build_hdr(skb, vs, min_headroom, md);
> + if (err)
> goto err;
> - }
> -
> - vxh = (struct vxlanhdr *) __skb_push(skb, sizeof(*vxh));
> - vxh->vx_flags = htonl(VXLAN_FLAGS);
> - vxh->vx_vni = vni;
> -
> - skb_set_inner_protocol(skb, htons(ETH_P_TEB));
>
> udp_tunnel6_xmit_skb(vs->sock, dst, skb, dev, saddr, daddr, prio,
> ttl, src_port, dst_port);
> @@ -1589,9 +1631,9 @@ err:
> int vxlan_xmit_skb(struct vxlan_sock *vs,
> struct rtable *rt, struct sk_buff *skb,
> __be32 src, __be32 dst, __u8 tos, __u8 ttl, __be16 df,
> - __be16 src_port, __be16 dst_port, __be32 vni, bool xnet)
> + __be16 src_port, __be16 dst_port,
> + struct vxlan_metadata *md, bool xnet)
> {
> - struct vxlanhdr *vxh;
> int min_headroom;
> int err;
> bool udp_sum = !vs->sock->sk->sk_no_check_tx;
> @@ -1604,22 +1646,9 @@ int vxlan_xmit_skb(struct vxlan_sock *vs,
> + VXLAN_HLEN + sizeof(struct iphdr)
> + (vlan_tx_tag_present(skb) ? VLAN_HLEN : 0);
>
> - /* Need space for new headers (invalidates iph ptr) */
> - err = skb_cow_head(skb, min_headroom);
> - if (unlikely(err)) {
> - kfree_skb(skb);
> + err = vxlan_build_hdr(skb, vs, min_headroom, md);
> + if (err)
> return err;
> - }
> -
> - skb = vlan_hwaccel_push_inside(skb);
> - if (WARN_ON(!skb))
> - return -ENOMEM;
> -
> - vxh = (struct vxlanhdr *) __skb_push(skb, sizeof(*vxh));
> - vxh->vx_flags = htonl(VXLAN_FLAGS);
> - vxh->vx_vni = vni;
> -
> - skb_set_inner_protocol(skb, htons(ETH_P_TEB));
>
> return udp_tunnel_xmit_skb(vs->sock, rt, skb, src, dst, tos,
> ttl, df, src_port, dst_port, xnet);
> @@ -1679,6 +1708,7 @@ static void vxlan_xmit_one(struct sk_buff *skb, struct net_device *dev,
> const struct iphdr *old_iph;
> struct flowi4 fl4;
> union vxlan_addr *dst;
> + struct vxlan_metadata md;
> __be16 src_port = 0, dst_port;
> u32 vni;
> __be16 df = 0;
> @@ -1749,11 +1779,12 @@ static void vxlan_xmit_one(struct sk_buff *skb, struct net_device *dev,
>
> tos = ip_tunnel_ecn_encap(tos, old_iph, skb);
> ttl = ttl ? : ip4_dst_hoplimit(&rt->dst);
> + md.vni = htonl(vni << 8);
> + md.gbp = skb->mark;
>
> err = vxlan_xmit_skb(vxlan->vn_sock, rt, skb,
> fl4.saddr, dst->sin.sin_addr.s_addr,
> - tos, ttl, df, src_port, dst_port,
> - htonl(vni << 8),
> + tos, ttl, df, src_port, dst_port, &md,
> !net_eq(vxlan->net, dev_net(vxlan->dev)));
> if (err < 0) {
> /* skb is already freed. */
> @@ -1806,10 +1837,12 @@ static void vxlan_xmit_one(struct sk_buff *skb, struct net_device *dev,
> }
>
> ttl = ttl ? : ip6_dst_hoplimit(ndst);
> + md.vni = htonl(vni << 8);
> + md.gbp = skb->mark;
>
> err = vxlan6_xmit_skb(vxlan->vn_sock, ndst, skb,
> dev, &fl6.saddr, &fl6.daddr, 0, ttl,
> - src_port, dst_port, htonl(vni << 8),
> + src_port, dst_port, &md,
> !net_eq(vxlan->net, dev_net(vxlan->dev)));
> #endif
> }
> @@ -2210,6 +2243,11 @@ static const struct nla_policy vxlan_policy[IFLA_VXLAN_MAX + 1] = {
> [IFLA_VXLAN_UDP_CSUM] = { .type = NLA_U8 },
> [IFLA_VXLAN_UDP_ZERO_CSUM6_TX] = { .type = NLA_U8 },
> [IFLA_VXLAN_UDP_ZERO_CSUM6_RX] = { .type = NLA_U8 },
> + [IFLA_VXLAN_EXTENSION] = { .type = NLA_NESTED },
> +};
> +
> +static const struct nla_policy vxlan_ext_policy[IFLA_VXLAN_EXT_MAX + 1] = {
> + [IFLA_VXLAN_EXT_GBP] = { .type = NLA_FLAG, },
> };
>
> static int vxlan_validate(struct nlattr *tb[], struct nlattr *data[])
> @@ -2246,6 +2284,18 @@ static int vxlan_validate(struct nlattr *tb[], struct nlattr *data[])
> }
> }
>
> + if (data[IFLA_VXLAN_EXTENSION]) {
> + int err;
> +
> + err = nla_validate_nested(data[IFLA_VXLAN_EXTENSION],
> + IFLA_VXLAN_EXT_MAX, vxlan_ext_policy);
> + if (err < 0) {
> + pr_debug("invalid VXLAN extension configuration: %d\n",
> + err);
> + return -EINVAL;
> + }
> + }
> +
> return 0;
> }
>
> @@ -2400,6 +2450,18 @@ static void vxlan_sock_work(struct work_struct *work)
> dev_put(vxlan->dev);
> }
>
> +static void configure_vxlan_exts(struct vxlan_dev *vxlan, struct nlattr *attr)
> +{
> + struct nlattr *exts[IFLA_VXLAN_EXT_MAX+1];
> +
> + /* Validated in vxlan_validate() */
> + if (nla_parse_nested(exts, IFLA_VXLAN_EXT_MAX, attr, NULL) < 0)
> + BUG();
> +
> + if (exts[IFLA_VXLAN_EXT_GBP])
> + vxlan->exts |= VXLAN_EXT_GBP;
> +}
> +
> static int vxlan_newlink(struct net *net, struct net_device *dev,
> struct nlattr *tb[], struct nlattr *data[])
> {
> @@ -2525,6 +2587,9 @@ static int vxlan_newlink(struct net *net, struct net_device *dev,
> nla_get_u8(data[IFLA_VXLAN_UDP_ZERO_CSUM6_RX]))
> vxlan->flags |= VXLAN_F_UDP_ZERO_CSUM6_RX;
>
> + if (data[IFLA_VXLAN_EXTENSION])
> + configure_vxlan_exts(vxlan, data[IFLA_VXLAN_EXTENSION]);
> +
> if (vxlan_find_vni(net, vni, use_ipv6 ? AF_INET6 : AF_INET,
> vxlan->dst_port)) {
> pr_info("duplicate VNI %u\n", vni);
> diff --git a/include/net/vxlan.h b/include/net/vxlan.h
> index 3e98d31..66000d0 100644
> --- a/include/net/vxlan.h
> +++ b/include/net/vxlan.h
> @@ -11,13 +11,60 @@
> #define VNI_HASH_BITS 10
> #define VNI_HASH_SIZE (1<<VNI_HASH_BITS)
>
> +/*
> + * VXLAN Group Based Policy Extension:
> + * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
> + * |1|-|-|-|1|-|-|-|R|D|R|R|A|R|R|R| Group Policy ID |
> + * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
> + * | VXLAN Network Identifier (VNI) | Reserved |
> + * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
> + *
> + * D = Don't Learn bit. When set, this bit indicates that the egress
> + * VTEP MUST NOT learn the source address of the encapsulated frame.
> + *
> + * A = Indicates that the group policy has already been applied to
> + * this packet. Policies MUST NOT be applied by devices when the
> + * A bit is set.
> + *
> + * [0] https://tools.ietf.org/html/draft-smith-vxlan-group-policy
> + */
> +struct vxlan_gbp {
> +#ifdef __LITTLE_ENDIAN_BITFIELD
> + __u8 reserved_flags1:3,
> + policy_applied:1,
> + reserved_flags2:2,
> + dont_learn:1,
> + reserved_flags3:1;
> +#elif defined(__BIG_ENDIAN_BITFIELD)
> + __u8 reserved_flags1:1,
> + dont_learn:1,
> + reserved_flags2:2,
> + policy_applied:1,
> + reserved_flags3:3;
> +#else
> +#error "Please fix <asm/byteorder.h>"
> +#endif
> + __be16 policy_id;
> +} __packed;
> +
> +/* skb->mark mapping
> + *
> + * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
> + * |R|R|R|R|R|R|R|R|R|D|R|R|A|R|R|R| Group Policy ID |
> + * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
> + */
> +#define VXLAN_GBP_DONT_LEARN (BIT(6) << 16)
> +#define VXLAN_GBP_POLICY_APPLIED (BIT(3) << 16)
> +#define VXLAN_GBP_ID_MASK (0xFFFF)
> +
> /* VXLAN protocol header:
> * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
> - * |R|R|R|R|I|R|R|R| Reserved |
> + * |G|R|R|R|I|R|R|R| Reserved |
> * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
> * | VXLAN Network Identifier (VNI) | Reserved |
> * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
> *
> + * G = 1 Group Policy (VXLAN-GBP)
> * I = 1 VXLAN Network Identifier (VNI) present
> */
> struct vxlanhdr {
> @@ -26,24 +73,42 @@ struct vxlanhdr {
> #ifdef __LITTLE_ENDIAN_BITFIELD
> __u8 reserved_flags1:3,
> vni_present:1,
> - reserved_flags2:4;
> + reserved_flags2:3,
> + gbp_present:1;
> #elif defined(__BIG_ENDIAN_BITFIELD)
> - __u8 reserved_flags2:4,
> + __u8 gbp_present:1,
> + reserved_flags2:3,
> vni_present:1,
> reserved_flags1:3;
> #else
> #error "Please fix <asm/byteorder.h>"
> #endif
> - __u8 vx_reserved1;
> - __be16 vx_reserved2;
> + union {
> + /* NOTE: Offset 0 will be 1 byte aligned, so
> + * all member structs must be marked packed.
> + */
> + struct vxlan_gbp gbp;
> + struct {
> + __u8 vx_reserved1;
> + __be16 vx_reserved2;
> + } __packed;
> + };
> };
> __be32 vx_flags;
> };
> __be32 vx_vni;
> };
>
> +struct vxlan_metadata {
> + __be32 vni;
> + u32 gbp;
> +};
> +
> struct vxlan_sock;
> -typedef void (vxlan_rcv_t)(struct vxlan_sock *vh, struct sk_buff *skb, __be32 key);
> +typedef void (vxlan_rcv_t)(struct vxlan_sock *vh, struct sk_buff *skb,
> + struct vxlan_metadata *md);
> +
> +#define VXLAN_EXT_GBP BIT(0)
>
> /* per UDP socket information */
> struct vxlan_sock {
> @@ -78,7 +143,8 @@ void vxlan_sock_release(struct vxlan_sock *vs);
> int vxlan_xmit_skb(struct vxlan_sock *vs,
> struct rtable *rt, struct sk_buff *skb,
> __be32 src, __be32 dst, __u8 tos, __u8 ttl, __be16 df,
> - __be16 src_port, __be16 dst_port, __be32 vni, bool xnet);
> + __be16 src_port, __be16 dst_port, struct vxlan_metadata *md,
> + bool xnet);
>
> static inline netdev_features_t vxlan_features_check(struct sk_buff *skb,
> netdev_features_t features)
> diff --git a/include/uapi/linux/if_link.h b/include/uapi/linux/if_link.h
> index f7d0d2d..9f07bf5 100644
> --- a/include/uapi/linux/if_link.h
> +++ b/include/uapi/linux/if_link.h
> @@ -370,10 +370,18 @@ enum {
> IFLA_VXLAN_UDP_CSUM,
> IFLA_VXLAN_UDP_ZERO_CSUM6_TX,
> IFLA_VXLAN_UDP_ZERO_CSUM6_RX,
> + IFLA_VXLAN_EXTENSION,
> __IFLA_VXLAN_MAX
> };
> #define IFLA_VXLAN_MAX (__IFLA_VXLAN_MAX - 1)
>
> +enum {
> + IFLA_VXLAN_EXT_UNSPEC,
> + IFLA_VXLAN_EXT_GBP,
> + __IFLA_VXLAN_EXT_MAX,
> +};
> +#define IFLA_VXLAN_EXT_MAX (__IFLA_VXLAN_EXT_MAX - 1)
> +
> struct ifla_vxlan_port_range {
> __be16 low;
> __be16 high;
> diff --git a/net/openvswitch/vport-vxlan.c b/net/openvswitch/vport-vxlan.c
> index d7c46b3..dd68c97 100644
> --- a/net/openvswitch/vport-vxlan.c
> +++ b/net/openvswitch/vport-vxlan.c
> @@ -59,7 +59,8 @@ static inline struct vxlan_port *vxlan_vport(const struct vport *vport)
> }
>
> /* Called with rcu_read_lock and BH disabled. */
> -static void vxlan_rcv(struct vxlan_sock *vs, struct sk_buff *skb, __be32 vx_vni)
> +static void vxlan_rcv(struct vxlan_sock *vs, struct sk_buff *skb,
> + struct vxlan_metadata *md)
> {
> struct ovs_tunnel_info tun_info;
> struct vport *vport = vs->data;
> @@ -68,7 +69,7 @@ static void vxlan_rcv(struct vxlan_sock *vs, struct sk_buff *skb, __be32 vx_vni)
>
> /* Save outer tunnel values */
> iph = ip_hdr(skb);
> - key = cpu_to_be64(ntohl(vx_vni) >> 8);
> + key = cpu_to_be64(ntohl(md->vni) >> 8);
> ovs_flow_tun_info_init(&tun_info, iph,
> udp_hdr(skb)->source, udp_hdr(skb)->dest,
> key, TUNNEL_KEY, NULL, 0);
> @@ -146,6 +147,7 @@ static int vxlan_tnl_send(struct vport *vport, struct sk_buff *skb)
> struct vxlan_port *vxlan_port = vxlan_vport(vport);
> __be16 dst_port = inet_sk(vxlan_port->vs->sock->sk)->inet_sport;
> struct ovs_key_ipv4_tunnel *tun_key;
> + struct vxlan_metadata md;
> struct rtable *rt;
> struct flowi4 fl;
> __be16 src_port;
> @@ -178,12 +180,13 @@ static int vxlan_tnl_send(struct vport *vport, struct sk_buff *skb)
> skb->ignore_df = 1;
>
> src_port = udp_flow_src_port(net, skb, 0, 0, true);
> + md.vni = htonl(be64_to_cpu(tun_key->tun_id) << 8);
>
> err = vxlan_xmit_skb(vxlan_port->vs, rt, skb,
> fl.saddr, tun_key->ipv4_dst,
> tun_key->ipv4_tos, tun_key->ipv4_ttl, df,
> src_port, dst_port,
> - htonl(be64_to_cpu(tun_key->tun_id) << 8),
> + &md,
> false);
> if (err < 0)
> ip_rt_put(rt);
> --
> 1.9.3
>
> --
> 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: [PATCH 2/6] vxlan: Group Policy extension
From: Thomas Graf @ 2015-01-07 16:21 UTC (permalink / raw)
To: Tom Herbert
Cc: dev-yBygre7rU0TnMu66kgdUjQ@public.gmane.org, Linux Netdev List,
Stephen Hemminger, David Miller
In-Reply-To: <CA+mtBx_Jj-tUM1nbHd2fHb0-=QpK3tcQgA=smWmg=cB-fupdGg-JsoAwUIsXosN+BqQ9rBEUg@public.gmane.org>
On 01/07/15 at 08:05am, Tom Herbert wrote:
> Associating a sixteen bit field with security is worrisome, especially
> considering that VXLAN provides no verification for any header fields
> and doesn't even advocate use of outer UDP checksum so the field is
> susceptible to an undetected single bit flip. The concept of a
> "trusted underlay" is weak justification and hardly universal, so the
> only way to actually secure this is through IPsec (this is mentioned
> in the VXLAN-GPB draft).
As you state correctly, this work requires a trusted underlay which can
be achieved with IPsec, OpenVPN, SSH, ...
> But if we have the security state of IPsec then why would we need
> this field anyway?
It's a separation of concern: the security label mechanism of the
overlay should not depend on an eventual encryption layer in the
underlay as not all of them provide a mechanism to label packets.
> Could this same functionality be achieved if we just match the VNI to
> a mark in IP tables?
If the VNI is not already used for another purpose, yes. The solution
as proposed can be integrated into existing VXLAN overlays separated by
VNI. It is also compatible with hardware VXLAN VTEPs which ignore the
reserved bits while continueing to maintain VNI separation.
_______________________________________________
dev mailing list
dev@openvswitch.org
http://openvswitch.org/mailman/listinfo/dev
^ permalink raw reply
* Re: [PATCH v4] can: Convert to runtime_pm
From: Marc Kleine-Budde @ 2015-01-07 16:30 UTC (permalink / raw)
To: Sören Brinkmann
Cc: Kedareswara rao Appana, wg, michal.simek, grant.likely, linux-can,
netdev, linux-kernel, Kedareswara rao Appana
In-Reply-To: <a868331b44ce4b2a80b572399530f1f9@BN1BFFO11FD043.protection.gbl>
[-- Attachment #1: Type: text/plain, Size: 1290 bytes --]
On 01/07/2015 04:58 PM, Sören Brinkmann wrote:
>> I think you have to convert the _remove() function, too. Have a look at
>> the gpio-zynq.c driver:
>>
>>> static int zynq_gpio_remove(struct platform_device *pdev)
>>> {
>>> struct zynq_gpio *gpio = platform_get_drvdata(pdev);
>>>
>>> pm_runtime_get_sync(&pdev->dev);
>>
>> However I don't understand why the get_sync() is here. Maybe Sören can help?
>
> IIRC, the concern was that the remove function may be called while the device is
> runtime suspended. Hence the remove function needs to resume the device since the
> remove function may access the HW.
What about the corresponding runtime_put()? Would some counter be
unbalanced upon device removal?
Without having tested it, unloading and loading, i.e. reloading a CAN
driver is easier than reloading the gpio driver on an average embedded
system. Kedareswara please test your driver with something like:
modprobe; ifconfig up; cansend; ifconfig down; rmmod in a loop.
Marc
--
Pengutronix e.K. | Marc Kleine-Budde |
Industrial Linux Solutions | Phone: +49-231-2826-924 |
Vertretung West/Dortmund | Fax: +49-5121-206917-5555 |
Amtsgericht Hildesheim, HRA 2686 | http://www.pengutronix.de |
[-- Attachment #2: OpenPGP digital signature --]
[-- Type: application/pgp-signature, Size: 819 bytes --]
^ permalink raw reply
* Re: [PATCH v4] can: Convert to runtime_pm
From: Sören Brinkmann @ 2015-01-07 16:32 UTC (permalink / raw)
To: Marc Kleine-Budde
Cc: Kedareswara rao Appana, wg, michal.simek, grant.likely, linux-can,
netdev, linux-kernel, Kedareswara rao Appana
In-Reply-To: <54AD5F13.1020107@pengutronix.de>
On Wed, 2015-01-07 at 05:30PM +0100, Marc Kleine-Budde wrote:
> On 01/07/2015 04:58 PM, Sören Brinkmann wrote:
> >> I think you have to convert the _remove() function, too. Have a look at
> >> the gpio-zynq.c driver:
> >>
> >>> static int zynq_gpio_remove(struct platform_device *pdev)
> >>> {
> >>> struct zynq_gpio *gpio = platform_get_drvdata(pdev);
> >>>
> >>> pm_runtime_get_sync(&pdev->dev);
> >>
> >> However I don't understand why the get_sync() is here. Maybe Sören can help?
> >
> > IIRC, the concern was that the remove function may be called while the device is
> > runtime suspended. Hence the remove function needs to resume the device since the
> > remove function may access the HW.
>
> What about the corresponding runtime_put()? Would some counter be
> unbalanced upon device removal?
Aren't those counters destroyed with module unloading?
Sören
^ permalink raw reply
* Re: [net-next PATCH v1 01/11] net: flow_table: create interface for hw match/action tables
From: John Fastabend @ 2015-01-07 16:35 UTC (permalink / raw)
To: Or Gerlitz
Cc: Thomas Graf, Scott Feldman, Jiří Pírko,
Jamal Hadi Salim, simon.horman, Linux Netdev List, David Miller,
Andy Gospodarek
In-Reply-To: <CAJ3xEMiMsHW9Wys2GMhD9CRhU03DF3KZywGQkTWF1sMKn8x+fQ@mail.gmail.com>
On 01/07/2015 02:07 AM, Or Gerlitz wrote:
> On Mon, Jan 5, 2015 at 8:59 PM, John Fastabend <john.fastabend@gmail.com> wrote:
>>>> +struct sk_buff *net_flow_build_actions_msg(struct net_flow_action **a,
>>>> + struct net_device *dev,
>>>> + u32 portid, int seq, u8 cmd)
>>>> +{
>>>> + struct genlmsghdr *hdr;
>>>> + struct sk_buff *skb;
>>>> + int err = -ENOBUFS;
>>>> +
>>>> + skb = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_KERNEL);
>>>
>>>
>>> genlmsg_new(GENLMSG_DEFAULT_SIZE, GFP_KERNEL);
>>
>>
>> fixed along with the other cases.
>
> small nit here, net_flow_build_actions_msg can be made static, it's
> called only from within this file
>
> few more nits... checkpatch --strict produces bunch of "CHECK: Please
> use a blank line after function/struct/union/enum declarations"
> comments, I guess worth fixing too.
>
Thanks. will fix in v2.
--
John Fastabend Intel Corporation
^ 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