* Re: [PATCH net-next 13/21] net: dsa: mv88e6xxx: factorize global setup
From: Andrew Lunn @ 2016-05-06 22:29 UTC (permalink / raw)
To: Vivien Didelot
Cc: netdev, linux-kernel, kernel, David S. Miller, Florian Fainelli
In-Reply-To: <1462571843-14397-14-git-send-email-vivien.didelot@savoirfairelinux.com>
>
> -int mv88e6xxx_setup_common(struct mv88e6xxx_priv_state *ps)
> +static int _mv88e6xxx_setup_global(struct mv88e6xxx_priv_state *ps)
Another _ prefix.
Andrew
^ permalink raw reply
* Re: [patch net 0/2] mlxsw: Couple of fixes
From: David Miller @ 2016-05-06 22:33 UTC (permalink / raw)
To: jiri; +Cc: netdev, idosch, eladr, yotamg, ogerlitz
In-Reply-To: <1462565920-1959-1-git-send-email-jiri@resnulli.us>
From: Jiri Pirko <jiri@resnulli.us>
Date: Fri, 6 May 2016 22:18:38 +0200
> From: Jiri Pirko <jiri@mellanox.com>
>
> Ido Schimmel (2):
> mlxsw: spectrum: Fix rollback order in LAG join failure
> mlxsw: spectrum: Add missing rollback in flood configuration
Applied.
^ permalink raw reply
* Re: [PATCH net-next 15/21] net: dsa: mv88e6xxx: factorize VLAN Ethertype
From: Andrew Lunn @ 2016-05-06 22:33 UTC (permalink / raw)
To: Vivien Didelot, f
Cc: netdev, linux-kernel, kernel, David S. Miller, Florian Fainelli
In-Reply-To: <1462571843-14397-16-git-send-email-vivien.didelot@savoirfairelinux.com>
On Fri, May 06, 2016 at 05:57:17PM -0400, Vivien Didelot wrote:
> The 6131 switch models have a Core Tag Type register. Add a
> MV88E6XXX_FLAG_CORE_TAG_TYPE flag and set the VLAN Ethertype to 0x8100
> in the shared setup code if it is present.
Do you have any idea what the core tag is?
Andrew
^ permalink raw reply
* Re: [PATCH v3 net-next 01/11] gso: Remove arbitrary checks for unsupported GSO
From: Alexander Duyck @ 2016-05-06 22:34 UTC (permalink / raw)
To: Tom Herbert, davem, netdev; +Cc: kernel-team
In-Reply-To: <1462572726-566137-2-git-send-email-tom@herbertland.com>
On 05/06/2016 03:11 PM, Tom Herbert wrote:
> In several gso_segment functions there are checks of gso_type against
> a seemingly arbitrary list of SKB_GSO_* flags. This seems like an
> attempt to identify unsupported GSO types, but since the stack is
> the one that set these GSO types in the first place this seems
> unnecessary to do. If a combination isn't valid in the first
> place that stack should not allow setting it.
>
> This is a code simplication especially for add new GSO types.
>
> Signed-off-by: Tom Herbert <tom@herbertland.com>
> ---
> net/ipv4/af_inet.c | 18 ------------------
> net/ipv4/gre_offload.c | 14 --------------
> net/ipv4/tcp_offload.c | 19 -------------------
> net/ipv4/udp_offload.c | 10 ----------
> net/ipv6/ip6_offload.c | 18 ------------------
> net/ipv6/udp_offload.c | 13 -------------
> net/mpls/mpls_gso.c | 9 ---------
> 7 files changed, 101 deletions(-)
>
This is a nice clean-up since tunnels have essentially made things like
trying to filter TSOV4 or TSOV6 pointless for the network layer.
Acked-by: Alexander Duyck <aduyck@mirantis.com>
^ permalink raw reply
* Re: [PATCH v3 net-next 02/11] net: define gso types for IPx over IPv4 and IPv6
From: Alexander Duyck @ 2016-05-06 22:48 UTC (permalink / raw)
To: Tom Herbert, davem, netdev; +Cc: kernel-team
In-Reply-To: <1462572726-566137-3-git-send-email-tom@herbertland.com>
On 05/06/2016 03:11 PM, Tom Herbert wrote:
> This patch defines two new GDO definitions SKB_GSO_IPXIP4 and
> SKB_GSO_IPXIP6 along with corresponding NETIF_F_GSO_IPXIP4 and
> NETIF_F_GSO_IPXIP6. These are used to described IP in IP
> tunnel and what the outer protocol is. The inner protocol
> can be deduced from other GSO types (e.g. SKB_GSO_TCPV4 and
> SKB_GSO_TCPV6). The GSO types of SKB_GSO_IPIP and SKB_GSO_SIT
> are removed (these are both instances of SKB_GSO_IPXIP4).
> SKB_GSO_IPXIP6 will be used when support for GSO with IP
> encapsulation over IPv6 is added.
>
> Signed-off-by: Tom Herbert <tom@herbertland.com>
> ---
> drivers/net/ethernet/broadcom/bnx2x/bnx2x_main.c | 5 ++---
> drivers/net/ethernet/broadcom/bnxt/bnxt.c | 4 ++--
> drivers/net/ethernet/intel/i40e/i40e_main.c | 3 +--
> drivers/net/ethernet/intel/i40e/i40e_txrx.c | 3 +--
> drivers/net/ethernet/intel/i40evf/i40e_txrx.c | 3 +--
> drivers/net/ethernet/intel/i40evf/i40evf_main.c | 3 +--
> drivers/net/ethernet/intel/ixgbe/ixgbe_main.c | 3 +--
> drivers/net/ethernet/intel/ixgbevf/ixgbevf_main.c | 3 +--
> include/linux/netdev_features.h | 12 ++++++------
> include/linux/netdevice.h | 4 ++--
> include/linux/skbuff.h | 4 ++--
> net/core/ethtool.c | 4 ++--
> net/ipv4/af_inet.c | 2 +-
> net/ipv4/ipip.c | 2 +-
> net/ipv6/ip6_offload.c | 4 ++--
> net/ipv6/sit.c | 4 ++--
> net/netfilter/ipvs/ip_vs_xmit.c | 17 +++++++----------
> 17 files changed, 35 insertions(+), 45 deletions(-)
>
> diff --git a/drivers/net/ethernet/broadcom/bnx2x/bnx2x_main.c b/drivers/net/ethernet/broadcom/bnx2x/bnx2x_main.c
> index d465bd7..0a5b770 100644
> --- a/drivers/net/ethernet/broadcom/bnx2x/bnx2x_main.c
> +++ b/drivers/net/ethernet/broadcom/bnx2x/bnx2x_main.c
> @@ -13259,12 +13259,11 @@ static int bnx2x_init_dev(struct bnx2x *bp, struct pci_dev *pdev,
> NETIF_F_RXHASH | NETIF_F_HW_VLAN_CTAG_TX;
> if (!chip_is_e1x) {
> dev->hw_features |= NETIF_F_GSO_GRE | NETIF_F_GSO_UDP_TUNNEL |
> - NETIF_F_GSO_IPIP | NETIF_F_GSO_SIT;
> + NETIF_F_GSO_IPXIP4;
> dev->hw_enc_features =
> NETIF_F_IP_CSUM | NETIF_F_IPV6_CSUM | NETIF_F_SG |
> NETIF_F_TSO | NETIF_F_TSO_ECN | NETIF_F_TSO6 |
> - NETIF_F_GSO_IPIP |
> - NETIF_F_GSO_SIT |
> + NETIF_F_GSO_IPXIP4 |
> NETIF_F_GSO_GRE | NETIF_F_GSO_UDP_TUNNEL;
> }
>
> diff --git a/drivers/net/ethernet/broadcom/bnxt/bnxt.c b/drivers/net/ethernet/broadcom/bnxt/bnxt.c
> index fd85b6d..e449228 100644
> --- a/drivers/net/ethernet/broadcom/bnxt/bnxt.c
> +++ b/drivers/net/ethernet/broadcom/bnxt/bnxt.c
> @@ -6218,7 +6218,7 @@ static int bnxt_init_one(struct pci_dev *pdev, const struct pci_device_id *ent)
> dev->hw_features = NETIF_F_IP_CSUM | NETIF_F_IPV6_CSUM | NETIF_F_SG |
> NETIF_F_TSO | NETIF_F_TSO6 |
> NETIF_F_GSO_UDP_TUNNEL | NETIF_F_GSO_GRE |
> - NETIF_F_GSO_IPIP | NETIF_F_GSO_SIT |
> + NETIF_F_GSO_IPXIP4 |
> NETIF_F_GSO_UDP_TUNNEL_CSUM | NETIF_F_GSO_GRE_CSUM |
> NETIF_F_GSO_PARTIAL | NETIF_F_RXHASH |
> NETIF_F_RXCSUM | NETIF_F_LRO | NETIF_F_GRO;
> @@ -6228,7 +6228,7 @@ static int bnxt_init_one(struct pci_dev *pdev, const struct pci_device_id *ent)
> NETIF_F_TSO | NETIF_F_TSO6 |
> NETIF_F_GSO_UDP_TUNNEL | NETIF_F_GSO_GRE |
> NETIF_F_GSO_UDP_TUNNEL_CSUM | NETIF_F_GSO_GRE_CSUM |
> - NETIF_F_GSO_IPIP | NETIF_F_GSO_SIT |
> + NETIF_F_GSO_IPXIP4;
> NETIF_F_GSO_PARTIAL;
> dev->gso_partial_features = NETIF_F_GSO_UDP_TUNNEL_CSUM |
> NETIF_F_GSO_GRE_CSUM;
You should try building the bnxt driver at least if you are making
changes to it. This bit is broken. It should be an '|' and not a ';' here.
The other bits seem to be correct. I'll try testing this over the next
few hours to see if I can find any other issues.
- Alex
^ permalink raw reply
* Re: [PATCH v3 net-next 02/11] net: define gso types for IPx over IPv4 and IPv6
From: Tom Herbert @ 2016-05-06 22:55 UTC (permalink / raw)
To: Alexander Duyck
Cc: David S. Miller, Linux Kernel Network Developers, Kernel Team
In-Reply-To: <572D1F33.9040206@gmail.com>
On Fri, May 6, 2016 at 3:48 PM, Alexander Duyck
<alexander.duyck@gmail.com> wrote:
> On 05/06/2016 03:11 PM, Tom Herbert wrote:
>>
>> This patch defines two new GDO definitions SKB_GSO_IPXIP4 and
>> SKB_GSO_IPXIP6 along with corresponding NETIF_F_GSO_IPXIP4 and
>> NETIF_F_GSO_IPXIP6. These are used to described IP in IP
>> tunnel and what the outer protocol is. The inner protocol
>> can be deduced from other GSO types (e.g. SKB_GSO_TCPV4 and
>> SKB_GSO_TCPV6). The GSO types of SKB_GSO_IPIP and SKB_GSO_SIT
>> are removed (these are both instances of SKB_GSO_IPXIP4).
>> SKB_GSO_IPXIP6 will be used when support for GSO with IP
>> encapsulation over IPv6 is added.
>>
>> Signed-off-by: Tom Herbert <tom@herbertland.com>
>> ---
>> drivers/net/ethernet/broadcom/bnx2x/bnx2x_main.c | 5 ++---
>> drivers/net/ethernet/broadcom/bnxt/bnxt.c | 4 ++--
>> drivers/net/ethernet/intel/i40e/i40e_main.c | 3 +--
>> drivers/net/ethernet/intel/i40e/i40e_txrx.c | 3 +--
>> drivers/net/ethernet/intel/i40evf/i40e_txrx.c | 3 +--
>> drivers/net/ethernet/intel/i40evf/i40evf_main.c | 3 +--
>> drivers/net/ethernet/intel/ixgbe/ixgbe_main.c | 3 +--
>> drivers/net/ethernet/intel/ixgbevf/ixgbevf_main.c | 3 +--
>> include/linux/netdev_features.h | 12 ++++++------
>> include/linux/netdevice.h | 4 ++--
>> include/linux/skbuff.h | 4 ++--
>> net/core/ethtool.c | 4 ++--
>> net/ipv4/af_inet.c | 2 +-
>> net/ipv4/ipip.c | 2 +-
>> net/ipv6/ip6_offload.c | 4 ++--
>> net/ipv6/sit.c | 4 ++--
>> net/netfilter/ipvs/ip_vs_xmit.c | 17 +++++++----------
>> 17 files changed, 35 insertions(+), 45 deletions(-)
>>
>> diff --git a/drivers/net/ethernet/broadcom/bnx2x/bnx2x_main.c
>> b/drivers/net/ethernet/broadcom/bnx2x/bnx2x_main.c
>> index d465bd7..0a5b770 100644
>> --- a/drivers/net/ethernet/broadcom/bnx2x/bnx2x_main.c
>> +++ b/drivers/net/ethernet/broadcom/bnx2x/bnx2x_main.c
>> @@ -13259,12 +13259,11 @@ static int bnx2x_init_dev(struct bnx2x *bp,
>> struct pci_dev *pdev,
>> NETIF_F_RXHASH | NETIF_F_HW_VLAN_CTAG_TX;
>> if (!chip_is_e1x) {
>> dev->hw_features |= NETIF_F_GSO_GRE |
>> NETIF_F_GSO_UDP_TUNNEL |
>> - NETIF_F_GSO_IPIP | NETIF_F_GSO_SIT;
>> + NETIF_F_GSO_IPXIP4;
>> dev->hw_enc_features =
>> NETIF_F_IP_CSUM | NETIF_F_IPV6_CSUM | NETIF_F_SG |
>> NETIF_F_TSO | NETIF_F_TSO_ECN | NETIF_F_TSO6 |
>> - NETIF_F_GSO_IPIP |
>> - NETIF_F_GSO_SIT |
>> + NETIF_F_GSO_IPXIP4 |
>> NETIF_F_GSO_GRE | NETIF_F_GSO_UDP_TUNNEL;
>> }
>>
>> diff --git a/drivers/net/ethernet/broadcom/bnxt/bnxt.c
>> b/drivers/net/ethernet/broadcom/bnxt/bnxt.c
>> index fd85b6d..e449228 100644
>> --- a/drivers/net/ethernet/broadcom/bnxt/bnxt.c
>> +++ b/drivers/net/ethernet/broadcom/bnxt/bnxt.c
>> @@ -6218,7 +6218,7 @@ static int bnxt_init_one(struct pci_dev *pdev, const
>> struct pci_device_id *ent)
>> dev->hw_features = NETIF_F_IP_CSUM | NETIF_F_IPV6_CSUM |
>> NETIF_F_SG |
>> NETIF_F_TSO | NETIF_F_TSO6 |
>> NETIF_F_GSO_UDP_TUNNEL | NETIF_F_GSO_GRE |
>> - NETIF_F_GSO_IPIP | NETIF_F_GSO_SIT |
>> + NETIF_F_GSO_IPXIP4 |
>> NETIF_F_GSO_UDP_TUNNEL_CSUM |
>> NETIF_F_GSO_GRE_CSUM |
>> NETIF_F_GSO_PARTIAL | NETIF_F_RXHASH |
>> NETIF_F_RXCSUM | NETIF_F_LRO | NETIF_F_GRO;
>> @@ -6228,7 +6228,7 @@ static int bnxt_init_one(struct pci_dev *pdev, const
>> struct pci_device_id *ent)
>> NETIF_F_TSO | NETIF_F_TSO6 |
>> NETIF_F_GSO_UDP_TUNNEL | NETIF_F_GSO_GRE |
>> NETIF_F_GSO_UDP_TUNNEL_CSUM | NETIF_F_GSO_GRE_CSUM
>> |
>> - NETIF_F_GSO_IPIP | NETIF_F_GSO_SIT |
>> + NETIF_F_GSO_IPXIP4;
>> NETIF_F_GSO_PARTIAL;
>> dev->gso_partial_features = NETIF_F_GSO_UDP_TUNNEL_CSUM |
>> NETIF_F_GSO_GRE_CSUM;
>
>
> You should try building the bnxt driver at least if you are making changes
> to it. This bit is broken. It should be an '|' and not a ';' here.
>
> The other bits seem to be correct. I'll try testing this over the next few
> hours to see if I can find any other issues.
Huh, that's odd. I'm pretty sure I built drivers/net with allyesconfig
with this.
Thanks for catching it.
>
> - Alex
^ permalink raw reply
* [PATCH net-next] net: make sch_handle_ingress() drop monitor ready
From: Eric Dumazet @ 2016-05-06 22:55 UTC (permalink / raw)
To: David Miller; +Cc: netdev, Jamal Hadi Salim
From: Eric Dumazet <edumazet@google.com>
TC_ACT_STOLEN is used when ingress traffic is mirred/redirected
to say ifb.
Packet is not dropped, but consumed.
Only TC_ACT_SHOT is a clear indication something went wrong.
Signed-off-by: Eric Dumazet <edumazet@google.com>
Cc: Jamal Hadi Salim <jhs@mojatatu.com>
---
net/core/dev.c | 4 +++-
1 file changed, 3 insertions(+), 1 deletion(-)
diff --git a/net/core/dev.c b/net/core/dev.c
index e98ba63fe2800c10d4d407f12d11ca8975dc1e8e..c7490339315cc0046a2da67c00a95f079e602588 100644
--- a/net/core/dev.c
+++ b/net/core/dev.c
@@ -3956,9 +3956,11 @@ sch_handle_ingress(struct sk_buff *skb, struct packet_type **pt_prev, int *ret,
break;
case TC_ACT_SHOT:
qdisc_qstats_cpu_drop(cl->q);
+ kfree_skb(skb);
+ return NULL;
case TC_ACT_STOLEN:
case TC_ACT_QUEUED:
- kfree_skb(skb);
+ consume_skb(skb);
return NULL;
case TC_ACT_REDIRECT:
/* skb_mac_header check was done by cls/act_bpf, so
^ permalink raw reply related
* Re: [RFC PATCH v3 17/19] calipso: Add validation of CALIPSO option.
From: Paul Moore @ 2016-05-06 22:59 UTC (permalink / raw)
To: Huw Davies; +Cc: netdev, linux-security-module, selinux, Paul Moore
In-Reply-To: <1455715329-9601-18-git-send-email-huw@codeweavers.com>
On Wed, Feb 17, 2016 at 8:22 AM, Huw Davies <huw@codeweavers.com> wrote:
> We check lengths, checksum and the DOI. We leave checking of the
> level and categories for the socket layer.
>
> Signed-off-by: Huw Davies <huw@codeweavers.com>
> ---
> include/net/calipso.h | 6 ++++++
> net/ipv6/calipso.c | 42 ++++++++++++++++++++++++++++++++++++++++++
> net/ipv6/exthdrs.c | 27 +++++++++++++++++++++++++++
> 3 files changed, 75 insertions(+)
>
> diff --git a/include/net/calipso.h b/include/net/calipso.h
> index 38dbb47..85404e2 100644
> --- a/include/net/calipso.h
> +++ b/include/net/calipso.h
> @@ -65,6 +65,7 @@ struct calipso_doi {
> #ifdef CONFIG_NETLABEL
> int __init calipso_init(void);
> void calipso_exit(void);
> +bool calipso_validate(const struct sk_buff *skb, const unsigned char *option);
> #else
> static inline int __init calipso_init(void)
> {
> @@ -74,6 +75,11 @@ static inline int __init calipso_init(void)
> static inline void calipso_exit(void)
> {
> }
> +static inline bool calipso_validate(const struct sk_buff *skb,
> + const unsigned char *option)
> +{
> + return true;
> +}
> #endif /* CONFIG_NETLABEL */
>
> #endif /* _CALIPSO_H */
> diff --git a/net/ipv6/calipso.c b/net/ipv6/calipso.c
> index fa371a8..b8bcf9f 100644
> --- a/net/ipv6/calipso.c
> +++ b/net/ipv6/calipso.c
> @@ -321,6 +321,48 @@ doi_walk_return:
> }
>
> /**
> + * calipso_validate - Validate a CALIPSO option
> + * @skb: the packet
> + * @option: the start of the option
> + *
> + * Description:
> + * This routine is called to validate a CALIPSO option.
> + * If the option is valid then a zero value is returned. If the
> + * option is invalid then a non-zero value is returned and
> + * representing the offset to the offending portion of the option.
> + *
> + * The caller should have already checked that the length of the
> + * option (including the TLV header) is >= 10 and that the catmap
> + * length is consistent with the option length.
> + *
> + * We leave checks on the level and categories to the socket layer.
> + */
> +bool calipso_validate(const struct sk_buff *skb, const unsigned char *option)
> +{
> + struct calipso_doi *doi_def;
> + int ret_val;
> + u16 crc, len = option[1] + 2;
> + static const u8 zero[2];
> +
> + /* The original CRC runs over the option including the TLV header
> + * with the CRC-16 field (at offset 8) zeroed out. */
> + crc = crc_ccitt(0xffff, option, 8);
> + crc = crc_ccitt(crc, zero, sizeof(zero));
> + if (len > 10)
> + crc = crc_ccitt(crc, option + 10, len - 10);
> + crc = ~crc;
I should have caught this in the v2 patchset when I mentioned it with
respect to the CRC generation, but why not simply do 'crc =
~crc_cccitt(...);'?
Also, while I'm looking at this, why not do the CRC verification in
ipv6_hop_calipso()? The only thing we should need to do here is the
DOI lookup/verification so that we still work correctly when
CONFIG_NETLABEL=n; all the core protocol stuff, e.g. length and
checksum validation, should be done in the core stack functions, e.g.
ipv6_hop_calipso().
> + if (option[8] != (crc & 0xff) || option[9] != ((crc >> 8) & 0xff))
> + return false;
> +
> + rcu_read_lock();
> + doi_def = calipso_doi_search(get_unaligned_be32(option + 2));
> + ret_val = !!doi_def;
> + rcu_read_unlock();
> +
> + return ret_val;
> +}
> +
> +/**
> * calipso_map_cat_hton - Perform a category mapping from host to network
> * @doi_def: the DOI definition
> * @secattr: the security attributes
> diff --git a/net/ipv6/exthdrs.c b/net/ipv6/exthdrs.c
> index d5fd3e7..0f69cab 100644
> --- a/net/ipv6/exthdrs.c
> +++ b/net/ipv6/exthdrs.c
> @@ -43,6 +43,7 @@
> #include <net/ndisc.h>
> #include <net/ip6_route.h>
> #include <net/addrconf.h>
> +#include <net/calipso.h>
> #if IS_ENABLED(CONFIG_IPV6_MIP6)
> #include <net/xfrm.h>
> #endif
> @@ -603,6 +604,28 @@ drop:
> return false;
> }
>
> +/* CALIPSO RFC 5570 */
> +
> +static bool ipv6_hop_calipso(struct sk_buff *skb, int optoff)
> +{
> + const unsigned char *nh = skb_network_header(skb);
> +
> + if (nh[optoff + 1] < 8)
> + goto drop;
> +
> + if (nh[optoff + 6] * 4 + 8 > nh[optoff + 1])
> + goto drop;
> +
> + if (!calipso_validate(skb, nh + optoff))
> + goto drop;
> +
> + return true;
> +
> +drop:
> + kfree_skb(skb);
> + return false;
> +}
> +
> static const struct tlvtype_proc tlvprochopopt_lst[] = {
> {
> .type = IPV6_TLV_ROUTERALERT,
> @@ -612,6 +635,10 @@ static const struct tlvtype_proc tlvprochopopt_lst[] = {
> .type = IPV6_TLV_JUMBO,
> .func = ipv6_hop_jumbo,
> },
> + {
> + .type = IPV6_TLV_CALIPSO,
> + .func = ipv6_hop_calipso,
> + },
> { -1, }
> };
>
> --
> 2.7.0
>
> --
> To unsubscribe from this list: send the line "unsubscribe linux-security-module" in
> the body of a message to majordomo@vger.kernel.org
> More majordomo info at http://vger.kernel.org/majordomo-info.html
--
paul moore
www.paul-moore.com
^ permalink raw reply
* [PATCH 0/2] Quiet noisy LSM denial when accessing net sysctl
From: Tyler Hicks @ 2016-05-06 23:04 UTC (permalink / raw)
To: linux-security-module, netdev, linux-kernel
Cc: Serge Hallyn, David S . Miller
This pair of patches does away with what I believe is a useless denial
audit message when a privileged process initially accesses a net sysctl.
The bug was first discovered when running Go applications under AppArmor
confinement. It can be triggered like so:
$ echo "profile test { file, }" | sudo apparmor_parser -rq
Once the profile is loaded, invoke Go as root under confinement:
$ sudo aa-exec -p test -- go version
go version go1.6.1 linux/amd64
Here's the denial:
audit: type=1400 audit(1462575436.832:29): apparmor="DENIED" operation="capable" profile="test" pid=1157 comm="go" capability=12 capname="net_admin"
The reproducer in minimal form is:
$ sudo aa-exec -p test -- cat /proc/sys/net/core/somaxconn
128
The denial:
audit: type=1400 audit(1462575670.000:29): apparmor="DENIED" operation="capable" profile="test" pid=1161 comm="cat" capability=12 capname="net_admin"
Thanks!
Tyler
^ permalink raw reply
* [PATCH 1/2] kernel: Add noaudit variant of ns_capable()
From: Tyler Hicks @ 2016-05-06 23:04 UTC (permalink / raw)
To: linux-security-module, netdev, linux-kernel
Cc: Serge Hallyn, David S . Miller
In-Reply-To: <1462575854-4301-1-git-send-email-tyhicks@canonical.com>
When checking the current cred for a capability in a specific user
namespace, it isn't always desirable to have the LSMs audit the check.
This patch adds a noaudit variant of ns_capable() for when those
situations arise.
The common logic between ns_capable() and the new ns_capable_noaudit()
is moved into a single, shared function to keep duplicated code to a
minimum and ease maintainability.
Signed-off-by: Tyler Hicks <tyhicks@canonical.com>
---
include/linux/capability.h | 5 +++++
kernel/capability.c | 46 ++++++++++++++++++++++++++++++++++++----------
2 files changed, 41 insertions(+), 10 deletions(-)
diff --git a/include/linux/capability.h b/include/linux/capability.h
index 00690ff..5f3c63d 100644
--- a/include/linux/capability.h
+++ b/include/linux/capability.h
@@ -206,6 +206,7 @@ extern bool has_ns_capability_noaudit(struct task_struct *t,
struct user_namespace *ns, int cap);
extern bool capable(int cap);
extern bool ns_capable(struct user_namespace *ns, int cap);
+extern bool ns_capable_noaudit(struct user_namespace *ns, int cap);
#else
static inline bool has_capability(struct task_struct *t, int cap)
{
@@ -233,6 +234,10 @@ static inline bool ns_capable(struct user_namespace *ns, int cap)
{
return true;
}
+static inline bool ns_capable_noaudit(struct user_namespace *ns, int cap)
+{
+ return true;
+}
#endif /* CONFIG_MULTIUSER */
extern bool capable_wrt_inode_uidgid(const struct inode *inode, int cap);
extern bool file_ns_capable(const struct file *file, struct user_namespace *ns, int cap);
diff --git a/kernel/capability.c b/kernel/capability.c
index 45432b5..00411c8 100644
--- a/kernel/capability.c
+++ b/kernel/capability.c
@@ -361,6 +361,24 @@ bool has_capability_noaudit(struct task_struct *t, int cap)
return has_ns_capability_noaudit(t, &init_user_ns, cap);
}
+static bool ns_capable_common(struct user_namespace *ns, int cap, bool audit)
+{
+ int capable;
+
+ if (unlikely(!cap_valid(cap))) {
+ pr_crit("capable() called with invalid cap=%u\n", cap);
+ BUG();
+ }
+
+ capable = audit ? security_capable(current_cred(), ns, cap) :
+ security_capable_noaudit(current_cred(), ns, cap);
+ if (capable == 0) {
+ current->flags |= PF_SUPERPRIV;
+ return true;
+ }
+ return false;
+}
+
/**
* ns_capable - Determine if the current task has a superior capability in effect
* @ns: The usernamespace we want the capability in
@@ -374,19 +392,27 @@ bool has_capability_noaudit(struct task_struct *t, int cap)
*/
bool ns_capable(struct user_namespace *ns, int cap)
{
- if (unlikely(!cap_valid(cap))) {
- pr_crit("capable() called with invalid cap=%u\n", cap);
- BUG();
- }
-
- if (security_capable(current_cred(), ns, cap) == 0) {
- current->flags |= PF_SUPERPRIV;
- return true;
- }
- return false;
+ return ns_capable_common(ns, cap, true);
}
EXPORT_SYMBOL(ns_capable);
+/**
+ * ns_capable_noaudit - Determine if the current task has a superior capability
+ * (unaudited) in effect
+ * @ns: The usernamespace we want the capability in
+ * @cap: The capability to be tested for
+ *
+ * Return true if the current task has the given superior capability currently
+ * available for use, false if not.
+ *
+ * This sets PF_SUPERPRIV on the task if the capability is available on the
+ * assumption that it's about to be used.
+ */
+bool ns_capable_noaudit(struct user_namespace *ns, int cap)
+{
+ return ns_capable_common(ns, cap, false);
+}
+EXPORT_SYMBOL(ns_capable_noaudit);
/**
* capable - Determine if the current task has a superior capability in effect
--
2.7.4
^ permalink raw reply related
* [PATCH 2/2] net: Use ns_capable_noaudit() when determining net sysctl permissions
From: Tyler Hicks @ 2016-05-06 23:04 UTC (permalink / raw)
To: linux-security-module, netdev, linux-kernel
Cc: Serge Hallyn, David S . Miller
In-Reply-To: <1462575854-4301-1-git-send-email-tyhicks@canonical.com>
The capability check should not be audited since it is only being used
to determine the inode permissions. A failed check does not indicate a
violation of security policy but, when an LSM is enabled, a denial audit
message was being generated.
The denial audit message caused confusion for some application authors
because root-running Go applications always triggered the denial. To
prevent this confusion, the capability check in net_ctl_permissions() is
switched to the noaudit variant.
BugLink: https://launchpad.net/bugs/1465724
Signed-off-by: Tyler Hicks <tyhicks@canonical.com>
---
net/sysctl_net.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/net/sysctl_net.c b/net/sysctl_net.c
index ed98c1f..46a71c7 100644
--- a/net/sysctl_net.c
+++ b/net/sysctl_net.c
@@ -46,7 +46,7 @@ static int net_ctl_permissions(struct ctl_table_header *head,
kgid_t root_gid = make_kgid(net->user_ns, 0);
/* Allow network administrator to have same access as root. */
- if (ns_capable(net->user_ns, CAP_NET_ADMIN) ||
+ if (ns_capable_noaudit(net->user_ns, CAP_NET_ADMIN) ||
uid_eq(root_uid, current_euid())) {
int mode = (table->mode >> 6) & 7;
return (mode << 6) | (mode << 3) | mode;
--
2.7.4
^ permalink raw reply related
* Re: [RFC PATCH v3 00/19] CALIPSO Implementation
From: Paul Moore @ 2016-05-06 23:07 UTC (permalink / raw)
To: Huw Davies, netdev, selinux, linux-security-module; +Cc: Paul Moore
In-Reply-To: <1455715329-9601-1-git-send-email-huw@codeweavers.com>
On Wed, Feb 17, 2016 at 8:21 AM, Huw Davies <huw@codeweavers.com> wrote:
> This patch series implements RFC 5570 - Common Architecture Label IPv6
> Security Option (CALIPSO). Its goal is to set MLS sensitivity labels
> on IPv6 packets using a hop-by-hop option. CALIPSO is very similar to
> its IPv4 cousin CIPSO and much of this series is based on that code.
>
> If anybody actually wants to play with this, then you'll need some patches
> to netlabel-tools that are currently available on the 'calipso' branch at:
> https://github.com/hdmdavies/netlabel_tools.git . The protocol has changed
> very slightly from the v2 patches, so please update to the latest.
>
> This patch series is based off v4.5-rc4.
>
> Thanks to Paul Moore, Hannes Frederic Sowa, Casey Schaufler and Julia
> Lawall for their comments so far.
>
> Changes between v3 and v2:
>
> * Change CALIPSO_MAP_PASS to 2.
> * Move calipso_init() before ipv6_sysctl_register().
> * Rewrite calipso_tlv_len() to check for overflows.
> * Simplify calispo_opt_find().
> * Simplify calipso_opt_insert().
> * Use calipso_tlv_len() in calipso_sock_getattr().
> * Simplify calipso_skbuff_setattr().
> * Return early from netlbl_domhsh_search_def() when a match is found.
> * Remove nested if from netlbl_domhsh_validate().
> * Don't return from netlbl_domhsh_add() with lock held.
> * Various style changes.
> * Rebased to v4.5-rc4.
>
> Changes between v2 and v1:
>
> * Simplify ipv6_renew_options_kern() to use set_fs(KERNEL_DS).
> Thanks to Hannes Frederic Sowa for suggesting this.
> * Use the parent socket to account for the listener socket
> option's memory usage. Again, thanks for Hannes for this.
> * Added netlbl_cfg_calipso_* functions for SMACK.
> * Rebased to v4.4-rc8.
>
> Huw Davies (19):
> netlabel: Mark rcu pointers with __rcu.
> netlabel: Add an address family to domain hash entries.
> netlabel: Initial support for the CALIPSO netlink protocol.
> netlabel: Add support for querying a CALIPSO DOI.
> netlabel: Add support for enumerating the CALIPSO DOI list.
> netlabel: Add support for creating a CALIPSO protocol domain mapping.
> netlabel: Add support for removing a CALIPSO DOI.
> ipv6: Add ipv6_renew_options_kern() that accepts a kernel mem pointer.
> netlabel: Move bitmap manipulation functions to the NetLabel core.
> calipso: Set the calipso socket label to match the secattr.
> netlabel: Prevent setsockopt() from changing the hop-by-hop option.
> ipv6: Allow request socks to contain IPv6 options.
> calipso: Allow request sockets to be relabelled by the lsm.
> ipv6: constify the skb pointer of ipv6_find_tlv().
> calipso: Allow the lsm to label the skbuff directly.
> netlabel: Pass a family parameter to netlbl_skbuff_err().
> calipso: Add validation of CALIPSO option.
> calipso: Add a label cache.
> netlabel: Implement CALIPSO config functions for SMACK.
Other than the small nit I just mentioned with respect to CALIPSO
option validation code, this all looks reasonable to me. I know you
are in the process of doing interop with Solaris TX folks, assuming
that goes well I think we are ready to throw this into linux-next with
an eye towards v4.8. For the past several weeks I've been including
this patchset in my Fedora COPR test kernels (located below), others
are welcome to try it out if they like.
DaveM, what is your take on this? I'm happy to get this into
linux-next via the SELinux tree, but it does touch some core network
code (the IPv6 option handling, much in the same way as CIPSO touched
the IPv4 option handling) and I don't want to push this if you aren't
okay with it. Of course if you want to take this via your tree that's
fine with me too.
--
paul moore
www.paul-moore.com
^ permalink raw reply
* [PATCH net-next 0/7] Driver: Vmxnet3: Version 3
From: Shrikrishna Khare @ 2016-05-06 23:12 UTC (permalink / raw)
To: netdev, linux-kernel, pv-drivers; +Cc: Shrikrishna Khare
This patchset upgrades Vmxnet3 to Version 3.
Shrikrishna Khare (7):
Driver: Vmxnet3: Prepare for version 3 changes
Driver: Vmxnet3: Introduce generic command interface to configure the
device
Driver: Vmxnet3: Allow variable length Transmit Data ring buffer
Driver: Vmxnet3: Add Receive Data Ring support
Driver: Vmxnet3: Add support for get_coalesce, set_coalesce ethtool
operations
Driver: Vmxnet3: Introduce command to register memory region
Driver: Vmxnet3: Update to Version 3
drivers/net/vmxnet3/Makefile | 4 +-
drivers/net/vmxnet3/upt1_defs.h | 4 +-
drivers/net/vmxnet3/vmxnet3_defs.h | 106 ++++++++++++-
drivers/net/vmxnet3/vmxnet3_drv.c | 278 +++++++++++++++++++++++++++-------
drivers/net/vmxnet3/vmxnet3_ethtool.c | 192 +++++++++++++++++++++--
drivers/net/vmxnet3/vmxnet3_int.h | 50 +++++-
6 files changed, 551 insertions(+), 83 deletions(-)
--
1.9.1
^ permalink raw reply
* [PATCH net-next 2/7] Driver: Vmxnet3: Introduce generic command interface to configure the device
From: Shrikrishna Khare @ 2016-05-06 23:12 UTC (permalink / raw)
To: netdev, linux-kernel, pv-drivers; +Cc: Shrikrishna Khare, Guolin Yang
In-Reply-To: <1462576336-83513-1-git-send-email-skhare@vmware.com>
Signed-off-by: Guolin Yang <gyang@vmware.com>
Signed-off-by: Shrikrishna Khare <skhare@vmware.com>
---
drivers/net/vmxnet3/vmxnet3_defs.h | 22 +++++++++++++++++++++-
1 file changed, 21 insertions(+), 1 deletion(-)
diff --git a/drivers/net/vmxnet3/vmxnet3_defs.h b/drivers/net/vmxnet3/vmxnet3_defs.h
index 8345e0c..a26a69d 100644
--- a/drivers/net/vmxnet3/vmxnet3_defs.h
+++ b/drivers/net/vmxnet3/vmxnet3_defs.h
@@ -79,6 +79,7 @@ enum {
VMXNET3_CMD_RESERVED1,
VMXNET3_CMD_LOAD_PLUGIN,
VMXNET3_CMD_RESERVED2,
+ VMXNET3_CMD_RESERVED3,
VMXNET3_CMD_FIRST_GET = 0xF00D0000,
VMXNET3_CMD_GET_QUEUE_STATUS = VMXNET3_CMD_FIRST_GET,
@@ -612,6 +613,18 @@ struct Vmxnet3_RxQueueDesc {
u8 __pad[88]; /* 128 aligned */
};
+struct Vmxnet3_SetPolling {
+ u8 enablePolling;
+};
+
+/* If the command data <= 16 bytes, use the shared memory directly.
+ * otherwise, use variable length configuration descriptor.
+ */
+union Vmxnet3_CmdInfo {
+ struct Vmxnet3_VariableLenConfDesc varConf;
+ struct Vmxnet3_SetPolling setPolling;
+ __le64 data[2];
+};
struct Vmxnet3_DSDevRead {
/* read-only region for device, read by dev in response to a SET cmd */
@@ -630,7 +643,14 @@ struct Vmxnet3_DriverShared {
__le32 pad;
struct Vmxnet3_DSDevRead devRead;
__le32 ecr;
- __le32 reserved[5];
+ __le32 reserved;
+ union {
+ __le32 reserved1[4];
+ union Vmxnet3_CmdInfo cmdInfo; /* only valid in the context of
+ * executing the relevant
+ * command
+ */
+ } cu;
};
--
1.9.1
^ permalink raw reply related
* [PATCH net-next 3/7] Driver: Vmxnet3: Allow variable length Transmit Data ring buffer
From: Shrikrishna Khare @ 2016-05-06 23:12 UTC (permalink / raw)
To: netdev, linux-kernel, pv-drivers; +Cc: Shrikrishna Khare, Sriram Rangarajan
In-Reply-To: <1462576336-83513-1-git-send-email-skhare@vmware.com>
Signed-off-by: Sriram Rangarajan <rangarajans@vmware.com>
Signed-off-by: Shrikrishna Khare <skhare@vmware.com>
---
drivers/net/vmxnet3/vmxnet3_defs.h | 12 +++++++-
drivers/net/vmxnet3/vmxnet3_drv.c | 55 ++++++++++++++++++++++++++---------
drivers/net/vmxnet3/vmxnet3_ethtool.c | 9 +++---
drivers/net/vmxnet3/vmxnet3_int.h | 7 ++++-
4 files changed, 64 insertions(+), 19 deletions(-)
diff --git a/drivers/net/vmxnet3/vmxnet3_defs.h b/drivers/net/vmxnet3/vmxnet3_defs.h
index a26a69d..701d989 100644
--- a/drivers/net/vmxnet3/vmxnet3_defs.h
+++ b/drivers/net/vmxnet3/vmxnet3_defs.h
@@ -92,6 +92,7 @@ enum {
VMXNET3_CMD_GET_DEV_EXTRA_INFO,
VMXNET3_CMD_GET_CONF_INTR,
VMXNET3_CMD_GET_RESERVED1,
+ VMXNET3_CMD_GET_TXDATA_DESC_SIZE
};
/*
@@ -377,6 +378,10 @@ union Vmxnet3_GenericDesc {
#define VMXNET3_RING_SIZE_ALIGN 32
#define VMXNET3_RING_SIZE_MASK (VMXNET3_RING_SIZE_ALIGN - 1)
+/* Tx Data Ring buffer size must be a multiple of 64 */
+#define VMXNET3_TXDATA_DESC_SIZE_ALIGN 64
+#define VMXNET3_TXDATA_DESC_SIZE_MASK (VMXNET3_TXDATA_DESC_SIZE_ALIGN - 1)
+
/* Max ring size */
#define VMXNET3_TX_RING_MAX_SIZE 4096
#define VMXNET3_TC_RING_MAX_SIZE 4096
@@ -384,6 +389,9 @@ union Vmxnet3_GenericDesc {
#define VMXNET3_RX_RING2_MAX_SIZE 4096
#define VMXNET3_RC_RING_MAX_SIZE 8192
+#define VMXNET3_TXDATA_DESC_MIN_SIZE 128
+#define VMXNET3_TXDATA_DESC_MAX_SIZE 2048
+
/* a list of reasons for queue stop */
enum {
@@ -470,7 +478,9 @@ struct Vmxnet3_TxQueueConf {
__le32 compRingSize; /* # of comp desc */
__le32 ddLen; /* size of driver data */
u8 intrIdx;
- u8 _pad[7];
+ u8 _pad1[1];
+ __le16 txDataRingDescSize;
+ u8 _pad2[4];
};
diff --git a/drivers/net/vmxnet3/vmxnet3_drv.c b/drivers/net/vmxnet3/vmxnet3_drv.c
index 53434ed..58632b1 100644
--- a/drivers/net/vmxnet3/vmxnet3_drv.c
+++ b/drivers/net/vmxnet3/vmxnet3_drv.c
@@ -435,8 +435,8 @@ vmxnet3_tq_destroy(struct vmxnet3_tx_queue *tq,
tq->tx_ring.base = NULL;
}
if (tq->data_ring.base) {
- dma_free_coherent(&adapter->pdev->dev, tq->data_ring.size *
- sizeof(struct Vmxnet3_TxDataDesc),
+ dma_free_coherent(&adapter->pdev->dev,
+ tq->data_ring.size * tq->txdata_desc_size,
tq->data_ring.base, tq->data_ring.basePA);
tq->data_ring.base = NULL;
}
@@ -478,8 +478,8 @@ vmxnet3_tq_init(struct vmxnet3_tx_queue *tq,
tq->tx_ring.next2fill = tq->tx_ring.next2comp = 0;
tq->tx_ring.gen = VMXNET3_INIT_GEN;
- memset(tq->data_ring.base, 0, tq->data_ring.size *
- sizeof(struct Vmxnet3_TxDataDesc));
+ memset(tq->data_ring.base, 0,
+ tq->data_ring.size * tq->txdata_desc_size);
/* reset the tx comp ring contents to 0 and reset comp ring states */
memset(tq->comp_ring.base, 0, tq->comp_ring.size *
@@ -514,10 +514,10 @@ vmxnet3_tq_create(struct vmxnet3_tx_queue *tq,
}
tq->data_ring.base = dma_alloc_coherent(&adapter->pdev->dev,
- tq->data_ring.size * sizeof(struct Vmxnet3_TxDataDesc),
+ tq->data_ring.size * tq->txdata_desc_size,
&tq->data_ring.basePA, GFP_KERNEL);
if (!tq->data_ring.base) {
- netdev_err(adapter->netdev, "failed to allocate data ring\n");
+ netdev_err(adapter->netdev, "failed to allocate tx data ring\n");
goto err;
}
@@ -689,7 +689,7 @@ vmxnet3_map_pkt(struct sk_buff *skb, struct vmxnet3_tx_ctx *ctx,
if (ctx->copy_size) {
ctx->sop_txd->txd.addr = cpu_to_le64(tq->data_ring.basePA +
tq->tx_ring.next2fill *
- sizeof(struct Vmxnet3_TxDataDesc));
+ tq->txdata_desc_size);
ctx->sop_txd->dword[2] = cpu_to_le32(dw2 | ctx->copy_size);
ctx->sop_txd->dword[3] = 0;
@@ -873,8 +873,9 @@ vmxnet3_parse_hdr(struct sk_buff *skb, struct vmxnet3_tx_queue *tq,
ctx->eth_ip_hdr_size = 0;
ctx->l4_hdr_size = 0;
/* copy as much as allowed */
- ctx->copy_size = min((unsigned int)VMXNET3_HDR_COPY_SIZE
- , skb_headlen(skb));
+ ctx->copy_size = min_t(unsigned int,
+ tq->txdata_desc_size,
+ skb_headlen(skb));
}
if (skb->len <= VMXNET3_HDR_COPY_SIZE)
@@ -885,7 +886,7 @@ vmxnet3_parse_hdr(struct sk_buff *skb, struct vmxnet3_tx_queue *tq,
goto err;
}
- if (unlikely(ctx->copy_size > VMXNET3_HDR_COPY_SIZE)) {
+ if (unlikely(ctx->copy_size > tq->txdata_desc_size)) {
tq->stats.oversized_hdr++;
ctx->copy_size = 0;
return 0;
@@ -2336,6 +2337,7 @@ vmxnet3_setup_driver_shared(struct vmxnet3_adapter *adapter)
tqc->ddPA = cpu_to_le64(tq->buf_info_pa);
tqc->txRingSize = cpu_to_le32(tq->tx_ring.size);
tqc->dataRingSize = cpu_to_le32(tq->data_ring.size);
+ tqc->txDataRingDescSize = cpu_to_le32(tq->txdata_desc_size);
tqc->compRingSize = cpu_to_le32(tq->comp_ring.size);
tqc->ddLen = cpu_to_le32(
sizeof(struct vmxnet3_tx_buf_info) *
@@ -2689,7 +2691,8 @@ vmxnet3_adjust_rx_ring_size(struct vmxnet3_adapter *adapter)
int
vmxnet3_create_queues(struct vmxnet3_adapter *adapter, u32 tx_ring_size,
- u32 rx_ring_size, u32 rx_ring2_size)
+ u32 rx_ring_size, u32 rx_ring2_size,
+ u16 txdata_desc_size)
{
int err = 0, i;
@@ -2698,6 +2701,7 @@ vmxnet3_create_queues(struct vmxnet3_adapter *adapter, u32 tx_ring_size,
tq->tx_ring.size = tx_ring_size;
tq->data_ring.size = tx_ring_size;
tq->comp_ring.size = tx_ring_size;
+ tq->txdata_desc_size = txdata_desc_size;
tq->shared = &adapter->tqd_start[i].ctrl;
tq->stopped = true;
tq->adapter = adapter;
@@ -2754,9 +2758,34 @@ vmxnet3_open(struct net_device *netdev)
for (i = 0; i < adapter->num_tx_queues; i++)
spin_lock_init(&adapter->tx_queue[i].tx_lock);
- err = vmxnet3_create_queues(adapter, adapter->tx_ring_size,
+ if (VMXNET3_VERSION_GE_3(adapter)) {
+ unsigned long flags;
+ u16 txdata_desc_size;
+
+ spin_lock_irqsave(&adapter->cmd_lock, flags);
+ VMXNET3_WRITE_BAR1_REG(adapter, VMXNET3_REG_CMD,
+ VMXNET3_CMD_GET_TXDATA_DESC_SIZE);
+ txdata_desc_size = VMXNET3_READ_BAR1_REG(adapter,
+ VMXNET3_REG_CMD);
+ spin_unlock_irqrestore(&adapter->cmd_lock, flags);
+
+ if ((txdata_desc_size < VMXNET3_TXDATA_DESC_MIN_SIZE) ||
+ (txdata_desc_size > VMXNET3_TXDATA_DESC_MAX_SIZE) ||
+ (txdata_desc_size & VMXNET3_TXDATA_DESC_SIZE_MASK)) {
+ adapter->txdata_desc_size =
+ sizeof(struct Vmxnet3_TxDataDesc);
+ } else {
+ adapter->txdata_desc_size = txdata_desc_size;
+ }
+ } else {
+ adapter->txdata_desc_size = sizeof(struct Vmxnet3_TxDataDesc);
+ }
+
+ err = vmxnet3_create_queues(adapter,
+ adapter->tx_ring_size,
adapter->rx_ring_size,
- adapter->rx_ring2_size);
+ adapter->rx_ring2_size,
+ adapter->txdata_desc_size);
if (err)
goto queue_err;
diff --git a/drivers/net/vmxnet3/vmxnet3_ethtool.c b/drivers/net/vmxnet3/vmxnet3_ethtool.c
index 163e99c..3b70cfe 100644
--- a/drivers/net/vmxnet3/vmxnet3_ethtool.c
+++ b/drivers/net/vmxnet3/vmxnet3_ethtool.c
@@ -396,8 +396,7 @@ vmxnet3_get_regs(struct net_device *netdev, struct ethtool_regs *regs, void *p)
buf[j++] = VMXNET3_GET_ADDR_LO(tq->data_ring.basePA);
buf[j++] = VMXNET3_GET_ADDR_HI(tq->data_ring.basePA);
buf[j++] = tq->data_ring.size;
- /* transmit data ring buffer size */
- buf[j++] = VMXNET3_HDR_COPY_SIZE;
+ buf[j++] = tq->txdata_desc_size;
buf[j++] = VMXNET3_GET_ADDR_LO(tq->comp_ring.basePA);
buf[j++] = VMXNET3_GET_ADDR_HI(tq->comp_ring.basePA);
@@ -591,7 +590,8 @@ vmxnet3_set_ringparam(struct net_device *netdev,
vmxnet3_rq_destroy_all(adapter);
err = vmxnet3_create_queues(adapter, new_tx_ring_size,
- new_rx_ring_size, new_rx_ring2_size);
+ new_rx_ring_size, new_rx_ring2_size,
+ adapter->txdata_desc_size);
if (err) {
/* failed, most likely because of OOM, try default
@@ -604,7 +604,8 @@ vmxnet3_set_ringparam(struct net_device *netdev,
err = vmxnet3_create_queues(adapter,
new_tx_ring_size,
new_rx_ring_size,
- new_rx_ring2_size);
+ new_rx_ring2_size,
+ adapter->txdata_desc_size);
if (err) {
netdev_err(netdev, "failed to create queues "
"with default sizes. Closing it\n");
diff --git a/drivers/net/vmxnet3/vmxnet3_int.h b/drivers/net/vmxnet3/vmxnet3_int.h
index 7a54903..6da7797 100644
--- a/drivers/net/vmxnet3/vmxnet3_int.h
+++ b/drivers/net/vmxnet3/vmxnet3_int.h
@@ -241,6 +241,7 @@ struct vmxnet3_tx_queue {
int num_stop; /* # of times the queue is
* stopped */
int qid;
+ u16 txdata_desc_size;
} __attribute__((__aligned__(SMP_CACHE_BYTES)));
enum vmxnet3_rx_buf_type {
@@ -363,6 +364,9 @@ struct vmxnet3_adapter {
u32 rx_ring_size;
u32 rx_ring2_size;
+ /* Size of buffer in the data ring */
+ u16 txdata_desc_size;
+
struct work_struct work;
unsigned long state; /* VMXNET3_STATE_BIT_xxx */
@@ -427,7 +431,8 @@ vmxnet3_set_features(struct net_device *netdev, netdev_features_t features);
int
vmxnet3_create_queues(struct vmxnet3_adapter *adapter,
- u32 tx_ring_size, u32 rx_ring_size, u32 rx_ring2_size);
+ u32 tx_ring_size, u32 rx_ring_size, u32 rx_ring2_size,
+ u16 txdata_desc_size);
void vmxnet3_set_ethtool_ops(struct net_device *netdev);
--
1.9.1
^ permalink raw reply related
* [PATCH net-next 4/7] Driver: Vmxnet3: Add Receive Data Ring support
From: Shrikrishna Khare @ 2016-05-06 23:12 UTC (permalink / raw)
To: netdev, linux-kernel, pv-drivers; +Cc: Shrikrishna Khare
In-Reply-To: <1462576336-83513-1-git-send-email-skhare@vmware.com>
Receive Data Ring buffer length is configurable via ethtool -G ethX rx-mini
Signed-off-by: Shrikrishna Khare <skhare@vmware.com>
---
drivers/net/vmxnet3/vmxnet3_defs.h | 14 +++-
drivers/net/vmxnet3/vmxnet3_drv.c | 153 +++++++++++++++++++++++++++-------
drivers/net/vmxnet3/vmxnet3_ethtool.c | 48 ++++++++---
drivers/net/vmxnet3/vmxnet3_int.h | 23 ++++-
4 files changed, 193 insertions(+), 45 deletions(-)
diff --git a/drivers/net/vmxnet3/vmxnet3_defs.h b/drivers/net/vmxnet3/vmxnet3_defs.h
index 701d989..f3b31c2 100644
--- a/drivers/net/vmxnet3/vmxnet3_defs.h
+++ b/drivers/net/vmxnet3/vmxnet3_defs.h
@@ -174,6 +174,8 @@ struct Vmxnet3_TxDataDesc {
u8 data[VMXNET3_HDR_COPY_SIZE];
};
+typedef u8 Vmxnet3_RxDataDesc;
+
#define VMXNET3_TCD_GEN_SHIFT 31
#define VMXNET3_TCD_GEN_SIZE 1
#define VMXNET3_TCD_TXIDX_SHIFT 0
@@ -382,6 +384,10 @@ union Vmxnet3_GenericDesc {
#define VMXNET3_TXDATA_DESC_SIZE_ALIGN 64
#define VMXNET3_TXDATA_DESC_SIZE_MASK (VMXNET3_TXDATA_DESC_SIZE_ALIGN - 1)
+/* Rx Data Ring buffer size must be a multiple of 64 */
+#define VMXNET3_RXDATA_DESC_SIZE_ALIGN 64
+#define VMXNET3_RXDATA_DESC_SIZE_MASK (VMXNET3_RXDATA_DESC_SIZE_ALIGN - 1)
+
/* Max ring size */
#define VMXNET3_TX_RING_MAX_SIZE 4096
#define VMXNET3_TC_RING_MAX_SIZE 4096
@@ -392,6 +398,8 @@ union Vmxnet3_GenericDesc {
#define VMXNET3_TXDATA_DESC_MIN_SIZE 128
#define VMXNET3_TXDATA_DESC_MAX_SIZE 2048
+#define VMXNET3_RXDATA_DESC_MAX_SIZE 2048
+
/* a list of reasons for queue stop */
enum {
@@ -488,12 +496,14 @@ struct Vmxnet3_RxQueueConf {
__le64 rxRingBasePA[2];
__le64 compRingBasePA;
__le64 ddPA; /* driver data */
- __le64 reserved;
+ __le64 rxDataRingBasePA;
__le32 rxRingSize[2]; /* # of rx desc */
__le32 compRingSize; /* # of rx comp desc */
__le32 ddLen; /* size of driver data */
u8 intrIdx;
- u8 _pad[7];
+ u8 _pad1[1];
+ __le16 rxDataRingDescSize; /* size of rx data ring buffer */
+ u8 _pad2[4];
};
diff --git a/drivers/net/vmxnet3/vmxnet3_drv.c b/drivers/net/vmxnet3/vmxnet3_drv.c
index 58632b1..a6dc7c7 100644
--- a/drivers/net/vmxnet3/vmxnet3_drv.c
+++ b/drivers/net/vmxnet3/vmxnet3_drv.c
@@ -1284,9 +1284,10 @@ vmxnet3_rq_rx_complete(struct vmxnet3_rx_queue *rq,
*/
break;
}
- BUG_ON(rcd->rqID != rq->qid && rcd->rqID != rq->qid2);
+ BUG_ON(rcd->rqID != rq->qid && rcd->rqID != rq->qid2 &&
+ rcd->rqID != rq->dataRingQid);
idx = rcd->rxdIdx;
- ring_idx = rcd->rqID < adapter->num_rx_queues ? 0 : 1;
+ ring_idx = VMXNET3_GET_RING_IDX(adapter, rcd->rqID);
ring = rq->rx_ring + ring_idx;
vmxnet3_getRxDesc(rxd, &rq->rx_ring[ring_idx].base[idx].rxd,
&rxCmdDesc);
@@ -1301,8 +1302,12 @@ vmxnet3_rq_rx_complete(struct vmxnet3_rx_queue *rq,
}
if (rcd->sop) { /* first buf of the pkt */
+ bool rxDataRingUsed;
+ u16 len;
+
BUG_ON(rxd->btype != VMXNET3_RXD_BTYPE_HEAD ||
- rcd->rqID != rq->qid);
+ (rcd->rqID != rq->qid &&
+ rcd->rqID != rq->dataRingQid));
BUG_ON(rbi->buf_type != VMXNET3_RX_BUF_SKB);
BUG_ON(ctx->skb != NULL || rbi->skb == NULL);
@@ -1318,8 +1323,12 @@ vmxnet3_rq_rx_complete(struct vmxnet3_rx_queue *rq,
skip_page_frags = false;
ctx->skb = rbi->skb;
+
+ rxDataRingUsed =
+ VMXNET3_RX_DATA_RING(adapter, rcd->rqID);
+ len = rxDataRingUsed ? rcd->len : rbi->len;
new_skb = netdev_alloc_skb_ip_align(adapter->netdev,
- rbi->len);
+ len);
if (new_skb == NULL) {
/* Skb allocation failed, do not handover this
* skb to stack. Reuse it. Drop the existing pkt
@@ -1330,25 +1339,48 @@ vmxnet3_rq_rx_complete(struct vmxnet3_rx_queue *rq,
skip_page_frags = true;
goto rcd_done;
}
- new_dma_addr = dma_map_single(&adapter->pdev->dev,
- new_skb->data, rbi->len,
- PCI_DMA_FROMDEVICE);
- if (dma_mapping_error(&adapter->pdev->dev,
- new_dma_addr)) {
- dev_kfree_skb(new_skb);
- /* Skb allocation failed, do not handover this
- * skb to stack. Reuse it. Drop the existing pkt
- */
- rq->stats.rx_buf_alloc_failure++;
- ctx->skb = NULL;
- rq->stats.drop_total++;
- skip_page_frags = true;
- goto rcd_done;
- }
- dma_unmap_single(&adapter->pdev->dev, rbi->dma_addr,
- rbi->len,
- PCI_DMA_FROMDEVICE);
+ if (rxDataRingUsed) {
+ size_t sz;
+
+ BUG_ON(rcd->len > rq->data_ring.desc_size);
+
+ ctx->skb = new_skb;
+ sz = rcd->rxdIdx * rq->data_ring.desc_size;
+ memcpy(new_skb->data,
+ &rq->data_ring.base[sz], rcd->len);
+ } else {
+ ctx->skb = rbi->skb;
+
+ new_dma_addr =
+ dma_map_single(&adapter->pdev->dev,
+ new_skb->data, rbi->len,
+ PCI_DMA_FROMDEVICE);
+ if (dma_mapping_error(&adapter->pdev->dev,
+ new_dma_addr)) {
+ dev_kfree_skb(new_skb);
+ /* Skb allocation failed, do not
+ * handover this skb to stack. Reuse
+ * it. Drop the existing pkt.
+ */
+ rq->stats.rx_buf_alloc_failure++;
+ ctx->skb = NULL;
+ rq->stats.drop_total++;
+ skip_page_frags = true;
+ goto rcd_done;
+ }
+
+ dma_unmap_single(&adapter->pdev->dev,
+ rbi->dma_addr,
+ rbi->len,
+ PCI_DMA_FROMDEVICE);
+
+ /* Immediate refill */
+ rbi->skb = new_skb;
+ rbi->dma_addr = new_dma_addr;
+ rxd->addr = cpu_to_le64(rbi->dma_addr);
+ rxd->len = rbi->len;
+ }
#ifdef VMXNET3_RSS
if (rcd->rssType != VMXNET3_RCD_RSS_TYPE_NONE &&
@@ -1359,11 +1391,6 @@ vmxnet3_rq_rx_complete(struct vmxnet3_rx_queue *rq,
#endif
skb_put(ctx->skb, rcd->len);
- /* Immediate refill */
- rbi->skb = new_skb;
- rbi->dma_addr = new_dma_addr;
- rxd->addr = cpu_to_le64(rbi->dma_addr);
- rxd->len = rbi->len;
if (VMXNET3_VERSION_GE_2(adapter) &&
rcd->type == VMXNET3_CDTYPE_RXCOMP_LRO) {
struct Vmxnet3_RxCompDescExt *rcdlro;
@@ -1590,6 +1617,13 @@ static void vmxnet3_rq_destroy(struct vmxnet3_rx_queue *rq,
rq->buf_info[i] = NULL;
}
+ if (rq->data_ring.base) {
+ dma_free_coherent(&adapter->pdev->dev,
+ rq->rx_ring[0].size * rq->data_ring.desc_size,
+ rq->data_ring.base, rq->data_ring.basePA);
+ rq->data_ring.base = NULL;
+ }
+
if (rq->comp_ring.base) {
dma_free_coherent(&adapter->pdev->dev, rq->comp_ring.size
* sizeof(struct Vmxnet3_RxCompDesc),
@@ -1605,6 +1639,25 @@ static void vmxnet3_rq_destroy(struct vmxnet3_rx_queue *rq,
}
}
+void
+vmxnet3_rq_destroy_all_rxdataring(struct vmxnet3_adapter *adapter)
+{
+ int i;
+
+ for (i = 0; i < adapter->num_rx_queues; i++) {
+ struct vmxnet3_rx_queue *rq = &adapter->rx_queue[i];
+
+ if (rq->data_ring.base) {
+ dma_free_coherent(&adapter->pdev->dev,
+ (rq->rx_ring[0].size *
+ rq->data_ring.desc_size),
+ rq->data_ring.base,
+ rq->data_ring.basePA);
+ rq->data_ring.base = NULL;
+ rq->data_ring.desc_size = 0;
+ }
+ }
+}
static int
vmxnet3_rq_init(struct vmxnet3_rx_queue *rq,
@@ -1698,6 +1751,22 @@ vmxnet3_rq_create(struct vmxnet3_rx_queue *rq, struct vmxnet3_adapter *adapter)
}
}
+ if ((adapter->rxdataring_enabled) && (rq->data_ring.desc_size != 0)) {
+ sz = rq->rx_ring[0].size * rq->data_ring.desc_size;
+ rq->data_ring.base =
+ dma_alloc_coherent(&adapter->pdev->dev, sz,
+ &rq->data_ring.basePA,
+ GFP_KERNEL);
+ if (!rq->data_ring.base) {
+ netdev_err(adapter->netdev,
+ "rx data ring will be disabled\n");
+ adapter->rxdataring_enabled = false;
+ }
+ } else {
+ rq->data_ring.base = NULL;
+ rq->data_ring.desc_size = 0;
+ }
+
sz = rq->comp_ring.size * sizeof(struct Vmxnet3_RxCompDesc);
rq->comp_ring.base = dma_alloc_coherent(&adapter->pdev->dev, sz,
&rq->comp_ring.basePA,
@@ -1730,6 +1799,8 @@ vmxnet3_rq_create_all(struct vmxnet3_adapter *adapter)
{
int i, err = 0;
+ adapter->rxdataring_enabled = VMXNET3_VERSION_GE_3(adapter);
+
for (i = 0; i < adapter->num_rx_queues; i++) {
err = vmxnet3_rq_create(&adapter->rx_queue[i], adapter);
if (unlikely(err)) {
@@ -1739,6 +1810,10 @@ vmxnet3_rq_create_all(struct vmxnet3_adapter *adapter)
goto err_out;
}
}
+
+ if (!adapter->rxdataring_enabled)
+ vmxnet3_rq_destroy_all_rxdataring(adapter);
+
return err;
err_out:
vmxnet3_rq_destroy_all(adapter);
@@ -2046,10 +2121,9 @@ vmxnet3_request_irqs(struct vmxnet3_adapter *adapter)
struct vmxnet3_rx_queue *rq = &adapter->rx_queue[i];
rq->qid = i;
rq->qid2 = i + adapter->num_rx_queues;
+ rq->dataRingQid = i + 2 * adapter->num_rx_queues;
}
-
-
/* init our intr settings */
for (i = 0; i < intr->num_intrs; i++)
intr->mod_levels[i] = UPT1_IML_ADAPTIVE;
@@ -2362,6 +2436,12 @@ vmxnet3_setup_driver_shared(struct vmxnet3_adapter *adapter)
(rqc->rxRingSize[0] +
rqc->rxRingSize[1]));
rqc->intrIdx = rq->comp_ring.intr_idx;
+ if (VMXNET3_VERSION_GE_3(adapter)) {
+ rqc->rxDataRingBasePA =
+ cpu_to_le64(rq->data_ring.basePA);
+ rqc->rxDataRingDescSize =
+ cpu_to_le16(rq->data_ring.desc_size);
+ }
}
#ifdef VMXNET3_RSS
@@ -2692,7 +2772,7 @@ vmxnet3_adjust_rx_ring_size(struct vmxnet3_adapter *adapter)
int
vmxnet3_create_queues(struct vmxnet3_adapter *adapter, u32 tx_ring_size,
u32 rx_ring_size, u32 rx_ring2_size,
- u16 txdata_desc_size)
+ u16 txdata_desc_size, u16 rxdata_desc_size)
{
int err = 0, i;
@@ -2718,12 +2798,15 @@ vmxnet3_create_queues(struct vmxnet3_adapter *adapter, u32 tx_ring_size,
adapter->rx_queue[0].rx_ring[0].size = rx_ring_size;
adapter->rx_queue[0].rx_ring[1].size = rx_ring2_size;
vmxnet3_adjust_rx_ring_size(adapter);
+
+ adapter->rxdataring_enabled = VMXNET3_VERSION_GE_3(adapter);
for (i = 0; i < adapter->num_rx_queues; i++) {
struct vmxnet3_rx_queue *rq = &adapter->rx_queue[i];
/* qid and qid2 for rx queues will be assigned later when num
* of rx queues is finalized after allocating intrs */
rq->shared = &adapter->rqd_start[i].ctrl;
rq->adapter = adapter;
+ rq->data_ring.desc_size = rxdata_desc_size;
err = vmxnet3_rq_create(rq, adapter);
if (err) {
if (i == 0) {
@@ -2741,6 +2824,10 @@ vmxnet3_create_queues(struct vmxnet3_adapter *adapter, u32 tx_ring_size,
}
}
}
+
+ if (!adapter->rxdataring_enabled)
+ vmxnet3_rq_destroy_all_rxdataring(adapter);
+
return err;
queue_err:
vmxnet3_tq_destroy_all(adapter);
@@ -2785,7 +2872,8 @@ vmxnet3_open(struct net_device *netdev)
adapter->tx_ring_size,
adapter->rx_ring_size,
adapter->rx_ring2_size,
- adapter->txdata_desc_size);
+ adapter->txdata_desc_size,
+ adapter->rxdata_desc_size);
if (err)
goto queue_err;
@@ -3260,6 +3348,9 @@ vmxnet3_probe_device(struct pci_dev *pdev,
SET_NETDEV_DEV(netdev, &pdev->dev);
vmxnet3_declare_features(adapter, dma64);
+ adapter->rxdata_desc_size = VMXNET3_VERSION_GE_3(adapter) ?
+ VMXNET3_DEF_RXDATA_DESC_SIZE : 0;
+
if (adapter->num_tx_queues == adapter->num_rx_queues)
adapter->share_intr = VMXNET3_INTR_BUDDYSHARE;
else
diff --git a/drivers/net/vmxnet3/vmxnet3_ethtool.c b/drivers/net/vmxnet3/vmxnet3_ethtool.c
index 3b70cfe..38f7c79 100644
--- a/drivers/net/vmxnet3/vmxnet3_ethtool.c
+++ b/drivers/net/vmxnet3/vmxnet3_ethtool.c
@@ -430,11 +430,10 @@ vmxnet3_get_regs(struct net_device *netdev, struct ethtool_regs *regs, void *p)
buf[j++] = rq->rx_ring[1].next2comp;
buf[j++] = rq->rx_ring[1].gen;
- /* receive data ring */
- buf[j++] = 0;
- buf[j++] = 0;
- buf[j++] = 0;
- buf[j++] = 0;
+ buf[j++] = VMXNET3_GET_ADDR_LO(rq->data_ring.basePA);
+ buf[j++] = VMXNET3_GET_ADDR_HI(rq->data_ring.basePA);
+ buf[j++] = rq->rx_ring[0].size;
+ buf[j++] = rq->data_ring.desc_size;
buf[j++] = VMXNET3_GET_ADDR_LO(rq->comp_ring.basePA);
buf[j++] = VMXNET3_GET_ADDR_HI(rq->comp_ring.basePA);
@@ -503,12 +502,14 @@ vmxnet3_get_ringparam(struct net_device *netdev,
param->rx_max_pending = VMXNET3_RX_RING_MAX_SIZE;
param->tx_max_pending = VMXNET3_TX_RING_MAX_SIZE;
- param->rx_mini_max_pending = 0;
+ param->rx_mini_max_pending = VMXNET3_VERSION_GE_3(adapter) ?
+ VMXNET3_RXDATA_DESC_MAX_SIZE : 0;
param->rx_jumbo_max_pending = VMXNET3_RX_RING2_MAX_SIZE;
param->rx_pending = adapter->rx_ring_size;
param->tx_pending = adapter->tx_ring_size;
- param->rx_mini_pending = 0;
+ param->rx_mini_pending = VMXNET3_VERSION_GE_3(adapter) ?
+ adapter->rxdata_desc_size : 0;
param->rx_jumbo_pending = adapter->rx_ring2_size;
}
@@ -519,6 +520,7 @@ vmxnet3_set_ringparam(struct net_device *netdev,
{
struct vmxnet3_adapter *adapter = netdev_priv(netdev);
u32 new_tx_ring_size, new_rx_ring_size, new_rx_ring2_size;
+ u16 new_rxdata_desc_size;
u32 sz;
int err = 0;
@@ -541,6 +543,15 @@ vmxnet3_set_ringparam(struct net_device *netdev,
return -EOPNOTSUPP;
}
+ if (VMXNET3_VERSION_GE_3(adapter)) {
+ if (param->rx_mini_pending < 0 ||
+ param->rx_mini_pending > VMXNET3_RXDATA_DESC_MAX_SIZE) {
+ return -EINVAL;
+ }
+ } else if (param->rx_mini_pending != 0) {
+ return -EINVAL;
+ }
+
/* round it up to a multiple of VMXNET3_RING_SIZE_ALIGN */
new_tx_ring_size = (param->tx_pending + VMXNET3_RING_SIZE_MASK) &
~VMXNET3_RING_SIZE_MASK;
@@ -567,9 +578,19 @@ vmxnet3_set_ringparam(struct net_device *netdev,
new_rx_ring2_size = min_t(u32, new_rx_ring2_size,
VMXNET3_RX_RING2_MAX_SIZE);
+ /* rx data ring buffer size has to be a multiple of
+ * VMXNET3_RXDATA_DESC_SIZE_ALIGN
+ */
+ new_rxdata_desc_size =
+ (param->rx_mini_pending + VMXNET3_RXDATA_DESC_SIZE_MASK) &
+ ~VMXNET3_RXDATA_DESC_SIZE_MASK;
+ new_rxdata_desc_size = min_t(u16, new_rxdata_desc_size,
+ VMXNET3_RXDATA_DESC_MAX_SIZE);
+
if (new_tx_ring_size == adapter->tx_ring_size &&
new_rx_ring_size == adapter->rx_ring_size &&
- new_rx_ring2_size == adapter->rx_ring2_size) {
+ new_rx_ring2_size == adapter->rx_ring2_size &&
+ new_rxdata_desc_size == adapter->rxdata_desc_size) {
return 0;
}
@@ -591,8 +612,8 @@ vmxnet3_set_ringparam(struct net_device *netdev,
err = vmxnet3_create_queues(adapter, new_tx_ring_size,
new_rx_ring_size, new_rx_ring2_size,
- adapter->txdata_desc_size);
-
+ adapter->txdata_desc_size,
+ new_rxdata_desc_size);
if (err) {
/* failed, most likely because of OOM, try default
* size */
@@ -601,11 +622,15 @@ vmxnet3_set_ringparam(struct net_device *netdev,
new_rx_ring_size = VMXNET3_DEF_RX_RING_SIZE;
new_rx_ring2_size = VMXNET3_DEF_RX_RING2_SIZE;
new_tx_ring_size = VMXNET3_DEF_TX_RING_SIZE;
+ new_rxdata_desc_size = VMXNET3_VERSION_GE_3(adapter) ?
+ VMXNET3_DEF_RXDATA_DESC_SIZE : 0;
+
err = vmxnet3_create_queues(adapter,
new_tx_ring_size,
new_rx_ring_size,
new_rx_ring2_size,
- adapter->txdata_desc_size);
+ adapter->txdata_desc_size,
+ new_rxdata_desc_size);
if (err) {
netdev_err(netdev, "failed to create queues "
"with default sizes. Closing it\n");
@@ -621,6 +646,7 @@ vmxnet3_set_ringparam(struct net_device *netdev,
adapter->tx_ring_size = new_tx_ring_size;
adapter->rx_ring_size = new_rx_ring_size;
adapter->rx_ring2_size = new_rx_ring2_size;
+ adapter->rxdata_desc_size = new_rxdata_desc_size;
out:
clear_bit(VMXNET3_STATE_BIT_RESETTING, &adapter->state);
diff --git a/drivers/net/vmxnet3/vmxnet3_int.h b/drivers/net/vmxnet3/vmxnet3_int.h
index 6da7797..72ef5a3 100644
--- a/drivers/net/vmxnet3/vmxnet3_int.h
+++ b/drivers/net/vmxnet3/vmxnet3_int.h
@@ -272,15 +272,23 @@ struct vmxnet3_rq_driver_stats {
u64 rx_buf_alloc_failure;
};
+struct vmxnet3_rx_data_ring {
+ Vmxnet3_RxDataDesc *base;
+ dma_addr_t basePA;
+ u16 desc_size;
+};
+
struct vmxnet3_rx_queue {
char name[IFNAMSIZ + 8]; /* To identify interrupt */
struct vmxnet3_adapter *adapter;
struct napi_struct napi;
struct vmxnet3_cmd_ring rx_ring[2];
+ struct vmxnet3_rx_data_ring data_ring;
struct vmxnet3_comp_ring comp_ring;
struct vmxnet3_rx_ctx rx_ctx;
u32 qid; /* rqID in RCD for buffer from 1st ring */
u32 qid2; /* rqID in RCD for buffer from 2nd ring */
+ u32 dataRingQid; /* rqID in RCD for buffer from data ring */
struct vmxnet3_rx_buf_info *buf_info[2];
dma_addr_t buf_info_pa;
struct Vmxnet3_RxQueueCtrl *shared;
@@ -366,6 +374,9 @@ struct vmxnet3_adapter {
/* Size of buffer in the data ring */
u16 txdata_desc_size;
+ u16 rxdata_desc_size;
+
+ bool rxdataring_enabled;
struct work_struct work;
@@ -405,9 +416,19 @@ struct vmxnet3_adapter {
#define VMXNET3_DEF_RX_RING_SIZE 256
#define VMXNET3_DEF_RX_RING2_SIZE 128
+#define VMXNET3_DEF_RXDATA_DESC_SIZE 128
+
#define VMXNET3_MAX_ETH_HDR_SIZE 22
#define VMXNET3_MAX_SKB_BUF_SIZE (3*1024)
+#define VMXNET3_GET_RING_IDX(adapter, rqID) \
+ ((rqID >= adapter->num_rx_queues && \
+ rqID < 2 * adapter->num_rx_queues) ? 1 : 0) \
+
+#define VMXNET3_RX_DATA_RING(adapter, rqID) \
+ (rqID >= 2 * adapter->num_rx_queues && \
+ rqID < 3 * adapter->num_rx_queues)
+
int
vmxnet3_quiesce_dev(struct vmxnet3_adapter *adapter);
@@ -432,7 +453,7 @@ vmxnet3_set_features(struct net_device *netdev, netdev_features_t features);
int
vmxnet3_create_queues(struct vmxnet3_adapter *adapter,
u32 tx_ring_size, u32 rx_ring_size, u32 rx_ring2_size,
- u16 txdata_desc_size);
+ u16 txdata_desc_size, u16 rxdata_desc_size);
void vmxnet3_set_ethtool_ops(struct net_device *netdev);
--
1.9.1
^ permalink raw reply related
* [PATCH net-next 5/7] Driver: Vmxnet3: Add support for get_coalesce, set_coalesce ethtool operations
From: Shrikrishna Khare @ 2016-05-06 23:12 UTC (permalink / raw)
To: netdev, linux-kernel, pv-drivers
Cc: Shrikrishna Khare, Keyong Sun, Manoj Tammali
In-Reply-To: <1462576336-83513-1-git-send-email-skhare@vmware.com>
Signed-off-by: Keyong Sun <sunk@vmware.com>
Signed-off-by: Manoj Tammali <tammalim@vmware.com>
Signed-off-by: Shrikrishna Khare <skhare@vmware.com>
---
drivers/net/vmxnet3/vmxnet3_defs.h | 32 +++++++-
drivers/net/vmxnet3/vmxnet3_drv.c | 47 ++++++++++++
drivers/net/vmxnet3/vmxnet3_ethtool.c | 135 ++++++++++++++++++++++++++++++++++
drivers/net/vmxnet3/vmxnet3_int.h | 5 ++
4 files changed, 218 insertions(+), 1 deletion(-)
diff --git a/drivers/net/vmxnet3/vmxnet3_defs.h b/drivers/net/vmxnet3/vmxnet3_defs.h
index f3b31c2..a0fdaac 100644
--- a/drivers/net/vmxnet3/vmxnet3_defs.h
+++ b/drivers/net/vmxnet3/vmxnet3_defs.h
@@ -80,6 +80,7 @@ enum {
VMXNET3_CMD_LOAD_PLUGIN,
VMXNET3_CMD_RESERVED2,
VMXNET3_CMD_RESERVED3,
+ VMXNET3_CMD_SET_COALESCE,
VMXNET3_CMD_FIRST_GET = 0xF00D0000,
VMXNET3_CMD_GET_QUEUE_STATUS = VMXNET3_CMD_FIRST_GET,
@@ -637,6 +638,36 @@ struct Vmxnet3_SetPolling {
u8 enablePolling;
};
+#define VMXNET3_COAL_STATIC_MAX_DEPTH 128
+#define VMXNET3_COAL_RBC_MIN_RATE 100
+#define VMXNET3_COAL_RBC_MAX_RATE 100000
+
+enum Vmxnet3_CoalesceMode {
+ VMXNET3_COALESCE_DEFAULT = 0,
+ VMXNET3_COALESCE_DISABLED = 1,
+ VMXNET3_COALESCE_ADAPT = 2,
+ VMXNET3_COALESCE_STATIC = 3,
+ VMXNET3_COALESCE_RBC = 4
+};
+
+struct Vmxnet3_CoalesceRbc {
+ u32 rbc_rate;
+};
+
+struct Vmxnet3_CoalesceStatic {
+ u32 tx_depth;
+ u32 tx_comp_depth;
+ u32 rx_depth;
+};
+
+struct Vmxnet3_CoalesceScheme {
+ enum Vmxnet3_CoalesceMode coalMode;
+ union {
+ struct Vmxnet3_CoalesceRbc coalRbc;
+ struct Vmxnet3_CoalesceStatic coalStatic;
+ } coalPara;
+};
+
/* If the command data <= 16 bytes, use the shared memory directly.
* otherwise, use variable length configuration descriptor.
*/
@@ -673,7 +704,6 @@ struct Vmxnet3_DriverShared {
} cu;
};
-
#define VMXNET3_ECR_RQERR (1 << 0)
#define VMXNET3_ECR_TQERR (1 << 1)
#define VMXNET3_ECR_LINK (1 << 2)
diff --git a/drivers/net/vmxnet3/vmxnet3_drv.c b/drivers/net/vmxnet3/vmxnet3_drv.c
index a6dc7c7..fe1c6ad 100644
--- a/drivers/net/vmxnet3/vmxnet3_drv.c
+++ b/drivers/net/vmxnet3/vmxnet3_drv.c
@@ -2491,6 +2491,26 @@ vmxnet3_setup_driver_shared(struct vmxnet3_adapter *adapter)
/* the rest are already zeroed */
}
+static void
+vmxnet3_init_coalesce(struct vmxnet3_adapter *adapter)
+{
+ struct Vmxnet3_DriverShared *shared = adapter->shared;
+ union Vmxnet3_CmdInfo *cmdInfo = &shared->cu.cmdInfo;
+ unsigned long flags;
+
+ if (!VMXNET3_VERSION_GE_3(adapter) ||
+ adapter->coal_conf->coalMode == VMXNET3_COALESCE_DEFAULT) {
+ return;
+ }
+
+ spin_lock_irqsave(&adapter->cmd_lock, flags);
+ cmdInfo->varConf.confVer = 1;
+ cmdInfo->varConf.confLen = cpu_to_le32(sizeof(*adapter->coal_conf));
+ cmdInfo->varConf.confPA = cpu_to_le64(adapter->coal_conf_pa);
+ VMXNET3_WRITE_BAR1_REG(adapter, VMXNET3_REG_CMD,
+ VMXNET3_CMD_SET_COALESCE);
+ spin_unlock_irqrestore(&adapter->cmd_lock, flags);
+}
int
vmxnet3_activate_dev(struct vmxnet3_adapter *adapter)
@@ -2540,6 +2560,8 @@ vmxnet3_activate_dev(struct vmxnet3_adapter *adapter)
goto activate_err;
}
+ vmxnet3_init_coalesce(adapter);
+
for (i = 0; i < adapter->num_rx_queues; i++) {
VMXNET3_WRITE_BAR0_REG(adapter,
VMXNET3_REG_RXPROD + i * VMXNET3_REG_ALIGN,
@@ -3345,6 +3367,21 @@ vmxnet3_probe_device(struct pci_dev *pdev,
goto err_ver;
}
+ if (VMXNET3_VERSION_GE_3(adapter)) {
+ adapter->coal_conf =
+ dma_alloc_coherent(&adapter->pdev->dev,
+ sizeof(struct Vmxnet3_CoalesceScheme)
+ ,
+ &adapter->coal_conf_pa,
+ GFP_KERNEL);
+ if (!adapter->coal_conf) {
+ err = -ENOMEM;
+ goto err_ver;
+ }
+ memset(adapter->coal_conf, 0, sizeof(*adapter->coal_conf));
+ adapter->coal_conf->coalMode = VMXNET3_COALESCE_DEFAULT;
+ }
+
SET_NETDEV_DEV(netdev, &pdev->dev);
vmxnet3_declare_features(adapter, dma64);
@@ -3407,6 +3444,11 @@ vmxnet3_probe_device(struct pci_dev *pdev,
return 0;
err_register:
+ if (VMXNET3_VERSION_GE_3(adapter)) {
+ dma_free_coherent(&adapter->pdev->dev,
+ sizeof(struct Vmxnet3_CoalesceScheme),
+ adapter->coal_conf, adapter->coal_conf_pa);
+ }
vmxnet3_free_intr_resources(adapter);
err_ver:
vmxnet3_free_pci_resources(adapter);
@@ -3457,6 +3499,11 @@ vmxnet3_remove_device(struct pci_dev *pdev)
vmxnet3_free_intr_resources(adapter);
vmxnet3_free_pci_resources(adapter);
+ if (VMXNET3_VERSION_GE_3(adapter)) {
+ dma_free_coherent(&adapter->pdev->dev,
+ sizeof(struct Vmxnet3_CoalesceScheme),
+ adapter->coal_conf, adapter->coal_conf_pa);
+ }
#ifdef VMXNET3_RSS
dma_free_coherent(&adapter->pdev->dev, sizeof(struct UPT1_RSSConf),
adapter->rss_conf, adapter->rss_conf_pa);
diff --git a/drivers/net/vmxnet3/vmxnet3_ethtool.c b/drivers/net/vmxnet3/vmxnet3_ethtool.c
index 38f7c79..fc52312 100644
--- a/drivers/net/vmxnet3/vmxnet3_ethtool.c
+++ b/drivers/net/vmxnet3/vmxnet3_ethtool.c
@@ -725,6 +725,139 @@ vmxnet3_set_rss(struct net_device *netdev, const u32 *p, const u8 *key,
}
#endif
+static int
+vmxnet3_get_coalesce(struct net_device *netdev, struct ethtool_coalesce *ec)
+{
+ struct vmxnet3_adapter *adapter = netdev_priv(netdev);
+
+ if (!VMXNET3_VERSION_GE_3(adapter))
+ return -EOPNOTSUPP;
+
+ switch (adapter->coal_conf->coalMode) {
+ case VMXNET3_COALESCE_DEFAULT:
+ case VMXNET3_COALESCE_DISABLED:
+ case VMXNET3_COALESCE_ADAPT:
+ case VMXNET3_COALESCE_STATIC:
+ ec->rx_coalesce_usecs = adapter->coal_conf->coalMode;
+ break;
+ case VMXNET3_COALESCE_RBC:
+ ec->rx_coalesce_usecs =
+ adapter->coal_conf->coalPara.coalRbc.rbc_rate;
+ break;
+ default:
+ return -EOPNOTSUPP;
+ }
+
+ return 0;
+}
+
+static int
+vmxnet3_set_coalesce(struct net_device *netdev, struct ethtool_coalesce *ec)
+{
+ struct vmxnet3_adapter *adapter = netdev_priv(netdev);
+ struct Vmxnet3_DriverShared *shared = adapter->shared;
+ union Vmxnet3_CmdInfo *cmdInfo = &shared->cu.cmdInfo;
+ unsigned long flags;
+
+ if (!VMXNET3_VERSION_GE_3(adapter))
+ return -EOPNOTSUPP;
+
+ if (ec->rx_max_coalesced_frames ||
+ ec->rx_coalesce_usecs_irq ||
+ ec->tx_coalesce_usecs ||
+ ec->tx_coalesce_usecs_irq ||
+ ec->stats_block_coalesce_usecs ||
+ ec->use_adaptive_rx_coalesce ||
+ ec->use_adaptive_tx_coalesce ||
+ ec->pkt_rate_low ||
+ ec->rx_coalesce_usecs_low ||
+ ec->rx_max_coalesced_frames_low ||
+ ec->tx_coalesce_usecs_low ||
+ ec->tx_max_coalesced_frames_low ||
+ ec->pkt_rate_high ||
+ ec->rx_coalesce_usecs_high ||
+ ec->rx_max_coalesced_frames_high ||
+ ec->tx_coalesce_usecs_high ||
+ ec->tx_max_coalesced_frames_high) {
+ return -EINVAL;
+ }
+
+ switch (ec->rx_coalesce_usecs) {
+ case VMXNET3_COALESCE_DEFAULT:
+ case VMXNET3_COALESCE_DISABLED:
+ case VMXNET3_COALESCE_ADAPT:
+ if (ec->tx_max_coalesced_frames ||
+ ec->tx_max_coalesced_frames_irq ||
+ ec->rx_max_coalesced_frames_irq) {
+ return -EINVAL;
+ }
+ memset(adapter->coal_conf, 0, sizeof(*adapter->coal_conf));
+ adapter->coal_conf->coalMode = ec->rx_coalesce_usecs;
+ break;
+ case VMXNET3_COALESCE_STATIC:
+ if (ec->tx_max_coalesced_frames >
+ VMXNET3_COAL_STATIC_MAX_DEPTH) {
+ return -EINVAL;
+ }
+
+ if (ec->tx_max_coalesced_frames_irq >
+ VMXNET3_COAL_STATIC_MAX_DEPTH) {
+ return -EINVAL;
+ }
+
+ if (ec->rx_max_coalesced_frames_irq >
+ VMXNET3_COAL_STATIC_MAX_DEPTH) {
+ return -EINVAL;
+ }
+
+ memset(adapter->coal_conf, 0, sizeof(*adapter->coal_conf));
+ adapter->coal_conf->coalMode = ec->rx_coalesce_usecs;
+
+ adapter->coal_conf->coalPara.coalStatic.tx_depth =
+ (ec->tx_max_coalesced_frames ?
+ ec->tx_max_coalesced_frames :
+ VMXNET3_COAL_STATIC_DEFAULT_DEPTH);
+
+ adapter->coal_conf->coalPara.coalStatic.tx_comp_depth =
+ (ec->tx_max_coalesced_frames_irq ?
+ ec->tx_max_coalesced_frames_irq :
+ VMXNET3_COAL_STATIC_DEFAULT_DEPTH);
+
+ adapter->coal_conf->coalPara.coalStatic.rx_depth =
+ (ec->rx_max_coalesced_frames_irq ?
+ ec->rx_max_coalesced_frames_irq :
+ VMXNET3_COAL_STATIC_DEFAULT_DEPTH);
+ break;
+ case VMXNET3_COAL_RBC_MIN_RATE ... VMXNET3_COAL_RBC_MAX_RATE:
+ if (ec->tx_max_coalesced_frames ||
+ ec->tx_max_coalesced_frames_irq ||
+ ec->rx_max_coalesced_frames_irq) {
+ return -EINVAL;
+ }
+ memset(adapter->coal_conf, 0, sizeof(*adapter->coal_conf));
+ adapter->coal_conf->coalMode = VMXNET3_COALESCE_RBC;
+
+ adapter->coal_conf->coalPara.coalRbc.rbc_rate =
+ ec->rx_coalesce_usecs;
+ break;
+ default:
+ return -EINVAL;
+ }
+
+ if (netif_running(netdev)) {
+ spin_lock_irqsave(&adapter->cmd_lock, flags);
+ cmdInfo->varConf.confVer = 1;
+ cmdInfo->varConf.confLen =
+ cpu_to_le32(sizeof(*adapter->coal_conf));
+ cmdInfo->varConf.confPA = cpu_to_le64(adapter->coal_conf_pa);
+ VMXNET3_WRITE_BAR1_REG(adapter, VMXNET3_REG_CMD,
+ VMXNET3_CMD_SET_COALESCE);
+ spin_unlock_irqrestore(&adapter->cmd_lock, flags);
+ }
+
+ return 0;
+}
+
static const struct ethtool_ops vmxnet3_ethtool_ops = {
.get_settings = vmxnet3_get_settings,
.get_drvinfo = vmxnet3_get_drvinfo,
@@ -733,6 +866,8 @@ static const struct ethtool_ops vmxnet3_ethtool_ops = {
.get_wol = vmxnet3_get_wol,
.set_wol = vmxnet3_set_wol,
.get_link = ethtool_op_get_link,
+ .get_coalesce = vmxnet3_get_coalesce,
+ .set_coalesce = vmxnet3_set_coalesce,
.get_strings = vmxnet3_get_strings,
.get_sset_count = vmxnet3_get_sset_count,
.get_ethtool_stats = vmxnet3_get_ethtool_stats,
diff --git a/drivers/net/vmxnet3/vmxnet3_int.h b/drivers/net/vmxnet3/vmxnet3_int.h
index 72ef5a3..8cd1851 100644
--- a/drivers/net/vmxnet3/vmxnet3_int.h
+++ b/drivers/net/vmxnet3/vmxnet3_int.h
@@ -358,6 +358,7 @@ struct vmxnet3_adapter {
int rx_buf_per_pkt; /* only apply to the 1st ring */
dma_addr_t shared_pa;
dma_addr_t queue_desc_pa;
+ dma_addr_t coal_conf_pa;
/* Wake-on-LAN */
u32 wol;
@@ -384,6 +385,8 @@ struct vmxnet3_adapter {
int share_intr;
+ struct Vmxnet3_CoalesceScheme *coal_conf;
+
dma_addr_t adapter_pa;
dma_addr_t pm_conf_pa;
dma_addr_t rss_conf_pa;
@@ -429,6 +432,8 @@ struct vmxnet3_adapter {
(rqID >= 2 * adapter->num_rx_queues && \
rqID < 3 * adapter->num_rx_queues)
+#define VMXNET3_COAL_STATIC_DEFAULT_DEPTH 64
+
int
vmxnet3_quiesce_dev(struct vmxnet3_adapter *adapter);
--
1.9.1
^ permalink raw reply related
* [PATCH net-next 6/7] Driver: Vmxnet3: Introduce command to register memory region
From: Shrikrishna Khare @ 2016-05-06 23:12 UTC (permalink / raw)
To: netdev, linux-kernel, pv-drivers; +Cc: Shrikrishna Khare, Guolin Yang
In-Reply-To: <1462576336-83513-1-git-send-email-skhare@vmware.com>
Signed-off-by: Guolin Yang <gyang@vmware.com>
Signed-off-by: Shrikrishna Khare <skhare@vmware.com>
---
drivers/net/vmxnet3/vmxnet3_defs.h | 17 +++++++++++++++++
1 file changed, 17 insertions(+)
diff --git a/drivers/net/vmxnet3/vmxnet3_defs.h b/drivers/net/vmxnet3/vmxnet3_defs.h
index a0fdaac..a336b25 100644
--- a/drivers/net/vmxnet3/vmxnet3_defs.h
+++ b/drivers/net/vmxnet3/vmxnet3_defs.h
@@ -81,6 +81,7 @@ enum {
VMXNET3_CMD_RESERVED2,
VMXNET3_CMD_RESERVED3,
VMXNET3_CMD_SET_COALESCE,
+ VMXNET3_CMD_REGISTER_MEMREGS,
VMXNET3_CMD_FIRST_GET = 0xF00D0000,
VMXNET3_CMD_GET_QUEUE_STATUS = VMXNET3_CMD_FIRST_GET,
@@ -668,6 +669,22 @@ struct Vmxnet3_CoalesceScheme {
} coalPara;
};
+struct Vmxnet3_MemoryRegion {
+ __le64 startPA;
+ __le32 length;
+ __le16 txQueueBits;
+ __le16 rxQueueBits;
+};
+
+#define MAX_MEMORY_REGION_PER_QUEUE 16
+#define MAX_MEMORY_REGION_PER_DEVICE 256
+
+struct Vmxnet3_MemRegs {
+ __le16 numRegs;
+ __le16 pad[3];
+ struct Vmxnet3_MemoryRegion memRegs[1];
+};
+
/* If the command data <= 16 bytes, use the shared memory directly.
* otherwise, use variable length configuration descriptor.
*/
--
1.9.1
^ permalink raw reply related
* [PATCH net-next 7/7] Driver: Vmxnet3: Update to Version 3
From: Shrikrishna Khare @ 2016-05-06 23:12 UTC (permalink / raw)
To: netdev, linux-kernel, pv-drivers; +Cc: Shrikrishna Khare
In-Reply-To: <1462576336-83513-1-git-send-email-skhare@vmware.com>
Signed-off-by: Shrikrishna Khare <skhare@vmware.com>
---
drivers/net/vmxnet3/vmxnet3_drv.c | 7 ++++++-
drivers/net/vmxnet3/vmxnet3_int.h | 4 ++--
2 files changed, 8 insertions(+), 3 deletions(-)
diff --git a/drivers/net/vmxnet3/vmxnet3_drv.c b/drivers/net/vmxnet3/vmxnet3_drv.c
index fe1c6ad..5f98fb2 100644
--- a/drivers/net/vmxnet3/vmxnet3_drv.c
+++ b/drivers/net/vmxnet3/vmxnet3_drv.c
@@ -3339,7 +3339,12 @@ vmxnet3_probe_device(struct pci_dev *pdev,
goto err_alloc_pci;
ver = VMXNET3_READ_BAR1_REG(adapter, VMXNET3_REG_VRRS);
- if (ver & (1 << VMXNET3_REV_2)) {
+ if (ver & (1 << VMXNET3_REV_3)) {
+ VMXNET3_WRITE_BAR1_REG(adapter,
+ VMXNET3_REG_VRRS,
+ 1 << VMXNET3_REV_3);
+ adapter->version = VMXNET3_REV_3 + 1;
+ } else if (ver & (1 << VMXNET3_REV_2)) {
VMXNET3_WRITE_BAR1_REG(adapter,
VMXNET3_REG_VRRS,
1 << VMXNET3_REV_2);
diff --git a/drivers/net/vmxnet3/vmxnet3_int.h b/drivers/net/vmxnet3/vmxnet3_int.h
index 8cd1851..cc67837 100644
--- a/drivers/net/vmxnet3/vmxnet3_int.h
+++ b/drivers/net/vmxnet3/vmxnet3_int.h
@@ -69,10 +69,10 @@
/*
* Version numbers
*/
-#define VMXNET3_DRIVER_VERSION_STRING "1.4.7.0-k"
+#define VMXNET3_DRIVER_VERSION_STRING "1.4.8.0-k"
/* a 32-bit int, each byte encode a verion number in VMXNET3_DRIVER_VERSION */
-#define VMXNET3_DRIVER_VERSION_NUM 0x01040700
+#define VMXNET3_DRIVER_VERSION_NUM 0x01040800
#if defined(CONFIG_PCI_MSI)
/* RSS only makes sense if MSI-X is supported. */
--
1.9.1
^ permalink raw reply related
* [PATCH net-next 1/7] Driver: Vmxnet3: Prepare for version 3 changes
From: Shrikrishna Khare @ 2016-05-06 23:12 UTC (permalink / raw)
To: netdev, linux-kernel, pv-drivers; +Cc: Shrikrishna Khare
In-Reply-To: <1462576336-83513-1-git-send-email-skhare@vmware.com>
Signed-off-by: Shrikrishna Khare <skhare@vmware.com>
---
drivers/net/vmxnet3/Makefile | 4 ++--
drivers/net/vmxnet3/upt1_defs.h | 4 ++--
drivers/net/vmxnet3/vmxnet3_defs.h | 9 ++++++---
drivers/net/vmxnet3/vmxnet3_drv.c | 22 +++++++++++++---------
drivers/net/vmxnet3/vmxnet3_ethtool.c | 4 ++--
drivers/net/vmxnet3/vmxnet3_int.h | 13 +++++++++++--
6 files changed, 36 insertions(+), 20 deletions(-)
diff --git a/drivers/net/vmxnet3/Makefile b/drivers/net/vmxnet3/Makefile
index 880f509..8cdbb63 100644
--- a/drivers/net/vmxnet3/Makefile
+++ b/drivers/net/vmxnet3/Makefile
@@ -2,7 +2,7 @@
#
# Linux driver for VMware's vmxnet3 ethernet NIC.
#
-# Copyright (C) 2007-2009, VMware, Inc. All Rights Reserved.
+# Copyright (C) 2007-2016, VMware, Inc. All Rights Reserved.
#
# This program is free software; you can redistribute it and/or modify it
# under the terms of the GNU General Public License as published by the
@@ -21,7 +21,7 @@
# The full GNU General Public License is included in this distribution in
# the file called "COPYING".
#
-# Maintained by: Shreyas Bhatewara <pv-drivers@vmware.com>
+# Maintained by: pv-drivers@vmware.com
#
#
################################################################################
diff --git a/drivers/net/vmxnet3/upt1_defs.h b/drivers/net/vmxnet3/upt1_defs.h
index 969c751..db9f1fd 100644
--- a/drivers/net/vmxnet3/upt1_defs.h
+++ b/drivers/net/vmxnet3/upt1_defs.h
@@ -1,7 +1,7 @@
/*
* Linux driver for VMware's vmxnet3 ethernet NIC.
*
- * Copyright (C) 2008-2009, VMware, Inc. All Rights Reserved.
+ * Copyright (C) 2008-2016, VMware, Inc. All Rights Reserved.
*
* This program is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License as published by the
@@ -20,7 +20,7 @@
* The full GNU General Public License is included in this distribution in
* the file called "COPYING".
*
- * Maintained by: Shreyas Bhatewara <pv-drivers@vmware.com>
+ * Maintained by: pv-drivers@vmware.com
*
*/
diff --git a/drivers/net/vmxnet3/vmxnet3_defs.h b/drivers/net/vmxnet3/vmxnet3_defs.h
index 72ba8ae..8345e0c 100644
--- a/drivers/net/vmxnet3/vmxnet3_defs.h
+++ b/drivers/net/vmxnet3/vmxnet3_defs.h
@@ -1,7 +1,7 @@
/*
* Linux driver for VMware's vmxnet3 ethernet NIC.
*
- * Copyright (C) 2008-2015, VMware, Inc. All Rights Reserved.
+ * Copyright (C) 2008-2016, VMware, Inc. All Rights Reserved.
*
* This program is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License as published by the
@@ -20,7 +20,7 @@
* The full GNU General Public License is included in this distribution in
* the file called "COPYING".
*
- * Maintained by: Shreyas Bhatewara <pv-drivers@vmware.com>
+ * Maintained by: pv-drivers@vmware.com
*
*/
@@ -76,7 +76,9 @@ enum {
VMXNET3_CMD_UPDATE_IML,
VMXNET3_CMD_UPDATE_PMCFG,
VMXNET3_CMD_UPDATE_FEATURE,
+ VMXNET3_CMD_RESERVED1,
VMXNET3_CMD_LOAD_PLUGIN,
+ VMXNET3_CMD_RESERVED2,
VMXNET3_CMD_FIRST_GET = 0xF00D0000,
VMXNET3_CMD_GET_QUEUE_STATUS = VMXNET3_CMD_FIRST_GET,
@@ -87,7 +89,8 @@ enum {
VMXNET3_CMD_GET_DID_LO,
VMXNET3_CMD_GET_DID_HI,
VMXNET3_CMD_GET_DEV_EXTRA_INFO,
- VMXNET3_CMD_GET_CONF_INTR
+ VMXNET3_CMD_GET_CONF_INTR,
+ VMXNET3_CMD_GET_RESERVED1,
};
/*
diff --git a/drivers/net/vmxnet3/vmxnet3_drv.c b/drivers/net/vmxnet3/vmxnet3_drv.c
index db8022a..53434ed 100644
--- a/drivers/net/vmxnet3/vmxnet3_drv.c
+++ b/drivers/net/vmxnet3/vmxnet3_drv.c
@@ -1,7 +1,7 @@
/*
* Linux driver for VMware's vmxnet3 ethernet NIC.
*
- * Copyright (C) 2008-2009, VMware, Inc. All Rights Reserved.
+ * Copyright (C) 2008-2016, VMware, Inc. All Rights Reserved.
*
* This program is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License as published by the
@@ -20,7 +20,7 @@
* The full GNU General Public License is included in this distribution in
* the file called "COPYING".
*
- * Maintained by: Shreyas Bhatewara <pv-drivers@vmware.com>
+ * Maintained by: pv-drivers@vmware.com
*
*/
@@ -1363,7 +1363,7 @@ vmxnet3_rq_rx_complete(struct vmxnet3_rx_queue *rq,
rbi->dma_addr = new_dma_addr;
rxd->addr = cpu_to_le64(rbi->dma_addr);
rxd->len = rbi->len;
- if (adapter->version == 2 &&
+ if (VMXNET3_VERSION_GE_2(adapter) &&
rcd->type == VMXNET3_CDTYPE_RXCOMP_LRO) {
struct Vmxnet3_RxCompDescExt *rcdlro;
rcdlro = (struct Vmxnet3_RxCompDescExt *)rcd;
@@ -3200,12 +3200,16 @@ vmxnet3_probe_device(struct pci_dev *pdev,
goto err_alloc_pci;
ver = VMXNET3_READ_BAR1_REG(adapter, VMXNET3_REG_VRRS);
- if (ver & 2) {
- VMXNET3_WRITE_BAR1_REG(adapter, VMXNET3_REG_VRRS, 2);
- adapter->version = 2;
- } else if (ver & 1) {
- VMXNET3_WRITE_BAR1_REG(adapter, VMXNET3_REG_VRRS, 1);
- adapter->version = 1;
+ if (ver & (1 << VMXNET3_REV_2)) {
+ VMXNET3_WRITE_BAR1_REG(adapter,
+ VMXNET3_REG_VRRS,
+ 1 << VMXNET3_REV_2);
+ adapter->version = VMXNET3_REV_2 + 1;
+ } else if (ver & (1 << VMXNET3_REV_1)) {
+ VMXNET3_WRITE_BAR1_REG(adapter,
+ VMXNET3_REG_VRRS,
+ 1 << VMXNET3_REV_1);
+ adapter->version = VMXNET3_REV_1 + 1;
} else {
dev_err(&pdev->dev,
"Incompatible h/w version (0x%x) for adapter\n", ver);
diff --git a/drivers/net/vmxnet3/vmxnet3_ethtool.c b/drivers/net/vmxnet3/vmxnet3_ethtool.c
index 9ba11d7..163e99c 100644
--- a/drivers/net/vmxnet3/vmxnet3_ethtool.c
+++ b/drivers/net/vmxnet3/vmxnet3_ethtool.c
@@ -1,7 +1,7 @@
/*
* Linux driver for VMware's vmxnet3 ethernet NIC.
*
- * Copyright (C) 2008-2009, VMware, Inc. All Rights Reserved.
+ * Copyright (C) 2008-2016, VMware, Inc. All Rights Reserved.
*
* This program is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License as published by the
@@ -20,7 +20,7 @@
* The full GNU General Public License is included in this distribution in
* the file called "COPYING".
*
- * Maintained by: Shreyas Bhatewara <pv-drivers@vmware.com>
+ * Maintained by: pv-drivers@vmware.com
*
*/
diff --git a/drivers/net/vmxnet3/vmxnet3_int.h b/drivers/net/vmxnet3/vmxnet3_int.h
index c482539..7a54903 100644
--- a/drivers/net/vmxnet3/vmxnet3_int.h
+++ b/drivers/net/vmxnet3/vmxnet3_int.h
@@ -1,7 +1,7 @@
/*
* Linux driver for VMware's vmxnet3 ethernet NIC.
*
- * Copyright (C) 2008-2009, VMware, Inc. All Rights Reserved.
+ * Copyright (C) 2008-2016, VMware, Inc. All Rights Reserved.
*
* This program is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License as published by the
@@ -20,7 +20,7 @@
* The full GNU General Public License is included in this distribution in
* the file called "COPYING".
*
- * Maintained by: Shreyas Bhatewara <pv-drivers@vmware.com>
+ * Maintained by: pv-drivers@vmware.com
*
*/
@@ -79,6 +79,10 @@
#define VMXNET3_RSS
#endif
+#define VMXNET3_REV_3 2 /* Vmxnet3 Rev. 3 */
+#define VMXNET3_REV_2 1 /* Vmxnet3 Rev. 2 */
+#define VMXNET3_REV_1 0 /* Vmxnet3 Rev. 1 */
+
/*
* Capabilities
*/
@@ -387,6 +391,11 @@ struct vmxnet3_adapter {
#define VMXNET3_GET_ADDR_LO(dma) ((u32)(dma))
#define VMXNET3_GET_ADDR_HI(dma) ((u32)(((u64)(dma)) >> 32))
+#define VMXNET3_VERSION_GE_2(adapter) \
+ (adapter->version >= VMXNET3_REV_2 + 1)
+#define VMXNET3_VERSION_GE_3(adapter) \
+ (adapter->version >= VMXNET3_REV_3 + 1)
+
/* must be a multiple of VMXNET3_RING_SIZE_ALIGN */
#define VMXNET3_DEF_TX_RING_SIZE 512
#define VMXNET3_DEF_RX_RING_SIZE 256
--
1.9.1
^ permalink raw reply related
* [PATCH 1/2] net: phy: add ethtool_phy_{get|set}_link_ksettings
From: Philippe Reynes @ 2016-05-06 23:18 UTC (permalink / raw)
To: f.fainelli, fugang.duan, davem; +Cc: netdev, linux-kernel, Philippe Reynes
The callback {get|set}_link_ksettings are often defined
in a very close way. There are mainly two differences in
those callback:
- the name of the netdev private structure
- the name of the struct phydev in the private structure
We add two defines ethtool_phy_{get|set}_link_ksettings
to avoid writing severals times almost the same function.
Signed-off-by: Philippe Reynes <tremyfr@gmail.com>
---
include/linux/phy.h | 46 ++++++++++++++++++++++++++++++++++++++++++++++
1 files changed, 46 insertions(+), 0 deletions(-)
diff --git a/include/linux/phy.h b/include/linux/phy.h
index be3f83b..e4a79fa 100644
--- a/include/linux/phy.h
+++ b/include/linux/phy.h
@@ -830,6 +830,52 @@ int phy_ethtool_set_wol(struct phy_device *phydev, struct ethtool_wolinfo *wol);
void phy_ethtool_get_wol(struct phy_device *phydev,
struct ethtool_wolinfo *wol);
+/**
+ * ethtool_phy_get_link_ksettings() - Helper macro for get_link_ksettings
+ * @name: name of the driver
+ * @private: name of the private structure in the net device
+ * @phy: name of the phydev variable in the private structure
+ *
+ * Helper macro for the callback get_link_ksettings which
+ * simply call phy_ethtool_ksettings_get.
+ */
+#define ethtool_phy_get_link_ksettings(name, private, phy) \
+ static int \
+ name##_get_link_ksettings(struct net_device *ndev, \
+ struct ethtool_link_ksettings *cmd) \
+ { \
+ struct private *priv = netdev_priv(ndev); \
+ struct phy_device *phydev = priv->phy; \
+ \
+ if (!phydev) \
+ return -ENODEV; \
+ \
+ return phy_ethtool_ksettings_get(phydev, cmd); \
+ }
+
+/**
+ * ethtool_phy_set_link_ksettings() - Helper macro for set_link_ksettings
+ * @name: name of the driver
+ * @private: name of the private structure in the net device
+ * @phy: name of the phydev variable in the private structure
+ *
+ * Helper macro for the callback set_link_ksettings which
+ * simply call phy_ethtool_ksettings_set.
+ */
+#define ethtool_phy_set_link_ksettings(name, private, phy) \
+ static int \
+ name##_set_link_ksettings(struct net_device *ndev, \
+ const struct ethtool_link_ksettings *cmd) \
+ { \
+ struct private *priv = netdev_priv(ndev); \
+ struct phy_device *phydev = priv->phy; \
+ \
+ if (!phydev) \
+ return -ENODEV; \
+ \
+ return phy_ethtool_ksettings_set(phydev, cmd); \
+ }
+
int __init mdio_bus_init(void);
void mdio_bus_exit(void);
--
1.7.4.4
^ permalink raw reply related
* [PATCH 2/2] net: ethernet: fec: use ethtool_phy_{get|set}_link_ksettings
From: Philippe Reynes @ 2016-05-06 23:18 UTC (permalink / raw)
To: f.fainelli, fugang.duan, davem; +Cc: netdev, linux-kernel, Philippe Reynes
In-Reply-To: <1462576729-5932-1-git-send-email-tremyfr@gmail.com>
Use the generic ethtool_phy_{get|set}_link_ksettings to
generate the callback for {get|set}_link_ksettings.
Signed-off-by: Philippe Reynes <tremyfr@gmail.com>
---
drivers/net/ethernet/freescale/fec_main.c | 25 ++-----------------------
1 files changed, 2 insertions(+), 23 deletions(-)
diff --git a/drivers/net/ethernet/freescale/fec_main.c b/drivers/net/ethernet/freescale/fec_main.c
index bfa10c3..00339d0 100644
--- a/drivers/net/ethernet/freescale/fec_main.c
+++ b/drivers/net/ethernet/freescale/fec_main.c
@@ -2058,29 +2058,8 @@ static void fec_enet_mii_remove(struct fec_enet_private *fep)
}
}
-static int fec_enet_get_link_ksettings(struct net_device *ndev,
- struct ethtool_link_ksettings *cmd)
-{
- struct fec_enet_private *fep = netdev_priv(ndev);
- struct phy_device *phydev = fep->phy_dev;
-
- if (!phydev)
- return -ENODEV;
-
- return phy_ethtool_ksettings_get(phydev, cmd);
-}
-
-static int fec_enet_set_link_ksettings(struct net_device *ndev,
- const struct ethtool_link_ksettings *cmd)
-{
- struct fec_enet_private *fep = netdev_priv(ndev);
- struct phy_device *phydev = fep->phy_dev;
-
- if (!phydev)
- return -ENODEV;
-
- return phy_ethtool_ksettings_set(phydev, cmd);
-}
+ethtool_phy_get_link_ksettings(fec_enet, fec_enet_private, phy_dev);
+ethtool_phy_set_link_ksettings(fec_enet, fec_enet_private, phy_dev);
static void fec_enet_get_drvinfo(struct net_device *ndev,
struct ethtool_drvinfo *info)
--
1.7.4.4
^ permalink raw reply related
* [PATCH net-next] ifb: support more features
From: Eric Dumazet @ 2016-05-06 23:41 UTC (permalink / raw)
To: David Miller; +Cc: netdev
From: Eric Dumazet <edumazet@google.com>
When using ifb+netem on ingress on SIT/IPIP/GRE traffic,
GRO packets are not properly processed.
Segmentation should not be forced, as ifb is already adding
quite a performance hit.
Signed-off-by: Eric Dumazet <edumazet@google.com>
---
drivers/net/ifb.c | 3 ++-
1 file changed, 2 insertions(+), 1 deletion(-)
diff --git a/drivers/net/ifb.c b/drivers/net/ifb.c
index cc56fac3c3f8..0cb5d8cbe679 100644
--- a/drivers/net/ifb.c
+++ b/drivers/net/ifb.c
@@ -197,7 +197,7 @@ static const struct net_device_ops ifb_netdev_ops = {
#define IFB_FEATURES (NETIF_F_HW_CSUM | NETIF_F_SG | NETIF_F_FRAGLIST | \
NETIF_F_TSO_ECN | NETIF_F_TSO | NETIF_F_TSO6 | \
NETIF_F_HIGHDMA | NETIF_F_HW_VLAN_CTAG_TX | \
- NETIF_F_HW_VLAN_STAG_TX)
+ NETIF_F_GSO_ENCAP_ALL | NETIF_F_HW_VLAN_STAG_TX)
static void ifb_dev_free(struct net_device *dev)
{
@@ -224,6 +224,7 @@ static void ifb_setup(struct net_device *dev)
dev->tx_queue_len = TX_Q_LIMIT;
dev->features |= IFB_FEATURES;
+ dev->hw_features |= NETIF_F_GSO_ENCAP_ALL;
dev->vlan_features |= IFB_FEATURES & ~(NETIF_F_HW_VLAN_CTAG_TX |
NETIF_F_HW_VLAN_STAG_TX);
^ permalink raw reply related
* Re: [PATCH 1/2] net: phy: add ethtool_phy_{get|set}_link_ksettings
From: Florian Fainelli @ 2016-05-06 23:41 UTC (permalink / raw)
To: Philippe Reynes, fugang.duan, davem; +Cc: netdev, linux-kernel
In-Reply-To: <1462576729-5932-1-git-send-email-tremyfr@gmail.com>
On 06/05/16 16:18, Philippe Reynes wrote:
> The callback {get|set}_link_ksettings are often defined
> in a very close way. There are mainly two differences in
> those callback:
> - the name of the netdev private structure
> - the name of the struct phydev in the private structure
>
> We add two defines ethtool_phy_{get|set}_link_ksettings
> to avoid writing severals times almost the same function.
This looks fine in principle, but then there is a whole ton of code that
could become like that in the kernel, I do not have any strong opinion
either way...
--
Florian
^ permalink raw reply
* Re: [Intel-wired-lan] [PATCH] e1000e: prevent division by zero if TIMINCA is zero
From: Rustad, Mark D @ 2016-05-06 23:43 UTC (permalink / raw)
To: Denys Vlasenko
Cc: Kirsher, Jeffrey T, intel-wired-lan@lists.osuosl.org, LKML,
netdev@vger.kernel.org
In-Reply-To: <1462563711-30350-1-git-send-email-dvlasenk@redhat.com>
[-- Attachment #1: Type: text/plain, Size: 2189 bytes --]
Denys Vlasenko <dvlasenk@redhat.com> wrote:
> Users report that under VMWare, er32(TIMINCA) returns zero.
> This causes division by zero at init time as follows:
>
> ==> incvalue = er32(TIMINCA) & E1000_TIMINCA_INCVALUE_MASK;
> for (i = 0; i < E1000_MAX_82574_SYSTIM_REREADS; i++) {
> /* latch SYSTIMH on read of SYSTIML */
> systim_next = (cycle_t)er32(SYSTIML);
> systim_next |= (cycle_t)er32(SYSTIMH) << 32;
>
> time_delta = systim_next - systim;
> temp = time_delta;
> ====> rem = do_div(temp, incvalue);
>
> This change makes kernel survive this, and users report that
> NIC does work after this change.
>
> Since on real hardware incvalue is never zero, this should not affect
> real hardware use case.
>
> Signed-off-by: Denys Vlasenko <dvlasenk@redhat.com>
> CC: Jeff Kirsher <jeffrey.t.kirsher@intel.com>
> CC: "Ruinskiy, Dima" <dima.ruinskiy@intel.com>
> CC: intel-wired-lan@lists.osuosl.org
> CC: netdev@vger.kernel.org
> CC: LKML <linux-kernel@vger.kernel.org>
> ---
> drivers/net/ethernet/intel/e1000e/netdev.c | 3 ++-
> 1 file changed, 2 insertions(+), 1 deletion(-)
>
> diff --git a/drivers/net/ethernet/intel/e1000e/netdev.c
> b/drivers/net/ethernet/intel/e1000e/netdev.c
> index 269087c..0626935 100644
> --- a/drivers/net/ethernet/intel/e1000e/netdev.c
> +++ b/drivers/net/ethernet/intel/e1000e/netdev.c
> @@ -4315,7 +4315,8 @@ static cycle_t e1000e_cyclecounter_read(const
> struct cyclecounter *cc)
>
> time_delta = systim_next - systim;
> temp = time_delta;
> - rem = do_div(temp, incvalue);
> + /* VMWare users have seen incvalue of zero, don't div / 0 */
> + rem = incvalue ? do_div(temp, incvalue) : (time_delta != 0);
>
> systim = systim_next;
>
I seem to recall that this was rejected before because it really is
VMWare's bug and, if they fix it, any existing VMs that use this will just
work. Changing the driver will only fix it for vms that install a new
driver. I don't object to doing it, it just seems like not the most
effective place to address the issue.
^ permalink raw reply
page: next (older) | prev (newer) | latest
- recent:[subjects (threaded)|topics (new)|topics (active)]
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox