* [U-Boot] [PATCH v3 7/8] x86: efi: Add a hello world test program
From: Simon Glass @ 2016-11-14 20:58 UTC (permalink / raw)
To: u-boot
In-Reply-To: <44437559-36e5-1551-27f5-4f47edf71246@suse.de>
Hi Alex,
On 14 November 2016 at 13:46, Alexander Graf <agraf@suse.de> wrote:
>
>
> On 14/11/2016 21:44, Simon Glass wrote:
>>
>> Hi Alex,
>>
>> On 11 November 2016 at 23:23, Alexander Graf <agraf@suse.de> wrote:
>>>
>>>
>>>
>>>> Am 11.11.2016 um 17:17 schrieb Simon Glass <sjg@chromium.org>:
>>>>
>>>> Hi Alex,
>>>>
>>>>> On 7 November 2016 at 09:32, Alexander Graf <agraf@suse.de> wrote:
>>>>>
>>>>>
>>>>>> On 07/11/2016 10:46, Simon Glass wrote:
>>>>>>
>>>>>> Hi Alex,
>>>>>>
>>>>>>> On 19 October 2016 at 01:09, Alexander Graf <agraf@suse.de> wrote:
>>>>>>>
>>>>>>>
>>>>>>>
>>>>>>>> On 18/10/2016 22:37, Simon Glass wrote:
>>>>>>>>
>>>>>>>> Hi Alex,
>>>>>>>>
>>>>>>>>> On 18 October 2016 at 01:14, Alexander Graf <agraf@suse.de> wrote:
>>>>>>>>>
>>>>>>>>>> On 10/18/2016 04:29 AM, Simon Glass wrote:
>>>>>>>>>>
>>>>>>>>>>
>>>>>>>>>> It is useful to have a basic sanity check for EFI loader support.
>>>>>>>>>> Add
>>>>>>>>>> a
>>>>>>>>>> 'bootefi hello' command which loads HelloWord.efi and runs it
>>>>>>>>>> under
>>>>>>>>>> U-Boot.
>>>>>>>>>>
>>>>>>>>>> Signed-off-by: Simon Glass <sjg@chromium.org>
>>>>>>>>>> ---
>>>>>>>>>>
>>>>>>>>>> Changes in v3:
>>>>>>>>>> - Include a link to the program instead of adding it to the tree
>>>>>>>>>
>>>>>>>>>
>>>>>>>>>
>>>>>>>>>
>>>>>>>>> So, uh, where is the link?
>>>>>>>>
>>>>>>>>
>>>>>>>>
>>>>>>>> I put it in the README (see the arm patch).
>>>>>>>>
>>>>>>>>>
>>>>>>>>> I'm really not convinced this command buys us anything yet. I do
>>>>>>>>> agree
>>>>>>>>> that
>>>>>>>>> we want automated testing - but can't we get that using QEMU and a
>>>>>>>>> downloadable image file that we pass in as disk and have the distro
>>>>>>>>> boot do
>>>>>>>>> its magic?
>>>>>>>>
>>>>>>>>
>>>>>>>>
>>>>>>>> That seems very heavyweight as a sanity check, although I agree it
>>>>>>>> is
>>>>>>>> useful.
>>>>>>>
>>>>>>>
>>>>>>>
>>>>>>> It's not really much more heavy weight. The "image file" could simply
>>>>>>> contain your hello world binary. But with this we don't just verify
>>>>>>> whether "bootefi" works, but also whether the default boot path works
>>>>>>> ok.
>>>>>>
>>>>>>
>>>>>>
>>>>>> I don't think I understand what you mean by 'image file'. Is it
>>>>>> something other than the .efi file? Do you mean a disk image?
>>>>>
>>>>>
>>>>>
>>>>> Yes. For reasonable test coverage, we should also verify that the
>>>>> distro
>>>>> defaults wrote a sane boot script that automatically searches for a
>>>>> default
>>>>> EFI binary in /efi/boot/bootx86.efi on the first partition of all
>>>>> devices
>>>>> and runs it.
>>>>>
>>>>> So if we just provide an SD card image or hard disk image to QEMU which
>>>>> contains a hello world .efi binary as that default boot file, we don't
>>>>> only
>>>>> test whether the "bootefi" command works, but also whether the distro
>>>>> boot
>>>>> script works.
>>>>
>>>>
>>>> That's right.
>>>>
>>>>>
>>>>>>
>>>>>>>
>>>>>>>> Here I am just making sure that EFI programs can start, print output
>>>>>>>> and exit. It is a test that we can easily run without a lot of
>>>>>>>> overhead, much less than a full distro boot.
>>>>>>>
>>>>>>>
>>>>>>>
>>>>>>> Again, I don't think it's much more overhead and I do believe it
>>>>>>> gives
>>>>>>> us much cleaner separation between responsibilities of code (tests go
>>>>>>> where tests are).
>>>>>>
>>>>>>
>>>>>>
>>>>>> You are talking about a functional test, something that tests things
>>>>>> end to end. I prefer to at least start with a smaller test. Granted it
>>>>>> takes a little more work but it means there are fewer things to hunt
>>>>>> through when something goes wrong.
>>>>>
>>>>>
>>>>>
>>>>> Yes, I personally find unit tests terribly annoying and unproductive
>>>>> and
>>>>> functional tests very helpful :). And in this case, the effort to write
>>>>> it
>>>>> is about the same for both, just that the functional test actually
>>>>> tells you
>>>>> that things work or don't work at the end of the day.
>>>>>
>>>>> With a code base like U-Boot, a simple functional test like the above
>>>>> plus
>>>>> git bisect should get you to an offending patch very quickly.
>>>>
>>>>
>>>> This is not a unit test - in fact the EFI stuff has no unit tests. I
>>>> suppose if we are trying to find a name this is a small functional
>>>> test since it exercises the general functionality.
>>>>
>>>> I am much keener on small tests than large ones for finding simple
>>>> bugs. Of course you can generally bisect to find a bug, but the more
>>>> layers of software you need to look for the harder this is.
>>>>
>>>> We could definitely use a pytest which checks an EFI boot into an
>>>> image, but I don't think this obviates the need for a smaller targeted
>>>> test like this one.
>>>
>>>
>>> I think arguing over this is moot :). More tests is usually a good thing,
>>> so whoever gets to write them gets to push them ;). As long as the licenses
>>> are sound at least.
>>
>>
>> OK good, well please can you review this at some point?
>
>
> Review what exactly?
I mean the patches. There should be ~14 in your queue.
>
>> Also, are you
>> planning to write the 'larger' test? How do you test this all in suse?
>
>
> Planning yes, but I'm very good at not writing tests :).
>
> Currently I'm testing this all in suse by running systems which rely on the
> code to work.
OK I see.
Regards,
Simon
^ permalink raw reply
* Re: linux-next: manual merge of the driver-core tree with the pm tree
From: Rafael J. Wysocki @ 2016-11-14 21:07 UTC (permalink / raw)
To: Stephen Rothwell; +Cc: Greg KH, linux-next, linux-kernel, Brian Norris
In-Reply-To: <20161114130902.532c3c64@canb.auug.org.au>
On Monday, November 14, 2016 01:09:02 PM Stephen Rothwell wrote:
> Hi Greg,
>
> Today's linux-next merge of the driver-core tree got a conflict in:
>
> drivers/base/power/main.c
>
> between commit:
>
> 6f75c3fd56da ("PM / sleep: don't suspend parent when async child suspend_{noirq, late} fails")
>
> from the pm tree and commit:
>
> 8c73b4288496 ("PM / sleep: Make async suspend/resume of devices use device links")
>
> from the driver-core tree.
Well, right. The device links series predates the Brian's fix (which is in -rc5
already, BTW).
> I fixed it up (maybe .. see below) and can carry the fix as necessary.
That's the correct one, thanks Stephen!
Cheers,
Rafael
^ permalink raw reply
* Re: [PATCH 1/5] PCI: Make pci_std_enable_acs() non-static
From: Bjorn Helgaas @ 2016-11-14 20:59 UTC (permalink / raw)
To: Alex Williamson; +Cc: linux-pci, bhelgaas, iommu, linux-kernel
In-Reply-To: <20161026180116.23495.77322.stgit@gimli.home>
On Wed, Oct 26, 2016 at 12:01:16PM -0600, Alex Williamson wrote:
> For use by quirks.
>
> Signed-off-by: Alex Williamson <alex.williamson@redhat.com>
> ---
> drivers/pci/pci.c | 2 +-
> include/linux/pci.h | 1 +
> 2 files changed, 2 insertions(+), 1 deletion(-)
>
> diff --git a/drivers/pci/pci.c b/drivers/pci/pci.c
> index aab9d51..b901ee7 100644
> --- a/drivers/pci/pci.c
> +++ b/drivers/pci/pci.c
> @@ -2728,7 +2728,7 @@ void pci_request_acs(void)
> * pci_std_enable_acs - enable ACS on devices using standard ACS capabilites
> * @dev: the PCI device
> */
> -static void pci_std_enable_acs(struct pci_dev *dev)
> +void pci_std_enable_acs(struct pci_dev *dev)
> {
> int pos;
> u16 cap;
> diff --git a/include/linux/pci.h b/include/linux/pci.h
> index 0ab8359..c3248d5 100644
> --- a/include/linux/pci.h
> +++ b/include/linux/pci.h
> @@ -1900,6 +1900,7 @@ static inline int pci_pcie_type(const struct pci_dev *dev)
> bool pci_acs_enabled(struct pci_dev *pdev, u16 acs_flags);
> bool pci_acs_path_enabled(struct pci_dev *start,
> struct pci_dev *end, u16 acs_flags);
> +void pci_std_enable_acs(struct pci_dev *dev);
I think putting this in drivers/pci/pci.h would be sufficient for what
you need, wouldn't it? Same for pcie_get_link() and pcie_retrain_link().
> #define PCI_VPD_LRDT 0x80 /* Large Resource Data Type */
> #define PCI_VPD_LRDT_ID(x) ((x) | PCI_VPD_LRDT)
>
^ permalink raw reply
* Re: [PATCH 1/3] perf: add PERF_RECORD_NAMESPACES to include namespaces related info
From: Eric W. Biederman @ 2016-11-14 20:57 UTC (permalink / raw)
To: Peter Zijlstra
Cc: Hari Bathini, ast, lkml, acme, alexander.shishkin, mingo, daniel,
rostedt, Ananth N Mavinakayanahalli, sargun, Aravinda Prasad,
brendan.d.gregg
In-Reply-To: <20161114104612.GA3102@twins.programming.kicks-ass.net>
Peter Zijlstra <peterz@infradead.org> writes:
> On Mon, Nov 14, 2016 at 04:02:30PM +0530, Hari Bathini wrote:
>
>> >> PERF_RECORD_SWITCH_CPU_WIDE = 15,
>> >>+ /*
>> >>+ * struct {
>> >>+ * struct perf_event_header header;
>> >>+ *
>> >>+ * u32 pid, tid;
>> >>+ * u64 time;
>> >>+ * u32 uts_ns_inum;
>> >>+ * u32 ipc_ns_inum;
>> >>+ * u32 mnt_ns_inum;
>> >>+ * u32 pid_ns_inum;
>> >>+ * u32 net_ns_inum;
>> >>+ * u32 cgroup_ns_inum;
>> >>+ * u32 user_ns_inum;
>> >>+ * struct sample_id sample_id;
>> >>+ * };
>> >>+ */
>> >>+ PERF_RECORD_NAMESPACES = 16,
>> >So this format is not extensible, that is, if someone adds yet another
>> >namespace, we'll need to introduce PERF_RECORD_NAMESPACES2.
>> >
>> >Is there a 'natural' and exposed namespace index that we can use to
>> >change it like:
>> >
>> > u32 nr_nss;
>> > u32 namespace[nr_nss];
>> >
>> >?
>>
>> Nothing of that sort exists, currently.
>> Maybe, time to introduce with this patch-set..?
>
> Would be good, but you'll have to sort that with the namespace folks.
The somewhat easy answer is to use the unshare flags. AKA CLONE_NEWNS,
CLONE_NEWUSER, ...
In the worst case things may get extended to the point where perf would
have to use a different set of values than we use to unshare, clone, and
setns (as the clone flags are effectively all used up) but for the
existing namespaces that index should work just fine.
That won't allow for a natural array in the record but it will allow for
an array with that has a tag for which namespace it is in, or
alternative it will allow for one record per namespace.
Eric
^ permalink raw reply
* Re: Debugging Ethernet issues
From: Florian Fainelli @ 2016-11-14 21:00 UTC (permalink / raw)
To: Mason
Cc: Sebastian Frias, Andrew Lunn, netdev, Mans Rullgard,
Sergei Shtylyov, Tom Lendacky, Zach Brown, Shaohui Xie, Tim Beale,
Brian Hill, Vince Bridgers, Balakumaran Kannan, David S. Miller,
Kirill Kapranov
In-Reply-To: <582A1E3F.8040908@free.fr>
On 11/14/2016 12:27 PM, Mason wrote:
> On 14/11/2016 19:20, Florian Fainelli wrote:
>
>> On 11/14/2016 09:59 AM, Sebastian Frias wrote:
>>
>>> Could you confirm that Mason's patch is correct and/or that it does not
>>> has negative side-effects?
>>
>> The patch is not correct nor incorrect per-se, it changes the default
>> policy of having pause frames advertised by default to not having them
>> advertised by default. This influences both your Ethernet MAC and the
>> link partner in that the result is either flow control is enabled
>> (before) or it is not (with the patch). There must be something amiss if
>> you see packet loss or some kind of problem like that with an early
>> exchange such as DHCP. Flow control tend to kick in under higher packet
>> rates (at least, that's what you expect).
>
> Did you note that, without the change under discussion (i.e. with
> the eth driver as it is upstream), when the board is connected to
> a 100 Mbps switch, then *nothing* works *systematically (no ping,
> no DHCP; are there other relevant low-level network tools?).
No I missed that, way too many emails, really. So how about you compare
the register settings that could be (that is, all that could be modified
by the PHYLIB adjust_link function) and try to spot where things could
go wrong? Any other register that can be influenced by the link speed?
It seems like a possible (yet after re-reading, very unlikely) scenario,
considering that priv->speed, priv->duplex and priv->link are initially
zero-initialized (because nb8800_priv is zero initialized) may not force
a correct link transition and a full MAC reconfiguration in
nb8800_link_reconfigure() where some of the cached values are used.
NB: you will see most drivers initialize the previous link, speed,
duplex values to -1, because those are outside of the range of values
that PHYLIB would assign to phydev->{link,duplex,speed}, and therefore,
this is guaranteed to make the adjust_link callback that tries to
minimize these settings to force a transition.
>
> Also, maybe this comment was lost in my own noise:
>
> If I manually set the link up, then down, then run udhcpc
> => then nothing works, as if something is wedged somewhere
> (a kernel thread gets borked by a race condition?)
Well then start seriously debugging the problem: firs thing you need to
check is is the RUNNING flag set on the interface (which indicates a
carrier on?) without that, the networking stack won't even send packets.
If it is not set, why is not it set? Did nb8800_mac_config() get called
in the first place to configure the MAC wrt. the link settings?
When you transmit, do transmit counters increase? That would indicate
the TX DMA does its job. When transmission occurs, it is successful or
is it reporting errors? If the PHY supports it, can you access PHY
counters and look for success/error counters changing? Finally, try to
put another golden (working) host and if your switch supports it,
configure port mirroring to look at packets. If the switch does not
support it, then try different link partners.
>
> Could not advertising pause frames result in making such a
> race condition impossible? (I don't really believe in a race,
> due to the 100% nature of the problem.)
>
>>> Right now we know that Mason's patch makes this work, but we do not understand
>>> why nor its implications.
>>
>> You need to understand why, right now, the way this problem is
>> presented, you came up with a workaround, not with the root cause or the
>> solution. What does your link partner (switch?) reports, that is, what
>> is the ethtool output when you have a link up from your nb8800 adapter?
>
> Isn't that what ethtool -a eth0 prints?
No, ethtool -a prints the local pause settings.
> How do I get the link partner information?
ethtool eth0:
# ethtool eth0
Settings for eth0:
Supported ports: [ TP MII ]
Supported link modes: 10baseT/Half 10baseT/Full
100baseT/Half 100baseT/Full
Supported pause frame use: Symmetric Receive-only
Supports auto-negotiation: Yes
Advertised link modes: 10baseT/Half 10baseT/Full
100baseT/Half 100baseT/Full
Advertised pause frame use: No
Advertised auto-negotiation: Yes
Link partner advertised link modes: 10baseT/Half 10baseT/Full
100baseT/Half 100baseT/Full
^======================
Link partner advertised pause frame use: Symmetric
Link partner advertised auto-negotiation: Yes
^========================
Speed: 100Mb/s
Duplex: Full
Port: MII
PHYAD: 1
Transceiver: internal
Auto-negotiation: on
Supports Wake-on: gs
Wake-on: d
SecureOn password: 00:00:00:00:00:00
Current message level: 0x00000007 (7)
drv probe link
Link detected: yes
#
> Just ethtool eth0?
Yes, just that.
--
Florian
^ permalink raw reply
* Re: Tracker "Source" field default value changed from "other" to empty
From: Gregory Farnum @ 2016-11-14 21:00 UTC (permalink / raw)
To: Nathan Cutler; +Cc: ceph-devel@vger.kernel.org
In-Reply-To: <939a67e9-160c-421b-eb60-87f054c53464@suse.cz>
On Fri, Nov 11, 2016 at 1:11 AM, Nathan Cutler <ncutler@suse.cz> wrote:
> The tracker has a custom field called "Source" which is supposed to indicate
> who found, or first reported, a given issue. In practice, the field is
> rarely used and it typically is left at its default value, which is "other".
> Over time, I have found this to be a low-grade annoyance, so today I changed
> the default value to empty (not filled out).
>
> For me, this is a no-brainer :-) but if anyone has objections let's discuss!
Thumbs up from me! I'm not sure about who else, but I definitely
maintain these fields whenever I'm handling a ticket, and these fields
have been used for statistics analysis in the past.
-Greg
^ permalink raw reply
* [RFC][PATCH 0/7] crypto: Adding Hash-Encrypt-Hash(HEH)
From: Alex Cope @ 2016-11-14 21:01 UTC (permalink / raw)
To: linux-crypto; +Cc: mhalcrow, edknapp, Alex Cope
This patchset implements HEH, which is currently specified by the
following Internet Draft:
https://tools.ietf.org/html/draft-cope-heh-00
This patchset is a request for comments, and should not be merged at
this time. We would like to wait for further comments on the Internet
Draft before merging this patchset.
Thanks
^ permalink raw reply
* [RFC][PATCH 1/7] crypto: skcipher adding skciper_walk_virt_init
From: Alex Cope @ 2016-11-14 21:01 UTC (permalink / raw)
To: linux-crypto; +Cc: mhalcrow, edknapp, Alex Cope, Eric Biggers
In-Reply-To: <1479157277-10251-1-git-send-email-alexcope@google.com>
Adding skcipher_walk_virt_init to allow a skciper_walk to specify
length and input/output sg. Provides similar funcationalty to
blkcipher_walk_init
Signed-off-by: Alex Cope <alexcope@google.com>
Signed-off-by: Eric Biggers <ebiggers@google.com>
---
crypto/skcipher.c | 32 +++++++++++++++++++++++---------
include/crypto/internal/skcipher.h | 4 ++++
2 files changed, 27 insertions(+), 9 deletions(-)
diff --git a/crypto/skcipher.c b/crypto/skcipher.c
index e1633e6..df4b2de 100644
--- a/crypto/skcipher.c
+++ b/crypto/skcipher.c
@@ -447,16 +447,19 @@ static int skcipher_walk_first(struct skcipher_walk *walk)
}
static int skcipher_walk_skcipher(struct skcipher_walk *walk,
- struct skcipher_request *req)
+ struct skcipher_request *req,
+ struct scatterlist *src,
+ struct scatterlist *dst,
+ unsigned int len)
{
struct crypto_skcipher *tfm = crypto_skcipher_reqtfm(req);
- scatterwalk_start(&walk->in, req->src);
- scatterwalk_start(&walk->out, req->dst);
+ scatterwalk_start(&walk->in, src);
+ scatterwalk_start(&walk->out, dst);
- walk->in.sg = req->src;
- walk->out.sg = req->dst;
- walk->total = req->cryptlen;
+ walk->in.sg = src;
+ walk->out.sg = dst;
+ walk->total = len;
walk->iv = req->iv;
walk->oiv = req->iv;
@@ -474,17 +477,27 @@ static int skcipher_walk_skcipher(struct skcipher_walk *walk,
int skcipher_walk_virt(struct skcipher_walk *walk,
struct skcipher_request *req, bool atomic)
{
+ return skcipher_walk_virt_init(walk, req, atomic, req->src, req->dst,
+ req->cryptlen);
+}
+EXPORT_SYMBOL_GPL(skcipher_walk_virt);
+
+int skcipher_walk_virt_init(struct skcipher_walk *walk,
+ struct skcipher_request *req, bool atomic,
+ struct scatterlist *src, struct scatterlist *dst,
+ unsigned int len)
+{
int err;
walk->flags &= ~SKCIPHER_WALK_PHYS;
- err = skcipher_walk_skcipher(walk, req);
+ err = skcipher_walk_skcipher(walk, req, src, dst, len);
walk->flags &= atomic ? ~SKCIPHER_WALK_SLEEP : ~0;
return err;
}
-EXPORT_SYMBOL_GPL(skcipher_walk_virt);
+EXPORT_SYMBOL_GPL(skcipher_walk_virt_init);
void skcipher_walk_atomise(struct skcipher_walk *walk)
{
@@ -499,7 +512,8 @@ int skcipher_walk_async(struct skcipher_walk *walk,
INIT_LIST_HEAD(&walk->buffers);
- return skcipher_walk_skcipher(walk, req);
+ return skcipher_walk_skcipher(walk, req, req->src, req->dst,
+ req->cryptlen);
}
EXPORT_SYMBOL_GPL(skcipher_walk_async);
diff --git a/include/crypto/internal/skcipher.h b/include/crypto/internal/skcipher.h
index 26934a6..1173701 100644
--- a/include/crypto/internal/skcipher.h
+++ b/include/crypto/internal/skcipher.h
@@ -144,6 +144,10 @@ int skcipher_walk_done(struct skcipher_walk *walk, int err);
int skcipher_walk_virt(struct skcipher_walk *walk,
struct skcipher_request *req,
bool atomic);
+int skcipher_walk_virt_init(struct skcipher_walk *walk,
+ struct skcipher_request *req,
+ bool atomic, struct scatterlist *src,
+ struct scatterlist *dst, unsigned int len);
void skcipher_walk_atomise(struct skcipher_walk *walk);
int skcipher_walk_async(struct skcipher_walk *walk,
struct skcipher_request *req);
--
2.8.0.rc3.226.g39d4020
^ permalink raw reply related
* [RFC][PATCH 2/7] crypto: gf128mul - Refactor gf128 overflow macros
From: Alex Cope @ 2016-11-14 21:01 UTC (permalink / raw)
To: linux-crypto; +Cc: mhalcrow, edknapp, Alex Cope, Eric Biggers
In-Reply-To: <1479157277-10251-1-git-send-email-alexcope@google.com>
Rename and clean up the overflow macros. Their usage is more general
than the name suggested.
Signed-off-by: Alex Cope <alexcope@google.com>
Signed-off-by: Eric Biggers <ebiggers@google.com>
---
crypto/gf128mul.c | 68 +++++++++++++++++++++++++++++++++----------------------
1 file changed, 41 insertions(+), 27 deletions(-)
diff --git a/crypto/gf128mul.c b/crypto/gf128mul.c
index 0594dd6..8b65b1e 100644
--- a/crypto/gf128mul.c
+++ b/crypto/gf128mul.c
@@ -88,33 +88,47 @@
q(0xf8), q(0xf9), q(0xfa), q(0xfb), q(0xfc), q(0xfd), q(0xfe), q(0xff) \
}
-/* Given the value i in 0..255 as the byte overflow when a field element
- in GHASH is multiplied by x^8, this function will return the values that
- are generated in the lo 16-bit word of the field value by applying the
- modular polynomial. The values lo_byte and hi_byte are returned via the
- macro xp_fun(lo_byte, hi_byte) so that the values can be assembled into
- memory as required by a suitable definition of this macro operating on
- the table above
-*/
-
-#define xx(p, q) 0x##p##q
+/*
+ * Given a value i in 0..255 as the byte overflow when a field element
+ * in GF(2^128) is multiplied by x^8, the following macro returns the
+ * 16-bit value that must be XOR-ed into the low-degree end of the
+ * product to reduce it modulo the irreducible polynomial x^128 + x^7 +
+ * x^2 + x + 1.
+ *
+ * There are two versions of the macro, and hence two tables: one for
+ * the "be" convention where the highest-order bit is the coefficient of
+ * the highest-degree polynomial term, and one for the "le" convention
+ * where the highest-order bit is the coefficient of the lowest-degree
+ * polynomial term. In both cases the values are stored in CPU byte
+ * endianness such that the coefficients are ordered consistently across
+ * bytes, i.e. in the "be" table bits 15..0 of the stored value
+ * correspond to the coefficients of x^15..x^0, and in the "le" table
+ * bits 15..0 correspond to the coefficients of x^0..x^15.
+ *
+ * Therefore, provided that the appropriate byte endianness conversions
+ * are done by the multiplication functions (and these must be in place
+ * anyway to support both little endian and big endian CPUs), the "be"
+ * table can be used for multiplications of both "bbe" and "ble"
+ * elements, and the "le" table can be used for multiplications of both
+ * "lle" and "lbe" elements.
+ */
-#define xda_bbe(i) ( \
- (i & 0x80 ? xx(43, 80) : 0) ^ (i & 0x40 ? xx(21, c0) : 0) ^ \
- (i & 0x20 ? xx(10, e0) : 0) ^ (i & 0x10 ? xx(08, 70) : 0) ^ \
- (i & 0x08 ? xx(04, 38) : 0) ^ (i & 0x04 ? xx(02, 1c) : 0) ^ \
- (i & 0x02 ? xx(01, 0e) : 0) ^ (i & 0x01 ? xx(00, 87) : 0) \
+#define xda_be(i) ( \
+ (i & 0x80 ? 0x4380 : 0) ^ (i & 0x40 ? 0x21c0 : 0) ^ \
+ (i & 0x20 ? 0x10e0 : 0) ^ (i & 0x10 ? 0x0870 : 0) ^ \
+ (i & 0x08 ? 0x0438 : 0) ^ (i & 0x04 ? 0x021c : 0) ^ \
+ (i & 0x02 ? 0x010e : 0) ^ (i & 0x01 ? 0x0087 : 0) \
)
-#define xda_lle(i) ( \
- (i & 0x80 ? xx(e1, 00) : 0) ^ (i & 0x40 ? xx(70, 80) : 0) ^ \
- (i & 0x20 ? xx(38, 40) : 0) ^ (i & 0x10 ? xx(1c, 20) : 0) ^ \
- (i & 0x08 ? xx(0e, 10) : 0) ^ (i & 0x04 ? xx(07, 08) : 0) ^ \
- (i & 0x02 ? xx(03, 84) : 0) ^ (i & 0x01 ? xx(01, c2) : 0) \
+#define xda_le(i) ( \
+ (i & 0x80 ? 0xe100 : 0) ^ (i & 0x40 ? 0x7080 : 0) ^ \
+ (i & 0x20 ? 0x3840 : 0) ^ (i & 0x10 ? 0x1c20 : 0) ^ \
+ (i & 0x08 ? 0x0e10 : 0) ^ (i & 0x04 ? 0x0708 : 0) ^ \
+ (i & 0x02 ? 0x0384 : 0) ^ (i & 0x01 ? 0x01c2 : 0) \
)
-static const u16 gf128mul_table_lle[256] = gf128mul_dat(xda_lle);
-static const u16 gf128mul_table_bbe[256] = gf128mul_dat(xda_bbe);
+static const u16 gf128mul_table_le[256] = gf128mul_dat(xda_le);
+static const u16 gf128mul_table_be[256] = gf128mul_dat(xda_be);
/* These functions multiply a field element by x, by x^4 and by x^8
* in the polynomial field representation. It uses 32-bit word operations
@@ -126,7 +140,7 @@ static void gf128mul_x_lle(be128 *r, const be128 *x)
{
u64 a = be64_to_cpu(x->a);
u64 b = be64_to_cpu(x->b);
- u64 _tt = gf128mul_table_lle[(b << 7) & 0xff];
+ u64 _tt = gf128mul_table_le[(b << 7) & 0xff];
r->b = cpu_to_be64((b >> 1) | (a << 63));
r->a = cpu_to_be64((a >> 1) ^ (_tt << 48));
@@ -136,7 +150,7 @@ static void gf128mul_x_bbe(be128 *r, const be128 *x)
{
u64 a = be64_to_cpu(x->a);
u64 b = be64_to_cpu(x->b);
- u64 _tt = gf128mul_table_bbe[a >> 63];
+ u64 _tt = gf128mul_table_be[a >> 63];
r->a = cpu_to_be64((a << 1) | (b >> 63));
r->b = cpu_to_be64((b << 1) ^ _tt);
@@ -146,7 +160,7 @@ void gf128mul_x_ble(be128 *r, const be128 *x)
{
u64 a = le64_to_cpu(x->a);
u64 b = le64_to_cpu(x->b);
- u64 _tt = gf128mul_table_bbe[b >> 63];
+ u64 _tt = gf128mul_table_be[b >> 63];
r->a = cpu_to_le64((a << 1) ^ _tt);
r->b = cpu_to_le64((b << 1) | (a >> 63));
@@ -157,7 +171,7 @@ static void gf128mul_x8_lle(be128 *x)
{
u64 a = be64_to_cpu(x->a);
u64 b = be64_to_cpu(x->b);
- u64 _tt = gf128mul_table_lle[b & 0xff];
+ u64 _tt = gf128mul_table_le[b & 0xff];
x->b = cpu_to_be64((b >> 8) | (a << 56));
x->a = cpu_to_be64((a >> 8) ^ (_tt << 48));
@@ -167,7 +181,7 @@ static void gf128mul_x8_bbe(be128 *x)
{
u64 a = be64_to_cpu(x->a);
u64 b = be64_to_cpu(x->b);
- u64 _tt = gf128mul_table_bbe[a >> 56];
+ u64 _tt = gf128mul_table_be[a >> 56];
x->a = cpu_to_be64((a << 8) | (b >> 56));
x->b = cpu_to_be64((b << 8) ^ _tt);
--
2.8.0.rc3.226.g39d4020
^ permalink raw reply related
* [RFC][PATCH 3/7] crypto: gf128mul - Add ble multiplication functions
From: Alex Cope @ 2016-11-14 21:01 UTC (permalink / raw)
To: linux-crypto; +Cc: mhalcrow, edknapp, Alex Cope, Eric Biggers
In-Reply-To: <1479157277-10251-1-git-send-email-alexcope@google.com>
Adding ble multiplication to GF128mul, and fixing up comments.
The ble multiplication functions multiply GF(2^128) elements in the
ble format. This format is preferable because the bits within each
byte map to polynomial coefficients in the natural order (lowest order
bit = coefficient of lowest degree polynomial term), and the bytes are
stored in little endian order which matches the endianness of most
modern CPUs.
These new functions will be used by the HEH algorithm.
Signed-off-by: Alex Cope <alexcope@google.com>
Signed-off-by: Eric Biggers <ebiggers@google.com>
---
crypto/gf128mul.c | 99 ++++++++++++++++++++++++++++++++++++++++++++---
include/crypto/gf128mul.h | 45 +++++++++++----------
2 files changed, 117 insertions(+), 27 deletions(-)
diff --git a/crypto/gf128mul.c b/crypto/gf128mul.c
index 8b65b1e..f3d9f6d 100644
--- a/crypto/gf128mul.c
+++ b/crypto/gf128mul.c
@@ -44,7 +44,7 @@
---------------------------------------------------------------------------
Issue 31/01/2006
- This file provides fast multiplication in GF(128) as required by several
+ This file provides fast multiplication in GF(2^128) as required by several
cryptographic authentication modes
*/
@@ -130,9 +130,10 @@
static const u16 gf128mul_table_le[256] = gf128mul_dat(xda_le);
static const u16 gf128mul_table_be[256] = gf128mul_dat(xda_be);
-/* These functions multiply a field element by x, by x^4 and by x^8
- * in the polynomial field representation. It uses 32-bit word operations
- * to gain speed but compensates for machine endianess and hence works
+/*
+ * The following functions multiply a field element by x or by x^8 in
+ * the polynomial field representation. They use 64-bit word operations
+ * to gain speed but compensate for machine endianness and hence work
* correctly on both styles of machine.
*/
@@ -187,6 +188,16 @@ static void gf128mul_x8_bbe(be128 *x)
x->b = cpu_to_be64((b << 8) ^ _tt);
}
+static void gf128mul_x8_ble(be128 *x)
+{
+ u64 a = le64_to_cpu(x->b);
+ u64 b = le64_to_cpu(x->a);
+ u64 _tt = gf128mul_table_be[a >> 56];
+
+ x->b = cpu_to_le64((a << 8) | (b >> 56));
+ x->a = cpu_to_le64((b << 8) ^ _tt);
+}
+
void gf128mul_lle(be128 *r, const be128 *b)
{
be128 p[8];
@@ -263,9 +274,48 @@ void gf128mul_bbe(be128 *r, const be128 *b)
}
EXPORT_SYMBOL(gf128mul_bbe);
+void gf128mul_ble(be128 *r, const be128 *b)
+{
+ be128 p[8];
+ int i;
+
+ p[0] = *r;
+ for (i = 0; i < 7; ++i)
+ gf128mul_x_ble((be128 *)&p[i + 1], (be128 *)&p[i]);
+
+ memset(r, 0, sizeof(*r));
+ for (i = 0;;) {
+ u8 ch = ((u8 *)b)[15 - i];
+
+ if (ch & 0x80)
+ be128_xor(r, r, &p[7]);
+ if (ch & 0x40)
+ be128_xor(r, r, &p[6]);
+ if (ch & 0x20)
+ be128_xor(r, r, &p[5]);
+ if (ch & 0x10)
+ be128_xor(r, r, &p[4]);
+ if (ch & 0x08)
+ be128_xor(r, r, &p[3]);
+ if (ch & 0x04)
+ be128_xor(r, r, &p[2]);
+ if (ch & 0x02)
+ be128_xor(r, r, &p[1]);
+ if (ch & 0x01)
+ be128_xor(r, r, &p[0]);
+
+ if (++i >= 16)
+ break;
+
+ gf128mul_x8_ble(r);
+ }
+}
+EXPORT_SYMBOL(gf128mul_ble);
+
+
/* This version uses 64k bytes of table space.
A 16 byte buffer has to be multiplied by a 16 byte key
- value in GF(128). If we consider a GF(128) value in
+ value in GF(2^128). If we consider a GF(2^128) value in
the buffer's lowest byte, we can construct a table of
the 256 16 byte values that result from the 256 values
of this byte. This requires 4096 bytes. But we also
@@ -399,7 +449,7 @@ EXPORT_SYMBOL(gf128mul_64k_bbe);
/* This version uses 4k bytes of table space.
A 16 byte buffer has to be multiplied by a 16 byte key
- value in GF(128). If we consider a GF(128) value in a
+ value in GF(2^128). If we consider a GF(2^128) value in a
single byte, we can construct a table of the 256 16 byte
values that result from the 256 values of this byte.
This requires 4096 bytes. If we take the highest byte in
@@ -457,6 +507,28 @@ struct gf128mul_4k *gf128mul_init_4k_bbe(const be128 *g)
}
EXPORT_SYMBOL(gf128mul_init_4k_bbe);
+struct gf128mul_4k *gf128mul_init_4k_ble(const be128 *g)
+{
+ struct gf128mul_4k *t;
+ int j, k;
+
+ t = kzalloc(sizeof(*t), GFP_KERNEL);
+ if (!t)
+ goto out;
+
+ t->t[1] = *g;
+ for (j = 1; j <= 64; j <<= 1)
+ gf128mul_x_ble(&t->t[j + j], &t->t[j]);
+
+ for (j = 2; j < 256; j += j)
+ for (k = 1; k < j; ++k)
+ be128_xor(&t->t[j + k], &t->t[j], &t->t[k]);
+
+out:
+ return t;
+}
+EXPORT_SYMBOL(gf128mul_init_4k_ble);
+
void gf128mul_4k_lle(be128 *a, struct gf128mul_4k *t)
{
u8 *ap = (u8 *)a;
@@ -487,5 +559,20 @@ void gf128mul_4k_bbe(be128 *a, struct gf128mul_4k *t)
}
EXPORT_SYMBOL(gf128mul_4k_bbe);
+void gf128mul_4k_ble(be128 *a, struct gf128mul_4k *t)
+{
+ u8 *ap = (u8 *)a;
+ be128 r[1];
+ int i = 15;
+
+ *r = t->t[ap[15]];
+ while (i--) {
+ gf128mul_x8_ble(r);
+ be128_xor(r, r, &t->t[ap[i]]);
+ }
+ *a = *r;
+}
+EXPORT_SYMBOL(gf128mul_4k_ble);
+
MODULE_LICENSE("GPL");
MODULE_DESCRIPTION("Functions for multiplying elements of GF(2^128)");
diff --git a/include/crypto/gf128mul.h b/include/crypto/gf128mul.h
index 7217fe6..230760a 100644
--- a/include/crypto/gf128mul.h
+++ b/include/crypto/gf128mul.h
@@ -43,7 +43,7 @@
---------------------------------------------------------------------------
Issue Date: 31/01/2006
- An implementation of field multiplication in Galois Field GF(128)
+ An implementation of field multiplication in Galois Field GF(2^128)
*/
#ifndef _CRYPTO_GF128MUL_H
@@ -65,7 +65,7 @@
* are left and the lsb's are right. char b[16] is an array and b[0] is
* the first octet.
*
- * 80000000 00000000 00000000 00000000 .... 00000000 00000000 00000000
+ * 10000000 00000000 00000000 00000000 .... 00000000 00000000 00000000
* b[0] b[1] b[2] b[3] b[13] b[14] b[15]
*
* Every bit is a coefficient of some power of X. We can store the bits
@@ -99,21 +99,21 @@
*
* bbe on a little endian machine u32 x[4]:
*
- * MS x[0] LS MS x[1] LS
+ * MS x[0] LS MS x[1] LS
* ms ls ms ls ms ls ms ls ms ls ms ls ms ls ms ls
* 103..96 111.104 119.112 127.120 71...64 79...72 87...80 95...88
*
- * MS x[2] LS MS x[3] LS
+ * MS x[2] LS MS x[3] LS
* ms ls ms ls ms ls ms ls ms ls ms ls ms ls ms ls
* 39...32 47...40 55...48 63...56 07...00 15...08 23...16 31...24
*
* ble on a little endian machine
*
- * MS x[0] LS MS x[1] LS
+ * MS x[0] LS MS x[1] LS
* ms ls ms ls ms ls ms ls ms ls ms ls ms ls ms ls
* 31...24 23...16 15...08 07...00 63...56 55...48 47...40 39...32
*
- * MS x[2] LS MS x[3] LS
+ * MS x[2] LS MS x[3] LS
* ms ls ms ls ms ls ms ls ms ls ms ls ms ls ms ls
* 95...88 87...80 79...72 71...64 127.120 199.112 111.104 103..96
*
@@ -127,7 +127,7 @@
* machines this will automatically aligned to wordsize and on a 64-bit
* machine also.
*/
-/* Multiply a GF128 field element by x. Field elements are held in arrays
+/* Multiply a GF128 field element by x. Field elements are held in arrays
of bytes in which field bits 8n..8n + 7 are held in byte[n], with lower
indexed bits placed in the more numerically significant bit positions
within bytes.
@@ -135,45 +135,47 @@
On little endian machines the bit indexes translate into the bit
positions within four 32-bit words in the following way
- MS x[0] LS MS x[1] LS
+ MS x[0] LS MS x[1] LS
ms ls ms ls ms ls ms ls ms ls ms ls ms ls ms ls
24...31 16...23 08...15 00...07 56...63 48...55 40...47 32...39
- MS x[2] LS MS x[3] LS
+ MS x[2] LS MS x[3] LS
ms ls ms ls ms ls ms ls ms ls ms ls ms ls ms ls
88...95 80...87 72...79 64...71 120.127 112.119 104.111 96..103
On big endian machines the bit indexes translate into the bit
positions within four 32-bit words in the following way
- MS x[0] LS MS x[1] LS
+ MS x[0] LS MS x[1] LS
ms ls ms ls ms ls ms ls ms ls ms ls ms ls ms ls
00...07 08...15 16...23 24...31 32...39 40...47 48...55 56...63
- MS x[2] LS MS x[3] LS
+ MS x[2] LS MS x[3] LS
ms ls ms ls ms ls ms ls ms ls ms ls ms ls ms ls
64...71 72...79 80...87 88...95 96..103 104.111 112.119 120.127
*/
-/* A slow generic version of gf_mul, implemented for lle and bbe
- * It multiplies a and b and puts the result in a */
+/* A slow generic version of gf_mul, implemented for lle, bbe, and ble.
+ * It multiplies a and b and puts the result in a
+ */
void gf128mul_lle(be128 *a, const be128 *b);
-
void gf128mul_bbe(be128 *a, const be128 *b);
+void gf128mul_ble(be128 *a, const be128 *b);
-/* multiply by x in ble format, needed by XTS */
+/* multiply by x in ble format, needed by XTS and HEH */
void gf128mul_x_ble(be128 *a, const be128 *b);
/* 4k table optimization */
-
struct gf128mul_4k {
be128 t[256];
};
struct gf128mul_4k *gf128mul_init_4k_lle(const be128 *g);
struct gf128mul_4k *gf128mul_init_4k_bbe(const be128 *g);
+struct gf128mul_4k *gf128mul_init_4k_ble(const be128 *g);
void gf128mul_4k_lle(be128 *a, struct gf128mul_4k *t);
void gf128mul_4k_bbe(be128 *a, struct gf128mul_4k *t);
+void gf128mul_4k_ble(be128 *a, struct gf128mul_4k *t);
static inline void gf128mul_free_4k(struct gf128mul_4k *t)
{
@@ -181,16 +183,17 @@ static inline void gf128mul_free_4k(struct gf128mul_4k *t)
}
-/* 64k table optimization, implemented for lle and bbe */
+/* 64k table optimization, implemented for lle, ble, and bbe */
struct gf128mul_64k {
struct gf128mul_4k *t[16];
};
-/* first initialize with the constant factor with which you
- * want to multiply and then call gf128_64k_lle with the other
- * factor in the first argument, the table in the second and a
- * scratch register in the third. Afterwards *a = *r. */
+/* First initialize with the constant factor with which you
+ * want to multiply and then call gf128mul_64k_bbe with the other
+ * factor in the first argument, and the table in the second.
+ * Afterwards, the result is stored in *a.
+ */
struct gf128mul_64k *gf128mul_init_64k_lle(const be128 *g);
struct gf128mul_64k *gf128mul_init_64k_bbe(const be128 *g);
void gf128mul_free_64k(struct gf128mul_64k *t);
--
2.8.0.rc3.226.g39d4020
^ permalink raw reply related
* [PATCH 1/2 nft] tests: py: add some testcases for log flags
From: Pablo Neira Ayuso @ 2016-11-14 21:01 UTC (permalink / raw)
To: netfilter-devel
Remove null and zero flags from tests, to reduce the noise when running
tests.
Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
---
tests/py/any/log.t.payload | 26 +++++++++++++-------------
tests/py/ip/icmp.t.payload.ip | 2 +-
tests/py/ip6/icmpv6.t.payload.ip6 | 6 +++---
3 files changed, 17 insertions(+), 17 deletions(-)
diff --git a/tests/py/any/log.t.payload b/tests/py/any/log.t.payload
index 689668b6ed68..dc885b4b3e47 100644
--- a/tests/py/any/log.t.payload
+++ b/tests/py/any/log.t.payload
@@ -1,52 +1,52 @@
# log
ip test-ip4 output
- [ log prefix (null) ]
+ [ log ]
# log level emerg
ip test-ip4 output
- [ log prefix (null) level 0 flags 0]
+ [ log level 0 ]
# log level alert
ip test-ip4 output
- [ log prefix (null) level 1 flags 0]
+ [ log level 1 ]
# log level crit
ip test-ip4 output
- [ log prefix (null) level 2 flags 0]
+ [ log level 2 ]
# log level err
ip test-ip4 output
- [ log prefix (null) level 3 flags 0]
+ [ log level 3 ]
# log level warn
ip test-ip4 output
- [ log prefix (null) level 4 flags 0]
+ [ log level 4 ]
# log level notice
ip test-ip4 output
- [ log prefix (null) level 5 flags 0]
+ [ log level 5 ]
# log level info
ip test-ip4 output
- [ log prefix (null) level 6 flags 0]
+ [ log level 6 ]
# log level debug
ip test-ip4 output
- [ log prefix (null) level 7 flags 0]
+ [ log level 7 ]
# log prefix aaaaa-aaaaaa group 2 snaplen 33
ip test-ip4 output
- [ log prefix aaaaa-aaaaaa group 2 snaplen 33 qthreshold 0]
+ [ log prefix aaaaa-aaaaaa group 2 snaplen 33 qthreshold 0 ]
# log group 2 queue-threshold 2
ip test-ip4 output
- [ log prefix (null) group 2 snaplen 0 qthreshold 2]
+ [ log group 2 snaplen 0 qthreshold 2 ]
# log group 2 snaplen 33
ip test-ip4 output
- [ log prefix (null) group 2 snaplen 33 qthreshold 0]
+ [ log group 2 snaplen 33 qthreshold 0 ]
# log group 2 prefix \"nft-test: \"
ip test-ip4 output
- [ log prefix nft-test: group 2 snaplen 0 qthreshold 0]
+ [ log prefix nft-test: group 2 snaplen 0 qthreshold 0 ]
diff --git a/tests/py/ip/icmp.t.payload.ip b/tests/py/ip/icmp.t.payload.ip
index c7df75db1f70..b740ff80eff6 100644
--- a/tests/py/ip/icmp.t.payload.ip
+++ b/tests/py/ip/icmp.t.payload.ip
@@ -225,7 +225,7 @@ ip test-ip4 input
[ cmp eq reg 1 0x00000001 ]
[ payload load 2b @ transport header + 4 => reg 1 ]
[ cmp eq reg 1 0x0000dd04 ]
- [ log prefix (null) ]
+ [ log ]
# icmp id 22
ip test-ip4 input
diff --git a/tests/py/ip6/icmpv6.t.payload.ip6 b/tests/py/ip6/icmpv6.t.payload.ip6
index 822db2d5a2c5..a00f392e9bb7 100644
--- a/tests/py/ip6/icmpv6.t.payload.ip6
+++ b/tests/py/ip6/icmpv6.t.payload.ip6
@@ -193,7 +193,7 @@ ip6 test-ip6 input
[ cmp eq reg 1 0x0000003a ]
[ payload load 2b @ transport header + 2 => reg 1 ]
[ cmp eq reg 1 0x0000ae08 ]
- [ log prefix (null) ]
+ [ log ]
# icmpv6 checksum != 2222 log
ip6 test-ip6 input
@@ -201,7 +201,7 @@ ip6 test-ip6 input
[ cmp eq reg 1 0x0000003a ]
[ payload load 2b @ transport header + 2 => reg 1 ]
[ cmp neq reg 1 0x0000ae08 ]
- [ log prefix (null) ]
+ [ log ]
# icmpv6 checksum 222-226
ip6 test-ip6 input
@@ -217,7 +217,7 @@ ip6 test-ip6 input
[ cmp eq reg 1 0x0000003a ]
[ payload load 2b @ transport header + 2 => reg 1 ]
[ cmp neq reg 1 0x0000ae08 ]
- [ log prefix (null) ]
+ [ log ]
# icmpv6 checksum { 222, 226}
__set%d test-ip6 3
--
2.1.4
^ permalink raw reply related
* [RFC][PATCH 4/7] crypto: shash - Add crypto_grab_shash() and crypto_spawn_shash_alg()
From: Alex Cope @ 2016-11-14 21:01 UTC (permalink / raw)
To: linux-crypto; +Cc: mhalcrow, edknapp, Alex Cope, Eric Biggers
In-Reply-To: <1479157277-10251-1-git-send-email-alexcope@google.com>
Analogous to crypto_grab_skcipher() and crypto_spawn_skcipher_alg(),
these are useful for algorithms that need to use a shash sub-algorithm,
possibly in addition to other sub-algorithms.
Signed-off-by: Alex Cope <alexcope@google.com>
Signed-off-by: Eric Biggers <ebiggers@google.com>
---
crypto/shash.c | 8 ++++++++
include/crypto/internal/hash.h | 8 ++++++++
2 files changed, 16 insertions(+)
diff --git a/crypto/shash.c b/crypto/shash.c
index a051541..55a5535 100644
--- a/crypto/shash.c
+++ b/crypto/shash.c
@@ -536,6 +536,14 @@ void shash_free_instance(struct crypto_instance *inst)
}
EXPORT_SYMBOL_GPL(shash_free_instance);
+int crypto_grab_shash(struct crypto_shash_spawn *spawn,
+ const char *name, u32 type, u32 mask)
+{
+ spawn->base.frontend = &crypto_shash_type;
+ return crypto_grab_spawn(&spawn->base, name, type, mask);
+}
+EXPORT_SYMBOL_GPL(crypto_grab_shash);
+
int crypto_init_shash_spawn(struct crypto_shash_spawn *spawn,
struct shash_alg *alg,
struct crypto_instance *inst)
diff --git a/include/crypto/internal/hash.h b/include/crypto/internal/hash.h
index 1d4f365..54e4425 100644
--- a/include/crypto/internal/hash.h
+++ b/include/crypto/internal/hash.h
@@ -99,6 +99,8 @@ int shash_register_instance(struct crypto_template *tmpl,
struct shash_instance *inst);
void shash_free_instance(struct crypto_instance *inst);
+int crypto_grab_shash(struct crypto_shash_spawn *spawn,
+ const char *name, u32 type, u32 mask);
int crypto_init_shash_spawn(struct crypto_shash_spawn *spawn,
struct shash_alg *alg,
struct crypto_instance *inst);
@@ -108,6 +110,12 @@ static inline void crypto_drop_shash(struct crypto_shash_spawn *spawn)
crypto_drop_spawn(&spawn->base);
}
+static inline struct shash_alg *crypto_spawn_shash_alg(
+ struct crypto_shash_spawn *spawn)
+{
+ return container_of(spawn->base.alg, struct shash_alg, base);
+}
+
struct shash_alg *shash_attr_alg(struct rtattr *rta, u32 type, u32 mask);
int shash_ahash_update(struct ahash_request *req, struct shash_desc *desc);
--
2.8.0.rc3.226.g39d4020
^ permalink raw reply related
* [RFC][PATCH 5/7] crypto: heh - Add Hash Encrypt Hash(HEH) algorithm
From: Alex Cope @ 2016-11-14 21:01 UTC (permalink / raw)
To: linux-crypto; +Cc: mhalcrow, edknapp, Alex Cope, Eric Biggers
In-Reply-To: <1479157277-10251-1-git-send-email-alexcope@google.com>
Hash Encrypt Hash (HEH) is a proposed block cipher mode of operation
which extends the strong pseudo-random permutation property of block
ciphers (e.g. AES) to arbitrary length input strings. This provides a
stronger notion of security than existing block cipher modes of
operation (e.g. CBC, CTR, XTS), though it is less performant. It uses
two keyed invertible hash functions with a layer of ECB encryption
applied in-between.
This patch adds HEH as a skcipher. Support for HEH as an AEAD is not
yet implemented.
HEH will use existing accelerated ecb(block_cipher) implementation for
the encrypt step if available. Accelerated versions of the hash step
are planned but not yet implemented.
HEH will be used for filename encryption in ext4 and f2fs.
The algorithm is currently specified by the following Internet Draft:
https://tools.ietf.org/html/draft-cope-heh-00
Signed-off-by: Alex Cope <alexcope@google.com>
Signed-off-by: Eric Biggers <ebiggers@google.com>
---
crypto/Kconfig | 17 ++
crypto/Makefile | 1 +
crypto/heh.c | 814 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++
3 files changed, 832 insertions(+)
create mode 100644 crypto/heh.c
diff --git a/crypto/Kconfig b/crypto/Kconfig
index 1db2a19..78b0e93 100644
--- a/crypto/Kconfig
+++ b/crypto/Kconfig
@@ -316,6 +316,23 @@ config CRYPTO_CBC
CBC: Cipher Block Chaining mode
This block cipher algorithm is required for IPSec.
+config CRYPTO_HEH
+ tristate "HEH support"
+ select CRYPTO_CMAC
+ select CRYPTO_ECB
+ select CRYPTO_GF128MUL
+ select CRYPTO_MANAGER
+ help
+ HEH: Hash Encrypt Hash mode
+ HEH is a proposed block cipher mode of operation which extends the
+ strong pseudo-random permutation (SPRP) property of block ciphers to
+ arbitrary-length input strings. This provides a stronger notion of
+ security than existing block cipher modes of operation (e.g. CBC, CTR,
+ XTS), though it is less performant. Applications include disk
+ encryption and encryption of file names and contents. Currently, this
+ implementation only provides a symmetric cipher interface, so it can't
+ yet be used as an AEAD.
+
config CRYPTO_CTR
tristate "CTR support"
select CRYPTO_BLKCIPHER
diff --git a/crypto/Makefile b/crypto/Makefile
index 82ffeee..1458d3f 100644
--- a/crypto/Makefile
+++ b/crypto/Makefile
@@ -78,6 +78,7 @@ obj-$(CONFIG_CRYPTO_TGR192) += tgr192.o
obj-$(CONFIG_CRYPTO_GF128MUL) += gf128mul.o
obj-$(CONFIG_CRYPTO_ECB) += ecb.o
obj-$(CONFIG_CRYPTO_CBC) += cbc.o
+obj-$(CONFIG_CRYPTO_HEH) += heh.o
obj-$(CONFIG_CRYPTO_PCBC) += pcbc.o
obj-$(CONFIG_CRYPTO_CTS) += cts.o
obj-$(CONFIG_CRYPTO_LRW) += lrw.o
diff --git a/crypto/heh.c b/crypto/heh.c
new file mode 100644
index 0000000..efd49cc
--- /dev/null
+++ b/crypto/heh.c
@@ -0,0 +1,814 @@
+/*
+ * HEH: Hash Encrypt Hash mode
+ *
+ * Copyright (c) 2016 Google Inc.
+ *
+ * Authors:
+ * Alex Cope <alexcope@google.com>
+ * Eric Biggers <ebiggers@google.com>
+ */
+
+/*
+ * Hash Encrypt Hash (HEH) is a proposed block cipher mode of operation which
+ * extends the strong pseudo-random permutation (SPRP) property of block ciphers
+ * (e.g. AES) to arbitrary length input strings. It uses two keyed invertible
+ * hash functions with a layer of ECB encryption applied in-between. The
+ * algorithm is specified by the following Internet Draft:
+ *
+ * https://tools.ietf.org/html/draft-cope-heh-00
+ *
+ * Although HEH can be used as either a regular symmetric cipher or as an AEAD,
+ * currently this module only provides it as a symmetric cipher (skcipher).
+ * Additionally, only 48-byte keys and 16-byte nonces are supported.
+ */
+
+#include <crypto/gf128mul.h>
+#include <crypto/internal/hash.h>
+#include <crypto/internal/skcipher.h>
+#include <crypto/scatterwalk.h>
+#include <crypto/skcipher.h>
+#include "internal.h"
+
+/*
+ * The block size is the size of GF(2^128) elements and also the required block
+ * size of the underlying block cipher.
+ */
+#define HEH_BLOCK_SIZE 16
+
+/* Required key size in bytes */
+#define HEH_KEY_SIZE 48
+#define HEH_PRF_KEY_OFFSET 16
+#define HEH_BLK_KEY_OFFSET 32
+
+/*
+ * Macro to get the offset in bytes to the last full block
+ * (or equivalently the length of all full blocks excluding the last)
+ */
+#define HEH_TAIL_OFFSET(len) (((len) - HEH_BLOCK_SIZE) & ~(HEH_BLOCK_SIZE - 1))
+
+struct heh_instance_ctx {
+ struct crypto_shash_spawn cmac;
+ struct crypto_skcipher_spawn ecb;
+};
+
+struct heh_tfm_ctx {
+ struct crypto_shash *cmac;
+ struct crypto_skcipher *ecb;
+ struct gf128mul_4k *tau_key;
+};
+
+struct heh_cmac_data {
+ u8 nonce[HEH_BLOCK_SIZE];
+ __le32 nonce_length;
+ __le32 aad_length;
+ __le32 message_length;
+ __le32 padding;
+};
+
+struct heh_req_ctx { /* aligned to alignmask */
+ be128 beta1_key;
+ be128 beta2_key;
+ union {
+ struct {
+ struct heh_cmac_data data;
+ struct shash_desc desc;
+ /* + crypto_shash_descsize(cmac) */
+ } cmac;
+ struct {
+ u8 tail[2 * HEH_BLOCK_SIZE];
+ int (*crypt)(struct skcipher_request *);
+ struct scatterlist tmp_sgl[2];
+ struct skcipher_request req;
+ /* + crypto_skcipher_reqsize(ecb) */
+ } ecb;
+ } u;
+};
+
+static inline struct heh_req_ctx *heh_req_ctx(struct skcipher_request *req)
+{
+ unsigned int alignmask = crypto_skcipher_alignmask(
+ crypto_skcipher_reqtfm(req));
+
+ return (void *)PTR_ALIGN((u8 *)skcipher_request_ctx(req),
+ alignmask + 1);
+}
+
+static inline void async_done(struct crypto_async_request *areq, int err,
+ int (*next_step)(struct skcipher_request *, u32))
+{
+ struct skcipher_request *req = areq->data;
+
+ if (err)
+ goto out;
+
+ err = next_step(req, req->base.flags & ~CRYPTO_TFM_REQ_MAY_SLEEP);
+ if (err == -EINPROGRESS ||
+ (err == -EBUSY && (req->base.flags & CRYPTO_TFM_REQ_MAY_BACKLOG)))
+ return;
+out:
+ skcipher_request_complete(req, err);
+}
+
+/*
+ * Generate the per-message "beta" keys used by the hashing layers of HEH. The
+ * first beta key is the CMAC of the nonce, the additional authenticated data
+ * (AAD), and the lengths in bytes of the nonce, AAD, and message. The nonce
+ * and AAD are each zero-padded to the next 16-byte block boundary, and the
+ * lengths are serialized as 4-byte little endian integers and zero-padded to
+ * the next 16-byte block boundary. The second beta key is the first one
+ * interpreted as an element in GF(2^128) and multiplied by x.
+ *
+ * Note that because the nonce and AAD may, in general, be variable-length, the
+ * key generation must be done by a pseudo-random function (PRF) on
+ * variable-length inputs. CBC-MAC does not satisfy this, as it is only a PRF
+ * on fixed-length inputs. CMAC remedies this flaw. Including the lengths of
+ * the nonce, AAD, and message is also critical to avoid collisions.
+ *
+ * That being said, this implementation does not yet operate as an AEAD and
+ * therefore there is never any AAD, nor are variable-length nonces supported.
+ */
+static int generate_betas(struct skcipher_request *req,
+ be128 *beta1_key, be128 *beta2_key)
+{
+ struct crypto_skcipher *tfm = crypto_skcipher_reqtfm(req);
+ struct heh_tfm_ctx *ctx = crypto_skcipher_ctx(tfm);
+ struct heh_req_ctx *rctx = heh_req_ctx(req);
+ struct heh_cmac_data *data = &rctx->u.cmac.data;
+ struct shash_desc *desc = &rctx->u.cmac.desc;
+ int err;
+
+ BUILD_BUG_ON(sizeof(*data) != HEH_BLOCK_SIZE + 16);
+ memcpy(data->nonce, req->iv, HEH_BLOCK_SIZE);
+ data->nonce_length = cpu_to_le32(HEH_BLOCK_SIZE);
+ data->aad_length = cpu_to_le32(0);
+ data->message_length = cpu_to_le32(req->cryptlen);
+ data->padding = cpu_to_le32(0);
+
+ desc->tfm = ctx->cmac;
+ desc->flags = req->base.flags;
+
+ err = crypto_shash_digest(desc, (const u8 *)data, sizeof(*data),
+ (u8 *)beta1_key);
+ if (err)
+ return err;
+
+ gf128mul_x_ble(beta2_key, beta1_key);
+ return 0;
+}
+
+/*
+ * Evaluation of a polynomial over GF(2^128) using Horner's rule. The
+ * polynomial is evaluated at 'point'. The polynomial's coefficients are taken
+ * from 'coeffs_sgl' and are for terms with consecutive descending degree ending
+ * at degree 1. 'bytes_of_coeffs' is 16 times the number of terms.
+ */
+static be128 evaluate_polynomial(struct gf128mul_4k *point,
+ struct scatterlist *coeffs_sgl,
+ unsigned int bytes_of_coeffs)
+{
+ be128 value = {0};
+ struct sg_mapping_iter miter;
+ unsigned int remaining = bytes_of_coeffs;
+ unsigned int needed = 0;
+
+ sg_miter_start(&miter, coeffs_sgl, sg_nents(coeffs_sgl),
+ SG_MITER_FROM_SG | SG_MITER_ATOMIC);
+ while (remaining) {
+ be128 coeff;
+ const u8 *src;
+ unsigned int srclen;
+ u8 *dst = (u8 *)&value;
+
+ /*
+ * Note: scatterlist elements are not necessarily evenly
+ * divisible into blocks, nor are they necessarily aligned to
+ * __alignof__(be128).
+ */
+ sg_miter_next(&miter);
+
+ src = miter.addr;
+ srclen = min_t(unsigned int, miter.length, remaining);
+ remaining -= srclen;
+
+ if (needed) {
+ unsigned int n = min(srclen, needed);
+ u8 *pos = dst + (HEH_BLOCK_SIZE - needed);
+
+ needed -= n;
+ srclen -= n;
+
+ while (n--)
+ *pos++ ^= *src++;
+
+ if (!needed)
+ gf128mul_4k_ble(&value, point);
+ }
+
+ while (srclen >= HEH_BLOCK_SIZE) {
+ memcpy(&coeff, src, HEH_BLOCK_SIZE);
+ be128_xor(&value, &value, &coeff);
+ gf128mul_4k_ble(&value, point);
+ src += HEH_BLOCK_SIZE;
+ srclen -= HEH_BLOCK_SIZE;
+ }
+
+ if (srclen) {
+ needed = HEH_BLOCK_SIZE - srclen;
+ do {
+ *dst++ ^= *src++;
+ } while (--srclen);
+ }
+ }
+ sg_miter_stop(&miter);
+ return value;
+}
+
+/*
+ * Split the message into 16 byte blocks, padding out the last block, and use
+ * the blocks as coefficients in the evaluation of a polynomial over GF(2^128)
+ * at the secret point 'tau_key'. For ease of implementing the higher-level
+ * heh_hash_inv() function, the constant and degree-1 coefficients are swapped.
+ *
+ * Mathematically, compute:
+ * t^N * m_0 + ... + t^2 * m_{N-2} + t * m_N + m_{N-1}
+ *
+ * where:
+ * t is tau_key
+ * N is the number of full blocks in the message
+ * m_i is the i-th full block in the message for i = 0 to N-1 inclusive
+ * m_N is the (possibly empty) partial block of the message padded up to 16
+ * bytes with a 0x01 byte followed by 0x00 bytes
+ *
+ * Note that when the message length is a multiple of 16, m_N is composed
+ * entirely of padding, i.e. 0x0100...00.
+ */
+static be128 poly_hash(struct crypto_skcipher *tfm, struct scatterlist *sgl,
+ unsigned int len)
+{
+ struct heh_tfm_ctx *ctx = crypto_skcipher_ctx(tfm);
+ unsigned int tail_offset = HEH_TAIL_OFFSET(len);
+ unsigned int tail_len = len - tail_offset;
+ be128 hash;
+ be128 tail[2];
+
+ /* Handle all full blocks except the last */
+ hash = evaluate_polynomial(ctx->tau_key, sgl, tail_offset);
+
+ /* Handle the last full block and the partial block */
+
+ scatterwalk_map_and_copy(tail, sgl, tail_offset, tail_len, 0);
+ *((u8 *)tail + tail_len) = 0x01;
+ memset((u8 *)tail + tail_len + 1, 0, sizeof(tail) - 1 - tail_len);
+
+ be128_xor(&hash, &hash, &tail[1]);
+ gf128mul_4k_ble(&hash, ctx->tau_key);
+ be128_xor(&hash, &hash, &tail[0]);
+ return hash;
+}
+
+/*
+ * Transform all full blocks except the last.
+ * This is used by both the hash and inverse hash phases.
+ */
+static int heh_tfm_blocks(struct skcipher_request *req,
+ struct scatterlist *src_sgl,
+ struct scatterlist *dst_sgl, unsigned int len,
+ const be128 *hash, const be128 *beta_key)
+{
+ struct skcipher_walk walk;
+ be128 e = *beta_key;
+ int err;
+ unsigned int nbytes;
+
+ err = skcipher_walk_virt_init(&walk, req, false, src_sgl, dst_sgl, len);
+ while ((nbytes = walk.nbytes)) {
+ const be128 *src = (be128 *)walk.src.virt.addr;
+ be128 *dst = (be128 *)walk.dst.virt.addr;
+
+ do {
+ gf128mul_x_ble(&e, &e);
+ be128_xor(dst, src, hash);
+ be128_xor(dst, dst, &e);
+ src++;
+ dst++;
+ } while ((nbytes -= HEH_BLOCK_SIZE) >= HEH_BLOCK_SIZE);
+ err = skcipher_walk_done(&walk, nbytes);
+ }
+ return err;
+}
+
+/*
+ * The hash phase of HEH. Given a message, compute:
+ *
+ * (m_0 + H, ..., m_{N-2} + H, H, m_N) + (xb, x^2b, ..., x^{N-1}b, b, 0)
+ *
+ * where:
+ * N is the number of full blocks in the message
+ * m_i is the i-th full block in the message for i = 0 to N-1 inclusive
+ * m_N is the unpadded partial block, possibly empty
+ * H is the poly_hash() of the message, keyed by tau_key
+ * b is beta_key
+ * x is the element x in our representation of GF(2^128)
+ *
+ * Note that the partial block remains unchanged, but it does affect the result
+ * of poly_hash() and therefore the transformation of all the full blocks.
+ */
+static int heh_hash(struct skcipher_request *req, const be128 *beta_key)
+{
+ be128 hash;
+ struct crypto_skcipher *tfm = crypto_skcipher_reqtfm(req);
+ unsigned int tail_offset = HEH_TAIL_OFFSET(req->cryptlen);
+ unsigned int partial_len = req->cryptlen % HEH_BLOCK_SIZE;
+ int err;
+
+ /* poly_hash() the full message including the partial block */
+ hash = poly_hash(tfm, req->src, req->cryptlen);
+
+ /* Transform all full blocks except the last */
+ err = heh_tfm_blocks(req, req->src, req->dst, tail_offset, &hash,
+ beta_key);
+ if (err)
+ return err;
+
+ /* Set the last full block to hash XOR beta_key */
+ be128_xor(&hash, &hash, beta_key);
+ scatterwalk_map_and_copy(&hash, req->dst, tail_offset, HEH_BLOCK_SIZE,
+ 1);
+
+ /* Copy the partial block if needed */
+ if (partial_len != 0 && req->src != req->dst) {
+ unsigned int offs = tail_offset + HEH_BLOCK_SIZE;
+
+ scatterwalk_map_and_copy(&hash, req->src, offs, partial_len, 0);
+ scatterwalk_map_and_copy(&hash, req->dst, offs, partial_len, 1);
+ }
+ return 0;
+}
+
+/*
+ * The inverse hash phase of HEH. This undoes the result of heh_hash().
+ */
+static int heh_hash_inv(struct skcipher_request *req, const be128 *beta_key)
+{
+ be128 hash;
+ be128 tmp;
+ struct scatterlist tmp_sgl[2];
+ struct scatterlist *tail_sgl;
+ unsigned int len = req->cryptlen;
+ unsigned int tail_offset = HEH_TAIL_OFFSET(len);
+ struct scatterlist *sgl = req->dst;
+ struct crypto_skcipher *tfm = crypto_skcipher_reqtfm(req);
+ int err;
+
+ /*
+ * The last full block was computed as hash XOR beta_key, so XOR it with
+ * beta_key to recover hash.
+ */
+ tail_sgl = scatterwalk_ffwd(tmp_sgl, sgl, tail_offset);
+ scatterwalk_map_and_copy(&hash, tail_sgl, 0, HEH_BLOCK_SIZE, 0);
+ be128_xor(&hash, &hash, beta_key);
+
+ /* Transform all full blocks except the last */
+ err = heh_tfm_blocks(req, sgl, sgl, tail_offset, &hash, beta_key);
+ if (err)
+ return err;
+
+ /*
+ * Recover the last full block. We know 'hash', i.e. the poly_hash() of
+ * the the original message. The last full block was the constant term
+ * of the polynomial. To recover the last full block, temporarily zero
+ * it, compute the poly_hash(), and take the difference from 'hash'.
+ */
+ memset(&tmp, 0, sizeof(tmp));
+ scatterwalk_map_and_copy(&tmp, tail_sgl, 0, HEH_BLOCK_SIZE, 1);
+ tmp = poly_hash(tfm, sgl, len);
+ be128_xor(&tmp, &tmp, &hash);
+ scatterwalk_map_and_copy(&tmp, tail_sgl, 0, HEH_BLOCK_SIZE, 1);
+ return 0;
+}
+
+static int heh_hash_inv_step(struct skcipher_request *req, u32 flags)
+{
+ struct heh_req_ctx *rctx = heh_req_ctx(req);
+
+ return heh_hash_inv(req, &rctx->beta2_key);
+}
+
+static void heh_ecb_tail_done(struct crypto_async_request *areq, int err)
+{
+ return async_done(areq, err, heh_hash_inv_step);
+}
+
+static int heh_ecb_tail(struct skcipher_request *req, u32 flags)
+{
+ struct heh_req_ctx *rctx = heh_req_ctx(req);
+ unsigned int partial_len = req->cryptlen % HEH_BLOCK_SIZE;
+ struct scatterlist *tail_sgl;
+ int err;
+
+ if (partial_len == 0) /* no partial block? */
+ goto next_step;
+
+ /*
+ * Extract the already encrypted/decrypted last full block and the not
+ * yet encrypted/decrypted partial block. The former will be used as a
+ * pad to encrypt/decrypt the partial block.
+ */
+ tail_sgl = scatterwalk_ffwd(rctx->u.ecb.tmp_sgl, req->dst,
+ HEH_TAIL_OFFSET(req->cryptlen));
+ scatterwalk_map_and_copy(rctx->u.ecb.tail, tail_sgl, 0,
+ HEH_BLOCK_SIZE + partial_len, 0);
+
+ /* Encrypt/decrypt the partial block using the pad */
+ crypto_xor(&rctx->u.ecb.tail[HEH_BLOCK_SIZE], rctx->u.ecb.tail,
+ partial_len);
+ scatterwalk_map_and_copy(&rctx->u.ecb.tail[HEH_BLOCK_SIZE], tail_sgl,
+ HEH_BLOCK_SIZE, partial_len, 1);
+
+ /* Encrypt/decrypt the last full block again */
+ skcipher_request_set_callback(&rctx->u.ecb.req, flags,
+ heh_ecb_tail_done, req);
+ skcipher_request_set_crypt(&rctx->u.ecb.req, tail_sgl, tail_sgl,
+ HEH_BLOCK_SIZE, NULL);
+ err = rctx->u.ecb.crypt(&rctx->u.ecb.req);
+ if (err)
+ return err;
+next_step:
+ return heh_hash_inv_step(req, flags);
+}
+
+static void heh_ecb_full_done(struct crypto_async_request *areq, int err)
+{
+ return async_done(areq, err, heh_ecb_tail);
+}
+
+/*
+ * The encrypt phase of HEH. This uses ECB encryption, with special handling
+ * for the partial block at the end if any. The source data is already in
+ * req->dst, so the encryption happens in-place.
+ *
+ * After the encrypt phase we continue on to the inverse hash phase. The
+ * functions calls are chained to support asynchronous ECB algorithms.
+ */
+static int heh_ecb(struct skcipher_request *req, bool decrypt)
+{
+ struct crypto_skcipher *tfm = crypto_skcipher_reqtfm(req);
+ struct heh_tfm_ctx *ctx = crypto_skcipher_ctx(tfm);
+ struct heh_req_ctx *rctx = heh_req_ctx(req);
+ struct skcipher_request *ecb_req = &rctx->u.ecb.req;
+ unsigned int full_len = HEH_TAIL_OFFSET(req->cryptlen) + HEH_BLOCK_SIZE;
+
+ rctx->u.ecb.crypt = decrypt ? crypto_skcipher_decrypt :
+ crypto_skcipher_encrypt;
+
+ /* Encrypt/decrypt all full blocks */
+ skcipher_request_set_tfm(ecb_req, ctx->ecb);
+ skcipher_request_set_callback(ecb_req, req->base.flags,
+ heh_ecb_full_done, req);
+ skcipher_request_set_crypt(ecb_req, req->dst, req->dst, full_len, NULL);
+ return rctx->u.ecb.crypt(ecb_req) ?: heh_ecb_tail(req, req->base.flags);
+}
+
+static int heh_crypt(struct skcipher_request *req, bool decrypt)
+{
+ struct crypto_skcipher *tfm = crypto_skcipher_reqtfm(req);
+ struct heh_tfm_ctx *ctx = crypto_skcipher_ctx(tfm);
+ struct heh_req_ctx *rctx = heh_req_ctx(req);
+ int err;
+
+ /* Inputs must be at least one full block */
+ if (req->cryptlen < HEH_BLOCK_SIZE)
+ return -EINVAL;
+
+ /* Key must have been set */
+ if (!ctx->tau_key)
+ return -ENOKEY;
+
+ err = generate_betas(req, &rctx->beta1_key, &rctx->beta2_key);
+ if (err)
+ return err;
+
+ if (decrypt)
+ swap(rctx->beta1_key, rctx->beta2_key);
+
+ err = heh_hash(req, &rctx->beta1_key);
+ if (err)
+ return err;
+
+ return heh_ecb(req, decrypt);
+}
+
+static int heh_encrypt(struct skcipher_request *req)
+{
+ return heh_crypt(req, false);
+}
+
+static int heh_decrypt(struct skcipher_request *req)
+{
+ return heh_crypt(req, true);
+}
+
+static int heh_setkey(struct crypto_skcipher *parent, const u8 *key,
+ unsigned int keylen)
+{
+ struct heh_tfm_ctx *ctx = crypto_skcipher_ctx(parent);
+ struct crypto_shash *cmac = ctx->cmac;
+ struct crypto_skcipher *ecb = ctx->ecb;
+ const u8 *prf_key, *blk_key;
+ int err;
+
+ if (keylen != HEH_KEY_SIZE) {
+ crypto_skcipher_set_flags(parent, CRYPTO_TFM_RES_BAD_KEY_LEN);
+ return -EINVAL;
+ }
+
+ prf_key = key + HEH_PRF_KEY_OFFSET;
+ blk_key = key + HEH_BLK_KEY_OFFSET;
+
+ /* tau_key */
+ if (ctx->tau_key)
+ gf128mul_free_4k(ctx->tau_key);
+ ctx->tau_key = gf128mul_init_4k_ble((const be128 *)key);
+ if (!ctx->tau_key)
+ return -ENOMEM;
+
+ /* prf_key */
+ crypto_shash_clear_flags(cmac, CRYPTO_TFM_REQ_MASK);
+ crypto_shash_set_flags(cmac, crypto_skcipher_get_flags(parent) &
+ CRYPTO_TFM_REQ_MASK);
+ err = crypto_shash_setkey(cmac, prf_key, 16);
+ crypto_skcipher_set_flags(parent, crypto_shash_get_flags(cmac) &
+ CRYPTO_TFM_RES_MASK);
+ if (err)
+ return err;
+
+ /* blk_key */
+ crypto_skcipher_clear_flags(ecb, CRYPTO_TFM_REQ_MASK);
+ crypto_skcipher_set_flags(ecb, crypto_skcipher_get_flags(parent) &
+ CRYPTO_TFM_REQ_MASK);
+ err = crypto_skcipher_setkey(ecb, blk_key, 16);
+ crypto_skcipher_set_flags(parent, crypto_skcipher_get_flags(ecb) &
+ CRYPTO_TFM_RES_MASK);
+ return err;
+}
+
+static int heh_init_tfm(struct crypto_skcipher *tfm)
+{
+ struct skcipher_instance *inst = skcipher_alg_instance(tfm);
+ struct heh_instance_ctx *ictx = skcipher_instance_ctx(inst);
+ struct heh_tfm_ctx *ctx = crypto_skcipher_ctx(tfm);
+ struct crypto_shash *cmac;
+ struct crypto_skcipher *ecb;
+ unsigned int reqsize;
+ int err;
+
+ cmac = crypto_spawn_shash(&ictx->cmac);
+ if (IS_ERR(cmac))
+ return PTR_ERR(cmac);
+
+ ecb = crypto_spawn_skcipher(&ictx->ecb);
+ err = PTR_ERR(ecb);
+ if (IS_ERR(ecb))
+ goto err_free_cmac;
+
+ ctx->cmac = cmac;
+ ctx->ecb = ecb;
+
+ reqsize = crypto_skcipher_alignmask(tfm) &
+ ~(crypto_tfm_ctx_alignment() - 1);
+ reqsize += max(offsetof(struct heh_req_ctx, u.cmac.desc) +
+ sizeof(struct shash_desc) +
+ crypto_shash_descsize(cmac),
+ offsetof(struct heh_req_ctx, u.ecb.req) +
+ sizeof(struct skcipher_request) +
+ crypto_skcipher_reqsize(ecb));
+ crypto_skcipher_set_reqsize(tfm, reqsize);
+ return 0;
+
+err_free_cmac:
+ crypto_free_shash(cmac);
+ return err;
+}
+
+static void heh_exit_tfm(struct crypto_skcipher *tfm)
+{
+ struct heh_tfm_ctx *ctx = crypto_skcipher_ctx(tfm);
+
+ gf128mul_free_4k(ctx->tau_key);
+ crypto_free_shash(ctx->cmac);
+ crypto_free_skcipher(ctx->ecb);
+}
+
+static void heh_free_instance(struct skcipher_instance *inst)
+{
+ struct heh_instance_ctx *ctx = skcipher_instance_ctx(inst);
+
+ crypto_drop_shash(&ctx->cmac);
+ crypto_drop_skcipher(&ctx->ecb);
+ kfree(inst);
+}
+
+/*
+ * Create an instance of HEH as a skcipher.
+ *
+ * This relies on underlying CMAC and ECB algorithms, usually cmac(aes) and
+ * ecb(aes). For performance reasons we support asynchronous ECB algorithms.
+ * However, we do not yet support asynchronous CMAC algorithms because CMAC is
+ * only used on a small fixed amount of data per request, independent of the
+ * request length. This would change if AEAD or variable-length nonce support
+ * were to be exposed.
+ */
+static int heh_create_common(struct crypto_template *tmpl, struct rtattr **tb,
+ const char *full_name, const char *cmac_name,
+ const char *ecb_name)
+{
+ struct crypto_attr_type *algt;
+ struct skcipher_instance *inst;
+ struct heh_instance_ctx *ctx;
+ struct shash_alg *cmac;
+ struct skcipher_alg *ecb;
+ int err;
+
+ algt = crypto_get_attr_type(tb);
+ if (IS_ERR(algt))
+ return PTR_ERR(algt);
+
+ /* User must be asking for something compatible with skcipher */
+ if ((algt->type ^ CRYPTO_ALG_TYPE_SKCIPHER) & algt->mask)
+ return -EINVAL;
+
+ /* Allocate the skcipher instance */
+ inst = kzalloc(sizeof(*inst) + sizeof(*ctx), GFP_KERNEL);
+ if (!inst)
+ return -ENOMEM;
+
+ ctx = skcipher_instance_ctx(inst);
+
+ /* Set up the cmac and ecb spawns */
+
+ ctx->cmac.base.inst = skcipher_crypto_instance(inst);
+ err = crypto_grab_shash(&ctx->cmac, cmac_name, 0, CRYPTO_ALG_ASYNC);
+ if (err)
+ goto err_free_inst;
+ cmac = crypto_spawn_shash_alg(&ctx->cmac);
+
+ ctx->ecb.base.inst = skcipher_crypto_instance(inst);
+ err = crypto_grab_skcipher(&ctx->ecb, ecb_name, 0,
+ crypto_requires_sync(algt->type,
+ algt->mask));
+ if (err)
+ goto err_drop_cmac;
+ ecb = crypto_spawn_skcipher_alg(&ctx->ecb);
+
+ /* HEH only supports block ciphers with 16 byte block size */
+ err = -EINVAL;
+ if (ecb->base.cra_blocksize != HEH_BLOCK_SIZE)
+ goto err_drop_ecb;
+
+ /* The underlying "ECB" algorithm must not require an IV */
+ err = -EINVAL;
+ if (crypto_skcipher_alg_ivsize(ecb) != 0)
+ goto err_drop_ecb;
+
+ /* Set the instance names */
+
+ err = -ENAMETOOLONG;
+ if (snprintf(inst->alg.base.cra_driver_name, CRYPTO_MAX_ALG_NAME,
+ "heh_base(%s,%s)", cmac->base.cra_driver_name,
+ ecb->base.cra_driver_name) >= CRYPTO_MAX_ALG_NAME)
+ goto err_drop_ecb;
+
+ strcpy(inst->alg.base.cra_name, full_name); /* guaranteed to fit */
+
+ /* Finish initializing the instance */
+
+ inst->alg.base.cra_flags = (cmac->base.cra_flags |
+ ecb->base.cra_flags) & CRYPTO_ALG_ASYNC;
+ inst->alg.base.cra_blocksize = HEH_BLOCK_SIZE;
+ inst->alg.base.cra_ctxsize = sizeof(struct heh_tfm_ctx);
+ inst->alg.base.cra_alignmask = ecb->base.cra_alignmask |
+ (__alignof__(be128) - 1);
+ inst->alg.base.cra_priority = ecb->base.cra_priority;
+
+ inst->alg.ivsize = HEH_BLOCK_SIZE;
+ inst->alg.min_keysize = HEH_KEY_SIZE;
+ inst->alg.max_keysize = HEH_KEY_SIZE;
+
+ inst->alg.init = heh_init_tfm;
+ inst->alg.exit = heh_exit_tfm;
+ inst->alg.setkey = heh_setkey;
+ inst->alg.encrypt = heh_encrypt;
+ inst->alg.decrypt = heh_decrypt;
+ inst->free = heh_free_instance;
+
+ /* Register the instance */
+ err = skcipher_register_instance(tmpl, inst);
+ if (err)
+ goto err_drop_ecb;
+ return 0;
+
+err_drop_ecb:
+ crypto_drop_skcipher(&ctx->ecb);
+err_drop_cmac:
+ crypto_drop_shash(&ctx->cmac);
+err_free_inst:
+ kfree(inst);
+ return err;
+}
+
+static int heh_create(struct crypto_template *tmpl, struct rtattr **tb)
+{
+ const char *cipher_name;
+ char full_name[CRYPTO_MAX_ALG_NAME];
+ char cmac_name[CRYPTO_MAX_ALG_NAME];
+ char ecb_name[CRYPTO_MAX_ALG_NAME];
+
+ /* Get the name of the requested block cipher (e.g. aes) */
+ cipher_name = crypto_attr_alg_name(tb[1]);
+ if (IS_ERR(cipher_name))
+ return PTR_ERR(cipher_name);
+
+ if (snprintf(full_name, CRYPTO_MAX_ALG_NAME, "heh(%s)", cipher_name) >=
+ CRYPTO_MAX_ALG_NAME)
+ return -ENAMETOOLONG;
+
+ if (snprintf(cmac_name, CRYPTO_MAX_ALG_NAME, "cmac(%s)", cipher_name) >=
+ CRYPTO_MAX_ALG_NAME)
+ return -ENAMETOOLONG;
+
+ if (snprintf(ecb_name, CRYPTO_MAX_ALG_NAME, "ecb(%s)", cipher_name) >=
+ CRYPTO_MAX_ALG_NAME)
+ return -ENAMETOOLONG;
+
+ return heh_create_common(tmpl, tb, full_name, cmac_name, ecb_name);
+}
+
+static struct crypto_template heh_tmpl = {
+ .name = "heh",
+ .create = heh_create,
+ .module = THIS_MODULE,
+};
+
+static int heh_base_create(struct crypto_template *tmpl, struct rtattr **tb)
+{
+ char full_name[CRYPTO_MAX_ALG_NAME];
+ const char *cmac_name;
+ const char *ecb_name;
+
+ cmac_name = crypto_attr_alg_name(tb[1]);
+ if (IS_ERR(cmac_name))
+ return PTR_ERR(cmac_name);
+
+ ecb_name = crypto_attr_alg_name(tb[2]);
+ if (IS_ERR(ecb_name))
+ return PTR_ERR(ecb_name);
+
+ if (snprintf(full_name, CRYPTO_MAX_ALG_NAME, "heh_base(%s,%s)",
+ cmac_name, ecb_name) >= CRYPTO_MAX_ALG_NAME)
+ return -ENAMETOOLONG;
+
+ return heh_create_common(tmpl, tb, full_name, cmac_name, ecb_name);
+}
+
+/*
+ * If HEH is instantiated as "heh_base" instead of "heh", then specific
+ * implementations of cmac and ecb can be specified instead of just the cipher
+ */
+static struct crypto_template heh_base_tmpl = {
+ .name = "heh_base",
+ .create = heh_base_create,
+ .module = THIS_MODULE,
+};
+
+static int __init heh_module_init(void)
+{
+ int err;
+
+ err = crypto_register_template(&heh_tmpl);
+ if (err)
+ return err;
+
+ err = crypto_register_template(&heh_base_tmpl);
+ if (err)
+ goto out_undo_heh;
+
+ return 0;
+
+out_undo_heh:
+ crypto_unregister_template(&heh_tmpl);
+ return err;
+}
+
+static void __exit heh_module_exit(void)
+{
+ crypto_unregister_template(&heh_tmpl);
+ crypto_unregister_template(&heh_base_tmpl);
+}
+
+module_init(heh_module_init);
+module_exit(heh_module_exit);
+
+MODULE_LICENSE("GPL");
+MODULE_DESCRIPTION("Hash-Encrypt-Hash block cipher mode");
+MODULE_ALIAS_CRYPTO("heh");
+MODULE_ALIAS_CRYPTO("heh_base");
--
2.8.0.rc3.226.g39d4020
^ permalink raw reply related
* [RFC][PATCH 6/7] crypto: testmgr - Add test vectors for HEH
From: Alex Cope @ 2016-11-14 21:01 UTC (permalink / raw)
To: linux-crypto; +Cc: mhalcrow, edknapp, Alex Cope, Eric Biggers
In-Reply-To: <1479157277-10251-1-git-send-email-alexcope@google.com>
Adding test vectors from
https://tools.ietf.org/html/draft-cope-heh-00
Signed-off-by: Alex Cope <alexcope@google.com>
Signed-off-by: Eric Biggers <ebiggers@google.com>
---
crypto/testmgr.c | 15 ++++
crypto/testmgr.h | 226 +++++++++++++++++++++++++++++++++++++++++++++++++++++++
2 files changed, 241 insertions(+)
diff --git a/crypto/testmgr.c b/crypto/testmgr.c
index ded50b6..bab027b 100644
--- a/crypto/testmgr.c
+++ b/crypto/testmgr.c
@@ -3481,6 +3481,21 @@ static const struct alg_test_desc alg_test_descs[] = {
}
}
}, {
+ .alg = "heh(aes)",
+ .test = alg_test_skcipher,
+ .suite = {
+ .cipher = {
+ .enc = {
+ .vecs = aes_heh_enc_tv_template,
+ .count = AES_HEH_ENC_TEST_VECTORS
+ },
+ .dec = {
+ .vecs = aes_heh_dec_tv_template,
+ .count = AES_HEH_DEC_TEST_VECTORS
+ }
+ }
+ }
+ }, {
.alg = "hmac(crc32)",
.test = alg_test_hash,
.suite = {
diff --git a/crypto/testmgr.h b/crypto/testmgr.h
index e64a4ef..b2daad3 100644
--- a/crypto/testmgr.h
+++ b/crypto/testmgr.h
@@ -15172,6 +15172,8 @@ static struct cipher_testvec cast6_xts_dec_tv_template[] = {
#define AES_DEC_TEST_VECTORS 4
#define AES_CBC_ENC_TEST_VECTORS 5
#define AES_CBC_DEC_TEST_VECTORS 5
+#define AES_HEH_ENC_TEST_VECTORS 4
+#define AES_HEH_DEC_TEST_VECTORS 4
#define HMAC_MD5_ECB_CIPHER_NULL_ENC_TEST_VECTORS 2
#define HMAC_MD5_ECB_CIPHER_NULL_DEC_TEST_VECTORS 2
#define HMAC_SHA1_ECB_CIPHER_NULL_ENC_TEST_VEC 2
@@ -15544,6 +15546,230 @@ static struct cipher_testvec aes_dec_tv_template[] = {
},
};
+static struct cipher_testvec aes_heh_enc_tv_template[] = {
+ {
+ .key = "\x00\x01\x02\x03\x04\x05\x06\x07"
+ "\x08\x09\x0A\x0B\x0C\x0D\x0E\x0F"
+ "\x00\x01\x02\x03\x04\x05\x06\x07"
+ "\x08\x09\x0A\x0B\x0C\x0D\x0E\x0F"
+ "\x00\x01\x02\x03\x04\x05\x06\x07"
+ "\x08\x09\x0A\x0B\x0C\x0D\x0E\x0F",
+ .klen = 48,
+ .iv = "\x00\x00\x00\x00\x00\x00\x00\x00"
+ "\x00\x00\x00\x00\x00\x00\x00\x00",
+ .input = "\x00\x01\x02\x03\x04\x05\x06\x07"
+ "\x08\x09\x0A\x0B\x0C\x0D\x0E\x0F",
+ .ilen = 16,
+ .result = "\x61\x76\x38\xa5\x12\x0b\x6d\x89"
+ "\x92\x68\x30\x7e\x0d\x6e\x81\xe3",
+ .rlen = 16,
+ .also_non_np = 1,
+ .np = 2,
+ .tap = { 8, 8 },
+ }, {
+ .key = "\x68\xf8\x27\x87\xdc\x30\x33\xfd"
+ "\x65\x5b\x8e\x51\x2e\x02\xff\x9d"
+ "\x21\x28\x1e\x64\xcd\x9c\x33\x88"
+ "\xf6\x2c\x43\x8f\xf5\x6f\xf5\x8f"
+ "\xa8\xda\x24\x9b\x5e\xfa\x13\xc2"
+ "\xc1\x94\xbf\x32\xba\x38\xa3\x77",
+ .klen = 48,
+ .iv = "\x4d\x47\x61\x37\x2b\x47\x86\xf0"
+ "\xd6\x47\xb5\xc2\xe8\xcf\x85\x27",
+ .input = "\xb8\xee\x29\xe4\xa5\xd1\xe7\x55"
+ "\xd0\xfd\xe7\x22\x63\x76\x36\xe2"
+ "\xf8\x0c\xf8\xfe\x65\x76\xe7\xca"
+ "\xc1\x42\xf5\xca\x5a\xa8\xac\x2a",
+ .ilen = 32,
+ .result = "\x1f\x4c\x6a\x1e\x1d\x20\x0d\x99"
+ "\xdf\xbb\x13\xd8\x35\xdc\x1d\xbe"
+ "\xed\x50\x0a\x9f\xfd\xd6\x94\x85"
+ "\xd0\x8b\xf7\xb4\x49\x7f\x70\x6d",
+ .rlen = 32,
+ .also_non_np = 1,
+ .np = 3,
+ .tap = { 16, 13, 3 },
+ }, {
+ .key = "\x00\x01\x02\x03\x04\x05\x06\x07"
+ "\x08\x09\x0A\x0B\x0C\x0D\x0E\x0F"
+ "\x00\x01\x02\x03\x04\x05\x06\x07"
+ "\x08\x09\x0A\x0B\x0C\x0D\x0E\x0F"
+ "\x00\x01\x02\x03\x04\x05\x06\x07"
+ "\x08\x09\x0A\x0B\x0C\x0D\x0E\x0F",
+ .klen = 48,
+ .iv = "\x00\x00\x00\x00\x00\x00\x00\x00"
+ "\x00\x00\x00\x00\x00\x00\x00\x00",
+ .input = "\x00\x00\x00\x00\x00\x00\x00\x00"
+ "\x00\x00\x00\x00\x00\x00\x00\x00"
+ "\x00\x00\x00\x00\x00\x00\x00\x00"
+ "\x00\x00\x00\x00\x00\x00\x00\x00"
+ "\x00\x00\x00\x00\x00\x00\x00\x00"
+ "\x00\x00\x00\x00\x00\x00\x00\x00"
+ "\x00\x00\x00\x00\x00\x00\x00\x00"
+ "\x00\x00\x00\x00\x00\x00\x00",
+ .ilen = 63,
+ .result = "\xfb\x30\x90\x47\xc5\x4e\xcc\xfd"
+ "\xc4\x90\xa2\x9f\x7c\x03\x63\xc3"
+ "\xcb\xaf\x2e\xee\x62\x18\xeb\x20"
+ "\x62\x97\xe4\x9b\xf2\x8b\xf3\x3f"
+ "\x76\x3b\xaa\xab\xf0\x19\x54\xdb"
+ "\xb4\xaf\x2e\xd9\xa7\xe0\x92\x04"
+ "\x5a\xe4\x81\xfc\x58\xf2\xda\xbf"
+ "\x5d\xc9\xb1\x47\xd5\x08\xb1",
+ .rlen = 63,
+ .also_non_np = 1,
+ .np = 8,
+ .tap = { 20, 20, 10, 8, 2, 1, 1, 1 },
+ }, {
+ .key = "\x00\x01\x02\x03\x04\x05\x06\x07"
+ "\x08\x09\x0A\x0B\x0C\x0D\x0E\x0F"
+ "\x00\x01\x02\x03\x04\x05\x06\x07"
+ "\x08\x09\x0A\x0B\x0C\x0D\x0E\x0F"
+ "\x00\x01\x02\x03\x04\x05\x06\x07"
+ "\x08\x09\x0A\x0B\x0C\x0D\x0E\x0F",
+ .klen = 48,
+ .iv = "\x00\x00\x00\x00\x00\x00\x00\x00"
+ "\x00\x00\x00\x00\x00\x00\x00\x00",
+ .input = "\x00\x00\x00\x00\x00\x00\x00\x00"
+ "\x00\x00\x00\x00\x00\x00\x00\x00"
+ "\x00\x00\x00\x00\x00\x00\x00\x00"
+ "\x00\x00\x00\x00\x00\x00\x00\x00"
+ "\x00\x00\x00\x00\x00\x00\x00\x00"
+ "\x00\x00\x00\x00\x00\x00\x00\x01"
+ "\x00\x00\x00\x00\x00\x00\x00\x00"
+ "\x00\x00\x00\x00\x00\x00\x00",
+ .ilen = 63,
+ .result = "\x9c\xdf\xa5\x50\x83\xe0\xa3\xb5"
+ "\x0d\x35\x83\x34\x6e\x6e\x40\xd6"
+ "\x0f\x81\xc8\x1a\x9c\x40\x81\xfb"
+ "\xb3\x6e\xb4\xbf\xfc\xca\xc9\x50"
+ "\xcd\x33\xfd\xb3\x43\x11\xe6\x32"
+ "\x02\x3d\x3e\xc6\x49\x6e\xcf\x58"
+ "\x3e\x14\x15\x6d\x39\x2a\x58\x99"
+ "\x83\xaf\xdd\x22\x3e\x7f\x6c",
+ .rlen = 63,
+ .also_non_np = 1,
+ .np = 8,
+ .tap = { 20, 20, 10, 8, 2, 1, 1, 1 },
+ }
+};
+
+static struct cipher_testvec aes_heh_dec_tv_template[] = {
+ {
+ .key = "\x00\x01\x02\x03\x04\x05\x06\x07"
+ "\x08\x09\x0A\x0B\x0C\x0D\x0E\x0F"
+ "\x00\x01\x02\x03\x04\x05\x06\x07"
+ "\x08\x09\x0A\x0B\x0C\x0D\x0E\x0F"
+ "\x00\x01\x02\x03\x04\x05\x06\x07"
+ "\x08\x09\x0A\x0B\x0C\x0D\x0E\x0F",
+ .klen = 48,
+ .iv = "\x00\x00\x00\x00\x00\x00\x00\x00"
+ "\x00\x00\x00\x00\x00\x00\x00\x00",
+ .input = "\x61\x76\x38\xa5\x12\x0b\x6d\x89"
+ "\x92\x68\x30\x7e\x0d\x6e\x81\xe3",
+ .ilen = 16,
+ .result = "\x00\x01\x02\x03\x04\x05\x06\x07"
+ "\x08\x09\x0A\x0B\x0C\x0D\x0E\x0F",
+ .rlen = 16,
+ .also_non_np = 1,
+ .np = 2,
+ .tap = { 8, 8 },
+ }, {
+ .key = "\x68\xf8\x27\x87\xdc\x30\x33\xfd"
+ "\x65\x5b\x8e\x51\x2e\x02\xff\x9d"
+ "\x21\x28\x1e\x64\xcd\x9c\x33\x88"
+ "\xf6\x2c\x43\x8f\xf5\x6f\xf5\x8f"
+ "\xa8\xda\x24\x9b\x5e\xfa\x13\xc2"
+ "\xc1\x94\xbf\x32\xba\x38\xa3\x77",
+ .klen = 48,
+ .iv = "\x4d\x47\x61\x37\x2b\x47\x86\xf0"
+ "\xd6\x47\xb5\xc2\xe8\xcf\x85\x27",
+ .input = "\x1f\x4c\x6a\x1e\x1d\x20\x0d\x99"
+ "\xdf\xbb\x13\xd8\x35\xdc\x1d\xbe"
+ "\xed\x50\x0a\x9f\xfd\xd6\x94\x85"
+ "\xd0\x8b\xf7\xb4\x49\x7f\x70\x6d",
+ .ilen = 32,
+ .result = "\xb8\xee\x29\xe4\xa5\xd1\xe7\x55"
+ "\xd0\xfd\xe7\x22\x63\x76\x36\xe2"
+ "\xf8\x0c\xf8\xfe\x65\x76\xe7\xca"
+ "\xc1\x42\xf5\xca\x5a\xa8\xac\x2a",
+ .rlen = 32,
+ .also_non_np = 1,
+ .np = 3,
+ .tap = { 16, 13, 3 },
+ }, {
+ .key = "\x00\x01\x02\x03\x04\x05\x06\x07"
+ "\x08\x09\x0A\x0B\x0C\x0D\x0E\x0F"
+ "\x00\x01\x02\x03\x04\x05\x06\x07"
+ "\x08\x09\x0A\x0B\x0C\x0D\x0E\x0F"
+ "\x00\x01\x02\x03\x04\x05\x06\x07"
+ "\x08\x09\x0A\x0B\x0C\x0D\x0E\x0F",
+ .klen = 48,
+ .iv = "\x00\x00\x00\x00\x00\x00\x00\x00"
+ "\x00\x00\x00\x00\x00\x00\x00\x00",
+ .result = "\xfb\x30\x90\x47\xc5\x4e\xcc\xfd"
+ "\xc4\x90\xa2\x9f\x7c\x03\x63\xc3"
+ "\xcb\xaf\x2e\xee\x62\x18\xeb\x20"
+ "\x62\x97\xe4\x9b\xf2\x8b\xf3\x3f"
+ "\x76\x3b\xaa\xab\xf0\x19\x54\xdb"
+ "\xb4\xaf\x2e\xd9\xa7\xe0\x92\x04"
+ "\x5a\xe4\x81\xfc\x58\xf2\xda\xbf"
+ "\x5d\xc9\xb1\x47\xd5\x08\xb1",
+ .ilen = 63,
+ .input = "\xfb\x30\x90\x47\xc5\x4e\xcc\xfd"
+ "\xc4\x90\xa2\x9f\x7c\x03\x63\xc3"
+ "\xcb\xaf\x2e\xee\x62\x18\xeb\x20"
+ "\x62\x97\xe4\x9b\xf2\x8b\xf3\x3f"
+ "\x76\x3b\xaa\xab\xf0\x19\x54\xdb"
+ "\xb4\xaf\x2e\xd9\xa7\xe0\x92\x04"
+ "\x5a\xe4\x81\xfc\x58\xf2\xda\xbf"
+ "\x5d\xc9\xb1\x47\xd5\x08\xb1",
+ .result = "\x00\x00\x00\x00\x00\x00\x00\x00"
+ "\x00\x00\x00\x00\x00\x00\x00\x00"
+ "\x00\x00\x00\x00\x00\x00\x00\x00"
+ "\x00\x00\x00\x00\x00\x00\x00\x00"
+ "\x00\x00\x00\x00\x00\x00\x00\x00"
+ "\x00\x00\x00\x00\x00\x00\x00\x00"
+ "\x00\x00\x00\x00\x00\x00\x00\x00"
+ "\x00\x00\x00\x00\x00\x00\x00",
+ .rlen = 63,
+ .also_non_np = 1,
+ .np = 8,
+ .tap = { 20, 20, 10, 8, 2, 1, 1, 1 },
+ }, {
+ .key = "\x00\x01\x02\x03\x04\x05\x06\x07"
+ "\x08\x09\x0A\x0B\x0C\x0D\x0E\x0F"
+ "\x00\x01\x02\x03\x04\x05\x06\x07"
+ "\x08\x09\x0A\x0B\x0C\x0D\x0E\x0F"
+ "\x00\x01\x02\x03\x04\x05\x06\x07"
+ "\x08\x09\x0A\x0B\x0C\x0D\x0E\x0F",
+ .klen = 48,
+ .iv = "\x00\x00\x00\x00\x00\x00\x00\x00"
+ "\x00\x00\x00\x00\x00\x00\x00\x00",
+ .input = "\x9c\xdf\xa5\x50\x83\xe0\xa3\xb5"
+ "\x0d\x35\x83\x34\x6e\x6e\x40\xd6"
+ "\x0f\x81\xc8\x1a\x9c\x40\x81\xfb"
+ "\xb3\x6e\xb4\xbf\xfc\xca\xc9\x50"
+ "\xcd\x33\xfd\xb3\x43\x11\xe6\x32"
+ "\x02\x3d\x3e\xc6\x49\x6e\xcf\x58"
+ "\x3e\x14\x15\x6d\x39\x2a\x58\x99"
+ "\x83\xaf\xdd\x22\x3e\x7f\x6c",
+ .ilen = 63,
+ .result = "\x00\x00\x00\x00\x00\x00\x00\x00"
+ "\x00\x00\x00\x00\x00\x00\x00\x00"
+ "\x00\x00\x00\x00\x00\x00\x00\x00"
+ "\x00\x00\x00\x00\x00\x00\x00\x00"
+ "\x00\x00\x00\x00\x00\x00\x00\x00"
+ "\x00\x00\x00\x00\x00\x00\x00\x01"
+ "\x00\x00\x00\x00\x00\x00\x00\x00"
+ "\x00\x00\x00\x00\x00\x00\x00",
+ .rlen = 63,
+ .also_non_np = 1,
+ .np = 8,
+ .tap = { 20, 20, 10, 8, 2, 1, 1, 1 },
+ }
+};
+
static struct cipher_testvec aes_cbc_enc_tv_template[] = {
{ /* From RFC 3602 */
.key = "\x06\xa9\x21\x40\x36\xb8\xa1\x5b"
--
2.8.0.rc3.226.g39d4020
^ permalink raw reply related
* Re: [PATCH 2/5] PCI: Extract link speed & width retrieval from pcie_get_minimum_link()
From: Bjorn Helgaas @ 2016-11-14 21:02 UTC (permalink / raw)
To: Alex Williamson; +Cc: linux-pci, bhelgaas, iommu, linux-kernel
In-Reply-To: <20161026180122.23495.26258.stgit@gimli.home>
On Wed, Oct 26, 2016 at 12:01:22PM -0600, Alex Williamson wrote:
> Signed-off-by: Alex Williamson <alex.williamson@redhat.com>
> ---
> drivers/pci/pci.c | 26 ++++++++++++++++++++------
> include/linux/pci.h | 2 ++
> 2 files changed, 22 insertions(+), 6 deletions(-)
>
> diff --git a/drivers/pci/pci.c b/drivers/pci/pci.c
> index b901ee7..6d6cf89 100644
> --- a/drivers/pci/pci.c
> +++ b/drivers/pci/pci.c
> @@ -4729,6 +4729,25 @@ int pcie_set_mps(struct pci_dev *dev, int mps)
> }
> EXPORT_SYMBOL(pcie_set_mps);
>
> +int pcie_get_link(struct pci_dev *dev, enum pci_bus_speed *speed,
> + enum pcie_link_width *width)
Seems like "pcie_get_link" is missing a word. I know
pcie_get_minimum_link() exists already and is similar.
pcie_get_link_speed(), maybe? I know it also gets the width, so maybe
there's a more inclusive term that would be better.
> +{
> + int ret;
> + u16 lnksta;
> +
> + ret = pcie_capability_read_word(dev, PCI_EXP_LNKSTA, &lnksta);
> + if (ret)
> + return ret;
> +
> + if (speed)
> + *speed = pcie_link_speed[lnksta & PCI_EXP_LNKSTA_CLS];
> + if (width)
> + *width = (lnksta & PCI_EXP_LNKSTA_NLW) >>
> + PCI_EXP_LNKSTA_NLW_SHIFT;
> +
> + return 0;
> +}
> +
> /**
> * pcie_get_minimum_link - determine minimum link settings of a PCI device
> * @dev: PCI device to query
> @@ -4747,18 +4766,13 @@ int pcie_get_minimum_link(struct pci_dev *dev, enum pci_bus_speed *speed,
> *width = PCIE_LNK_WIDTH_UNKNOWN;
>
> while (dev) {
> - u16 lnksta;
> enum pci_bus_speed next_speed;
> enum pcie_link_width next_width;
>
> - ret = pcie_capability_read_word(dev, PCI_EXP_LNKSTA, &lnksta);
> + ret = pcie_get_link(dev, &next_speed, &next_width);
> if (ret)
> return ret;
>
> - next_speed = pcie_link_speed[lnksta & PCI_EXP_LNKSTA_CLS];
> - next_width = (lnksta & PCI_EXP_LNKSTA_NLW) >>
> - PCI_EXP_LNKSTA_NLW_SHIFT;
> -
> if (next_speed < *speed)
> *speed = next_speed;
>
> diff --git a/include/linux/pci.h b/include/linux/pci.h
> index c3248d5..fbfbb40 100644
> --- a/include/linux/pci.h
> +++ b/include/linux/pci.h
> @@ -1026,6 +1026,8 @@ static inline int pci_is_managed(struct pci_dev *pdev)
> int pcie_set_mps(struct pci_dev *dev, int mps);
> int pcie_get_minimum_link(struct pci_dev *dev, enum pci_bus_speed *speed,
> enum pcie_link_width *width);
> +int pcie_get_link(struct pci_dev *dev, enum pci_bus_speed *speed,
> + enum pcie_link_width *width);
> int __pci_reset_function(struct pci_dev *dev);
> int __pci_reset_function_locked(struct pci_dev *dev);
> int pci_reset_function(struct pci_dev *dev);
>
> --
> To unsubscribe from this list: send the line "unsubscribe linux-pci" in
> the body of a message to majordomo@vger.kernel.org
> More majordomo info at http://vger.kernel.org/majordomo-info.html
^ permalink raw reply
* [PATCH 2/2 nft] tests: py: missing range conversion in icmpv6
From: Pablo Neira Ayuso @ 2016-11-14 21:01 UTC (permalink / raw)
To: netfilter-devel
In-Reply-To: <1479157289-26503-1-git-send-email-pablo@netfilter.org>
Use range expression to negate ranges.
Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
---
tests/py/ip6/icmpv6.t.payload.ip6 | 3 +--
1 file changed, 1 insertion(+), 2 deletions(-)
diff --git a/tests/py/ip6/icmpv6.t.payload.ip6 b/tests/py/ip6/icmpv6.t.payload.ip6
index a00f392e9bb7..8d33249e49f3 100644
--- a/tests/py/ip6/icmpv6.t.payload.ip6
+++ b/tests/py/ip6/icmpv6.t.payload.ip6
@@ -389,8 +389,7 @@ ip6 test-ip6 input
[ payload load 1b @ network header + 6 => reg 1 ]
[ cmp eq reg 1 0x0000003a ]
[ payload load 2b @ transport header + 4 => reg 1 ]
- [ cmp lt reg 1 0x00002100 ]
- [ cmp gt reg 1 0x00002d00 ]
+ [ range neq reg 1 0x00002100 0x00002d00 ]
# icmpv6 max-delay {33, 55, 67, 88}
__set%d test-ip6 3
--
2.1.4
^ permalink raw reply related
* Re: [PATCH 5/5] PCI: Balance ports to avoid ACS errata on Pericom switches
From: Bjorn Helgaas @ 2016-11-14 21:03 UTC (permalink / raw)
To: Alex Williamson; +Cc: linux-pci, bhelgaas, iommu, linux-kernel
In-Reply-To: <20161026180140.23495.27388.stgit@gimli.home>
On Wed, Oct 26, 2016 at 12:01:40PM -0600, Alex Williamson wrote:
> As described in the included code comment, this quirk is intended to
> work around an errata in a variety of Pericom 4-lane, 3 and 4 port
> PCIe 2.0 switches. The switches advertise ACS capabilities, but the
> P2P Request Redirection support includes an errata that PCI_ACS_RR
> effectively doesn't work and results in transactions being queued and
> not delivered within the PCIe switch. The errata has no planned
> hardware fix.
Is there a published erratum we can reference here? It'd be really
nice to have a URL.
^ permalink raw reply
* [PATCH dtv-scan-tables] Rename pl-Krosno_Sucha_Gora with only ASCII characters
From: Thomas Petazzoni @ 2016-11-14 21:05 UTC (permalink / raw)
To: Olliver Schinagl, linux-media, Mauro Carvalho Chehab; +Cc: Thomas Petazzoni
The pl-Krosno_Sucha_Gora file, added in commit
4cb113fd15e562f0629000fcad9f41405595198d, is the only file that
contains non-ASCII characters in the tree. This causes a number of
build issues with other packages that don't necessarily handle very
well non-ASCII file name encodings.
Since no other file in the tree contain non-ASCII characters in their
name, this commit renames pl-Krosno_Sucha_Gora similarly.
Examples of files that are named with only ASCII characters even if
the city name really contains non-ASCII characters:
- pl-Wroclaw should be written pl-Wrocław
- se-Laxsjo should be written se-Laxsjö
- de-Dusseldorf should be written de-Düsseldorf
- vn-Thaibinh should be written vn-Thái_Bình
Since there is no real standardization on the encoding of file names,
we'd better be safe and use only ASCII characters.
Signed-off-by: Thomas Petazzoni <thomas.petazzoni@free-electrons.com>
---
"dvb-t/pl-Krosno_Sucha_G\303\263ra" => dvb-t/pl-Krosno_Sucha_Gora | 0
1 file changed, 0 insertions(+), 0 deletions(-)
rename "dvb-t/pl-Krosno_Sucha_G\303\263ra" => dvb-t/pl-Krosno_Sucha_Gora (100%)
diff --git "a/dvb-t/pl-Krosno_Sucha_G\303\263ra" b/dvb-t/pl-Krosno_Sucha_Gora
similarity index 100%
rename from "dvb-t/pl-Krosno_Sucha_G\303\263ra"
rename to dvb-t/pl-Krosno_Sucha_Gora
--
2.7.4
^ permalink raw reply
* [Intel-wired-lan] [next PATCH S53-V2 1/5] i40e: use unsigned printf format specifier for active_filters count
From: Bimmy Pujari @ 2016-11-14 21:06 UTC (permalink / raw)
To: intel-wired-lan
From: Jacob Keller <jacob.e.keller@intel.com>
Replace the %d specifier used for printing vsi->active_filters and
vsi->promisc_threshold with an unsigned %u format specifier. While it is
unlikely in practice that these values will ever reach such a large
number they are unsigned values and thus should not be interpreted as
negative numbers.
Signed-off-by: Jacob Keller <jacob.e.keller@intel.com>
Change-ID: Iff050fad5a1c8537c4c57fcd527441cd95cfc0d4
---
Testing-hints:
This should go upstream, even though it is in debugfs code. We're not
adding features but simply correcting output of existing features.
drivers/net/ethernet/intel/i40e/i40e_debugfs.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/drivers/net/ethernet/intel/i40e/i40e_debugfs.c b/drivers/net/ethernet/intel/i40e/i40e_debugfs.c
index b8a03a0..f1f41f1 100644
--- a/drivers/net/ethernet/intel/i40e/i40e_debugfs.c
+++ b/drivers/net/ethernet/intel/i40e/i40e_debugfs.c
@@ -172,7 +172,7 @@ static void i40e_dbg_dump_vsi_seid(struct i40e_pf *pf, int seid)
f->macaddr, f->vlan,
i40e_filter_state_string[f->state]);
}
- dev_info(&pf->pdev->dev, " active_filters %d, promisc_threshold %d, overflow promisc %s\n",
+ dev_info(&pf->pdev->dev, " active_filters %u, promisc_threshold %u, overflow promisc %s\n",
vsi->active_filters, vsi->promisc_threshold,
(test_bit(__I40E_FILTER_OVERFLOW_PROMISC, &vsi->state) ?
"ON" : "OFF"));
--
2.4.11
^ permalink raw reply related
* [Intel-wired-lan] [next PATCH S53-V2 2/5] i40e: Add support for 25G devices
From: Bimmy Pujari @ 2016-11-14 21:06 UTC (permalink / raw)
To: intel-wired-lan
In-Reply-To: <1479157609-30812-1-git-send-email-bimmy.pujari@intel.com>
From: Carolyn Wyborny <carolyn.wyborny@intel.com>
Add support for 25G devices - defines and data structures.
One tricky part here is that the firmware support for these
Devices introduces a mismatch between the PHY type enum and
the bitfields for the phy types.
This change creates a macro and uses it to increment the 25G
PHY values when creating 25G bitfields.
Signed-off-by: Carolyn Wyborny <carolyn.wyborny@intel.com>
Signed-off-by: Michal Kosiarz <michal.kosiarz@intel.com>
Signed-off-by: Eric Joyner <eric.joyner@intel.com>
Signed-off-by: Mitch Williams <mitch.a.williams@intel.com>
Signed-off-by: Henry Tieman <henry.w.tieman@intel.com>
Signed-off-by: Avinash Dayanand <avinash.dayanand@intel.com>
Change-ID: I69b24d837d44cf9220bf5cb8dd46c5be89ce490b
---
Testing Hints : Check that 25G devices link and report
correct device speed.
drivers/net/ethernet/intel/i40e/i40e_adminq_cmd.h | 30 +++++++-
drivers/net/ethernet/intel/i40e/i40e_common.c | 11 ++-
drivers/net/ethernet/intel/i40e/i40e_devids.h | 2 +
drivers/net/ethernet/intel/i40e/i40e_ethtool.c | 20 +++++-
drivers/net/ethernet/intel/i40e/i40e_main.c | 6 +-
drivers/net/ethernet/intel/i40e/i40e_type.h | 82 +++++++++++++---------
drivers/net/ethernet/intel/i40e/i40e_virtchnl_pf.c | 3 +
.../net/ethernet/intel/i40evf/i40e_adminq_cmd.h | 30 +++++++-
drivers/net/ethernet/intel/i40evf/i40e_common.c | 2 +
drivers/net/ethernet/intel/i40evf/i40e_devids.h | 2 +
drivers/net/ethernet/intel/i40evf/i40e_type.h | 82 +++++++++++++---------
drivers/net/ethernet/intel/i40evf/i40evf_ethtool.c | 8 +++
.../net/ethernet/intel/i40evf/i40evf_virtchnl.c | 3 +
13 files changed, 202 insertions(+), 79 deletions(-)
diff --git a/drivers/net/ethernet/intel/i40e/i40e_adminq_cmd.h b/drivers/net/ethernet/intel/i40e/i40e_adminq_cmd.h
index 67e396b..c9d1f91 100644
--- a/drivers/net/ethernet/intel/i40e/i40e_adminq_cmd.h
+++ b/drivers/net/ethernet/intel/i40e/i40e_adminq_cmd.h
@@ -1642,6 +1642,10 @@ enum i40e_aq_phy_type {
I40E_PHY_TYPE_1000BASE_LX = 0x1C,
I40E_PHY_TYPE_1000BASE_T_OPTICAL = 0x1D,
I40E_PHY_TYPE_20GBASE_KR2 = 0x1E,
+ I40E_PHY_TYPE_25GBASE_KR = 0x1F,
+ I40E_PHY_TYPE_25GBASE_CR = 0x20,
+ I40E_PHY_TYPE_25GBASE_SR = 0x21,
+ I40E_PHY_TYPE_25GBASE_LR = 0x22,
I40E_PHY_TYPE_MAX
};
@@ -1650,6 +1654,7 @@ enum i40e_aq_phy_type {
#define I40E_LINK_SPEED_10GB_SHIFT 0x3
#define I40E_LINK_SPEED_40GB_SHIFT 0x4
#define I40E_LINK_SPEED_20GB_SHIFT 0x5
+#define I40E_LINK_SPEED_25GB_SHIFT 0x6
enum i40e_aq_link_speed {
I40E_LINK_SPEED_UNKNOWN = 0,
@@ -1657,7 +1662,8 @@ enum i40e_aq_link_speed {
I40E_LINK_SPEED_1GB = BIT(I40E_LINK_SPEED_1000MB_SHIFT),
I40E_LINK_SPEED_10GB = BIT(I40E_LINK_SPEED_10GB_SHIFT),
I40E_LINK_SPEED_40GB = BIT(I40E_LINK_SPEED_40GB_SHIFT),
- I40E_LINK_SPEED_20GB = BIT(I40E_LINK_SPEED_20GB_SHIFT)
+ I40E_LINK_SPEED_20GB = BIT(I40E_LINK_SPEED_20GB_SHIFT),
+ I40E_LINK_SPEED_25GB = BIT(I40E_LINK_SPEED_25GB_SHIFT),
};
struct i40e_aqc_module_desc {
@@ -1690,7 +1696,13 @@ struct i40e_aq_get_phy_abilities_resp {
__le32 eeer_val;
u8 d3_lpan;
#define I40E_AQ_SET_PHY_D3_LPAN_ENA 0x01
- u8 reserved[3];
+ u8 phy_type_ext;
+#define I40E_AQ_PHY_TYPE_EXT_25G_KR 0X01
+#define I40E_AQ_PHY_TYPE_EXT_25G_CR 0X02
+#define I40E_AQ_PHY_TYPE_EXT_25G_SR 0x04
+#define I40E_AQ_PHY_TYPE_EXT_25G_LR 0x08
+ u8 mod_type_ext;
+ u8 ext_comp_code;
u8 phy_id[4];
u8 module_type[3];
u8 qualified_module_count;
@@ -1712,7 +1724,12 @@ struct i40e_aq_set_phy_config { /* same bits as above in all */
__le16 eee_capability;
__le32 eeer;
u8 low_power_ctrl;
- u8 reserved[3];
+ u8 phy_type_ext;
+#define I40E_AQ_PHY_TYPE_EXT_25G_KR 0X01
+#define I40E_AQ_PHY_TYPE_EXT_25G_CR 0X02
+#define I40E_AQ_PHY_TYPE_EXT_25G_SR 0x04
+#define I40E_AQ_PHY_TYPE_EXT_25G_LR 0x08
+ u8 reserved[2];
};
I40E_CHECK_CMD_LENGTH(i40e_aq_set_phy_config);
@@ -1792,6 +1809,13 @@ struct i40e_aqc_get_link_status {
#define I40E_AQ_LINK_TX_DRAINED 0x01
#define I40E_AQ_LINK_TX_FLUSHED 0x03
#define I40E_AQ_LINK_FORCED_40G 0x10
+/* 25G Error Codes */
+#define I40E_AQ_25G_NO_ERR 0X00
+#define I40E_AQ_25G_NOT_PRESENT 0X01
+#define I40E_AQ_25G_NVM_CRC_ERR 0X02
+#define I40E_AQ_25G_SBUS_UCODE_ERR 0X03
+#define I40E_AQ_25G_SERDES_UCODE_ERR 0X04
+#define I40E_AQ_25G_NIMB_UCODE_ERR 0X05
u8 loopback; /* use defines from i40e_aqc_set_lb_mode */
__le16 max_frame_size;
u8 config;
diff --git a/drivers/net/ethernet/intel/i40e/i40e_common.c b/drivers/net/ethernet/intel/i40e/i40e_common.c
index d1dcd4f..3961fc2 100644
--- a/drivers/net/ethernet/intel/i40e/i40e_common.c
+++ b/drivers/net/ethernet/intel/i40e/i40e_common.c
@@ -53,6 +53,8 @@ static i40e_status i40e_set_mac_type(struct i40e_hw *hw)
case I40E_DEV_ID_10G_BASE_T4:
case I40E_DEV_ID_20G_KR2:
case I40E_DEV_ID_20G_KR2_A:
+ case I40E_DEV_ID_25G_B:
+ case I40E_DEV_ID_25G_SFP28:
hw->mac.type = I40E_MAC_XL710;
break;
case I40E_DEV_ID_KX_X722:
@@ -1183,6 +1185,8 @@ static enum i40e_media_type i40e_get_media_type(struct i40e_hw *hw)
case I40E_PHY_TYPE_1000BASE_LX:
case I40E_PHY_TYPE_40GBASE_SR4:
case I40E_PHY_TYPE_40GBASE_LR4:
+ case I40E_PHY_TYPE_25GBASE_LR:
+ case I40E_PHY_TYPE_25GBASE_SR:
media = I40E_MEDIA_TYPE_FIBER;
break;
case I40E_PHY_TYPE_100BASE_TX:
@@ -1197,6 +1201,7 @@ static enum i40e_media_type i40e_get_media_type(struct i40e_hw *hw)
case I40E_PHY_TYPE_10GBASE_SFPP_CU:
case I40E_PHY_TYPE_40GBASE_AOC:
case I40E_PHY_TYPE_10GBASE_AOC:
+ case I40E_PHY_TYPE_25GBASE_CR:
media = I40E_MEDIA_TYPE_DA;
break;
case I40E_PHY_TYPE_1000BASE_KX:
@@ -1204,6 +1209,7 @@ static enum i40e_media_type i40e_get_media_type(struct i40e_hw *hw)
case I40E_PHY_TYPE_10GBASE_KR:
case I40E_PHY_TYPE_40GBASE_KR4:
case I40E_PHY_TYPE_20GBASE_KR2:
+ case I40E_PHY_TYPE_25GBASE_KR:
media = I40E_MEDIA_TYPE_BACKPLANE;
break;
case I40E_PHY_TYPE_SGMII:
@@ -1608,8 +1614,10 @@ i40e_status i40e_aq_get_phy_capabilities(struct i40e_hw *hw,
if (hw->aq.asq_last_status == I40E_AQ_RC_EIO)
status = I40E_ERR_UNKNOWN_PHY;
- if (report_init)
+ if (report_init) {
hw->phy.phy_types = le32_to_cpu(abilities->phy_type);
+ hw->phy.phy_types |= ((u64)abilities->phy_type_ext << 32);
+ }
return status;
}
@@ -1701,6 +1709,7 @@ enum i40e_status_code i40e_set_fc(struct i40e_hw *hw, u8 *aq_failures,
config.abilities |= I40E_AQ_PHY_ENABLE_ATOMIC_LINK;
/* Copy over all the old settings */
config.phy_type = abilities.phy_type;
+ config.phy_type_ext = abilities.phy_type_ext;
config.link_speed = abilities.link_speed;
config.eee_capability = abilities.eee_capability;
config.eeer = abilities.eeer_val;
diff --git a/drivers/net/ethernet/intel/i40e/i40e_devids.h b/drivers/net/ethernet/intel/i40e/i40e_devids.h
index dd4457d..8e46098 100644
--- a/drivers/net/ethernet/intel/i40e/i40e_devids.h
+++ b/drivers/net/ethernet/intel/i40e/i40e_devids.h
@@ -39,6 +39,8 @@
#define I40E_DEV_ID_20G_KR2 0x1587
#define I40E_DEV_ID_20G_KR2_A 0x1588
#define I40E_DEV_ID_10G_BASE_T4 0x1589
+#define I40E_DEV_ID_25G_B 0x158A
+#define I40E_DEV_ID_25G_SFP28 0x158B
#define I40E_DEV_ID_KX_X722 0x37CE
#define I40E_DEV_ID_QSFP_X722 0x37CF
#define I40E_DEV_ID_SFP_X722 0x37D0
diff --git a/drivers/net/ethernet/intel/i40e/i40e_ethtool.c b/drivers/net/ethernet/intel/i40e/i40e_ethtool.c
index 6ba0035..4b3a71a 100644
--- a/drivers/net/ethernet/intel/i40e/i40e_ethtool.c
+++ b/drivers/net/ethernet/intel/i40e/i40e_ethtool.c
@@ -265,8 +265,9 @@ static void i40e_partition_setting_complaint(struct i40e_pf *pf)
static void i40e_phy_type_to_ethtool(struct i40e_pf *pf, u32 *supported,
u32 *advertising)
{
- enum i40e_aq_capabilities_phy_type phy_types = pf->hw.phy.phy_types;
struct i40e_link_status *hw_link_info = &pf->hw.phy.link_info;
+ u64 phy_types = pf->hw.phy.phy_types;
+
*supported = 0x0;
*advertising = 0x0;
@@ -369,6 +370,15 @@ static void i40e_phy_type_to_ethtool(struct i40e_pf *pf, u32 *supported,
if (!(pf->flags & I40E_FLAG_HAVE_CRT_RETIMER))
*advertising |= ADVERTISED_1000baseKX_Full;
}
+ if (phy_types & I40E_CAP_PHY_TYPE_25GBASE_KR ||
+ phy_types & I40E_CAP_PHY_TYPE_25GBASE_CR ||
+ phy_types & I40E_CAP_PHY_TYPE_25GBASE_SR ||
+ phy_types & I40E_CAP_PHY_TYPE_25GBASE_LR) {
+ *supported |= SUPPORTED_Autoneg |
+ SUPPORTED_2500baseX_Full;
+ *advertising |= ADVERTISED_Autoneg |
+ ADVERTISED_2500baseX_Full;
+ }
}
/**
@@ -491,6 +501,14 @@ static void i40e_get_settings_link_up(struct i40e_hw *hw,
ADVERTISED_1000baseKX_Full |
ADVERTISED_Autoneg;
break;
+ case I40E_PHY_TYPE_25GBASE_KR:
+ case I40E_PHY_TYPE_25GBASE_CR:
+ case I40E_PHY_TYPE_25GBASE_SR:
+ case I40E_PHY_TYPE_25GBASE_LR:
+ ecmd->supported |= SUPPORTED_2500baseX_Full |
+ SUPPORTED_Autoneg;
+ ecmd->advertising |= ADVERTISED_2500baseX_Full |
+ ADVERTISED_Autoneg;
default:
/* if we got here and link is up something bad is afoot */
netdev_info(netdev, "WARNING: Link is up but PHY type 0x%x is not recognized.\n",
diff --git a/drivers/net/ethernet/intel/i40e/i40e_main.c b/drivers/net/ethernet/intel/i40e/i40e_main.c
index a032dfd..849feaa 100644
--- a/drivers/net/ethernet/intel/i40e/i40e_main.c
+++ b/drivers/net/ethernet/intel/i40e/i40e_main.c
@@ -86,6 +86,8 @@ static const struct pci_device_id i40e_pci_tbl[] = {
{PCI_VDEVICE(INTEL, I40E_DEV_ID_SFP_I_X722), 0},
{PCI_VDEVICE(INTEL, I40E_DEV_ID_20G_KR2), 0},
{PCI_VDEVICE(INTEL, I40E_DEV_ID_20G_KR2_A), 0},
+ {PCI_VDEVICE(INTEL, I40E_DEV_ID_25G_B), 0},
+ {PCI_VDEVICE(INTEL, I40E_DEV_ID_25G_SFP28), 0},
/* required last entry */
{0, }
};
@@ -5248,6 +5250,9 @@ void i40e_print_link_message(struct i40e_vsi *vsi, bool isup)
case I40E_LINK_SPEED_20GB:
speed = "20 G";
break;
+ case I40E_LINK_SPEED_25GB:
+ speed = "25 G";
+ break;
case I40E_LINK_SPEED_10GB:
speed = "10 G";
break;
@@ -11356,7 +11361,6 @@ static int i40e_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
dev_dbg(&pf->pdev->dev, "get supported phy types ret = %s last_status = %s\n",
i40e_stat_str(&pf->hw, err),
i40e_aq_str(&pf->hw, pf->hw.aq.asq_last_status));
- pf->hw.phy.phy_types = le32_to_cpu(abilities.phy_type);
/* Add a filter to drop all Flow control frames from any VSI from being
* transmitted. By doing so we stop a malicious VF from sending out
diff --git a/drivers/net/ethernet/intel/i40e/i40e_type.h b/drivers/net/ethernet/intel/i40e/i40e_type.h
index e02cb73..7272be3 100644
--- a/drivers/net/ethernet/intel/i40e/i40e_type.h
+++ b/drivers/net/ethernet/intel/i40e/i40e_type.h
@@ -213,47 +213,59 @@ struct i40e_link_status {
#define I40E_MODULE_TYPE_1000BASE_T 0x08
};
-enum i40e_aq_capabilities_phy_type {
- I40E_CAP_PHY_TYPE_SGMII = BIT(I40E_PHY_TYPE_SGMII),
- I40E_CAP_PHY_TYPE_1000BASE_KX = BIT(I40E_PHY_TYPE_1000BASE_KX),
- I40E_CAP_PHY_TYPE_10GBASE_KX4 = BIT(I40E_PHY_TYPE_10GBASE_KX4),
- I40E_CAP_PHY_TYPE_10GBASE_KR = BIT(I40E_PHY_TYPE_10GBASE_KR),
- I40E_CAP_PHY_TYPE_40GBASE_KR4 = BIT(I40E_PHY_TYPE_40GBASE_KR4),
- I40E_CAP_PHY_TYPE_XAUI = BIT(I40E_PHY_TYPE_XAUI),
- I40E_CAP_PHY_TYPE_XFI = BIT(I40E_PHY_TYPE_XFI),
- I40E_CAP_PHY_TYPE_SFI = BIT(I40E_PHY_TYPE_SFI),
- I40E_CAP_PHY_TYPE_XLAUI = BIT(I40E_PHY_TYPE_XLAUI),
- I40E_CAP_PHY_TYPE_XLPPI = BIT(I40E_PHY_TYPE_XLPPI),
- I40E_CAP_PHY_TYPE_40GBASE_CR4_CU = BIT(I40E_PHY_TYPE_40GBASE_CR4_CU),
- I40E_CAP_PHY_TYPE_10GBASE_CR1_CU = BIT(I40E_PHY_TYPE_10GBASE_CR1_CU),
- I40E_CAP_PHY_TYPE_10GBASE_AOC = BIT(I40E_PHY_TYPE_10GBASE_AOC),
- I40E_CAP_PHY_TYPE_40GBASE_AOC = BIT(I40E_PHY_TYPE_40GBASE_AOC),
- I40E_CAP_PHY_TYPE_100BASE_TX = BIT(I40E_PHY_TYPE_100BASE_TX),
- I40E_CAP_PHY_TYPE_1000BASE_T = BIT(I40E_PHY_TYPE_1000BASE_T),
- I40E_CAP_PHY_TYPE_10GBASE_T = BIT(I40E_PHY_TYPE_10GBASE_T),
- I40E_CAP_PHY_TYPE_10GBASE_SR = BIT(I40E_PHY_TYPE_10GBASE_SR),
- I40E_CAP_PHY_TYPE_10GBASE_LR = BIT(I40E_PHY_TYPE_10GBASE_LR),
- I40E_CAP_PHY_TYPE_10GBASE_SFPP_CU = BIT(I40E_PHY_TYPE_10GBASE_SFPP_CU),
- I40E_CAP_PHY_TYPE_10GBASE_CR1 = BIT(I40E_PHY_TYPE_10GBASE_CR1),
- I40E_CAP_PHY_TYPE_40GBASE_CR4 = BIT(I40E_PHY_TYPE_40GBASE_CR4),
- I40E_CAP_PHY_TYPE_40GBASE_SR4 = BIT(I40E_PHY_TYPE_40GBASE_SR4),
- I40E_CAP_PHY_TYPE_40GBASE_LR4 = BIT(I40E_PHY_TYPE_40GBASE_LR4),
- I40E_CAP_PHY_TYPE_1000BASE_SX = BIT(I40E_PHY_TYPE_1000BASE_SX),
- I40E_CAP_PHY_TYPE_1000BASE_LX = BIT(I40E_PHY_TYPE_1000BASE_LX),
- I40E_CAP_PHY_TYPE_1000BASE_T_OPTICAL =
- BIT(I40E_PHY_TYPE_1000BASE_T_OPTICAL),
- I40E_CAP_PHY_TYPE_20GBASE_KR2 = BIT(I40E_PHY_TYPE_20GBASE_KR2)
-};
-
struct i40e_phy_info {
struct i40e_link_status link_info;
struct i40e_link_status link_info_old;
bool get_link_info;
enum i40e_media_type media_type;
/* all the phy types the NVM is capable of */
- enum i40e_aq_capabilities_phy_type phy_types;
-};
-
+ u64 phy_types;
+};
+
+#define I40E_CAP_PHY_TYPE_SGMII BIT_ULL(I40E_PHY_TYPE_SGMII)
+#define I40E_CAP_PHY_TYPE_1000BASE_KX BIT_ULL(I40E_PHY_TYPE_1000BASE_KX)
+#define I40E_CAP_PHY_TYPE_10GBASE_KX4 BIT_ULL(I40E_PHY_TYPE_10GBASE_KX4)
+#define I40E_CAP_PHY_TYPE_10GBASE_KR BIT_ULL(I40E_PHY_TYPE_10GBASE_KR)
+#define I40E_CAP_PHY_TYPE_40GBASE_KR4 BIT_ULL(I40E_PHY_TYPE_40GBASE_KR4)
+#define I40E_CAP_PHY_TYPE_XAUI BIT_ULL(I40E_PHY_TYPE_XAUI)
+#define I40E_CAP_PHY_TYPE_XFI BIT_ULL(I40E_PHY_TYPE_XFI)
+#define I40E_CAP_PHY_TYPE_SFI BIT_ULL(I40E_PHY_TYPE_SFI)
+#define I40E_CAP_PHY_TYPE_XLAUI BIT_ULL(I40E_PHY_TYPE_XLAUI)
+#define I40E_CAP_PHY_TYPE_XLPPI BIT_ULL(I40E_PHY_TYPE_XLPPI)
+#define I40E_CAP_PHY_TYPE_40GBASE_CR4_CU BIT_ULL(I40E_PHY_TYPE_40GBASE_CR4_CU)
+#define I40E_CAP_PHY_TYPE_10GBASE_CR1_CU BIT_ULL(I40E_PHY_TYPE_10GBASE_CR1_CU)
+#define I40E_CAP_PHY_TYPE_10GBASE_AOC BIT_ULL(I40E_PHY_TYPE_10GBASE_AOC)
+#define I40E_CAP_PHY_TYPE_40GBASE_AOC BIT_ULL(I40E_PHY_TYPE_40GBASE_AOC)
+#define I40E_CAP_PHY_TYPE_100BASE_TX BIT_ULL(I40E_PHY_TYPE_100BASE_TX)
+#define I40E_CAP_PHY_TYPE_1000BASE_T BIT_ULL(I40E_PHY_TYPE_1000BASE_T)
+#define I40E_CAP_PHY_TYPE_10GBASE_T BIT_ULL(I40E_PHY_TYPE_10GBASE_T)
+#define I40E_CAP_PHY_TYPE_10GBASE_SR BIT_ULL(I40E_PHY_TYPE_10GBASE_SR)
+#define I40E_CAP_PHY_TYPE_10GBASE_LR BIT_ULL(I40E_PHY_TYPE_10GBASE_LR)
+#define I40E_CAP_PHY_TYPE_10GBASE_SFPP_CU BIT_ULL(I40E_PHY_TYPE_10GBASE_SFPP_CU)
+#define I40E_CAP_PHY_TYPE_10GBASE_CR1 BIT_ULL(I40E_PHY_TYPE_10GBASE_CR1)
+#define I40E_CAP_PHY_TYPE_40GBASE_CR4 BIT_ULL(I40E_PHY_TYPE_40GBASE_CR4)
+#define I40E_CAP_PHY_TYPE_40GBASE_SR4 BIT_ULL(I40E_PHY_TYPE_40GBASE_SR4)
+#define I40E_CAP_PHY_TYPE_40GBASE_LR4 BIT_ULL(I40E_PHY_TYPE_40GBASE_LR4)
+#define I40E_CAP_PHY_TYPE_1000BASE_SX BIT_ULL(I40E_PHY_TYPE_1000BASE_SX)
+#define I40E_CAP_PHY_TYPE_1000BASE_LX BIT_ULL(I40E_PHY_TYPE_1000BASE_LX)
+#define I40E_CAP_PHY_TYPE_1000BASE_T_OPTICAL \
+ BIT_ULL(I40E_PHY_TYPE_1000BASE_T_OPTICAL)
+#define I40E_CAP_PHY_TYPE_20GBASE_KR2 BIT_ULL(I40E_PHY_TYPE_20GBASE_KR2)
+/* Defining the macro I40E_TYPE_OFFSET to implement a bit shift for some
+ * PHY types. There is an unused bit (31) in the I40E_CAP_PHY_TYPE_* bit
+ * fields but no corresponding gap in the i40e_aq_phy_type enumeration. So,
+ * a shift is needed to adjust for this with values larger than 31. The
+ * only affected values are I40E_PHY_TYPE_25GBASE_*.
+ */
+#define I40E_PHY_TYPE_OFFSET 1
+#define I40E_CAP_PHY_TYPE_25GBASE_KR BIT_ULL(I40E_PHY_TYPE_25GBASE_KR + \
+ I40E_PHY_TYPE_OFFSET)
+#define I40E_CAP_PHY_TYPE_25GBASE_CR BIT_ULL(I40E_PHY_TYPE_25GBASE_CR + \
+ I40E_PHY_TYPE_OFFSET)
+#define I40E_CAP_PHY_TYPE_25GBASE_SR BIT_ULL(I40E_PHY_TYPE_25GBASE_SR + \
+ I40E_PHY_TYPE_OFFSET)
+#define I40E_CAP_PHY_TYPE_25GBASE_LR BIT_ULL(I40E_PHY_TYPE_25GBASE_LR + \
+ I40E_PHY_TYPE_OFFSET)
#define I40E_HW_CAP_MAX_GPIO 30
/* Capabilities of a PF or a VF or the whole device */
struct i40e_hw_capabilities {
diff --git a/drivers/net/ethernet/intel/i40e/i40e_virtchnl_pf.c b/drivers/net/ethernet/intel/i40e/i40e_virtchnl_pf.c
index 05ed49b..d28b684 100644
--- a/drivers/net/ethernet/intel/i40e/i40e_virtchnl_pf.c
+++ b/drivers/net/ethernet/intel/i40e/i40e_virtchnl_pf.c
@@ -2921,6 +2921,9 @@ int i40e_ndo_set_vf_bw(struct net_device *netdev, int vf_id, int min_tx_rate,
case I40E_LINK_SPEED_40GB:
speed = 40000;
break;
+ case I40E_LINK_SPEED_25GB:
+ speed = 25000;
+ break;
case I40E_LINK_SPEED_20GB:
speed = 20000;
break;
diff --git a/drivers/net/ethernet/intel/i40evf/i40e_adminq_cmd.h b/drivers/net/ethernet/intel/i40evf/i40e_adminq_cmd.h
index 40b0eaf..f8d7d95 100644
--- a/drivers/net/ethernet/intel/i40evf/i40e_adminq_cmd.h
+++ b/drivers/net/ethernet/intel/i40evf/i40e_adminq_cmd.h
@@ -1639,6 +1639,10 @@ enum i40e_aq_phy_type {
I40E_PHY_TYPE_1000BASE_LX = 0x1C,
I40E_PHY_TYPE_1000BASE_T_OPTICAL = 0x1D,
I40E_PHY_TYPE_20GBASE_KR2 = 0x1E,
+ I40E_PHY_TYPE_25GBASE_KR = 0x1F,
+ I40E_PHY_TYPE_25GBASE_CR = 0x20,
+ I40E_PHY_TYPE_25GBASE_SR = 0x21,
+ I40E_PHY_TYPE_25GBASE_LR = 0x22,
I40E_PHY_TYPE_MAX
};
@@ -1647,6 +1651,7 @@ enum i40e_aq_phy_type {
#define I40E_LINK_SPEED_10GB_SHIFT 0x3
#define I40E_LINK_SPEED_40GB_SHIFT 0x4
#define I40E_LINK_SPEED_20GB_SHIFT 0x5
+#define I40E_LINK_SPEED_25GB_SHIFT 0x6
enum i40e_aq_link_speed {
I40E_LINK_SPEED_UNKNOWN = 0,
@@ -1654,7 +1659,8 @@ enum i40e_aq_link_speed {
I40E_LINK_SPEED_1GB = BIT(I40E_LINK_SPEED_1000MB_SHIFT),
I40E_LINK_SPEED_10GB = BIT(I40E_LINK_SPEED_10GB_SHIFT),
I40E_LINK_SPEED_40GB = BIT(I40E_LINK_SPEED_40GB_SHIFT),
- I40E_LINK_SPEED_20GB = BIT(I40E_LINK_SPEED_20GB_SHIFT)
+ I40E_LINK_SPEED_20GB = BIT(I40E_LINK_SPEED_20GB_SHIFT),
+ I40E_LINK_SPEED_25GB = BIT(I40E_LINK_SPEED_25GB_SHIFT),
};
struct i40e_aqc_module_desc {
@@ -1687,7 +1693,13 @@ struct i40e_aq_get_phy_abilities_resp {
__le32 eeer_val;
u8 d3_lpan;
#define I40E_AQ_SET_PHY_D3_LPAN_ENA 0x01
- u8 reserved[3];
+ u8 phy_type_ext;
+#define I40E_AQ_PHY_TYPE_EXT_25G_KR 0X01
+#define I40E_AQ_PHY_TYPE_EXT_25G_CR 0X02
+#define I40E_AQ_PHY_TYPE_EXT_25G_SR 0x04
+#define I40E_AQ_PHY_TYPE_EXT_25G_LR 0x08
+ u8 mod_type_ext;
+ u8 ext_comp_code;
u8 phy_id[4];
u8 module_type[3];
u8 qualified_module_count;
@@ -1709,7 +1721,12 @@ struct i40e_aq_set_phy_config { /* same bits as above in all */
__le16 eee_capability;
__le32 eeer;
u8 low_power_ctrl;
- u8 reserved[3];
+ u8 phy_type_ext;
+#define I40E_AQ_PHY_TYPE_EXT_25G_KR 0X01
+#define I40E_AQ_PHY_TYPE_EXT_25G_CR 0X02
+#define I40E_AQ_PHY_TYPE_EXT_25G_SR 0x04
+#define I40E_AQ_PHY_TYPE_EXT_25G_LR 0x08
+ u8 reserved[2];
};
I40E_CHECK_CMD_LENGTH(i40e_aq_set_phy_config);
@@ -1789,6 +1806,13 @@ struct i40e_aqc_get_link_status {
#define I40E_AQ_LINK_TX_DRAINED 0x01
#define I40E_AQ_LINK_TX_FLUSHED 0x03
#define I40E_AQ_LINK_FORCED_40G 0x10
+/* 25G Error Codes */
+#define I40E_AQ_25G_NO_ERR 0X00
+#define I40E_AQ_25G_NOT_PRESENT 0X01
+#define I40E_AQ_25G_NVM_CRC_ERR 0X02
+#define I40E_AQ_25G_SBUS_UCODE_ERR 0X03
+#define I40E_AQ_25G_SERDES_UCODE_ERR 0X04
+#define I40E_AQ_25G_NIMB_UCODE_ERR 0X05
u8 loopback; /* use defines from i40e_aqc_set_lb_mode */
__le16 max_frame_size;
u8 config;
diff --git a/drivers/net/ethernet/intel/i40evf/i40e_common.c b/drivers/net/ethernet/intel/i40evf/i40e_common.c
index 7953c13..aa63b7f 100644
--- a/drivers/net/ethernet/intel/i40evf/i40e_common.c
+++ b/drivers/net/ethernet/intel/i40evf/i40e_common.c
@@ -53,6 +53,8 @@ i40e_status i40e_set_mac_type(struct i40e_hw *hw)
case I40E_DEV_ID_10G_BASE_T4:
case I40E_DEV_ID_20G_KR2:
case I40E_DEV_ID_20G_KR2_A:
+ case I40E_DEV_ID_25G_B:
+ case I40E_DEV_ID_25G_SFP28:
hw->mac.type = I40E_MAC_XL710;
break;
case I40E_DEV_ID_SFP_X722:
diff --git a/drivers/net/ethernet/intel/i40evf/i40e_devids.h b/drivers/net/ethernet/intel/i40evf/i40e_devids.h
index 7023570..21dcaee 100644
--- a/drivers/net/ethernet/intel/i40evf/i40e_devids.h
+++ b/drivers/net/ethernet/intel/i40evf/i40e_devids.h
@@ -39,6 +39,8 @@
#define I40E_DEV_ID_20G_KR2 0x1587
#define I40E_DEV_ID_20G_KR2_A 0x1588
#define I40E_DEV_ID_10G_BASE_T4 0x1589
+#define I40E_DEV_ID_25G_B 0x158A
+#define I40E_DEV_ID_25G_SFP28 0x158B
#define I40E_DEV_ID_VF 0x154C
#define I40E_DEV_ID_VF_HV 0x1571
#define I40E_DEV_ID_SFP_X722 0x37D0
diff --git a/drivers/net/ethernet/intel/i40evf/i40e_type.h b/drivers/net/ethernet/intel/i40evf/i40e_type.h
index 515484c..c85e8a3 100644
--- a/drivers/net/ethernet/intel/i40evf/i40e_type.h
+++ b/drivers/net/ethernet/intel/i40evf/i40e_type.h
@@ -187,47 +187,59 @@ struct i40e_link_status {
#define I40E_MODULE_TYPE_1000BASE_T 0x08
};
-enum i40e_aq_capabilities_phy_type {
- I40E_CAP_PHY_TYPE_SGMII = BIT(I40E_PHY_TYPE_SGMII),
- I40E_CAP_PHY_TYPE_1000BASE_KX = BIT(I40E_PHY_TYPE_1000BASE_KX),
- I40E_CAP_PHY_TYPE_10GBASE_KX4 = BIT(I40E_PHY_TYPE_10GBASE_KX4),
- I40E_CAP_PHY_TYPE_10GBASE_KR = BIT(I40E_PHY_TYPE_10GBASE_KR),
- I40E_CAP_PHY_TYPE_40GBASE_KR4 = BIT(I40E_PHY_TYPE_40GBASE_KR4),
- I40E_CAP_PHY_TYPE_XAUI = BIT(I40E_PHY_TYPE_XAUI),
- I40E_CAP_PHY_TYPE_XFI = BIT(I40E_PHY_TYPE_XFI),
- I40E_CAP_PHY_TYPE_SFI = BIT(I40E_PHY_TYPE_SFI),
- I40E_CAP_PHY_TYPE_XLAUI = BIT(I40E_PHY_TYPE_XLAUI),
- I40E_CAP_PHY_TYPE_XLPPI = BIT(I40E_PHY_TYPE_XLPPI),
- I40E_CAP_PHY_TYPE_40GBASE_CR4_CU = BIT(I40E_PHY_TYPE_40GBASE_CR4_CU),
- I40E_CAP_PHY_TYPE_10GBASE_CR1_CU = BIT(I40E_PHY_TYPE_10GBASE_CR1_CU),
- I40E_CAP_PHY_TYPE_10GBASE_AOC = BIT(I40E_PHY_TYPE_10GBASE_AOC),
- I40E_CAP_PHY_TYPE_40GBASE_AOC = BIT(I40E_PHY_TYPE_40GBASE_AOC),
- I40E_CAP_PHY_TYPE_100BASE_TX = BIT(I40E_PHY_TYPE_100BASE_TX),
- I40E_CAP_PHY_TYPE_1000BASE_T = BIT(I40E_PHY_TYPE_1000BASE_T),
- I40E_CAP_PHY_TYPE_10GBASE_T = BIT(I40E_PHY_TYPE_10GBASE_T),
- I40E_CAP_PHY_TYPE_10GBASE_SR = BIT(I40E_PHY_TYPE_10GBASE_SR),
- I40E_CAP_PHY_TYPE_10GBASE_LR = BIT(I40E_PHY_TYPE_10GBASE_LR),
- I40E_CAP_PHY_TYPE_10GBASE_SFPP_CU = BIT(I40E_PHY_TYPE_10GBASE_SFPP_CU),
- I40E_CAP_PHY_TYPE_10GBASE_CR1 = BIT(I40E_PHY_TYPE_10GBASE_CR1),
- I40E_CAP_PHY_TYPE_40GBASE_CR4 = BIT(I40E_PHY_TYPE_40GBASE_CR4),
- I40E_CAP_PHY_TYPE_40GBASE_SR4 = BIT(I40E_PHY_TYPE_40GBASE_SR4),
- I40E_CAP_PHY_TYPE_40GBASE_LR4 = BIT(I40E_PHY_TYPE_40GBASE_LR4),
- I40E_CAP_PHY_TYPE_1000BASE_SX = BIT(I40E_PHY_TYPE_1000BASE_SX),
- I40E_CAP_PHY_TYPE_1000BASE_LX = BIT(I40E_PHY_TYPE_1000BASE_LX),
- I40E_CAP_PHY_TYPE_1000BASE_T_OPTICAL =
- BIT(I40E_PHY_TYPE_1000BASE_T_OPTICAL),
- I40E_CAP_PHY_TYPE_20GBASE_KR2 = BIT(I40E_PHY_TYPE_20GBASE_KR2)
-};
-
struct i40e_phy_info {
struct i40e_link_status link_info;
struct i40e_link_status link_info_old;
bool get_link_info;
enum i40e_media_type media_type;
/* all the phy types the NVM is capable of */
- enum i40e_aq_capabilities_phy_type phy_types;
-};
-
+ u64 phy_types;
+};
+
+#define I40E_CAP_PHY_TYPE_SGMII BIT_ULL(I40E_PHY_TYPE_SGMII)
+#define I40E_CAP_PHY_TYPE_1000BASE_KX BIT_ULL(I40E_PHY_TYPE_1000BASE_KX)
+#define I40E_CAP_PHY_TYPE_10GBASE_KX4 BIT_ULL(I40E_PHY_TYPE_10GBASE_KX4)
+#define I40E_CAP_PHY_TYPE_10GBASE_KR BIT_ULL(I40E_PHY_TYPE_10GBASE_KR)
+#define I40E_CAP_PHY_TYPE_40GBASE_KR4 BIT_ULL(I40E_PHY_TYPE_40GBASE_KR4)
+#define I40E_CAP_PHY_TYPE_XAUI BIT_ULL(I40E_PHY_TYPE_XAUI)
+#define I40E_CAP_PHY_TYPE_XFI BIT_ULL(I40E_PHY_TYPE_XFI)
+#define I40E_CAP_PHY_TYPE_SFI BIT_ULL(I40E_PHY_TYPE_SFI)
+#define I40E_CAP_PHY_TYPE_XLAUI BIT_ULL(I40E_PHY_TYPE_XLAUI)
+#define I40E_CAP_PHY_TYPE_XLPPI BIT_ULL(I40E_PHY_TYPE_XLPPI)
+#define I40E_CAP_PHY_TYPE_40GBASE_CR4_CU BIT_ULL(I40E_PHY_TYPE_40GBASE_CR4_CU)
+#define I40E_CAP_PHY_TYPE_10GBASE_CR1_CU BIT_ULL(I40E_PHY_TYPE_10GBASE_CR1_CU)
+#define I40E_CAP_PHY_TYPE_10GBASE_AOC BIT_ULL(I40E_PHY_TYPE_10GBASE_AOC)
+#define I40E_CAP_PHY_TYPE_40GBASE_AOC BIT_ULL(I40E_PHY_TYPE_40GBASE_AOC)
+#define I40E_CAP_PHY_TYPE_100BASE_TX BIT_ULL(I40E_PHY_TYPE_100BASE_TX)
+#define I40E_CAP_PHY_TYPE_1000BASE_T BIT_ULL(I40E_PHY_TYPE_1000BASE_T)
+#define I40E_CAP_PHY_TYPE_10GBASE_T BIT_ULL(I40E_PHY_TYPE_10GBASE_T)
+#define I40E_CAP_PHY_TYPE_10GBASE_SR BIT_ULL(I40E_PHY_TYPE_10GBASE_SR)
+#define I40E_CAP_PHY_TYPE_10GBASE_LR BIT_ULL(I40E_PHY_TYPE_10GBASE_LR)
+#define I40E_CAP_PHY_TYPE_10GBASE_SFPP_CU BIT_ULL(I40E_PHY_TYPE_10GBASE_SFPP_CU)
+#define I40E_CAP_PHY_TYPE_10GBASE_CR1 BIT_ULL(I40E_PHY_TYPE_10GBASE_CR1)
+#define I40E_CAP_PHY_TYPE_40GBASE_CR4 BIT_ULL(I40E_PHY_TYPE_40GBASE_CR4)
+#define I40E_CAP_PHY_TYPE_40GBASE_SR4 BIT_ULL(I40E_PHY_TYPE_40GBASE_SR4)
+#define I40E_CAP_PHY_TYPE_40GBASE_LR4 BIT_ULL(I40E_PHY_TYPE_40GBASE_LR4)
+#define I40E_CAP_PHY_TYPE_1000BASE_SX BIT_ULL(I40E_PHY_TYPE_1000BASE_SX)
+#define I40E_CAP_PHY_TYPE_1000BASE_LX BIT_ULL(I40E_PHY_TYPE_1000BASE_LX)
+#define I40E_CAP_PHY_TYPE_1000BASE_T_OPTICAL \
+ BIT_ULL(I40E_PHY_TYPE_1000BASE_T_OPTICAL)
+#define I40E_CAP_PHY_TYPE_20GBASE_KR2 BIT_ULL(I40E_PHY_TYPE_20GBASE_KR2)
+/* Defining the macro I40E_TYPE_OFFSET to implement a bit shift for some
+ * PHY types. There is an unused bit (31) in the I40E_CAP_PHY_TYPE_* bit
+ * fields but no corresponding gap in the i40e_aq_phy_type enumeration. So,
+ * a shift is needed to adjust for this with values larger than 31. The
+ * only affected values are I40E_PHY_TYPE_25GBASE_*.
+ */
+#define I40E_PHY_TYPE_OFFSET 1
+#define I40E_CAP_PHY_TYPE_25GBASE_KR BIT_ULL(I40E_PHY_TYPE_25GBASE_KR + \
+ I40E_PHY_TYPE_OFFSET)
+#define I40E_CAP_PHY_TYPE_25GBASE_CR BIT_ULL(I40E_PHY_TYPE_25GBASE_CR + \
+ I40E_PHY_TYPE_OFFSET)
+#define I40E_CAP_PHY_TYPE_25GBASE_SR BIT_ULL(I40E_PHY_TYPE_25GBASE_SR + \
+ I40E_PHY_TYPE_OFFSET)
+#define I40E_CAP_PHY_TYPE_25GBASE_LR BIT_ULL(I40E_PHY_TYPE_25GBASE_LR + \
+ I40E_PHY_TYPE_OFFSET)
#define I40E_HW_CAP_MAX_GPIO 30
/* Capabilities of a PF or a VF or the whole device */
struct i40e_hw_capabilities {
diff --git a/drivers/net/ethernet/intel/i40evf/i40evf_ethtool.c b/drivers/net/ethernet/intel/i40evf/i40evf_ethtool.c
index a994015..272d600 100644
--- a/drivers/net/ethernet/intel/i40evf/i40evf_ethtool.c
+++ b/drivers/net/ethernet/intel/i40evf/i40evf_ethtool.c
@@ -85,6 +85,14 @@ static int i40evf_get_settings(struct net_device *netdev,
case I40E_LINK_SPEED_40GB:
ethtool_cmd_speed_set(ecmd, SPEED_40000);
break;
+ case I40E_LINK_SPEED_25GB:
+#ifdef SPEED_25000
+ ethtool_cmd_speed_set(ecmd, SPEED_25000);
+#else
+ netdev_info(netdev,
+ "Speed is 25G, display not supported by this version of ethtool.\n");
+#endif
+ break;
case I40E_LINK_SPEED_20GB:
ethtool_cmd_speed_set(ecmd, SPEED_20000);
break;
diff --git a/drivers/net/ethernet/intel/i40evf/i40evf_virtchnl.c b/drivers/net/ethernet/intel/i40evf/i40evf_virtchnl.c
index ddf478d..2059a8e 100644
--- a/drivers/net/ethernet/intel/i40evf/i40evf_virtchnl.c
+++ b/drivers/net/ethernet/intel/i40evf/i40evf_virtchnl.c
@@ -836,6 +836,9 @@ static void i40evf_print_link_message(struct i40evf_adapter *adapter)
case I40E_LINK_SPEED_40GB:
speed = "40 G";
break;
+ case I40E_LINK_SPEED_25GB:
+ speed = "25 G";
+ break;
case I40E_LINK_SPEED_20GB:
speed = "20 G";
break;
--
2.4.11
^ permalink raw reply related
* Re: BUG: KASAN: use-after-free in snd_usb_audio_free
From: Takashi Iwai @ 2016-11-14 21:06 UTC (permalink / raw)
To: Shuah Khan; +Cc: Shuah Khan, alsa-devel, LKML
In-Reply-To: <c0ebdec6-717a-c5d8-56e4-9b9a5a9e111d@osg.samsung.com>
On Mon, 14 Nov 2016 17:55:54 +0100,
Shuah Khan wrote:
>
> On 11/14/2016 03:25 AM, Takashi Iwai wrote:
> > On Sat, 12 Nov 2016 00:34:38 +0100,
> > Shuah Khan wrote:
> >>
> >> Hi Takashi,
> >>
> >> I am seeing the following use-after-free error when I disconnect an
> >> USB speaker. I saw this on 4.9-rc4 and 4.8.7. There might be race
> >> condition between the disconnect and pcm close perhaps.
> >
> > Thanks, this looks like a new discovery.
> > Could you check whether the patch below works?
> >
> >
> > Takashi
> >
> > ---
> > diff --git a/sound/usb/card.c b/sound/usb/card.c
> > index 9e5276d6dda0..2ddc034673a8 100644
> > --- a/sound/usb/card.c
> > +++ b/sound/usb/card.c
> > @@ -315,7 +315,8 @@ static int snd_usb_audio_free(struct snd_usb_audio *chip)
> > snd_usb_endpoint_free(ep);
> >
> > mutex_destroy(&chip->mutex);
> > - dev_set_drvdata(&chip->dev->dev, NULL);
> > + if (!atomic_read(&chip->shutdown))
> > + dev_set_drvdata(&chip->dev->dev, NULL);
> > kfree(chip);
> > return 0;
> > }
> >
>
> Hi Takashi,
>
> The patch fixed the problem on 4.9-rc4. Didn't get a chance
> to test it on 4.8.7.
Thanks, this should fix for 4.8.x, too, as there hasn't been any
significant changes in usb-audio recently.
FWIW, below is the proper patch I'm going to queue.
Takashi
-- 8< --
From: Takashi Iwai <tiwai@suse.de>
Subject: [PATCH] ALSA: usb-audio: Fix use-after-free of usb_device at
disconnect
The usb-audio driver implements the deferred device disconnection for
the device in use. In this mode, the disconnection callback returns
immediately while the actual ALSA card object removal happens later
when all files get closed. As Shuah reported, this code flow,
however, leads to a use-after-free, detected by KASAN:
BUG: KASAN: use-after-free in snd_usb_audio_free+0x134/0x160 [snd_usb_audio] at addr ffff8801c863ce10
Write of size 8 by task pulseaudio/2244
Call Trace:
[<ffffffff81b31473>] dump_stack+0x67/0x94
[<ffffffff81564ef1>] kasan_object_err+0x21/0x70
[<ffffffff8156518a>] kasan_report_error+0x1fa/0x4e0
[<ffffffff81564ad7>] ? kasan_slab_free+0x87/0xb0
[<ffffffff81565733>] __asan_report_store8_noabort+0x43/0x50
[<ffffffffa0fc0f54>] ? snd_usb_audio_free+0x134/0x160 [snd_usb_audio]
[<ffffffffa0fc0f54>] snd_usb_audio_free+0x134/0x160 [snd_usb_audio]
[<ffffffffa0fc0fb1>] snd_usb_audio_dev_free+0x31/0x40 [snd_usb_audio]
[<ffffffff8243c78a>] __snd_device_free+0x12a/0x210
[<ffffffff8243d1f5>] snd_device_free_all+0x85/0xd0
[<ffffffff8242cae4>] release_card_device+0x34/0x130
[<ffffffff81ef1846>] device_release+0x76/0x1e0
[<ffffffff81b37ad7>] kobject_release+0x107/0x370
.....
Object at ffff8801c863cc80, in cache kmalloc-2048 size: 2048
Allocated:
[<ffffffff810804eb>] save_stack_trace+0x2b/0x50
[<ffffffff81564296>] save_stack+0x46/0xd0
[<ffffffff8156450d>] kasan_kmalloc+0xad/0xe0
[<ffffffff81560d1a>] kmem_cache_alloc_trace+0xfa/0x240
[<ffffffff8214ea47>] usb_alloc_dev+0x57/0xc90
[<ffffffff8216349d>] hub_event+0xf1d/0x35f0
....
Freed:
[<ffffffff810804eb>] save_stack_trace+0x2b/0x50
[<ffffffff81564296>] save_stack+0x46/0xd0
[<ffffffff81564ac1>] kasan_slab_free+0x71/0xb0
[<ffffffff81560929>] kfree+0xd9/0x280
[<ffffffff8214de6e>] usb_release_dev+0xde/0x110
[<ffffffff81ef1846>] device_release+0x76/0x1e0
....
It's the code trying to clear drvdata of the assigned usb_device where
the usb_device itself was already released in usb_release_dev() after
the disconnect callback.
This patch fixes it by checking whether the code path is via the
disconnect callback, i.e. chip->shutdown flag is set.
Fixes: 79289e24194a ('ALSA: usb-audio: Refer to chip->usb_id for quirks...')
Reported-and-tested-by: Shuah Khan <shuahkh@osg.samsung.com>
Cc: <stable@vger.kernel.org> # v4.6+
Signed-off-by: Takashi Iwai <tiwai@suse.de>
---
sound/usb/card.c | 3 ++-
1 file changed, 2 insertions(+), 1 deletion(-)
diff --git a/sound/usb/card.c b/sound/usb/card.c
index 9e5276d6dda0..2ddc034673a8 100644
--- a/sound/usb/card.c
+++ b/sound/usb/card.c
@@ -315,7 +315,8 @@ static int snd_usb_audio_free(struct snd_usb_audio *chip)
snd_usb_endpoint_free(ep);
mutex_destroy(&chip->mutex);
- dev_set_drvdata(&chip->dev->dev, NULL);
+ if (!atomic_read(&chip->shutdown))
+ dev_set_drvdata(&chip->dev->dev, NULL);
kfree(chip);
return 0;
}
--
2.10.2
^ permalink raw reply related
* [Intel-wired-lan] [next PATCH S53-V2 3/5] i40e: Add FEC for 25g
From: Bimmy Pujari @ 2016-11-14 21:06 UTC (permalink / raw)
To: intel-wired-lan
In-Reply-To: <1479157609-30812-1-git-send-email-bimmy.pujari@intel.com>
From: Carolyn Wyborny <carolyn.wyborny@intel.com>
This patch adds adminq support for Forward Error
Correction ("FEC")for 25g products.
Signed-off-by: Carolyn Wyborny <carolyn.wyborny@intel.com>
Signed-off-by: Mitch Williams <mitch.a.williams@intel.com>
Signed-off-by: Jacek Naczyk <jacek.naczyk@intel.com>
Change-ID: Iaff4910737c239d2c730e5c22a313ce9c37d3964
---
drivers/net/ethernet/intel/i40e/i40e_adminq_cmd.h | 25 ++++++++++++++++++++--
drivers/net/ethernet/intel/i40e/i40e_common.c | 2 ++
.../net/ethernet/intel/i40evf/i40e_adminq_cmd.h | 25 ++++++++++++++++++++--
3 files changed, 48 insertions(+), 4 deletions(-)
diff --git a/drivers/net/ethernet/intel/i40e/i40e_adminq_cmd.h b/drivers/net/ethernet/intel/i40e/i40e_adminq_cmd.h
index c9d1f91..b2101a5 100644
--- a/drivers/net/ethernet/intel/i40e/i40e_adminq_cmd.h
+++ b/drivers/net/ethernet/intel/i40e/i40e_adminq_cmd.h
@@ -1686,6 +1686,8 @@ struct i40e_aq_get_phy_abilities_resp {
#define I40E_AQ_PHY_LINK_ENABLED 0x08
#define I40E_AQ_PHY_AN_ENABLED 0x10
#define I40E_AQ_PHY_FLAG_MODULE_QUAL 0x20
+#define I40E_AQ_PHY_FEC_ABILITY_KR 0x40
+#define I40E_AQ_PHY_FEC_ABILITY_RS 0x80
__le16 eee_capability;
#define I40E_AQ_EEE_100BASE_TX 0x0002
#define I40E_AQ_EEE_1000BASE_T 0x0004
@@ -1701,7 +1703,16 @@ struct i40e_aq_get_phy_abilities_resp {
#define I40E_AQ_PHY_TYPE_EXT_25G_CR 0X02
#define I40E_AQ_PHY_TYPE_EXT_25G_SR 0x04
#define I40E_AQ_PHY_TYPE_EXT_25G_LR 0x08
- u8 mod_type_ext;
+ u8 fec_cfg_curr_mod_ext_info;
+#define I40E_AQ_ENABLE_FEC_KR 0x01
+#define I40E_AQ_ENABLE_FEC_RS 0x02
+#define I40E_AQ_REQUEST_FEC_KR 0x04
+#define I40E_AQ_REQUEST_FEC_RS 0x08
+#define I40E_AQ_ENABLE_FEC_AUTO 0x10
+#define I40E_AQ_FEC
+#define I40E_AQ_MODULE_TYPE_EXT_MASK 0xE0
+#define I40E_AQ_MODULE_TYPE_EXT_SHIFT 5
+
u8 ext_comp_code;
u8 phy_id[4];
u8 module_type[3];
@@ -1729,7 +1740,15 @@ struct i40e_aq_set_phy_config { /* same bits as above in all */
#define I40E_AQ_PHY_TYPE_EXT_25G_CR 0X02
#define I40E_AQ_PHY_TYPE_EXT_25G_SR 0x04
#define I40E_AQ_PHY_TYPE_EXT_25G_LR 0x08
- u8 reserved[2];
+ u8 fec_config;
+#define I40E_AQ_SET_FEC_ABILITY_KR BIT(0)
+#define I40E_AQ_SET_FEC_ABILITY_RS BIT(1)
+#define I40E_AQ_SET_FEC_REQUEST_KR BIT(2)
+#define I40E_AQ_SET_FEC_REQUEST_RS BIT(3)
+#define I40E_AQ_SET_FEC_AUTO BIT(4)
+#define I40E_AQ_PHY_FEC_CONFIG_SHIFT 0x0
+#define I40E_AQ_PHY_FEC_CONFIG_MASK (0x1F << I40E_AQ_PHY_FEC_CONFIG_SHIFT)
+ u8 reserved;
};
I40E_CHECK_CMD_LENGTH(i40e_aq_set_phy_config);
@@ -1819,6 +1838,8 @@ struct i40e_aqc_get_link_status {
u8 loopback; /* use defines from i40e_aqc_set_lb_mode */
__le16 max_frame_size;
u8 config;
+#define I40E_AQ_CONFIG_FEC_KR_ENA 0x01
+#define I40E_AQ_CONFIG_FEC_RS_ENA 0x02
#define I40E_AQ_CONFIG_CRC_ENA 0x04
#define I40E_AQ_CONFIG_PACING_MASK 0x78
u8 external_power_ability;
diff --git a/drivers/net/ethernet/intel/i40e/i40e_common.c b/drivers/net/ethernet/intel/i40e/i40e_common.c
index 3961fc2..d9da786 100644
--- a/drivers/net/ethernet/intel/i40e/i40e_common.c
+++ b/drivers/net/ethernet/intel/i40e/i40e_common.c
@@ -1714,6 +1714,8 @@ enum i40e_status_code i40e_set_fc(struct i40e_hw *hw, u8 *aq_failures,
config.eee_capability = abilities.eee_capability;
config.eeer = abilities.eeer_val;
config.low_power_ctrl = abilities.d3_lpan;
+ config.fec_config = abilities.fec_cfg_curr_mod_ext_info &
+ I40E_AQ_PHY_FEC_CONFIG_MASK;
status = i40e_aq_set_phy_config(hw, &config, NULL);
if (status)
diff --git a/drivers/net/ethernet/intel/i40evf/i40e_adminq_cmd.h b/drivers/net/ethernet/intel/i40evf/i40e_adminq_cmd.h
index f8d7d95..eeb9864 100644
--- a/drivers/net/ethernet/intel/i40evf/i40e_adminq_cmd.h
+++ b/drivers/net/ethernet/intel/i40evf/i40e_adminq_cmd.h
@@ -1683,6 +1683,8 @@ struct i40e_aq_get_phy_abilities_resp {
#define I40E_AQ_PHY_LINK_ENABLED 0x08
#define I40E_AQ_PHY_AN_ENABLED 0x10
#define I40E_AQ_PHY_FLAG_MODULE_QUAL 0x20
+#define I40E_AQ_PHY_FEC_ABILITY_KR 0x40
+#define I40E_AQ_PHY_FEC_ABILITY_RS 0x80
__le16 eee_capability;
#define I40E_AQ_EEE_100BASE_TX 0x0002
#define I40E_AQ_EEE_1000BASE_T 0x0004
@@ -1698,7 +1700,16 @@ struct i40e_aq_get_phy_abilities_resp {
#define I40E_AQ_PHY_TYPE_EXT_25G_CR 0X02
#define I40E_AQ_PHY_TYPE_EXT_25G_SR 0x04
#define I40E_AQ_PHY_TYPE_EXT_25G_LR 0x08
- u8 mod_type_ext;
+ u8 fec_cfg_curr_mod_ext_info;
+#define I40E_AQ_ENABLE_FEC_KR 0x01
+#define I40E_AQ_ENABLE_FEC_RS 0x02
+#define I40E_AQ_REQUEST_FEC_KR 0x04
+#define I40E_AQ_REQUEST_FEC_RS 0x08
+#define I40E_AQ_ENABLE_FEC_AUTO 0x10
+#define I40E_AQ_FEC
+#define I40E_AQ_MODULE_TYPE_EXT_MASK 0xE0
+#define I40E_AQ_MODULE_TYPE_EXT_SHIFT 5
+
u8 ext_comp_code;
u8 phy_id[4];
u8 module_type[3];
@@ -1726,7 +1737,15 @@ struct i40e_aq_set_phy_config { /* same bits as above in all */
#define I40E_AQ_PHY_TYPE_EXT_25G_CR 0X02
#define I40E_AQ_PHY_TYPE_EXT_25G_SR 0x04
#define I40E_AQ_PHY_TYPE_EXT_25G_LR 0x08
- u8 reserved[2];
+ u8 fec_config;
+#define I40E_AQ_SET_FEC_ABILITY_KR BIT(0)
+#define I40E_AQ_SET_FEC_ABILITY_RS BIT(1)
+#define I40E_AQ_SET_FEC_REQUEST_KR BIT(2)
+#define I40E_AQ_SET_FEC_REQUEST_RS BIT(3)
+#define I40E_AQ_SET_FEC_AUTO BIT(4)
+#define I40E_AQ_PHY_FEC_CONFIG_SHIFT 0x0
+#define I40E_AQ_PHY_FEC_CONFIG_MASK (0x1F << I40E_AQ_PHY_FEC_CONFIG_SHIFT)
+ u8 reserved;
};
I40E_CHECK_CMD_LENGTH(i40e_aq_set_phy_config);
@@ -1816,6 +1835,8 @@ struct i40e_aqc_get_link_status {
u8 loopback; /* use defines from i40e_aqc_set_lb_mode */
__le16 max_frame_size;
u8 config;
+#define I40E_AQ_CONFIG_FEC_KR_ENA 0x01
+#define I40E_AQ_CONFIG_FEC_RS_ENA 0x02
#define I40E_AQ_CONFIG_CRC_ENA 0x04
#define I40E_AQ_CONFIG_PACING_MASK 0x78
u8 external_power_ability;
--
2.4.11
^ permalink raw reply related
* [Intel-wired-lan] [next PATCH S53-V2 4/5] i40e: Add functions which apply correct PHY access method for read and write operation
From: Bimmy Pujari @ 2016-11-14 21:06 UTC (permalink / raw)
To: intel-wired-lan
In-Reply-To: <1479157609-30812-1-git-send-email-bimmy.pujari@intel.com>
From: Michal Kosiarz <michal.kosiarz@intel.com>
Depending on external PHY type, register access method should be
different. Clause22 or Clause45 can be chosen for different PHYs.
Implemented functions apply correct access method for used device.
Signed-off-by: Michal Kosiarz <michal.kosiarz@intel.com>
Change-ID: If39d5f0da9c0b905a8cbdc1ab89885535e7d0426
---
drivers/net/ethernet/intel/i40e/i40e_common.c | 72 ++++++++++++++++++++++
drivers/net/ethernet/intel/i40e/i40e_prototype.h | 4 ++
drivers/net/ethernet/intel/i40evf/i40e_prototype.h | 4 ++
3 files changed, 80 insertions(+)
diff --git a/drivers/net/ethernet/intel/i40e/i40e_common.c b/drivers/net/ethernet/intel/i40e/i40e_common.c
index d9da786..59e766c 100644
--- a/drivers/net/ethernet/intel/i40e/i40e_common.c
+++ b/drivers/net/ethernet/intel/i40e/i40e_common.c
@@ -4676,6 +4676,78 @@ i40e_status i40e_write_phy_register_clause45(struct i40e_hw *hw, u8 page,
}
/**
+ * i40e_write_phy_register
+ * @hw: pointer to the HW structure
+ * @page: registers page number
+ * @reg: register address in the page
+ * @phy_adr: PHY address on MDIO interface
+ * @value: PHY register value
+ *
+ * Writes value to specified PHY register
+ **/
+i40e_status i40e_write_phy_register(struct i40e_hw *hw,
+ u8 page, u16 reg, u8 phy_addr, u16 value)
+{
+ i40e_status status;
+
+ switch (hw->device_id) {
+ case I40E_DEV_ID_1G_BASE_T_X722:
+ status = i40e_write_phy_register_clause22(hw,
+ reg, phy_addr, value);
+ break;
+ case I40E_DEV_ID_10G_BASE_T:
+ case I40E_DEV_ID_10G_BASE_T4:
+ case I40E_DEV_ID_10G_BASE_T_X722:
+ case I40E_DEV_ID_25G_B:
+ case I40E_DEV_ID_25G_SFP28:
+ status = i40e_write_phy_register_clause45(hw,
+ page, reg, phy_addr, value);
+ break;
+ default:
+ status = I40E_ERR_UNKNOWN_PHY;
+ break;
+ }
+
+ return status;
+}
+
+/**
+ * i40e_read_phy_register
+ * @hw: pointer to the HW structure
+ * @page: registers page number
+ * @reg: register address in the page
+ * @phy_adr: PHY address on MDIO interface
+ * @value: PHY register value
+ *
+ * Reads specified PHY register value
+ **/
+i40e_status i40e_read_phy_register(struct i40e_hw *hw,
+ u8 page, u16 reg, u8 phy_addr, u16 *value)
+{
+ i40e_status status;
+
+ switch (hw->device_id) {
+ case I40E_DEV_ID_1G_BASE_T_X722:
+ status = i40e_read_phy_register_clause22(hw, reg, phy_addr,
+ value);
+ break;
+ case I40E_DEV_ID_10G_BASE_T:
+ case I40E_DEV_ID_10G_BASE_T4:
+ case I40E_DEV_ID_10G_BASE_T_X722:
+ case I40E_DEV_ID_25G_B:
+ case I40E_DEV_ID_25G_SFP28:
+ status = i40e_read_phy_register_clause45(hw, page, reg,
+ phy_addr, value);
+ break;
+ default:
+ status = I40E_ERR_UNKNOWN_PHY;
+ break;
+ }
+
+ return status;
+}
+
+/**
* i40e_get_phy_address
* @hw: pointer to the HW structure
* @dev_num: PHY port num that address we want
diff --git a/drivers/net/ethernet/intel/i40e/i40e_prototype.h b/drivers/net/ethernet/intel/i40e/i40e_prototype.h
index 4e641a6..bb5c982 100644
--- a/drivers/net/ethernet/intel/i40e/i40e_prototype.h
+++ b/drivers/net/ethernet/intel/i40e/i40e_prototype.h
@@ -373,6 +373,10 @@ i40e_status i40e_read_phy_register_clause45(struct i40e_hw *hw,
u8 page, u16 reg, u8 phy_addr, u16 *value);
i40e_status i40e_write_phy_register_clause45(struct i40e_hw *hw,
u8 page, u16 reg, u8 phy_addr, u16 value);
+i40e_status i40e_read_phy_register(struct i40e_hw *hw,
+ u8 page, u16 reg, u8 phy_addr, u16 *value);
+i40e_status i40e_write_phy_register(struct i40e_hw *hw,
+ u8 page, u16 reg, u8 phy_addr, u16 value);
u8 i40e_get_phy_address(struct i40e_hw *hw, u8 dev_num);
i40e_status i40e_blink_phy_link_led(struct i40e_hw *hw,
u32 time, u32 interval);
diff --git a/drivers/net/ethernet/intel/i40evf/i40e_prototype.h b/drivers/net/ethernet/intel/i40evf/i40e_prototype.h
index d89d521..ee5d7fe 100644
--- a/drivers/net/ethernet/intel/i40evf/i40e_prototype.h
+++ b/drivers/net/ethernet/intel/i40evf/i40e_prototype.h
@@ -115,6 +115,10 @@ i40e_status i40e_read_phy_register(struct i40e_hw *hw, u8 page,
u16 reg, u8 phy_addr, u16 *value);
i40e_status i40e_write_phy_register(struct i40e_hw *hw, u8 page,
u16 reg, u8 phy_addr, u16 value);
+i40e_status i40e_read_phy_register(struct i40e_hw *hw,
+ u8 page, u16 reg, u8 phy_addr, u16 *value);
+i40e_status i40e_write_phy_register(struct i40e_hw *hw,
+ u8 page, u16 reg, u8 phy_addr, u16 value);
u8 i40e_get_phy_address(struct i40e_hw *hw, u8 dev_num);
i40e_status i40e_blink_phy_link_led(struct i40e_hw *hw,
u32 time, u32 interval);
--
2.4.11
^ permalink raw reply related
* [Intel-wired-lan] [next PATCH S53-V2 5/5] i40e: lock service task correctly
From: Bimmy Pujari @ 2016-11-14 21:06 UTC (permalink / raw)
To: intel-wired-lan
In-Reply-To: <1479157609-30812-1-git-send-email-bimmy.pujari@intel.com>
From: Mitch Williams <mitch.a.williams@intel.com>
The service task lock was being set in the scheduling function, not the
actual service task. This would potentially leave the bit set for a long
time before the task actually ran. Furthermore, if the service task
takes too long, it calls the schedule function to reschedule itself -
which would fail to take the lock and do nothing.
Instead, set and clear the lock bit in the service task itself. In the
process, get rid of the i40e_service_event_complete() function, which is
really just two lines of code that can be put right in the service task
itself.
Signed-off-by: Mitch Williams <mitch.a.williams@intel.com>
Change-ID: I83155e682b686121e2897f4429eb7d3f7c669168
---
Testing Hints : Should be no functional change, particularly around
link up/down events. This is prep work for using this lock bit in
the client.
drivers/net/ethernet/intel/i40e/i40e_main.c | 24 +++++++-----------------
1 file changed, 7 insertions(+), 17 deletions(-)
diff --git a/drivers/net/ethernet/intel/i40e/i40e_main.c b/drivers/net/ethernet/intel/i40e/i40e_main.c
index 849feaa..57850fd 100644
--- a/drivers/net/ethernet/intel/i40e/i40e_main.c
+++ b/drivers/net/ethernet/intel/i40e/i40e_main.c
@@ -288,8 +288,7 @@ struct i40e_vsi *i40e_find_vsi_from_id(struct i40e_pf *pf, u16 id)
void i40e_service_event_schedule(struct i40e_pf *pf)
{
if (!test_bit(__I40E_DOWN, &pf->state) &&
- !test_bit(__I40E_RESET_RECOVERY_PENDING, &pf->state) &&
- !test_and_set_bit(__I40E_SERVICE_SCHED, &pf->state))
+ !test_bit(__I40E_RESET_RECOVERY_PENDING, &pf->state))
queue_work(i40e_wq, &pf->service_task);
}
@@ -5943,19 +5942,6 @@ static void i40e_handle_lan_overflow_event(struct i40e_pf *pf,
}
/**
- * i40e_service_event_complete - Finish up the service event
- * @pf: board private structure
- **/
-static void i40e_service_event_complete(struct i40e_pf *pf)
-{
- WARN_ON(!test_bit(__I40E_SERVICE_SCHED, &pf->state));
-
- /* flush memory to make sure state is correct before next watchog */
- smp_mb__before_atomic();
- clear_bit(__I40E_SERVICE_SCHED, &pf->state);
-}
-
-/**
* i40e_get_cur_guaranteed_fd_count - Get the consumed guaranteed FD filters
* @pf: board private structure
**/
@@ -7264,10 +7250,12 @@ static void i40e_service_task(struct work_struct *work)
/* don't bother with service tasks if a reset is in progress */
if (test_bit(__I40E_RESET_RECOVERY_PENDING, &pf->state)) {
- i40e_service_event_complete(pf);
return;
}
+ if (test_and_set_bit(__I40E_SERVICE_SCHED, &pf->state))
+ return;
+
i40e_detect_recover_hung(pf);
i40e_sync_filters_subtask(pf);
i40e_reset_subtask(pf);
@@ -7280,7 +7268,9 @@ static void i40e_service_task(struct work_struct *work)
i40e_sync_udp_filters_subtask(pf);
i40e_clean_adminq_subtask(pf);
- i40e_service_event_complete(pf);
+ /* flush memory to make sure state is correct before next watchdog */
+ smp_mb__before_atomic();
+ clear_bit(__I40E_SERVICE_SCHED, &pf->state);
/* If the tasks have taken longer than one timer cycle or there
* is more work to be done, reschedule the service task now
--
2.4.11
^ permalink raw reply related
* [Intel-wired-lan] [jkirsher-net-queue:dev-queue] BUILD SUCCESS 3b5d0516c41e3411e7028d90bf9ea60d3062a362
From: kbuild test robot @ 2016-11-14 21:06 UTC (permalink / raw)
To: intel-wired-lan
https://git.kernel.org/pub/scm/linux/kernel/git/jkirsher/net-queue.git dev-queue
3b5d0516c41e3411e7028d90bf9ea60d3062a362 igb: re-assign hw address pointer on reset after PCI error
elapsed time: 76m
configs tested: 178
The following configs have been built successfully.
More configs may be tested in the coming days.
i386 randconfig-a0-201646
x86_64 randconfig-a0-11150150
x86_64 acpi-redef
x86_64 allyesdebian
x86_64 nfsroot
blackfin BF526-EZBRD_defconfig
blackfin BF533-EZKIT_defconfig
blackfin BF561-EZKIT-SMP_defconfig
blackfin TCM-BF537_defconfig
cris etrax-100lx_v2_defconfig
i386 tinyconfig
sh allnoconfig
sh rsk7269_defconfig
sh sh7785lcr_32bit_defconfig
sh titan_defconfig
i386 randconfig-c0-11150231
x86_64 kexec
x86_64 rhel
x86_64 rhel-7.2
x86_64 randconfig-g0-11150243
avr32 atngw100_defconfig
avr32 atstk1006_defconfig
frv defconfig
mn10300 asb2364_defconfig
openrisc or1ksim_defconfig
tile tilegx_defconfig
um i386_defconfig
um x86_64_defconfig
alpha defconfig
parisc allnoconfig
parisc b180_defconfig
parisc c3000_defconfig
parisc defconfig
i386 allmodconfig
powerpc mpc83xx_defconfig
sh ecovec24-romimage_defconfig
um allmodconfig
arm ebsa110_defconfig
mips ar7_defconfig
sh urquell_defconfig
tile allnoconfig
x86_64 randconfig-x011-201646
x86_64 randconfig-x014-201646
x86_64 randconfig-x017-201646
x86_64 randconfig-x015-201646
x86_64 randconfig-x012-201646
x86_64 randconfig-x018-201646
x86_64 randconfig-x019-201646
x86_64 randconfig-x013-201646
x86_64 randconfig-x010-201646
x86_64 randconfig-x016-201646
i386 alldefconfig
i386 allnoconfig
i386 defconfig
arm allmodconfig
arm arm5
arm arm67
arm imx_v6_v7_defconfig
arm ixp4xx_defconfig
arm mvebu_v7_defconfig
arm omap2plus_defconfig
arm sa1100
arm samsung
arm sh
arm tegra_defconfig
arm64 alldefconfig
arm64 allmodconfig
m68k m5475evb_defconfig
m68k multi_defconfig
m68k sun3_defconfig
i386 randconfig-s0-201646
i386 randconfig-s1-201646
x86_64 randconfig-s0-11150359
x86_64 randconfig-s1-11150359
x86_64 randconfig-s2-11150359
x86_64 randconfig-s3-11150352
x86_64 randconfig-s4-11150352
x86_64 randconfig-s5-11150352
powerpc allnoconfig
powerpc defconfig
powerpc ppc64_defconfig
s390 default_defconfig
x86_64 randconfig-i0-201646
microblaze mmu_defconfig
microblaze nommu_defconfig
i386 randconfig-i0-11140126
i386 randconfig-i1-11140126
x86_64 randconfig-b0-11150030
sparc defconfig
sparc64 allnoconfig
sparc64 defconfig
x86_64 allmodconfig
x86_64 randconfig-u0-11150246
x86_64 randconfig-u0-11150439
c6x evmc6678_defconfig
h8300 h8300h-sim_defconfig
m32r m32104ut_defconfig
m32r mappi3.smp_defconfig
m32r opsput_defconfig
m32r usrv_defconfig
nios2 10m50_defconfig
score spct6600_defconfig
xtensa common_defconfig
xtensa iss_defconfig
arm pleb_defconfig
arm cm_x2xx_defconfig
arm pxa_defconfig
x86_64 randconfig-ne0-11150251
c6x dsk6455_defconfig
mips sb1250_swarm_defconfig
powerpc wii_defconfig
i386 randconfig-x014-201646
i386 randconfig-x019-201646
i386 randconfig-x018-201646
i386 randconfig-x017-201646
i386 randconfig-x015-201646
i386 randconfig-x016-201646
i386 randconfig-x012-201646
i386 randconfig-x011-201646
i386 randconfig-x013-201646
i386 randconfig-x010-201646
x86_64 lkp
i386 randconfig-n0-201646
ia64 alldefconfig
ia64 allnoconfig
ia64 defconfig
i386 randconfig-x070-201646
i386 randconfig-x071-201646
i386 randconfig-x072-201646
i386 randconfig-x073-201646
i386 randconfig-x074-201646
i386 randconfig-x075-201646
i386 randconfig-x076-201646
i386 randconfig-x077-201646
i386 randconfig-x078-201646
i386 randconfig-x079-201646
i386 randconfig-sb0-11150109
arm allnoconfig
arm at91_dt_defconfig
arm efm32_defconfig
arm exynos_defconfig
arm multi_v5_defconfig
arm multi_v7_defconfig
arm shmobile_defconfig
arm sunxi_defconfig
arm64 allnoconfig
arm64 defconfig
x86_64 randconfig-ws0-11150035
x86_64 randconfig-x008-201646
x86_64 randconfig-x001-201646
x86_64 randconfig-x009-201646
x86_64 randconfig-x000-201646
x86_64 randconfig-x003-201646
x86_64 randconfig-x005-201646
x86_64 randconfig-x002-201646
x86_64 randconfig-x007-201646
x86_64 randconfig-x004-201646
x86_64 randconfig-x006-201646
i386 randconfig-r0-201646
x86_64 randconfig-r0-11150207
i386 randconfig-x006-201646
i386 randconfig-x004-201646
i386 randconfig-x007-201646
i386 randconfig-x003-201646
i386 randconfig-x008-201646
i386 randconfig-x000-201646
i386 randconfig-x009-201646
i386 randconfig-x002-201646
i386 randconfig-x001-201646
i386 randconfig-x005-201646
mips 32r2_defconfig
mips 64r6el_defconfig
mips allnoconfig
mips fuloong2e_defconfig
mips jz4740
mips malta_kvm_defconfig
mips txx9
Thanks,
Fengguang
^ permalink raw reply
page: next (older) | prev (newer) | latest
- recent:[subjects (threaded)|topics (new)|topics (active)]
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.