Re: [PATCH v2 04/12] net: ethernet: aquantia: Low-level hardware interfaces
Hi David, [auto build test ERROR on net-next/master] [also build test ERROR on v4.10-rc2 next-20170106] [if your patch is applied to the wrong git tree, please drop us a note to help improve the system] url: https://github.com/0day-ci/linux/commits/Alexander-Loktionov/net-ethernet-aquantia-Add-AQtion-2-5-5-GB-NIC-driver/20170107-100651 config: ia64-allmodconfig (attached as .config) compiler: ia64-linux-gcc (GCC) 6.2.0 reproduce: wget https://git.kernel.org/cgit/linux/kernel/git/wfg/lkp-tests.git/plain/sbin/make.cross -O ~/bin/make.cross chmod +x ~/bin/make.cross # save the attached .config to linux build tree make.cross ARCH=ia64 Note: the linux-review/Alexander-Loktionov/net-ethernet-aquantia-Add-AQtion-2-5-5-GB-NIC-driver/20170107-100651 HEAD 3bdfdbb2c526cec3941e8e4136feb26e06a8df90 builds fine. It only hurts bisectibility. All errors (new ones prefixed by >>): >> drivers/net/ethernet/aquantia/hw_atl/hw_atl_llh.c:17:28: fatal error: >> ../aq_hw_utils.h: No such file or directory #include "../aq_hw_utils.h" ^ compilation terminated. vim +17 drivers/net/ethernet/aquantia/hw_atl/hw_atl_llh.c 11 * Atlantic registers. 12 */ 13 14 #include "hw_atl_llh.h" 15 #include "hw_atl_llh_internal.h" 16 > 17 #include "../aq_hw_utils.h" 18 19 /* global */ 20 void reg_glb_cpu_sem_set(struct aq_hw_s *aq_hw, u32 glb_cpu_sem, u32 semaphore) --- 0-DAY kernel test infrastructureOpen Source Technology Center https://lists.01.org/pipermail/kbuild-all Intel Corporation .config.gz Description: application/gzip
[PATCH net-next] mdio: Demote print from info to debug in mdio_device_register
While it is useful to know which MDIO device is being registered, demote the dev_info() to a dev_dbg(). Signed-off-by: Florian Fainelli --- drivers/net/phy/mdio_device.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/net/phy/mdio_device.c b/drivers/net/phy/mdio_device.c index 43c8fd46504b..fc336b1d 100644 --- a/drivers/net/phy/mdio_device.c +++ b/drivers/net/phy/mdio_device.c @@ -67,7 +67,7 @@ int mdio_device_register(struct mdio_device *mdiodev) { int err; - dev_info(&mdiodev->dev, "mdio_device_register\n"); + dev_dbg(&mdiodev->dev, "mdio_device_register\n"); err = mdiobus_register_device(mdiodev); if (err) -- 2.9.3
Re: [PATCH v2 12/12] net: ethernet: aquantia: Receive side scaling
Hi David, [auto build test ERROR on net-next/master] [also build test ERROR on v4.10-rc2 next-20170106] [if your patch is applied to the wrong git tree, please drop us a note to help improve the system] url: https://github.com/0day-ci/linux/commits/Alexander-Loktionov/net-ethernet-aquantia-Add-AQtion-2-5-5-GB-NIC-driver/20170107-100651 config: tile-allyesconfig (attached as .config) compiler: tilegx-linux-gcc (GCC) 4.6.2 reproduce: wget https://git.kernel.org/cgit/linux/kernel/git/wfg/lkp-tests.git/plain/sbin/make.cross -O ~/bin/make.cross chmod +x ~/bin/make.cross # save the attached .config to linux build tree make.cross ARCH=tile All error/warnings (new ones prefixed by >>): In file included from drivers/net/ethernet/aquantia/aq_main.c:14:0: >> drivers/net/ethernet/aquantia/aq_pci_func.h:20:19: warning: 'struct pci_dev' >> declared inside parameter list [enabled by default] >> drivers/net/ethernet/aquantia/aq_pci_func.h:20:19: warning: its scope is >> only this definition or declaration, which is probably not what you want >> [enabled by default] In file included from drivers/net/ethernet/aquantia/aq_main.c:16:0: >> drivers/net/ethernet/aquantia/hw_atl/hw_atl_a0.h:32:50: warning: 'struct >> pci_dev' declared inside parameter list [enabled by default] In file included from drivers/net/ethernet/aquantia/aq_main.c:17:0: >> drivers/net/ethernet/aquantia/hw_atl/hw_atl_b0.h:32:50: warning: 'struct >> pci_dev' declared inside parameter list [enabled by default] drivers/net/ethernet/aquantia/aq_main.c: In function 'aq_pci_probe_get_hw_ops_by_id': >> drivers/net/ethernet/aquantia/aq_main.c:44:2: warning: passing argument 1 of >> 'hw_atl_a0_get_ops_by_id' from incompatible pointer type [enabled by default] drivers/net/ethernet/aquantia/hw_atl/hw_atl_a0.h:32:19: note: expected 'struct pci_dev *' but argument is of type 'struct pci_dev *' >> drivers/net/ethernet/aquantia/aq_main.c:50:2: warning: passing argument 1 of >> 'hw_atl_b0_get_ops_by_id' from incompatible pointer type [enabled by default] drivers/net/ethernet/aquantia/hw_atl/hw_atl_b0.h:32:19: note: expected 'struct pci_dev *' but argument is of type 'struct pci_dev *' drivers/net/ethernet/aquantia/aq_main.c: In function 'aq_pci_probe': >> drivers/net/ethernet/aquantia/aq_main.c:224:6: warning: passing argument 2 >> of 'aq_pci_func_alloc' from incompatible pointer type [enabled by default] drivers/net/ethernet/aquantia/aq_pci_func.h:17:23: note: expected 'struct pci_dev *' but argument is of type 'struct pci_dev *' -- In file included from drivers/net/ethernet/aquantia/aq_nic.c:16:0: >> drivers/net/ethernet/aquantia/aq_pci_func.h:20:19: warning: 'struct pci_dev' >> declared inside parameter list [enabled by default] >> drivers/net/ethernet/aquantia/aq_pci_func.h:20:19: warning: its scope is >> only this definition or declaration, which is probably not what you want >> [enabled by default] -- In file included from drivers/net/ethernet/aquantia/aq_pci_func.c:12:0: >> drivers/net/ethernet/aquantia/aq_pci_func.h:20:19: warning: 'struct pci_dev' >> declared inside parameter list [enabled by default] >> drivers/net/ethernet/aquantia/aq_pci_func.h:20:19: warning: its scope is >> only this definition or declaration, which is probably not what you want >> [enabled by default] >> drivers/net/ethernet/aquantia/aq_pci_func.c:36:23: error: conflicting types >> for 'aq_pci_func_alloc' drivers/net/ethernet/aquantia/aq_pci_func.h:17:23: note: previous declaration of 'aq_pci_func_alloc' was here -- In file included from drivers/net/ethernet/aquantia/hw_atl/hw_atl_a0.c:15:0: >> drivers/net/ethernet/aquantia/hw_atl/hw_atl_a0.h:32:50: warning: 'struct >> pci_dev' declared inside parameter list [enabled by default] >> drivers/net/ethernet/aquantia/hw_atl/hw_atl_a0.h:32:50: warning: its scope >> is only this definition or declaration, which is probably not what you want >> [enabled by default] >> drivers/net/ethernet/aquantia/hw_atl/hw_atl_a0.c:897:19: error: conflicting >> types for 'hw_atl_a0_get_ops_by_id' drivers/net/ethernet/aquantia/hw_atl/hw_atl_a0.h:32:19: note: previous declaration of 'hw_atl_a0_get_ops_by_id' was here -- In file included from drivers/net/ethernet/aquantia/hw_atl/hw_atl_b0.c:14:0: >> drivers/net/ethernet/aquantia/hw_atl/../aq_pci_func.h:20:19: warning: >> 'struct pci_dev' declared inside parameter list [enabled by default] >> drivers/net/ethernet/aquantia/hw_atl/../aq_pci_func.h:20:19: warning: its
Re: [PATCH v2 12/12] net: ethernet: aquantia: Receive side scaling
Hi David, [auto build test ERROR on net-next/master] [also build test ERROR on v4.10-rc2 next-20170106] [if your patch is applied to the wrong git tree, please drop us a note to help improve the system] url: https://github.com/0day-ci/linux/commits/Alexander-Loktionov/net-ethernet-aquantia-Add-AQtion-2-5-5-GB-NIC-driver/20170107-100651 config: ia64-allyesconfig (attached as .config) compiler: ia64-linux-gcc (GCC) 6.2.0 reproduce: wget https://git.kernel.org/cgit/linux/kernel/git/wfg/lkp-tests.git/plain/sbin/make.cross -O ~/bin/make.cross chmod +x ~/bin/make.cross # save the attached .config to linux build tree make.cross ARCH=ia64 All errors (new ones prefixed by >>): In file included from drivers/net/ethernet/aquantia/hw_atl/hw_atl_a0.c:13:0: drivers/net/ethernet/aquantia/hw_atl/hw_atl_a0.c: In function 'hw_atl_a0_hw_interrupt_moderation_set': >> drivers/net/ethernet/aquantia/hw_atl/../aq_hw_utils.h:44:13: error: inlining >> failed in call to always_inline 'aq_hw_write_reg': function body not >> available inline void aq_hw_write_reg(struct aq_hw_s *hw, u32 reg, u32 value); ^~~ drivers/net/ethernet/aquantia/hw_atl/hw_atl_a0.c:811:4: note: called from here aq_hw_write_reg(self, 0x2A00U, 0x8D00U); ^~~ In file included from drivers/net/ethernet/aquantia/hw_atl/hw_atl_a0.c:13:0: >> drivers/net/ethernet/aquantia/hw_atl/../aq_hw_utils.h:44:13: error: inlining >> failed in call to always_inline 'aq_hw_write_reg': function body not >> available inline void aq_hw_write_reg(struct aq_hw_s *hw, u32 reg, u32 value); ^~~ drivers/net/ethernet/aquantia/hw_atl/hw_atl_a0.c:810:4: note: called from here aq_hw_write_reg(self, 0x2A00U, 0x4000U); ^~~ -- In file included from drivers/net/ethernet/aquantia/hw_atl/hw_atl_b0.c:13:0: drivers/net/ethernet/aquantia/hw_atl/hw_atl_b0.c: In function 'hw_atl_b0_hw_init_tx_path': >> drivers/net/ethernet/aquantia/hw_atl/../aq_hw_utils.h:44:13: error: inlining >> failed in call to always_inline 'aq_hw_write_reg': function body not >> available inline void aq_hw_write_reg(struct aq_hw_s *hw, u32 reg, u32 value); ^~~ drivers/net/ethernet/aquantia/hw_atl/hw_atl_b0.c:273:2: note: called from here aq_hw_write_reg(self, 0x7040U, IS_CHIP_FEATURE(TPO2) ? ^~ 0x0001U : 0xU); ~~ -- In file included from drivers/net/ethernet/aquantia/hw_atl/hw_atl_utils.c:15:0: drivers/net/ethernet/aquantia/hw_atl/hw_atl_utils.c: In function 'hw_atl_utils_fw_downld_dwords': >> drivers/net/ethernet/aquantia/hw_atl/../aq_hw_utils.h:44:13: error: inlining >> failed in call to always_inline 'aq_hw_write_reg': function body not >> available inline void aq_hw_write_reg(struct aq_hw_s *hw, u32 reg, u32 value); ^~~ drivers/net/ethernet/aquantia/hw_atl/hw_atl_utils.c:53:2: note: called from here aq_hw_write_reg(self, 0x0208U, a); ^ In file included from drivers/net/ethernet/aquantia/hw_atl/hw_atl_utils.c:15:0: >> drivers/net/ethernet/aquantia/hw_atl/../aq_hw_utils.h:44:13: error: inlining >> failed in call to always_inline 'aq_hw_write_reg': function body not >> available inline void aq_hw_write_reg(struct aq_hw_s *hw, u32 reg, u32 value); ^~~ drivers/net/ethernet/aquantia/hw_atl/hw_atl_utils.c:58:3: note: called from here aq_hw_write_reg(self, 0x0200U, 0x8000U); ^~~ -- In file included from drivers/net/ethernet/aquantia/hw_atl/hw_atl_llh.c:17:0: drivers/net/ethernet/aquantia/hw_atl/hw_atl_llh.c: In function 'reg_glb_cpu_sem_set': >> drivers/net/ethernet/aquantia/hw_atl/../aq_hw_utils.h:44:13: error: inlining >> failed in call to always_inline 'aq_hw_write_reg': function body not >> available inline void aq_hw_write_reg(struct aq_hw_s *hw, u32 reg, u32 value); ^~~ drivers/net/ethernet/aquantia/hw_atl/hw_atl_llh.c:22:2: note: called from here aq_hw_write_reg(aq_hw, glb_cpu_sem_adr(semaphore), glb_cpu_sem); ^~~ vim +/aq_hw_write_reg +44 drivers/net/ethernet/aquantia/hw_atl/../aq_hw_utils.h 96511018 David VomLehn 2017-01-06 28 unsigned int AQ_HW_WAIT_FOR_i; \ 96511018 David VomLehn 2017-01-06 29 for (AQ_HW_WAIT_FOR_i = _N_; (!(_B_)) && (AQ_HW_WAIT_FOR_i);\ 96511018 D
Re: [PATCH net-next 1/4] siphash: add cryptographically secure PRF
Hi Jason, just a few comments: On Fri, Jan 06, 2017 at 09:10:52PM +0100, Jason A. Donenfeld wrote: > +#define SIPHASH_ALIGNMENT __alignof__(u64) > +typedef u64 siphash_key_t[2]; I was confused by all the functions passing siphash_key_t "by value" until I saw that it's actually typedefed to u64[2]. Have you considered making it a struct instead, something like this? typedef struct { u64 v[2]; } siphash_key_t; Then it would be strongly typed and thus harder to misuse, and all the functions would take 'const siphash_key_t *' instead of 'const siphash_key_t' which would make it clear that the key is passed by pointer not by value. > +static inline u64 ___siphash_aligned(const __le64 *data, size_t len, const > siphash_key_t key) > +{ > + if (__builtin_constant_p(len) && len == 4) > + return siphash_1u32(le32_to_cpu(data[0]), key); Small bug here: data[0] is not valid if len is 4. This can be fixed by casting to a le32 pointer: return siphash_1u32(le32_to_cpup((const __le32 *)data), key); > +static int __init siphash_test_init(void) > +{ > + u8 in[64] __aligned(SIPHASH_ALIGNMENT); > + u8 in_unaligned[65]; It seems that in_unaligned+1 is meant to be misaligned, but that's not guaranteed because in_unaligned has no alignment restriction, so it could theoretically be misaligned in a way that makes in_unaligned+1 aligned. So it should be 'in_unaligned[65] __aligned(SIPHASH_ALIGNMENT)'. There are also a lot of checkpatch warnings produced by this patch. It looks like many of them can be ignored, but there may be some that should be addressed. - Eric
[PATCH] treewide: fix semicolon.cocci warnings
net/netfilter/x_tables.c:716:59-60: Unneeded semicolon Remove unneeded semicolon. Generated by: scripts/coccinelle/misc/semicolon.cocci Signed-off-by: Fengguang Wu --- x_tables.c |2 +- 1 file changed, 1 insertion(+), 1 deletion(-) --- a/net/netfilter/x_tables.c +++ b/net/netfilter/x_tables.c @@ -713,7 +713,7 @@ EXPORT_SYMBOL(xt_check_entry_offsets); unsigned int *xt_alloc_entry_offsets(unsigned int size) { if (size < (SIZE_MAX / sizeof(unsigned int))) - return kvmalloc(size * sizeof(unsigned int), GFP_KERNEL);; + return kvmalloc(size * sizeof(unsigned int), GFP_KERNEL); return NULL;
Re: [PATCH net] be2net: fix accesses to unicast list
From: Ivan Vecera Date: Fri, 6 Jan 2017 20:30:02 +0100 > Commit 988d44b "be2net: Avoid redundant addition of mac address in HW" > introduced be_dev_mac_add & be_uc_mac_add helpers that incorrectly > access adapter->uc_list as an array of bytes instead of an array of > be_eth_addr. Consequently NIC is not filled with valid data so unicast > filtering is broken. > > Cc: Sathya Perla > Cc: Ajit Khaparde > Cc: Sriharsha Basavapatna > Cc: Somnath Kotur > Fixes: 988d44b be2net: Avoid redundant addition of mac address in HW > Signed-off-by: Ivan Vecera Applied.
Re: [PATCH] netlabel: add CALIPSO to the list of built-in protocols
From: Paul Moore Date: Fri, 06 Jan 2017 14:26:54 -0500 > From: Paul Moore > > When we added CALIPSO support in Linux v4.8 we forgot to add it to the > list of supported protocols with display at boot. > > Signed-off-by: Paul Moore Applied.
Re: [PATCH net-next 0/4] l2tp: cleanup socket lookup code in l2tp_ip and l2tp_ip6
From: Guillaume Nault Date: Fri, 6 Jan 2017 20:03:53 +0100 > First three patches remove redundant tests and add missing "const" > qualifiers. > > Fourth patch splits the conditionals found in __l2tp_ip*_bind_lookup(), > to make these functions easier to review. In the process, I found that > some corner cases were still not handled properly. So I've added the > missing tests in this patch too, because they're pretty simple and the > whole "if" statements are modified anyway. > > I expect it to be easier to review this way. If not, I can split up > patch #4, post the missing tests separately to -net, and later repost > this series as pure cleanup. Just let me know. Looks good to me, series applied, thanks.
Re: [net-next][PATCH] RDS: validate the requested traces user input against max supported
From: Santosh Shilimkar Date: Fri, 6 Jan 2017 10:44:15 -0800 > Larger than supported value can lead to array read/write overflow. > > Reported-by: Colin Ian King > Signed-off-by: Santosh Shilimkar Applied, thanks.
Re: [PATCH net-next] bridge: multicast to unicast
On Mon, 2 Jan 2017 20:32:14 +0100 Linus Lüssing wrote: > This feature is intended for interface types which have a more reliable > and/or efficient way to deliver unicast packets than broadcast ones > (e.g. wifi). Why is this not done in MAC80211 rather than bridge?
[PATCH net-next v2 1/2] net: make ndo_get_stats64 a void function
The network device operation for reading statistics is only called in one place, and it ignores the return value. Having a structure return value is potentially confusing because some future driver could incorrectly assume that the return value was used. Fix all drivers with ndo_get_stats64 to have a void function. Signed-off-by: Stephen Hemminger --- v2 - fix a couple of warnings drivers/net/bonding/bond_main.c | 10 -- drivers/net/dummy.c | 5 ++--- drivers/net/ethernet/alacritech/slicoss.c| 6 ++ drivers/net/ethernet/amazon/ena/ena_netdev.c | 10 -- drivers/net/ethernet/amd/xgbe/xgbe-drv.c | 6 ++ drivers/net/ethernet/apm/xgene/xgene_enet_main.c | 4 +--- drivers/net/ethernet/atheros/alx/main.c | 6 ++ drivers/net/ethernet/broadcom/b44.c | 5 ++--- drivers/net/ethernet/broadcom/bnx2.c | 5 ++--- drivers/net/ethernet/broadcom/bnxt/bnxt.c| 6 ++ drivers/net/ethernet/broadcom/tg3.c | 8 +++- drivers/net/ethernet/brocade/bna/bnad.c | 6 ++ drivers/net/ethernet/calxeda/xgmac.c | 5 ++--- drivers/net/ethernet/cavium/thunder/nicvf_main.c | 5 ++--- drivers/net/ethernet/chelsio/cxgb4/cxgb4_main.c | 7 +++ drivers/net/ethernet/cisco/enic/enic_main.c | 8 +++- drivers/net/ethernet/ec_bhf.c| 4 +--- drivers/net/ethernet/emulex/benet/be_main.c | 5 ++--- drivers/net/ethernet/freescale/dpaa/dpaa_eth.c | 6 ++ drivers/net/ethernet/hisilicon/hns/hns_enet.c| 6 ++ drivers/net/ethernet/ibm/ehea/ehea_main.c| 5 ++--- drivers/net/ethernet/intel/e1000e/e1000.h| 4 ++-- drivers/net/ethernet/intel/e1000e/netdev.c | 5 ++--- drivers/net/ethernet/intel/fm10k/fm10k_netdev.c | 6 ++ drivers/net/ethernet/intel/i40e/i40e.h | 5 ++--- drivers/net/ethernet/intel/i40e/i40e_main.c | 18 ++ drivers/net/ethernet/intel/igb/igb_main.c| 10 -- drivers/net/ethernet/intel/ixgbe/ixgbe_main.c| 7 --- drivers/net/ethernet/intel/ixgbevf/ixgbevf_main.c| 6 ++ drivers/net/ethernet/marvell/mvneta.c| 4 +--- drivers/net/ethernet/marvell/mvpp2.c | 4 +--- drivers/net/ethernet/marvell/sky2.c | 6 ++ drivers/net/ethernet/mediatek/mtk_eth_soc.c | 6 ++ drivers/net/ethernet/mellanox/mlx4/en_netdev.c | 4 +--- drivers/net/ethernet/mellanox/mlx5/core/en_main.c| 3 +-- drivers/net/ethernet/mellanox/mlx5/core/en_rep.c | 3 +-- drivers/net/ethernet/mellanox/mlxsw/spectrum.c | 4 +--- drivers/net/ethernet/mellanox/mlxsw/switchx2.c | 3 +-- drivers/net/ethernet/myricom/myri10ge/myri10ge.c | 9 - drivers/net/ethernet/neterion/vxge/vxge-main.c | 4 +--- drivers/net/ethernet/netronome/nfp/nfp_net_common.c | 6 ++ drivers/net/ethernet/nvidia/forcedeth.c | 4 +--- drivers/net/ethernet/qlogic/netxen/netxen_nic_main.c | 10 -- drivers/net/ethernet/qlogic/qede/qede_main.c | 7 ++- drivers/net/ethernet/qualcomm/emac/emac.c| 6 ++ drivers/net/ethernet/realtek/8139too.c | 9 +++-- drivers/net/ethernet/realtek/r8169.c | 4 +--- drivers/net/ethernet/samsung/sxgbe/sxgbe_main.c | 8 ++-- drivers/net/ethernet/sfc/efx.c | 6 ++ drivers/net/ethernet/sfc/falcon/efx.c| 6 ++ drivers/net/ethernet/sun/niu.c | 6 ++ drivers/net/ethernet/synopsys/dwc_eth_qos.c | 4 +--- drivers/net/ethernet/tile/tilepro.c | 4 ++-- drivers/net/ethernet/via/via-rhine.c | 8 +++- drivers/net/fjes/fjes_main.c | 7 ++- drivers/net/hyperv/netvsc_drv.c | 6 ++ drivers/net/ifb.c| 6 ++ drivers/net/ipvlan/ipvlan_main.c | 5 ++--- drivers/net/loopback.c | 5 ++--- drivers/net/macsec.c | 8 +++- drivers/net/macvlan.c| 5 ++--- drivers/net/nlmon.c | 4 +--- drivers/net/ppp/ppp_generic.c| 4 +--- drivers/net/slip/slip.c | 3 +-- drivers/net/team/team.c | 3 +-- drivers/net/tun.c| 3 +-- drivers/net/veth.c | 6 ++ drivers/net/virtio_net.c | 6 ++ drivers/net/vmxnet3/vmxnet3_ethtool.c| 4 +--- drivers/net/vmxnet3/vmxnet3_int.h| 4 ++-- driv
[PATCH net-next 2/2] net: remove useless memset's in drivers get_stats64
In dev_get_stats() the statistic structure storage has already been zeroed. Therefore network drivers do not need to call memset() again. Signed-off-by: Stephen Hemminger --- Found while reviewing earlier patch drivers/net/ethernet/apm/xgene/xgene_enet_main.c | 1 - drivers/net/ethernet/broadcom/bnxt/bnxt.c| 2 -- drivers/net/ethernet/intel/e1000e/netdev.c | 1 - 3 files changed, 4 deletions(-) diff --git a/drivers/net/ethernet/apm/xgene/xgene_enet_main.c b/drivers/net/ethernet/apm/xgene/xgene_enet_main.c index 45f2204e6695..de59db6c5841 100644 --- a/drivers/net/ethernet/apm/xgene/xgene_enet_main.c +++ b/drivers/net/ethernet/apm/xgene/xgene_enet_main.c @@ -1462,7 +1462,6 @@ static void xgene_enet_get_stats64( struct xgene_enet_desc_ring *ring; int i; - memset(stats, 0, sizeof(struct rtnl_link_stats64)); for (i = 0; i < pdata->txq_cnt; i++) { ring = pdata->tx_ring[i]; if (ring) { diff --git a/drivers/net/ethernet/broadcom/bnxt/bnxt.c b/drivers/net/ethernet/broadcom/bnxt/bnxt.c index e5f458396e1a..7bd2a85694dd 100644 --- a/drivers/net/ethernet/broadcom/bnxt/bnxt.c +++ b/drivers/net/ethernet/broadcom/bnxt/bnxt.c @@ -5885,8 +5885,6 @@ bnxt_get_stats64(struct net_device *dev, struct rtnl_link_stats64 *stats) u32 i; struct bnxt *bp = netdev_priv(dev); - memset(stats, 0, sizeof(struct rtnl_link_stats64)); - if (!bp->bnapi) return; diff --git a/drivers/net/ethernet/intel/e1000e/netdev.c b/drivers/net/ethernet/intel/e1000e/netdev.c index bd09e5f79742..db23c9c85964 100644 --- a/drivers/net/ethernet/intel/e1000e/netdev.c +++ b/drivers/net/ethernet/intel/e1000e/netdev.c @@ -5925,7 +5925,6 @@ void e1000e_get_stats64(struct net_device *netdev, { struct e1000_adapter *adapter = netdev_priv(netdev); - memset(stats, 0, sizeof(struct rtnl_link_stats64)); spin_lock(&adapter->stats64_lock); e1000e_update_stats(adapter); /* Fill out the OS statistics structure */ -- 2.11.0
Re: [net-next PATCH] net: reduce cycles spend on ICMP replies that gets rate limited
From: Eric Dumazet Date: Fri, 06 Jan 2017 14:08:06 -0800 > On Fri, 2017-01-06 at 11:40 -0800, Eric Dumazet wrote: >> On Fri, 2017-01-06 at 18:39 +0100, Jesper Dangaard Brouer wrote: >> >> >> > @@ -648,13 +668,17 @@ void icmp_send(struct sk_buff *skb_in, int type, int >> > code, __be32 info) >> >} >> >} >> > >> > - icmp_param = kmalloc(sizeof(*icmp_param), GFP_ATOMIC); >> > - if (!icmp_param) >> > - return; >> > - >> >sk = icmp_xmit_lock(net); >> >if (!sk) >> > - goto out_free; >> > + goto out; >> > + >> > + /* Check global sysctl_icmp_msgs_per_sec ratelimit */ >> > + if (!icmpv4_global_allow(net, type, code)) >> > + goto out_unlock; >> > + >> > + icmp_param = kmalloc(sizeof(*icmp_param), GFP_ATOMIC); >> > + if (!icmp_param) >> > + goto out_unlock; >> > > You could call icmp_xmit_lock() _after_ checking global limit perhaps. BTW Eric, you asked about kmalloc() allocation, you were CC:'d in the patch which did this :-) commit 9a99d4a50cb8ce516adf0f2436138d4c8e6e4535 Author: Cong Wang Date: Sun Jun 2 15:00:52 2013 + icmp: avoid allocating large struct on stack struct icmp_bxm is a large struct, reduce stack usage by allocating it on heap. Cc: Eric Dumazet Cc: Joe Perches Cc: David S. Miller Signed-off-by: Cong Wang Signed-off-by: David S. Miller diff --git a/net/ipv4/icmp.c b/net/ipv4/icmp.c index 2864ca3..5f7d11a 100644 --- a/net/ipv4/icmp.c +++ b/net/ipv4/icmp.c @@ -482,7 +482,7 @@ void icmp_send(struct sk_buff *skb_in, int type, int code, __be32 info) { struct iphdr *iph; int room; - struct icmp_bxm icmp_param; + struct icmp_bxm *icmp_param; struct rtable *rt = skb_rtable(skb_in); struct ipcm_cookie ipc; struct flowi4 fl4; @@ -558,9 +558,13 @@ void icmp_send(struct sk_buff *skb_in, int type, int code, __be32 info) } } + icmp_param = kmalloc(sizeof(*icmp_param), GFP_ATOMIC); + if (!icmp_param) + return; + sk = icmp_xmit_lock(net); if (sk == NULL) - return; + goto out_free; /* * Construct source address and options. @@ -586,7 +590,7 @@ void icmp_send(struct sk_buff *skb_in, int type, int code, __be32 info) IPTOS_PREC_INTERNETCONTROL) : iph->tos; - if (ip_options_echo(&icmp_param.replyopts.opt.opt, skb_in)) + if (ip_options_echo(&icmp_param->replyopts.opt.opt, skb_in)) goto out_unlock; @@ -594,19 +598,19 @@ void icmp_send(struct sk_buff *skb_in, int type, int code, __be32 info) * Prepare data for ICMP header. */ - icmp_param.data.icmph.type = type; - icmp_param.data.icmph.code = code; - icmp_param.data.icmph.un.gateway = info; - icmp_param.data.icmph.checksum = 0; - icmp_param.skb= skb_in; - icmp_param.offset = skb_network_offset(skb_in); + icmp_param->data.icmph.type = type; + icmp_param->data.icmph.code = code; + icmp_param->data.icmph.un.gateway = info; + icmp_param->data.icmph.checksum = 0; + icmp_param->skb = skb_in; + icmp_param->offset = skb_network_offset(skb_in); inet_sk(sk)->tos = tos; ipc.addr = iph->saddr; - ipc.opt = &icmp_param.replyopts.opt; + ipc.opt = &icmp_param->replyopts.opt; ipc.tx_flags = 0; rt = icmp_route_lookup(net, &fl4, skb_in, iph, saddr, tos, - type, code, &icmp_param); + type, code, icmp_param); if (IS_ERR(rt)) goto out_unlock; @@ -618,19 +622,21 @@ void icmp_send(struct sk_buff *skb_in, int type, int code, __be32 info) room = dst_mtu(&rt->dst); if (room > 576) room = 576; - room -= sizeof(struct iphdr) + icmp_param.replyopts.opt.opt.optlen; + room -= sizeof(struct iphdr) + icmp_param->replyopts.opt.opt.optlen; room -= sizeof(struct icmphdr); - icmp_param.data_len = skb_in->len - icmp_param.offset; - if (icmp_param.data_len > room) - icmp_param.data_len = room; - icmp_param.head_len = sizeof(struct icmphdr); + icmp_param->data_len = skb_in->len - icmp_param->offset; + if (icmp_param->data_len > room) + icmp_param->data_len = room; + icmp_param->head_len = sizeof(struct icmphdr); - icmp_push_reply(&icmp_param, &fl4, &ipc, &rt); + icmp_push_reply(icmp_param, &fl4, &ipc, &rt); ende: ip_rt_put(rt); out_unlock: icmp_xmit_unlock(sk); +out_free: + kfree(icmp_param); out:; } EXPORT_SYMBOL(icmp_send);
Re: [PATCH net-next 0/2] afs: Implement bulk read
From: David Howells Date: Fri, 06 Jan 2017 17:08:40 + > This pair of patches implements bulk data reading from an AFS server. > > The patches can be found here also: > > > http://git.kernel.org/cgit/linux/kernel/git/dhowells/linux-fs.git/log/?h=rxrpc-rewrite > > Tagged thusly: > > git://git.kernel.org/pub/scm/linux/kernel/git/dhowells/linux-fs.git > rxrpc-rewrite-20170106 Pulled, thanks David.
Re: [PATCH next v1] ipvlan: don't use IDR for generating dev_id
From: Mahesh Bandewar Date: Fri, 6 Jan 2017 16:33:11 -0800 > From: Mahesh Bandewar > > The patch 009146d117b ("ipvlan: assign unique dev-id for each slave > device.") used ida_simple_get() to generate dev_ids assigned to the > slave devices. However (Eric has pointed out that) there is a shortcoming > with that approach as it always uses the first available ID. This > becomes a problem when a slave gets deleted and a new slave gets added. > The ID gets reassigned causing the new slave to get the same link-local > address. This side-effect is undesirable. > > This patch replaces IDR logic with a simple per-port variable that keeps > incrementing and wraps around when the MAX (0xFFFE) is reached. The > only downside is that this is an inefficient (n^2) search if there are > 64k (or close to 64k) slaves in the system, the dev-id search takes time. > However having these many devices in the system has it's own challenges. > > Fixes: 009146d117b ("ipvlan: assign unique dev-id for each slave device.") > Signed-off-by: Mahesh Bandewar I kind of cringe when I see yet another implementation of an integer ID allocator. I think it's much simpler to keep using ida_simple_alloc(), but alongside it have start point you maintain based upon previous allocations. Put it in the ipvl_port, just like dev_id_base, but call it "dev_id_start". Then your ID allocation sequence becomes: err = ida_simple_get(&port->ida, port->dev_id_start, 0xFFFE, GFP_KERNEL); if (err < 0) err = ida_simple_get(&port->ida, 0, port->dev_id_start, GFP_KERNEL); if (err < 0) goto destroy_ipvlan_port; dev->dev_id = err; port->dev_id_start = err; if (port->dev_id_start = 0FFFE) port->dev_id_start = 0; Something like that. Alternatively, IDR/IDA can be extended to have this kind of functionality too.
Re: [PATCHv3 net-next] sctp: prepare asoc stream for stream reconf
From: Xin Long Date: Fri, 6 Jan 2017 22:18:33 +0800 > sctp stream reconf, described in RFC 6525, needs a structure to > save per stream information in assoc, like stream state. > > In the future, sctp stream scheduler also needs it to save some > stream scheduler params and queues. > > This patchset is to prepare the stream array in assoc for stream > reconf. It defines sctp_stream that includes stream arrays inside > to replace ssnmap. > > Note that we use different structures for IN and OUT streams, as > the members in per OUT stream will get more and more different > from per IN stream. > > v1->v2: > - put these patches into a smaller group. > v2->v3: > - define sctp_stream to contain stream arrays, and create stream.c > to put stream-related functions. > - merge 3 patches into 1, as new sctp_stream has the same name > with before. > > Signed-off-by: Xin Long Applied, thanks.
Re: [PATCH v5 0/3] adding new glue driver dwmac-dwc-qos-eth
From: Joao Pinto Date: Fri, 6 Jan 2017 10:48:30 + > This patch set contains the porting of the synopsys/dwc_eth_qos.c driver > to the stmmac structure. This operation resulted in the creation of a new > platform glue driver called dwmac-dwc-qos-eth which was based in the > dwc_eth_qos as is. > > dwmac-dwc-qos-eth inherited dwc_eth_qos DT bindings, to assure that current > and old users can continue to use it as before. We can see this driver as > being deprecated, since all new development will be done in stmmac. > > Please check each patch for implementation details. Patch #3 doesn't apply cleanly, respin your patch against the net-next tree please.
Re: [PATCH net] udp: inuse checks can quit early for reuseport
From: Eric Garver Date: Thu, 5 Jan 2017 20:22:36 -0500 > UDP lib inuse checks will walk the entire hash bucket to check if the > portaddr is in use. In the case of reuseport we can stop searching when > we find a matching reuseport. > > On a 16-core VM a test program that spawns 16 threads that each bind to > 1024 sockets (one per 10ms) takes 1m45s. With this change it takes 11s. > > Also add a cond_resched() when the port is not specified. > > Signed-off-by: Eric Garver Applied to net-next.
Re: [PATCH net-next V2 0/3] net/sched: act_pedit: Use offset relative to conventional network headers
From: Amir Vadai Date: Thu, 5 Jan 2017 11:54:51 +0200 > Enhancing the UAPI to allow for specifying that would allow the same > flows to be set into both SW and HW. This is actually not backward compatible. When pedit rules are dumped, older tools will not know about the type field and therefore will completely misinterpret the rule. You must extend this the proper way, which is to add a new attribute or something along those lines. The presense of a new attribute is an explicit communication to older tools that somethng they might not support and understand is going on.
[PATCH net-next] net: ipmr: Remove nowait arg to ipmr_get_route
ipmr_get_route has 1 caller and the nowait arg is 0. Remove the arg and simplify ipmr_get_route accordingly. Signed-off-by: David Ahern --- include/linux/mroute.h | 2 +- net/ipv4/ipmr.c| 7 +-- net/ipv4/route.c | 2 +- 3 files changed, 3 insertions(+), 8 deletions(-) diff --git a/include/linux/mroute.h b/include/linux/mroute.h index e5fb81376e92..f019b62f27b5 100644 --- a/include/linux/mroute.h +++ b/include/linux/mroute.h @@ -120,5 +120,5 @@ struct mfc_cache { struct rtmsg; int ipmr_get_route(struct net *net, struct sk_buff *skb, __be32 saddr, __be32 daddr, - struct rtmsg *rtm, int nowait, u32 portid); + struct rtmsg *rtm, u32 portid); #endif diff --git a/net/ipv4/ipmr.c b/net/ipv4/ipmr.c index b35dda57586b..824c4fdf21eb 100644 --- a/net/ipv4/ipmr.c +++ b/net/ipv4/ipmr.c @@ -2136,7 +2136,7 @@ static int __ipmr_fill_mroute(struct mr_table *mrt, struct sk_buff *skb, int ipmr_get_route(struct net *net, struct sk_buff *skb, __be32 saddr, __be32 daddr, - struct rtmsg *rtm, int nowait, u32 portid) + struct rtmsg *rtm, u32 portid) { struct mfc_cache *cache; struct mr_table *mrt; @@ -2160,11 +2160,6 @@ int ipmr_get_route(struct net *net, struct sk_buff *skb, struct net_device *dev; int vif = -1; - if (nowait) { - rcu_read_unlock(); - return -EAGAIN; - } - dev = skb->dev; read_lock(&mrt_lock); if (dev) diff --git a/net/ipv4/route.c b/net/ipv4/route.c index b9bff78274bf..f51823dc998b 100644 --- a/net/ipv4/route.c +++ b/net/ipv4/route.c @@ -2540,7 +2540,7 @@ static int rt_fill_info(struct net *net, __be32 dst, __be32 src, u32 table_id, IPV4_DEVCONF_ALL(net, MC_FORWARDING)) { int err = ipmr_get_route(net, skb, fl4->saddr, fl4->daddr, -r, 0, portid); +r, portid); if (err <= 0) { if (err == 0) -- 2.1.4
[PATCH net-next] net: ipv4: Remove flow arg from ip_mkroute_input
fl4 arg is not used; remove it. Signed-off-by: David Ahern --- net/ipv4/route.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/net/ipv4/route.c b/net/ipv4/route.c index 7b52ac20145b..b9bff78274bf 100644 --- a/net/ipv4/route.c +++ b/net/ipv4/route.c @@ -1758,7 +1758,6 @@ static int ip_multipath_icmp_hash(struct sk_buff *skb) static int ip_mkroute_input(struct sk_buff *skb, struct fib_result *res, - const struct flowi4 *fl4, struct in_device *in_dev, __be32 daddr, __be32 saddr, u32 tos) { @@ -1883,7 +1882,7 @@ static int ip_route_input_slow(struct sk_buff *skb, __be32 daddr, __be32 saddr, if (res.type != RTN_UNICAST) goto martian_destination; - err = ip_mkroute_input(skb, &res, &fl4, in_dev, daddr, saddr, tos); + err = ip_mkroute_input(skb, &res, in_dev, daddr, saddr, tos); out: return err; brd_input: -- 2.1.4
Re: [net-next PATCH v6 0/3] net: dummy: Introduce dummy virtual functions
From: Phil Sutter Date: Thu, 5 Jan 2017 20:09:10 +0100 > This series adds VF support to dummy device driver after adding the > necessary infrastructure changes: > > Patch 1 adds a netdevice callback for device-specific VF count > retrieval. Patch 2 then changes dev_num_vf() implementation to make use > of that new callback (if implemented), falling back to the old > behaviour. Patch 3 then implements VF support in dummy, without the fake > PCI parent device hack from v5. Please don't make this a netdev specific method and interface. Put the method in "struct bus_device", thereby making it a generic "device" layer thing. So the pci BUS type will implement pci_bus_type.num_vf(). And you'll make a bus type for the dummy device to attach to which will implement it's own.
[PATCH v5] net: stmmac: fix maxmtu assignment to be within valid range
From: "Kweh, Hock Leong" There is no checking valid value of maxmtu when getting it from device tree. This resolution added the checking condition to ensure the assignment is made within a valid range. Signed-off-by: Kweh, Hock Leong --- changelog v5: * revert back that plat->maxmtu > ndev->max_mtu is a valid case when ndev->max_mtu assignment is entering to the else statement * add comment to enchance clarification changelog v4: * add print warning message when maxmtu > max_mtu as well * add maxmtu = JUMBO_LEN into each *_default_data() at stmmac_pci.c changelog v3: * print the warning message only if maxmtu < min_mtu * add maxmtu = JUMBO_LEN at stmmac_pci.c to follow stmmac_platform.c changelog v2: * correction of "devicetree" to "device tree" reported by Andy * print warning message while maxmtu is not in valid range drivers/net/ethernet/stmicro/stmmac/stmmac_main.c | 10 +- drivers/net/ethernet/stmicro/stmmac/stmmac_pci.c |6 ++ 2 files changed, 15 insertions(+), 1 deletion(-) diff --git a/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c b/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c index 92ac006..8e56dc4 100644 --- a/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c +++ b/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c @@ -3345,8 +3345,16 @@ int stmmac_dvr_probe(struct device *device, ndev->max_mtu = JUMBO_LEN; else ndev->max_mtu = SKB_MAX_HEAD(NET_SKB_PAD + NET_IP_ALIGN); - if (priv->plat->maxmtu < ndev->max_mtu) + /* Will not overwrite ndev->max_mtu if plat->maxmtu > ndev->max_mtu +* as well as plat->maxmtu < ndev->min_mtu which is a invalid range. +*/ + if ((priv->plat->maxmtu < ndev->max_mtu) && + (priv->plat->maxmtu >= ndev->min_mtu)) ndev->max_mtu = priv->plat->maxmtu; + else if (priv->plat->maxmtu < ndev->min_mtu) + netdev_warn(priv->dev, + "%s: warning: maxmtu having invalid value (%d)\n", + __func__, priv->plat->maxmtu); if (flow_ctrl) priv->flow_ctrl = FLOW_AUTO;/* RX/TX pause on */ diff --git a/drivers/net/ethernet/stmicro/stmmac/stmmac_pci.c b/drivers/net/ethernet/stmicro/stmmac/stmmac_pci.c index a283177..3da4737 100644 --- a/drivers/net/ethernet/stmicro/stmmac/stmmac_pci.c +++ b/drivers/net/ethernet/stmicro/stmmac/stmmac_pci.c @@ -89,6 +89,9 @@ static void stmmac_default_data(struct plat_stmmacenet_data *plat) /* Set default value for unicast filter entries */ plat->unicast_filter_entries = 1; + + /* Set the maxmtu to a default of JUMBO_LEN */ + plat->maxmtu = JUMBO_LEN; } static int quark_default_data(struct plat_stmmacenet_data *plat, @@ -126,6 +129,9 @@ static int quark_default_data(struct plat_stmmacenet_data *plat, /* Set default value for unicast filter entries */ plat->unicast_filter_entries = 1; + /* Set the maxmtu to a default of JUMBO_LEN */ + plat->maxmtu = JUMBO_LEN; + return 0; } -- 1.7.9.5
[PATCH net-next] liquidio: simplify octeon_flush_iq()
From: Derek Chickles Because every call to octeon_flush_iq() has a hardcoded 1 for the pending_thresh argument, simplify that function by removing that argument. This avoids one atomic read as well. Signed-off-by: Derek Chickles Signed-off-by: Felix Manlunas Signed-off-by: Satanand Burla --- drivers/net/ethernet/cavium/liquidio/lio_main.c| 2 +- drivers/net/ethernet/cavium/liquidio/lio_vf_main.c | 2 +- drivers/net/ethernet/cavium/liquidio/octeon_iq.h | 2 +- .../net/ethernet/cavium/liquidio/request_manager.c | 49 +++--- 4 files changed, 27 insertions(+), 28 deletions(-) diff --git a/drivers/net/ethernet/cavium/liquidio/lio_main.c b/drivers/net/ethernet/cavium/liquidio/lio_main.c index 6443bc1..13f67a3 100644 --- a/drivers/net/ethernet/cavium/liquidio/lio_main.c +++ b/drivers/net/ethernet/cavium/liquidio/lio_main.c @@ -2441,7 +2441,7 @@ static int liquidio_napi_poll(struct napi_struct *napi, int budget) iq = oct->instr_queue[iq_no]; if (iq) { /* Process iq buffers with in the budget limits */ - tx_done = octeon_flush_iq(oct, iq, 1, budget); + tx_done = octeon_flush_iq(oct, iq, budget); /* Update iq read-index rather than waiting for next interrupt. * Return back if tx_done is false. */ diff --git a/drivers/net/ethernet/cavium/liquidio/lio_vf_main.c b/drivers/net/ethernet/cavium/liquidio/lio_vf_main.c index 70d96c1..55846f2 100644 --- a/drivers/net/ethernet/cavium/liquidio/lio_vf_main.c +++ b/drivers/net/ethernet/cavium/liquidio/lio_vf_main.c @@ -1627,7 +1627,7 @@ static int liquidio_napi_poll(struct napi_struct *napi, int budget) iq = oct->instr_queue[iq_no]; if (iq) { /* Process iq buffers with in the budget limits */ - tx_done = octeon_flush_iq(oct, iq, 1, budget); + tx_done = octeon_flush_iq(oct, iq, budget); /* Update iq read-index rather than waiting for next interrupt. * Return back if tx_done is false. */ diff --git a/drivers/net/ethernet/cavium/liquidio/octeon_iq.h b/drivers/net/ethernet/cavium/liquidio/octeon_iq.h index e04ca8f..4608a5a 100644 --- a/drivers/net/ethernet/cavium/liquidio/octeon_iq.h +++ b/drivers/net/ethernet/cavium/liquidio/octeon_iq.h @@ -369,5 +369,5 @@ int octeon_setup_iq(struct octeon_device *oct, int ifidx, void *app_ctx); int octeon_flush_iq(struct octeon_device *oct, struct octeon_instr_queue *iq, - u32 pending_thresh, u32 napi_budget); + u32 napi_budget); #endif /* __OCTEON_IQ_H__ */ diff --git a/drivers/net/ethernet/cavium/liquidio/request_manager.c b/drivers/net/ethernet/cavium/liquidio/request_manager.c index 3ce6675..707bc15 100644 --- a/drivers/net/ethernet/cavium/liquidio/request_manager.c +++ b/drivers/net/ethernet/cavium/liquidio/request_manager.c @@ -455,7 +455,7 @@ lio_process_iq_request_list(struct octeon_device *oct, /* Can only be called from process context */ int octeon_flush_iq(struct octeon_device *oct, struct octeon_instr_queue *iq, - u32 pending_thresh, u32 napi_budget) + u32 napi_budget) { u32 inst_processed = 0; u32 tot_inst_processed = 0; @@ -468,33 +468,32 @@ octeon_flush_iq(struct octeon_device *oct, struct octeon_instr_queue *iq, iq->octeon_read_index = oct->fn_list.update_iq_read_idx(iq); - if (atomic_read(&iq->instr_pending) >= (s32)pending_thresh) { - do { - /* Process any outstanding IQ packets. */ - if (iq->flush_index == iq->octeon_read_index) - break; - - if (napi_budget) - inst_processed = lio_process_iq_request_list - (oct, iq, -napi_budget - tot_inst_processed); - else - inst_processed = - lio_process_iq_request_list(oct, iq, 0); + do { + /* Process any outstanding IQ packets. */ + if (iq->flush_index == iq->octeon_read_index) + break; - if (inst_processed) { - atomic_sub(inst_processed, &iq->instr_pending); - iq->stats.instr_processed += inst_processed; - } + if (napi_budget) + inst_processed = + lio_process_iq_request_list(oct, iq, + napi_budget - + tot_inst_processed); + else + inst_processed = + lio_process_iq_request_list(oct, iq, 0); +
Re: [next PATCH 00/11] ixgbe: Add support for writable pages and build_skb
On Fri, 2017-01-06 at 16:41 -0500, David Miller wrote: > From: Alexander Duyck > Date: Fri, 06 Jan 2017 08:06:16 -0800 > > > The testing matrix for all of these patches is going to be pretty > > extensive. Basically we want to test these patches on as many > > platforms > > and architectures as possible with as many features being toggled as > > possible including RSC, FCoE, SR-IOV, and Jumbo Frames all while > > receiving > > traffic. > > Overall looks very nice to me. > > I am assuming that I will get a formal submission once the necessary > amount of testing is performed. Yes, your assumption is correct. :-) signature.asc Description: This is a digitally signed message part
Re: [PATCH v2 03/12] net: ethernet: aquantia: Add ring support code
On 06.01.2017 09:06, Alexander Loktionov wrote: From: David VomLehn Add code to support the transmit and receive ring buffers. Signed-off-by: Alexander Loktionov Signed-off-by: Dmitrii Tarakanov Signed-off-by: Pavel Belous Signed-off-by: David M. VomLehn --- drivers/net/ethernet/aquantia/aq_ring.c | 380 drivers/net/ethernet/aquantia/aq_ring.h | 147 2 files changed, 527 insertions(+) create mode 100644 drivers/net/ethernet/aquantia/aq_ring.c create mode 100644 drivers/net/ethernet/aquantia/aq_ring.h diff --git a/drivers/net/ethernet/aquantia/aq_ring.c b/drivers/net/ethernet/aquantia/aq_ring.c new file mode 100644 index 000..a7ef6aa --- /dev/null +++ b/drivers/net/ethernet/aquantia/aq_ring.c @@ -0,0 +1,380 @@ +/* + * aQuantia Corporation Network Driver + * Copyright (C) 2014-2016 aQuantia Corporation. All rights reserved + * + * This program is free software; you can redistribute it and/or modify it + * under the terms and conditions of the GNU General Public License, + * version 2, as published by the Free Software Foundation. + */ + +/* File aq_pci_ring.c: Definition of functions for Rx/Tx rings. */ + +#include "aq_ring.h" +#include "aq_nic.h" +#include "aq_hw.h" + +#include +#include + +static struct aq_ring_s *aq_ring_alloc(struct aq_ring_s *self, + struct aq_nic_s *aq_nic, + struct aq_nic_cfg_s *aq_nic_cfg) +{ + int err = 0; + + if (!self) { + err = -ENOMEM; + goto err_exit; + } Why do you check this parameter but not the others? Beside this since the function is static the only caller is your own code, so why is a check needed at all? Can self ever be NULL? Same pattern occurs in several other functions. + +struct aq_ring_s *aq_ring_tx_alloc(struct aq_ring_s *self, + struct aq_nic_s *aq_nic, + unsigned int idx, + struct aq_nic_cfg_s *aq_nic_cfg) + +struct aq_ring_s *aq_ring_rx_alloc(struct aq_ring_s *self, + struct aq_nic_s *aq_nic, + unsigned int idx, + struct aq_nic_cfg_s *aq_nic_cfg) +{ + int err = 0; + + if (!self) { + err = -ENOMEM; + goto err_exit; + +void aq_ring_free(struct aq_ring_s *self) +{ + if (!self) + goto err_exit; + + kfree(self->buff_ring); + + if (self->dx_ring) + dma_free_coherent(aq_nic_get_dev(self->aq_nic), + self->size * self->dx_size, self->dx_ring, + self->dx_ring_pa); + +err_exit:; +} This does not make sense. Just return immediately if "self" is NULL (and if you really have to make this check). + +int aq_ring_rx_clean(struct aq_ring_s *self, int *work_done, int budget) +{ + struct net_device *ndev = aq_nic_get_ndev(self->aq_nic); + int err = 0; + bool is_rsc_completed = true; + + for (; (self->sw_head != self->hw_head) && budget; + self->sw_head = aq_ring_next_dx(self, self->sw_head), + --budget, ++(*work_done)) { + struct aq_ring_buff_s *buff = &self->buff_ring[self->sw_head]; + struct sk_buff *skb = NULL; + unsigned int next_ = 0U; + unsigned int i = 0U; + struct aq_ring_buff_s *buff_ = NULL; + + if (buff->is_error) { + __free_pages(buff->page, 0); + continue; + } + + if (buff->is_cleaned) + continue; + + ++self->stats.rx_packets; + ++ndev->stats.rx_packets; + ndev->stats.rx_bytes += buff->len; + + if (!buff->is_eop) { + for (next_ = buff->next, +buff_ = &self->buff_ring[next_]; true; +next_ = buff_->next, +buff_ = &self->buff_ring[next_]) { + is_rsc_completed = + aq_ring_dx_in_range(self->sw_head, + next_, + self->hw_head); + + if (unlikely(!is_rsc_completed)) { + is_rsc_completed = false; + break; + } + + if (buff_->is_eop) + break; + } + + if (!is_rsc_completed) { + err = 0; + goto err_exit; + } + } + + skb =
[PATCH net-next] liquidio: store the L4 hash of rx packets in skb
From: Prasad Kanneganti Store the L4 hash of received packets in the skb; the hash is computed in the NIC firmware. Signed-off-by: Prasad Kanneganti Signed-off-by: Felix Manlunas Signed-off-by: Derek Chickles Signed-off-by: Satanand Burla --- drivers/net/ethernet/cavium/liquidio/lio_main.c| 17 +++-- drivers/net/ethernet/cavium/liquidio/lio_vf_main.c | 15 ++- drivers/net/ethernet/cavium/liquidio/liquidio_common.h | 2 ++ 3 files changed, 31 insertions(+), 3 deletions(-) diff --git a/drivers/net/ethernet/cavium/liquidio/lio_main.c b/drivers/net/ethernet/cavium/liquidio/lio_main.c index 39a9665..adae858 100644 --- a/drivers/net/ethernet/cavium/liquidio/lio_main.c +++ b/drivers/net/ethernet/cavium/liquidio/lio_main.c @@ -2263,6 +2263,7 @@ liquidio_push_packet(u32 octeon_id __attribute__((unused)), struct skb_shared_hwtstamps *shhwtstamps; u64 ns; u16 vtag = 0; + u32 r_dh_off; struct net_device *netdev = (struct net_device *)arg; struct octeon_droq *droq = container_of(param, struct octeon_droq, napi); @@ -2308,6 +2309,8 @@ liquidio_push_packet(u32 octeon_id __attribute__((unused)), put_page(pg_info->page); } + r_dh_off = (rh->r_dh.len - 1) * BYTES_PER_DHLEN_UNIT; + if (((oct->chip_id == OCTEON_CN66XX) || (oct->chip_id == OCTEON_CN68XX)) && ptp_enable) { @@ -2320,16 +2323,26 @@ liquidio_push_packet(u32 octeon_id __attribute__((unused)), /* Nanoseconds are in the first 64-bits * of the packet. */ - memcpy(&ns, (skb->data), sizeof(ns)); + memcpy(&ns, (skb->data + r_dh_off), + sizeof(ns)); + r_dh_off -= BYTES_PER_DHLEN_UNIT; shhwtstamps = skb_hwtstamps(skb); shhwtstamps->hwtstamp = ns_to_ktime(ns + lio->ptp_adjust); } - skb_pull(skb, sizeof(ns)); } } + if (rh->r_dh.has_hash) { + u32 hash = be32_to_cpu(*(u32 *)(skb->data + r_dh_off)); + + skb_set_hash(skb, hash, PKT_HASH_TYPE_L4); + r_dh_off -= BYTES_PER_DHLEN_UNIT; + } + + skb_pull(skb, rh->r_dh.len * BYTES_PER_DHLEN_UNIT); + skb->protocol = eth_type_trans(skb, skb->dev); if ((netdev->features & NETIF_F_RXCSUM) && (((rh->r_dh.encap_on) && diff --git a/drivers/net/ethernet/cavium/liquidio/lio_vf_main.c b/drivers/net/ethernet/cavium/liquidio/lio_vf_main.c index 70d96c1..c0ee746 100644 --- a/drivers/net/ethernet/cavium/liquidio/lio_vf_main.c +++ b/drivers/net/ethernet/cavium/liquidio/lio_vf_main.c @@ -1497,6 +1497,7 @@ liquidio_push_packet(u32 octeon_id __attribute__((unused)), struct net_device *netdev = (struct net_device *)arg; struct sk_buff *skb = (struct sk_buff *)skbuff; u16 vtag = 0; + u32 r_dh_off; if (netdev) { struct lio *lio = GET_LIO(netdev); @@ -1540,7 +1541,19 @@ liquidio_push_packet(u32 octeon_id __attribute__((unused)), put_page(pg_info->page); } - skb_pull(skb, rh->r_dh.len * 8); + r_dh_off = (rh->r_dh.len - 1) * BYTES_PER_DHLEN_UNIT; + + if (rh->r_dh.has_hwtstamp) + r_dh_off -= BYTES_PER_DHLEN_UNIT; + + if (rh->r_dh.has_hash) { + u32 hash = be32_to_cpu(*(u32 *)(skb->data + r_dh_off)); + + skb_set_hash(skb, hash, PKT_HASH_TYPE_L4); + r_dh_off -= BYTES_PER_DHLEN_UNIT; + } + + skb_pull(skb, rh->r_dh.len * BYTES_PER_DHLEN_UNIT); skb->protocol = eth_type_trans(skb, skb->dev); if ((netdev->features & NETIF_F_RXCSUM) && diff --git a/drivers/net/ethernet/cavium/liquidio/liquidio_common.h b/drivers/net/ethernet/cavium/liquidio/liquidio_common.h index ba329f6..bc0af8a 100644 --- a/drivers/net/ethernet/cavium/liquidio/liquidio_common.h +++ b/drivers/net/ethernet/cavium/liquidio/liquidio_common.h @@ -98,6 +98,8 @@ enum octeon_tag_type { #define CVM_DRV_INVALID_APP (CVM_DRV_APP_START + 0x2) #define CVM_DRV_APP_END (CVM_DRV_INVALID_APP - 1) +#define BYTES_PER_DHLEN_UNIT8 + static inline u32 incr_index(u32 index, u32 count, u32 max) { if ((index +
RE: [PATCH v3] net: stmmac: fix maxmtu assignment to be within valid range
> -Original Message- > From: Andy Shevchenko [mailto:andy.shevche...@gmail.com] > Sent: Saturday, January 07, 2017 8:07 AM > To: Kweh, Hock Leong > Cc: David S. Miller ; Joao Pinto > ; Giuseppe CAVALLARO ; > seraphin.bonna...@st.com; Jarod Wilson ; Alexandre > TORGUE ; Joachim Eastwood > ; Niklas Cassel ; Johan Hovold > ; Pavel Machek ; lars.pers...@axis.com; > netdev ; LKML > Subject: Re: [PATCH v3] net: stmmac: fix maxmtu assignment to be within valid > range > > On Sat, Jan 7, 2017 at 1:47 AM, Kweh, Hock Leong > wrote: > > >> > --- a/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c > >> > +++ b/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c > >> > @@ -3345,8 +3345,14 @@ int stmmac_dvr_probe(struct device *device, > >> > ndev->max_mtu = JUMBO_LEN; > >> > else > >> > ndev->max_mtu = SKB_MAX_HEAD(NET_SKB_PAD + > NET_IP_ALIGN); > >> > - if (priv->plat->maxmtu < ndev->max_mtu) > >> > >> > + if ((priv->plat->maxmtu < ndev->max_mtu) && > >> > + (priv->plat->maxmtu >= ndev->min_mtu)) > >> > >> > ndev->max_mtu = priv->plat->maxmtu; > >> > >> > + else if (priv->plat->maxmtu < ndev->min_mtu) > >> > >> And if it > ndev->max_mtu?.. > >> > > > > Base on my understanding to the original code, the "maxmtu >= ndev- > >max_mtu" > > is meant for products that would want to use the value from logic which is > > just > above > > this statement where you just ask me not to add new line. That the reason > > the > > stmmac_platform.c put in "plat->maxmtu = JUMBO_LEN;" as generic and I > also > > follow it in stmmac_pci.c. > > > > Or do you mean only take maxmtu = JUMBO_LEN for the option to use driver > itself > > assignment statement above and all the > max_mtu consider invalid? > > So, just answer to the simple question: is it a valid case to have > plat->maxmtu > ndev->max_mtu? If it so, how is it used? > Otherwise we need a warning in such case. What did I miss? > it is a valid case for priv->plat->maxmtu > ndev->max_mtu if referring to the statement above it: /* MTU range: 46 - hw-specific max */ ndev->min_mtu = ETH_ZLEN - ETH_HLEN; if ((priv->plat->enh_desc) || (priv->synopsys_id >= DWMAC_CORE_4_00)) ndev->max_mtu = JUMBO_LEN; else ndev->max_mtu = SKB_MAX_HEAD(NET_SKB_PAD + NET_IP_ALIGN); When the ndev->max_mtu go into the else statement, then the assignment in stmmac_platform.c & stammac_pci.c plat->maxmtu = JUMBO_LEN is actually greater than ndev->max_mtu. That is what I understanding that maxmtu > max_mtu is an option trick to allow driver assign value through the logic above instead of getting it from of_property_read_u32(np, "max-frame-size", &plat->maxmtu); or *_default_data(). I need to revert back the V4 and submit V5. > > > >> > + netdev_warn(priv->dev, > >> > + "%s: warning: maxmtu having invalid value > >> > (%d)\n", > >> > + __func__, priv->plat->maxmtu); > > > >> > + /* Set the maxmtu to a default of JUMBO_LEN in case the > >> > +* parameter is not defined for the device. > >> > +*/ > >> > + plat->maxmtu = JUMBO_LEN; > >> > >> Please, use *_default_data() hooks for that. > >> > >> At some point it might make sense to extract > >> static int common_default_data() {...} > >> and call it at the beginning of the rest of *_defautl_data() hooks. > >> > > > > Just try to understand, are you referring changing the code something > > like this: > > > > stmmac_default_data(plat); > > if (info) { > > info->pdev = pdev; > > if (info->setup) { > > ret = info->setup(plat, info); > > if (ret) > > return ret; > > } > > } > > > > Where all the common code is inside the stmmac_default_data()? > > No. > > common_default_data() > { > ... common defaults among *_default_data() ... > } > > *_default_data() > { > ... > common_default_data(); > ... > } > Ok noted. Will be a separate patch. Thanks. Regards, Wilson > -- > With Best Regards, > Andy Shevchenko
RE: [PATCH v4] net: stmmac: fix maxmtu assignment to be within valid range
> -Original Message- > From: Andy Shevchenko [mailto:andy.shevche...@gmail.com] > Sent: Saturday, January 07, 2017 8:12 AM > To: Kweh, Hock Leong > Cc: David S. Miller ; Joao Pinto > ; Giuseppe CAVALLARO ; > seraphin.bonna...@st.com; Jarod Wilson ; Alexandre > TORGUE ; Joachim Eastwood > ; Niklas Cassel ; Johan Hovold > ; Pavel Machek ; lars.pers...@axis.com; > netdev ; LKML > Subject: Re: [PATCH v4] net: stmmac: fix maxmtu assignment to be within valid > range > > On Sat, Jan 7, 2017 at 10:10 AM, Kweh, Hock Leong > wrote: > > From: "Kweh, Hock Leong" > > > > There is no checking valid value of maxmtu when getting it from device tree. > > This resolution added the checking condition to ensure the assignment is > > made within a valid range. > > > changelog v4: > > * add print warning message when maxmtu > max_mtu as well > > Yep. > > > * add maxmtu = JUMBO_LEN into each *_default_data() at stmmac_pci.c > > Yep. > > But see comment below. > > P.S. And perhaps next time send into our internal mailing list first for > review. > > > @@ -3345,8 +3345,14 @@ int stmmac_dvr_probe(struct device *device, > > ndev->max_mtu = JUMBO_LEN; > > else > > ndev->max_mtu = SKB_MAX_HEAD(NET_SKB_PAD + NET_IP_ALIGN); > > - if (priv->plat->maxmtu < ndev->max_mtu) > > + if ((priv->plat->maxmtu < ndev->max_mtu) && > > + (priv->plat->maxmtu >= ndev->min_mtu)) > > ndev->max_mtu = priv->plat->maxmtu; > > > + else if ((priv->plat->maxmtu < ndev->min_mtu) || > > +(priv->plat->maxmtu > ndev->max_mtu)) > > + netdev_warn(priv->dev, > > What is the difference to just 'else'? (Returning back to my initial > proposal, I don't remember telling anything about 'else if' concept) > When priv->plat->maxmtu == ndev->max_mtu will not be a warning message. Oh NO ... it is a valid case for priv->plat->maxmtu > ndev->max_mtu if the assignment of ndev->max_mtu is using SKB_MAX_HEAD(NET_SKB_PAD + NET_IP_ALIGN), which is < JUMBO_LEN, then priv->plat->maxmtu > ndev->max_mtu is valid. Revert back and submit V5. Thanks. > > + "%s: warning: maxmtu having invalid value > > (%d)\n", > > + __func__, priv->plat->maxmtu); > > -- > With Best Regards, > Andy Shevchenko
[PATCH next v1] ipvlan: don't use IDR for generating dev_id
From: Mahesh Bandewar The patch 009146d117b ("ipvlan: assign unique dev-id for each slave device.") used ida_simple_get() to generate dev_ids assigned to the slave devices. However (Eric has pointed out that) there is a shortcoming with that approach as it always uses the first available ID. This becomes a problem when a slave gets deleted and a new slave gets added. The ID gets reassigned causing the new slave to get the same link-local address. This side-effect is undesirable. This patch replaces IDR logic with a simple per-port variable that keeps incrementing and wraps around when the MAX (0xFFFE) is reached. The only downside is that this is an inefficient (n^2) search if there are 64k (or close to 64k) slaves in the system, the dev-id search takes time. However having these many devices in the system has it's own challenges. Fixes: 009146d117b ("ipvlan: assign unique dev-id for each slave device.") Signed-off-by: Mahesh Bandewar CC: Eric Dumazet --- drivers/net/ipvlan/ipvlan.h | 2 +- drivers/net/ipvlan/ipvlan_main.c | 69 ++-- 2 files changed, 61 insertions(+), 10 deletions(-) diff --git a/drivers/net/ipvlan/ipvlan.h b/drivers/net/ipvlan/ipvlan.h index 0a9068fdee0f..535f254324ba 100644 --- a/drivers/net/ipvlan/ipvlan.h +++ b/drivers/net/ipvlan/ipvlan.h @@ -94,10 +94,10 @@ struct ipvl_port { struct hlist_head hlhead[IPVLAN_HASH_SIZE]; struct list_headipvlans; u16 mode; + u16 dev_id_base; struct work_struct wq; struct sk_buff_head backlog; int count; - struct ida ida; }; struct ipvl_skb_cb { diff --git a/drivers/net/ipvlan/ipvlan_main.c b/drivers/net/ipvlan/ipvlan_main.c index ce7ca6a5aa8a..691662e02abb 100644 --- a/drivers/net/ipvlan/ipvlan_main.c +++ b/drivers/net/ipvlan/ipvlan_main.c @@ -119,7 +119,7 @@ static int ipvlan_port_create(struct net_device *dev) skb_queue_head_init(&port->backlog); INIT_WORK(&port->wq, ipvlan_process_multicast); - ida_init(&port->ida); + port->dev_id_base = 1; err = netdev_rx_handler_register(dev, ipvlan_handle_frame, port); if (err) @@ -151,7 +151,6 @@ static void ipvlan_port_destroy(struct net_device *dev) dev_put(skb->dev); kfree_skb(skb); } - ida_destroy(&port->ida); kfree(port); } @@ -496,6 +495,60 @@ static int ipvlan_nl_fillinfo(struct sk_buff *skb, return ret; } +static u16 ipvlan_get_dev_id(struct ipvl_port *port) +{ + struct ipvl_dev *ipvlan; + u16 tid, dev_id = 0; + bool found, exhausted = false, second_round = false; + + /* Idea here is to get the next available ID while avoiding +* reuse of already used IDs. Per port variable (dev_id_base) +* is used to get the next available ID. +* +* Possibilities are from 0x1 to 0xfffe so finding next available +* ID is not be that difficult. However if the system is up for a +* long time and these slave devices are getting added / deleted +* routinely and it reaches the MAX, then only the assignment will +* attempt to recycle previously used IDs starting from 0x1 (Provided +* these are not currently in use). +* +* In case of a failure, dev-id search will return 0. All IDs in-use +* case is very inefficient (n^2 search) but having close to 64k +* slaves has it's own system limitations. +*/ + while (!exhausted) { + tid = port->dev_id_base++; + + if (tid == 0xFFFE) { + /* Reached MAX; restart from 1 */ + port->dev_id_base = 1; + if (second_round) + exhausted = true; + else + second_round = true; + continue; + } + /* Should not be same as the masters' (if present) */ + if (tid == port->dev->dev_id) + continue; + /* Make sure that it's already not assigned to any of the +* existing slaves. +*/ + found = false; + list_for_each_entry(ipvlan, &port->ipvlans, pnode) { + if (ipvlan->dev->dev_id == tid) { + found = true; + break; + } + } + if (!found) { + dev_id = tid; + break; + } + } + return dev_id; +} + static int ipvlan_link_new(struct net *src_net, struct net_device *dev, struct nlattr *tb[], struct nlattr *data[]) { @@ -540,10 +593,11 @@ static int ipvlan_link_new(struct net *src_net, struct net_devic
Re: [PATCH v2 02/12] net: ethernet: aquantia: Common functions and definitions
Hi, On 06.01.2017 09:06, Alexander Loktionov wrote: + +#define TXT(_T_) #_T_ +#define TXTTXT(_T_) TXT(_T_) do you really need these (IMHO ugly) macros? AFAICS you only use them to build the driver version string. + +#define AQ_CFG_DRV_AUTHOR "aQuantia" +#define AQ_CFG_DRV_DESC"aQuantia Corporation(R) Network Driver" +#define AQ_CFG_DRV_NAME"aquantia" +#define AQ_CFG_DRV_VERSION TXTTXT(NIC_MAJOR_DRIVER_VERSION)"."\ + TXTTXT(NIC_MINOR_DRIVER_VERSION)"."\ + TXTTXT(NIC_BUILD_DRIVER_VERSION)"."\ + TXTTXT(NIC_REVISION_DRIVER_VERSION) Regards, Lino
Re: [PATCH v4] net: stmmac: fix maxmtu assignment to be within valid range
On Sat, Jan 7, 2017 at 10:10 AM, Kweh, Hock Leong wrote: > From: "Kweh, Hock Leong" > > There is no checking valid value of maxmtu when getting it from device tree. > This resolution added the checking condition to ensure the assignment is > made within a valid range. > changelog v4: > * add print warning message when maxmtu > max_mtu as well Yep. > * add maxmtu = JUMBO_LEN into each *_default_data() at stmmac_pci.c Yep. But see comment below. P.S. And perhaps next time send into our internal mailing list first for review. > @@ -3345,8 +3345,14 @@ int stmmac_dvr_probe(struct device *device, > ndev->max_mtu = JUMBO_LEN; > else > ndev->max_mtu = SKB_MAX_HEAD(NET_SKB_PAD + NET_IP_ALIGN); > - if (priv->plat->maxmtu < ndev->max_mtu) > + if ((priv->plat->maxmtu < ndev->max_mtu) && > + (priv->plat->maxmtu >= ndev->min_mtu)) > ndev->max_mtu = priv->plat->maxmtu; > + else if ((priv->plat->maxmtu < ndev->min_mtu) || > +(priv->plat->maxmtu > ndev->max_mtu)) > + netdev_warn(priv->dev, What is the difference to just 'else'? (Returning back to my initial proposal, I don't remember telling anything about 'else if' concept) > + "%s: warning: maxmtu having invalid value (%d)\n", > + __func__, priv->plat->maxmtu); -- With Best Regards, Andy Shevchenko
Re: [PATCH v3] net: stmmac: fix maxmtu assignment to be within valid range
On Sat, Jan 7, 2017 at 1:47 AM, Kweh, Hock Leong wrote: >> > --- a/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c >> > +++ b/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c >> > @@ -3345,8 +3345,14 @@ int stmmac_dvr_probe(struct device *device, >> > ndev->max_mtu = JUMBO_LEN; >> > else >> > ndev->max_mtu = SKB_MAX_HEAD(NET_SKB_PAD + NET_IP_ALIGN); >> > - if (priv->plat->maxmtu < ndev->max_mtu) >> >> > + if ((priv->plat->maxmtu < ndev->max_mtu) && >> > + (priv->plat->maxmtu >= ndev->min_mtu)) >> >> > ndev->max_mtu = priv->plat->maxmtu; >> >> > + else if (priv->plat->maxmtu < ndev->min_mtu) >> >> And if it > ndev->max_mtu?.. >> > > Base on my understanding to the original code, the "maxmtu >= ndev->max_mtu" > is meant for products that would want to use the value from logic which is > just above > this statement where you just ask me not to add new line. That the reason the > stmmac_platform.c put in "plat->maxmtu = JUMBO_LEN;" as generic and I also > follow it in stmmac_pci.c. > > Or do you mean only take maxmtu = JUMBO_LEN for the option to use driver > itself > assignment statement above and all the > max_mtu consider invalid? So, just answer to the simple question: is it a valid case to have plat->maxmtu > ndev->max_mtu? If it so, how is it used? Otherwise we need a warning in such case. What did I miss? > >> > + netdev_warn(priv->dev, >> > + "%s: warning: maxmtu having invalid value >> > (%d)\n", >> > + __func__, priv->plat->maxmtu); >> > + /* Set the maxmtu to a default of JUMBO_LEN in case the >> > +* parameter is not defined for the device. >> > +*/ >> > + plat->maxmtu = JUMBO_LEN; >> >> Please, use *_default_data() hooks for that. >> >> At some point it might make sense to extract >> static int common_default_data() {...} >> and call it at the beginning of the rest of *_defautl_data() hooks. >> > > Just try to understand, are you referring changing the code something > like this: > > stmmac_default_data(plat); > if (info) { > info->pdev = pdev; > if (info->setup) { > ret = info->setup(plat, info); > if (ret) > return ret; > } > } > > Where all the common code is inside the stmmac_default_data()? No. common_default_data() { ... common defaults among *_default_data() ... } *_default_data() { ... common_default_data(); ... } -- With Best Regards, Andy Shevchenko
[PATCH v4] net: stmmac: fix maxmtu assignment to be within valid range
From: "Kweh, Hock Leong" There is no checking valid value of maxmtu when getting it from device tree. This resolution added the checking condition to ensure the assignment is made within a valid range. Signed-off-by: Kweh, Hock Leong --- changelog v4: * add print warning message when maxmtu > max_mtu as well * add maxmtu = JUMBO_LEN into each *_default_data() at stmmac_pci.c changelog v3: * print the warning message only if maxmtu < min_mtu * add maxmtu = JUMBO_LEN at stmmac_pci.c to follow stmmac_platform.c changelog v2: * correction of "devicetree" to "device tree" reported by Andy * print warning message while maxmtu is not in valid range drivers/net/ethernet/stmicro/stmmac/stmmac_main.c |8 +++- drivers/net/ethernet/stmicro/stmmac/stmmac_pci.c |6 ++ 2 files changed, 13 insertions(+), 1 deletion(-) diff --git a/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c b/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c index 92ac006..f2a352f 100644 --- a/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c +++ b/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c @@ -3345,8 +3345,14 @@ int stmmac_dvr_probe(struct device *device, ndev->max_mtu = JUMBO_LEN; else ndev->max_mtu = SKB_MAX_HEAD(NET_SKB_PAD + NET_IP_ALIGN); - if (priv->plat->maxmtu < ndev->max_mtu) + if ((priv->plat->maxmtu < ndev->max_mtu) && + (priv->plat->maxmtu >= ndev->min_mtu)) ndev->max_mtu = priv->plat->maxmtu; + else if ((priv->plat->maxmtu < ndev->min_mtu) || +(priv->plat->maxmtu > ndev->max_mtu)) + netdev_warn(priv->dev, + "%s: warning: maxmtu having invalid value (%d)\n", + __func__, priv->plat->maxmtu); if (flow_ctrl) priv->flow_ctrl = FLOW_AUTO;/* RX/TX pause on */ diff --git a/drivers/net/ethernet/stmicro/stmmac/stmmac_pci.c b/drivers/net/ethernet/stmicro/stmmac/stmmac_pci.c index a283177..3da4737 100644 --- a/drivers/net/ethernet/stmicro/stmmac/stmmac_pci.c +++ b/drivers/net/ethernet/stmicro/stmmac/stmmac_pci.c @@ -89,6 +89,9 @@ static void stmmac_default_data(struct plat_stmmacenet_data *plat) /* Set default value for unicast filter entries */ plat->unicast_filter_entries = 1; + + /* Set the maxmtu to a default of JUMBO_LEN */ + plat->maxmtu = JUMBO_LEN; } static int quark_default_data(struct plat_stmmacenet_data *plat, @@ -126,6 +129,9 @@ static int quark_default_data(struct plat_stmmacenet_data *plat, /* Set default value for unicast filter entries */ plat->unicast_filter_entries = 1; + /* Set the maxmtu to a default of JUMBO_LEN */ + plat->maxmtu = JUMBO_LEN; + return 0; } -- 1.7.9.5
RE: [PATCH v3] net: stmmac: fix maxmtu assignment to be within valid range
> -Original Message- > From: Andy Shevchenko [mailto:andy.shevche...@gmail.com] > Sent: Saturday, January 07, 2017 1:07 AM > To: Kweh, Hock Leong > Cc: David S. Miller ; Joao Pinto > ; Giuseppe CAVALLARO ; > seraphin.bonna...@st.com; Jarod Wilson ; Alexandre > TORGUE ; Joachim Eastwood > ; Niklas Cassel ; Johan Hovold > ; Pavel Machek ; lars.pers...@axis.com; > netdev ; LKML > Subject: Re: [PATCH v3] net: stmmac: fix maxmtu assignment to be within valid > range > > On Sat, Jan 7, 2017 at 2:49 AM, Kweh, Hock Leong > wrote: > > From: "Kweh, Hock Leong" > > > > There is no checking valid value of maxmtu when getting it from device tree. > > This resolution added the checking condition to ensure the assignment is > > made within a valid range. > > > --- a/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c > > +++ b/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c > > @@ -3345,8 +3345,14 @@ int stmmac_dvr_probe(struct device *device, > > ndev->max_mtu = JUMBO_LEN; > > else > > ndev->max_mtu = SKB_MAX_HEAD(NET_SKB_PAD + NET_IP_ALIGN); > > - if (priv->plat->maxmtu < ndev->max_mtu) > > > + > > The lines are logically grouped here. No need to split it. Thus, > remove this extra line. > Ok noted. > > + if ((priv->plat->maxmtu < ndev->max_mtu) && > > + (priv->plat->maxmtu >= ndev->min_mtu)) > > > ndev->max_mtu = priv->plat->maxmtu; > > > + else if (priv->plat->maxmtu < ndev->min_mtu) > > And if it > ndev->max_mtu?.. > Base on my understanding to the original code, the "maxmtu >= ndev->max_mtu" is meant for products that would want to use the value from logic which is just above this statement where you just ask me not to add new line. That the reason the stmmac_platform.c put in "plat->maxmtu = JUMBO_LEN;" as generic and I also follow it in stmmac_pci.c. Or do you mean only take maxmtu = JUMBO_LEN for the option to use driver itself assignment statement above and all the > max_mtu consider invalid? > > + netdev_warn(priv->dev, > > + "%s: warning: maxmtu having invalid value > > (%d)\n", > > + __func__, priv->plat->maxmtu); > > > > --- a/drivers/net/ethernet/stmicro/stmmac/stmmac_pci.c > > +++ b/drivers/net/ethernet/stmicro/stmmac/stmmac_pci.c > > @@ -204,6 +204,10 @@ static int stmmac_pci_probe(struct pci_dev *pdev, > > > > pci_set_master(pdev); > > > > + /* Set the maxmtu to a default of JUMBO_LEN in case the > > +* parameter is not defined for the device. > > +*/ > > + plat->maxmtu = JUMBO_LEN; > > Please, use *_default_data() hooks for that. > > At some point it might make sense to extract > static int common_default_data() {...} > and call it at the beginning of the rest of *_defautl_data() hooks. > Just try to understand, are you referring changing the code something like this: stmmac_default_data(plat); if (info) { info->pdev = pdev; if (info->setup) { ret = info->setup(plat, info); if (ret) return ret; } } Where all the common code is inside the stmmac_default_data()? Anyway, this patch is focus for fixing the maxmtu assignment in valid range. I will submit V4 to put "plat->maxmtu = JUMBO_LEN;" into each *_default_data(). Regarding the common_default_data() would be a new patch for better code structuring. Thanks. > -- > With Best Regards, > Andy Shevchenko
Re: [PATCHv1 7/7] IPVTAP: IP-VLAN based tap driver
few superficial comments inline. On Fri, Jan 6, 2017 at 2:33 PM, Sainath Grandhi wrote: > This patch adds a tap character device driver that is based on the > IP-VLAN network interface, called ipvtap. An ipvtap device can be created > in the same way as an ipvlan device, using 'type ipvtap', and then accessed > using the tap user space interface. > > Signed-off-by: Sainath Grandhi > Tested-by: Sainath Grandhi > --- > drivers/net/Kconfig | 12 ++ > drivers/net/Makefile | 1 + > drivers/net/ipvlan/Makefile | 1 + > drivers/net/ipvlan/ipvlan.h | 7 ++ > drivers/net/ipvlan/ipvlan_core.c | 5 +- > drivers/net/ipvlan/ipvlan_main.c | 37 +++--- > drivers/net/ipvlan/ipvtap.c | 238 > +++ > 7 files changed, 282 insertions(+), 19 deletions(-) > create mode 100644 drivers/net/ipvlan/ipvtap.c > > diff --git a/drivers/net/Kconfig b/drivers/net/Kconfig > index 280380d..ddfb30a 100644 > --- a/drivers/net/Kconfig > +++ b/drivers/net/Kconfig > @@ -165,6 +165,18 @@ config IPVLAN >To compile this driver as a module, choose M here: the module >will be called ipvlan. > > +config IPVTAP > +tristate "IP-VLAN based tap driver" > +depends on IPVLAN > +depends on INET > +help > + This adds a specialized tap character device driver that is based > + on the IP-VLAN network interface, called ipvtap. An ipvtap device > + can be added in the same way as a ipvlan device, using 'type > + ipvtap', and then be accessed through the tap user space interface. > + > + To compile this driver as a module, choose M here: the module > + will be called macvtap. > > config VXLAN > tristate "Virtual eXtensible Local Area Network (VXLAN)" > diff --git a/drivers/net/Makefile b/drivers/net/Makefile > index 7dd86ca..98ed4d9 100644 > --- a/drivers/net/Makefile > +++ b/drivers/net/Makefile > @@ -7,6 +7,7 @@ > # > obj-$(CONFIG_BONDING) += bonding/ > obj-$(CONFIG_IPVLAN) += ipvlan/ > +obj-$(CONFIG_IPVTAP) += ipvlan/ > obj-$(CONFIG_DUMMY) += dummy.o > obj-$(CONFIG_EQUALIZER) += eql.o > obj-$(CONFIG_IFB) += ifb.o > diff --git a/drivers/net/ipvlan/Makefile b/drivers/net/ipvlan/Makefile > index df79910..8a2c64d 100644 > --- a/drivers/net/ipvlan/Makefile > +++ b/drivers/net/ipvlan/Makefile > @@ -3,5 +3,6 @@ > # > > obj-$(CONFIG_IPVLAN) += ipvlan.o > +obj-$(CONFIG_IPVTAP) += ipvtap.o > > ipvlan-objs := ipvlan_core.o ipvlan_main.o > diff --git a/drivers/net/ipvlan/ipvlan.h b/drivers/net/ipvlan/ipvlan.h > index dbfbb33..4362d88 100644 > --- a/drivers/net/ipvlan/ipvlan.h > +++ b/drivers/net/ipvlan/ipvlan.h > @@ -133,4 +133,11 @@ struct sk_buff *ipvlan_l3_rcv(struct net_device *dev, > struct sk_buff *skb, > u16 proto); > unsigned int ipvlan_nf_input(void *priv, struct sk_buff *skb, > const struct nf_hook_state *state); > +void ipvlan_count_rx(const struct ipvl_dev *ipvlan, > +unsigned int len, bool success, bool mcast); > +int ipvlan_link_new(struct net *src_net, struct net_device *dev, > + struct nlattr *tb[], struct nlattr *data[]); > +void ipvlan_link_delete(struct net_device *dev, struct list_head *head); > +void ipvlan_link_setup(struct net_device *dev); > +int ipvlan_link_register(struct rtnl_link_ops *ops); > #endif /* __IPVLAN_H */ > diff --git a/drivers/net/ipvlan/ipvlan_core.c > b/drivers/net/ipvlan/ipvlan_core.c > index 83ce74a..9af16ab 100644 > --- a/drivers/net/ipvlan/ipvlan_core.c > +++ b/drivers/net/ipvlan/ipvlan_core.c > @@ -16,8 +16,8 @@ void ipvlan_init_secret(void) > net_get_random_once(&ipvlan_jhash_secret, > sizeof(ipvlan_jhash_secret)); > } > > -static void ipvlan_count_rx(const struct ipvl_dev *ipvlan, > - unsigned int len, bool success, bool mcast) > +void ipvlan_count_rx(const struct ipvl_dev *ipvlan, > +unsigned int len, bool success, bool mcast) > { > if (!ipvlan) > return; > @@ -36,6 +36,7 @@ static void ipvlan_count_rx(const struct ipvl_dev *ipvlan, > this_cpu_inc(ipvlan->pcpu_stats->rx_errs); > } > } > +EXPORT_SYMBOL_GPL(ipvlan_count_rx); Why export, isn't just removing 'static' enough? > > static u8 ipvlan_get_v6_hash(const void *iaddr) > { > diff --git a/drivers/net/ipvlan/ipvlan_main.c > b/drivers/net/ipvlan/ipvlan_main.c > index 8b0f993..666a05d 100644 > --- a/drivers/net/ipvlan/ipvlan_main.c > +++ b/drivers/net/ipvlan/ipvlan_main.c > @@ -13,14 +13,14 @@ static u32 ipvl_nf_hook_refcnt = 0; > > static struct nf_hook_ops ipvl_nfops[] __read_mostly = { > { > - .hook = ipvlan_nf_input, > - .pf = NFPROTO_IPV4, > + .hook = ipvlan_nf_input, > + .pf = NFPROTO_IPV4, spurious? > .hooknum = NF_INET_LOCAL_IN, > .prio
RE: [PATCH v3] net: stmmac: fix maxmtu assignment to be within valid range
> -Original Message- > From: Joao Pinto [mailto:joao.pi...@synopsys.com] > Sent: Saturday, January 07, 2017 12:58 AM > To: Kweh, Hock Leong ; David S. Miller > ; Joao Pinto ; Giuseppe > CAVALLARO ; seraphin.bonna...@st.com; Jarod > Wilson ; Andy Shevchenko > Cc: Alexandre TORGUE ; Joachim Eastwood > ; Niklas Cassel ; Johan Hovold > ; pa...@ucw.cz; lars.pers...@axis.com; netdev > ; LKML > Subject: Re: [PATCH v3] net: stmmac: fix maxmtu assignment to be within valid > range > > > Hi Wilson, > > Às 12:49 AM de 1/7/2017, Kweh, Hock Leong escreveu: > > From: "Kweh, Hock Leong" > > > > There is no checking valid value of maxmtu when getting it from device tree. > > This resolution added the checking condition to ensure the assignment is > > made within a valid range. > > > > Signed-off-by: Kweh, Hock Leong > > --- > > changelog v3: > > * print the warning message only if maxmtu < min_mtu > > * add maxmtu = JUMBO_LEN at stmmac_pci.c to follow stmmac_platform.c > > > > changelog v2: > > * correction of "devicetree" to "device tree" reported by Andy > > * print warning message while maxmtu is not in valid range > > > > drivers/net/ethernet/stmicro/stmmac/stmmac_main.c |8 +++- > > drivers/net/ethernet/stmicro/stmmac/stmmac_pci.c |4 > > 2 files changed, 11 insertions(+), 1 deletion(-) > > > > diff --git a/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c > b/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c > > index 92ac006..ce74ae6 100644 > > --- a/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c > > +++ b/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c > > @@ -3345,8 +3345,14 @@ int stmmac_dvr_probe(struct device *device, > > ndev->max_mtu = JUMBO_LEN; > > else > > ndev->max_mtu = SKB_MAX_HEAD(NET_SKB_PAD + > NET_IP_ALIGN); > > - if (priv->plat->maxmtu < ndev->max_mtu) > > + > > + if ((priv->plat->maxmtu < ndev->max_mtu) && > > + (priv->plat->maxmtu >= ndev->min_mtu)) > > ndev->max_mtu = priv->plat->maxmtu; > > + else if (priv->plat->maxmtu < ndev->min_mtu) > > + netdev_warn(priv->dev, > > + "%s: warning: maxmtu having invalid value (%d)\n", > > + __func__, priv->plat->maxmtu); > > > > if (flow_ctrl) > > priv->flow_ctrl = FLOW_AUTO;/* RX/TX pause on */ > > diff --git a/drivers/net/ethernet/stmicro/stmmac/stmmac_pci.c > b/drivers/net/ethernet/stmicro/stmmac/stmmac_pci.c > > index a283177..e539afe 100644 > > --- a/drivers/net/ethernet/stmicro/stmmac/stmmac_pci.c > > +++ b/drivers/net/ethernet/stmicro/stmmac/stmmac_pci.c > > @@ -204,6 +204,10 @@ static int stmmac_pci_probe(struct pci_dev *pdev, > > > > pci_set_master(pdev); > > > > + /* Set the maxmtu to a default of JUMBO_LEN in case the > > +* parameter is not defined for the device. > > +*/ > > + plat->maxmtu = JUMBO_LEN; > > I suggest to put this configuration in one of the default config functions. > > Tahnks. > My original thought is to have one line for all *_default_data() instead of having multiple same line inside each *_default_data(). If this is not a big concern of future expand, I can do that. Thanks. > > if (info) { > > info->pdev = pdev; > > if (info->setup) { > >
Re: [Intel-wired-lan] [PATCH v2] PCI: lock each enable/disable num_vfs operation in sysfs
On Fri, 2017-01-06 at 23:28 +, Tantilov, Emil S wrote: > >-Original Message- > >From: Intel-wired-lan [mailto:intel-wired-lan-boun...@lists.osuosl.org] On > >Behalf Of Greg > >Sent: Friday, January 06, 2017 3:18 PM > >To: Tantilov, Emil S > >Cc: linux-...@vger.kernel.org; intel-wired-...@lists.osuosl.org; linux- > >ker...@vger.kernel.org; netdev@vger.kernel.org > >Subject: Re: [Intel-wired-lan] [PATCH v2] PCI: lock each enable/disable > >num_vfs operation in sysfs > > > >On Fri, 2017-01-06 at 13:59 -0800, Emil Tantilov wrote: > >> Enabling/disabling SRIOV via sysfs by echo-ing multiple values > >> simultaneously: > >> > >> echo 63 > /sys/class/net/ethX/device/sriov_numvfs& > >> echo 63 > /sys/class/net/ethX/device/sriov_numvfs > >> > >> sleep 5 > >> > >> echo 0 > /sys/class/net/ethX/device/sriov_numvfs& > >> echo 0 > /sys/class/net/ethX/device/sriov_numvfs > >> > >> Results in the following bug: > >> > >> kernel BUG at drivers/pci/iov.c:495! > >> invalid opcode: [#1] SMP > >> CPU: 1 PID: 8050 Comm: bash Tainted: G W 4.9.0-rc7-net-next #2092 > >> RIP: 0010:[] > >> [] pci_iov_release+0x57/0x60 > >> > >> Call Trace: > >> [] pci_release_dev+0x26/0x70 > >> [] device_release+0x3e/0xb0 > >> [] kobject_cleanup+0x67/0x180 > >> [] kobject_put+0x2d/0x60 > >> [] put_device+0x17/0x20 > >> [] pci_dev_put+0x1a/0x20 > >> [] pci_get_dev_by_id+0x5b/0x90 > >> [] pci_get_subsys+0x35/0x40 > >> [] pci_get_device+0x18/0x20 > >> [] pci_get_domain_bus_and_slot+0x2b/0x60 > >> [] pci_iov_remove_virtfn+0x57/0x180 > >> [] pci_disable_sriov+0x65/0x140 > >> [] ixgbe_disable_sriov+0xc7/0x1d0 [ixgbe] > >> [] ixgbe_pci_sriov_configure+0x3d/0x170 [ixgbe] > >> [] sriov_numvfs_store+0xdc/0x130 > >> ... > >> RIP [] pci_iov_release+0x57/0x60 > >> > >> Use the existing mutex lock to protect each enable/disable operation. > >> > >> -v2: move the existing lock from protecting the config of the IOV bus > >> to protecting the writes to sriov_numvfs in sysfs without maintaining > >> a "locked" version of pci_iov_add/remove_virtfn(). > >> As suggested by Gavin Shan > >> > >> CC: Alexander Duyck > >> Signed-off-by: Emil Tantilov > >> --- > >> drivers/pci/iov.c |7 --- > >> drivers/pci/pci-sysfs.c | 23 --- > >> drivers/pci/pci.h |2 +- > >> 3 files changed, 17 insertions(+), 15 deletions(-) > >> > >> diff --git a/drivers/pci/iov.c b/drivers/pci/iov.c > >> index 4722782..2479ae8 100644 > >> --- a/drivers/pci/iov.c > >> +++ b/drivers/pci/iov.c > >> @@ -124,7 +124,6 @@ int pci_iov_add_virtfn(struct pci_dev *dev, int id, > >int reset) > >>struct pci_sriov *iov = dev->sriov; > >>struct pci_bus *bus; > >> > >> - mutex_lock(&iov->dev->sriov->lock); > >>bus = virtfn_add_bus(dev->bus, pci_iov_virtfn_bus(dev, id)); > >>if (!bus) > >>goto failed; > >> @@ -162,7 +161,6 @@ int pci_iov_add_virtfn(struct pci_dev *dev, int id, > >int reset) > >>__pci_reset_function(virtfn); > >> > >>pci_device_add(virtfn, virtfn->bus); > >> - mutex_unlock(&iov->dev->sriov->lock); > >> > >>pci_bus_add_device(virtfn); > >>sprintf(buf, "virtfn%u", id); > >> @@ -181,12 +179,10 @@ int pci_iov_add_virtfn(struct pci_dev *dev, int id, > >int reset) > >>sysfs_remove_link(&dev->dev.kobj, buf); > >> failed1: > >>pci_dev_put(dev); > >> - mutex_lock(&iov->dev->sriov->lock); > >>pci_stop_and_remove_bus_device(virtfn); > >> failed0: > >>virtfn_remove_bus(dev->bus, bus); > >> failed: > >> - mutex_unlock(&iov->dev->sriov->lock); > >> > >>return rc; > >> } > >> @@ -195,7 +191,6 @@ void pci_iov_remove_virtfn(struct pci_dev *dev, int > >id, int reset) > >> { > >>char buf[VIRTFN_ID_LEN]; > >>struct pci_dev *virtfn; > >> - struct pci_sriov *iov = dev->sriov; > >> > >>virtfn = pci_get_domain_bus_and_slot(pci_domain_nr(dev->bus), > >> pci_iov_virtfn_bus(dev, id), > >> @@ -218,10 +213,8 @@ void pci_iov_remove_virtfn(struct pci_dev *dev, int > >id, int reset) > >>if (virtfn->dev.kobj.sd) > >>sysfs_remove_link(&virtfn->dev.kobj, "physfn"); > >> > >> - mutex_lock(&iov->dev->sriov->lock); > >>pci_stop_and_remove_bus_device(virtfn); > >>virtfn_remove_bus(dev->bus, virtfn->bus); > >> - mutex_unlock(&iov->dev->sriov->lock); > >> > >>/* balance pci_get_domain_bus_and_slot() */ > >>pci_dev_put(virtfn); > >> diff --git a/drivers/pci/pci-sysfs.c b/drivers/pci/pci-sysfs.c > >> index 0666287..25d010d 100644 > >> --- a/drivers/pci/pci-sysfs.c > >> +++ b/drivers/pci/pci-sysfs.c > >> @@ -472,6 +472,7 @@ static ssize_t sriov_numvfs_store(struct device *dev, > >> const char *buf, size_t count) > >> { > >>struct pci_dev *pdev = to_pci_dev(dev); > >> + struct pci_sriov *iov = pdev->sriov; > >>int ret; > >>u16 num_vfs; > >> > >> @@ -482,38 +483,46 @@ static ssize_t sriov_numvfs_store(struct device > >*dev, > >>if (num_vfs > pci
RE: [Intel-wired-lan] [PATCH v2] PCI: lock each enable/disable num_vfs operation in sysfs
>-Original Message- >From: Intel-wired-lan [mailto:intel-wired-lan-boun...@lists.osuosl.org] On >Behalf Of Greg >Sent: Friday, January 06, 2017 3:18 PM >To: Tantilov, Emil S >Cc: linux-...@vger.kernel.org; intel-wired-...@lists.osuosl.org; linux- >ker...@vger.kernel.org; netdev@vger.kernel.org >Subject: Re: [Intel-wired-lan] [PATCH v2] PCI: lock each enable/disable >num_vfs operation in sysfs > >On Fri, 2017-01-06 at 13:59 -0800, Emil Tantilov wrote: >> Enabling/disabling SRIOV via sysfs by echo-ing multiple values >> simultaneously: >> >> echo 63 > /sys/class/net/ethX/device/sriov_numvfs& >> echo 63 > /sys/class/net/ethX/device/sriov_numvfs >> >> sleep 5 >> >> echo 0 > /sys/class/net/ethX/device/sriov_numvfs& >> echo 0 > /sys/class/net/ethX/device/sriov_numvfs >> >> Results in the following bug: >> >> kernel BUG at drivers/pci/iov.c:495! >> invalid opcode: [#1] SMP >> CPU: 1 PID: 8050 Comm: bash Tainted: G W 4.9.0-rc7-net-next #2092 >> RIP: 0010:[] >>[] pci_iov_release+0x57/0x60 >> >> Call Trace: >> [] pci_release_dev+0x26/0x70 >> [] device_release+0x3e/0xb0 >> [] kobject_cleanup+0x67/0x180 >> [] kobject_put+0x2d/0x60 >> [] put_device+0x17/0x20 >> [] pci_dev_put+0x1a/0x20 >> [] pci_get_dev_by_id+0x5b/0x90 >> [] pci_get_subsys+0x35/0x40 >> [] pci_get_device+0x18/0x20 >> [] pci_get_domain_bus_and_slot+0x2b/0x60 >> [] pci_iov_remove_virtfn+0x57/0x180 >> [] pci_disable_sriov+0x65/0x140 >> [] ixgbe_disable_sriov+0xc7/0x1d0 [ixgbe] >> [] ixgbe_pci_sriov_configure+0x3d/0x170 [ixgbe] >> [] sriov_numvfs_store+0xdc/0x130 >> ... >> RIP [] pci_iov_release+0x57/0x60 >> >> Use the existing mutex lock to protect each enable/disable operation. >> >> -v2: move the existing lock from protecting the config of the IOV bus >> to protecting the writes to sriov_numvfs in sysfs without maintaining >> a "locked" version of pci_iov_add/remove_virtfn(). >> As suggested by Gavin Shan >> >> CC: Alexander Duyck >> Signed-off-by: Emil Tantilov >> --- >> drivers/pci/iov.c |7 --- >> drivers/pci/pci-sysfs.c | 23 --- >> drivers/pci/pci.h |2 +- >> 3 files changed, 17 insertions(+), 15 deletions(-) >> >> diff --git a/drivers/pci/iov.c b/drivers/pci/iov.c >> index 4722782..2479ae8 100644 >> --- a/drivers/pci/iov.c >> +++ b/drivers/pci/iov.c >> @@ -124,7 +124,6 @@ int pci_iov_add_virtfn(struct pci_dev *dev, int id, >int reset) >> struct pci_sriov *iov = dev->sriov; >> struct pci_bus *bus; >> >> -mutex_lock(&iov->dev->sriov->lock); >> bus = virtfn_add_bus(dev->bus, pci_iov_virtfn_bus(dev, id)); >> if (!bus) >> goto failed; >> @@ -162,7 +161,6 @@ int pci_iov_add_virtfn(struct pci_dev *dev, int id, >int reset) >> __pci_reset_function(virtfn); >> >> pci_device_add(virtfn, virtfn->bus); >> -mutex_unlock(&iov->dev->sriov->lock); >> >> pci_bus_add_device(virtfn); >> sprintf(buf, "virtfn%u", id); >> @@ -181,12 +179,10 @@ int pci_iov_add_virtfn(struct pci_dev *dev, int id, >int reset) >> sysfs_remove_link(&dev->dev.kobj, buf); >> failed1: >> pci_dev_put(dev); >> -mutex_lock(&iov->dev->sriov->lock); >> pci_stop_and_remove_bus_device(virtfn); >> failed0: >> virtfn_remove_bus(dev->bus, bus); >> failed: >> -mutex_unlock(&iov->dev->sriov->lock); >> >> return rc; >> } >> @@ -195,7 +191,6 @@ void pci_iov_remove_virtfn(struct pci_dev *dev, int >id, int reset) >> { >> char buf[VIRTFN_ID_LEN]; >> struct pci_dev *virtfn; >> -struct pci_sriov *iov = dev->sriov; >> >> virtfn = pci_get_domain_bus_and_slot(pci_domain_nr(dev->bus), >> pci_iov_virtfn_bus(dev, id), >> @@ -218,10 +213,8 @@ void pci_iov_remove_virtfn(struct pci_dev *dev, int >id, int reset) >> if (virtfn->dev.kobj.sd) >> sysfs_remove_link(&virtfn->dev.kobj, "physfn"); >> >> -mutex_lock(&iov->dev->sriov->lock); >> pci_stop_and_remove_bus_device(virtfn); >> virtfn_remove_bus(dev->bus, virtfn->bus); >> -mutex_unlock(&iov->dev->sriov->lock); >> >> /* balance pci_get_domain_bus_and_slot() */ >> pci_dev_put(virtfn); >> diff --git a/drivers/pci/pci-sysfs.c b/drivers/pci/pci-sysfs.c >> index 0666287..25d010d 100644 >> --- a/drivers/pci/pci-sysfs.c >> +++ b/drivers/pci/pci-sysfs.c >> @@ -472,6 +472,7 @@ static ssize_t sriov_numvfs_store(struct device *dev, >>const char *buf, size_t count) >> { >> struct pci_dev *pdev = to_pci_dev(dev); >> +struct pci_sriov *iov = pdev->sriov; >> int ret; >> u16 num_vfs; >> >> @@ -482,38 +483,46 @@ static ssize_t sriov_numvfs_store(struct device >*dev, >> if (num_vfs > pci_sriov_get_totalvfs(pdev)) >> return -ERANGE; >> >> +mutex_lock(&iov->dev->sriov->lock); >> + >> if (num_vfs == pdev->sriov->num_VFs) >> -return count; /* no change */ >> +goto exit; >> >> /* is
[PATCH net] bpf: change back to orig prog on too many passes
If after too many passes still no image could be emitted, then swap back to the original program as we do in all other cases and don't use the one with blinding. Fixes: 959a75791603 ("bpf, x86: add support for constant blinding") Signed-off-by: Daniel Borkmann Acked-by: Alexei Starovoitov --- arch/x86/net/bpf_jit_comp.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/arch/x86/net/bpf_jit_comp.c b/arch/x86/net/bpf_jit_comp.c index e76d1af..bb660e5 100644 --- a/arch/x86/net/bpf_jit_comp.c +++ b/arch/x86/net/bpf_jit_comp.c @@ -1172,6 +1172,8 @@ struct bpf_prog *bpf_int_jit_compile(struct bpf_prog *prog) set_memory_ro((unsigned long)header, header->pages); prog->bpf_func = (void *)image; prog->jited = 1; + } else { + prog = orig_prog; } out_addrs: -- 1.9.3
Re: [PATCHv1 5/7] TAP: Extending tap device create/destroy APIs
On Fri, 2017-01-06 at 14:33 -0800, Sainath Grandhi wrote: > +static int tap_list_add(dev_t major, const char *device_name) > +{ > + int err = 0; > + struct major_info *tap_major; > + > + tap_major = kzalloc(sizeof(*tap_major), GFP_ATOMIC); > + > + tap_major->major = MAJOR(major); > + kzalloc() can perfectly return NULL. You do not want to crash it that happens.
Re: [PATCHv1 5/7] TAP: Extending tap device create/destroy APIs
On Sat, Jan 7, 2017 at 12:33 AM, Sainath Grandhi wrote: > Extending tap APIs get/free_minor and create/destroy_cdev to handle more than > one > type of virtual interface. > > Signed-off-by: Sainath Grandhi > Tested-by: Sainath Grandhi Usually it implies that commiter has tested the stuff. > --- a/drivers/net/tap.c > +++ b/drivers/net/tap.c > @@ -99,12 +99,16 @@ static struct proto tap_proto = { > }; > > #define TAP_NUM_DEVS (1U << MINORBITS) > + > +LIST_HEAD(major_list); > + static ? > -int tap_get_minor(struct tap_dev *tap) > +int tap_get_minor(dev_t major, struct tap_dev *tap) > { > int retval = -ENOMEM; > + struct major_info *tap_major, *tmp; > + bool found = false; > > - mutex_lock(&macvtap_major.minor_lock); > - retval = idr_alloc(&macvtap_major.minor_idr, tap, 1, TAP_NUM_DEVS, > GFP_KERNEL); > + list_for_each_entry_safe(tap_major, tmp, &major_list, next) { > + if (tap_major->major == MAJOR(major)) { > + found = true; > + break; > + } > + } > + > + if (!found) > + return -EINVAL; This is candidate to be a separate helper function. See also below. > -void tap_free_minor(struct tap_dev *tap) > +void tap_free_minor(dev_t major, struct tap_dev *tap) > { > - mutex_lock(&macvtap_major.minor_lock); > + struct major_info *tap_major, *tmp; > + bool found = false; > + > + list_for_each_entry_safe(tap_major, tmp, &major_list, next) { > + if (tap_major->major == MAJOR(major)) { > + found = true; > + break; > + } > + } > + > + if (!found) > + return; Here is quite the same code (as above). > -static struct tap_dev *dev_get_by_tap_minor(int minor) > +static struct tap_dev *dev_get_by_tap_file(int major, int minor) > { > struct net_device *dev = NULL; > struct tap_dev *tap; > + struct major_info *tap_major, *tmp; > + bool found = false; > > - mutex_lock(&macvtap_major.minor_lock); > - tap = idr_find(&macvtap_major.minor_idr, minor); > + list_for_each_entry_safe(tap_major, tmp, &major_list, next) { > + if (tap_major->major == major) { > + found = true; > + break; > + } > + } > + > + if (!found) > + return NULL; And here. > +static int tap_list_add(dev_t major, const char *device_name) > +{ > + int err = 0; > + struct major_info *tap_major; Perhaps + struct major_info *tap_major; + int err = 0; > + > + tap_major = kzalloc(sizeof(*tap_major), GFP_ATOMIC); > + > + tap_major->major = MAJOR(major); > + > + idr_init(&tap_major->minor_idr); > + mutex_init(&tap_major->minor_lock); > + > + tap_major->device_name = device_name; > + > + list_add_tail(&tap_major->next, &major_list); > + return err; > + err = tap_list_add(*tap_major, device_name); > > return err; return tap_list_add(); > void tap_destroy_cdev(dev_t major, struct cdev *tap_cdev) > { > + struct major_info *tap_major, *tmp; > + bool found = false; > + > + list_for_each_entry_safe(tap_major, tmp, &major_list, next) { > + if (tap_major->major == MAJOR(major)) { > + found = true; > + break; > + } > + } > + > + if (!found) > + return; And here. -- With Best Regards, Andy Shevchenko
Re: [PATCH v2] PCI: lock each enable/disable num_vfs operation in sysfs
On Fri, 2017-01-06 at 13:59 -0800, Emil Tantilov wrote: > Enabling/disabling SRIOV via sysfs by echo-ing multiple values > simultaneously: > > echo 63 > /sys/class/net/ethX/device/sriov_numvfs& > echo 63 > /sys/class/net/ethX/device/sriov_numvfs > > sleep 5 > > echo 0 > /sys/class/net/ethX/device/sriov_numvfs& > echo 0 > /sys/class/net/ethX/device/sriov_numvfs > > Results in the following bug: > > kernel BUG at drivers/pci/iov.c:495! > invalid opcode: [#1] SMP > CPU: 1 PID: 8050 Comm: bash Tainted: G W 4.9.0-rc7-net-next #2092 > RIP: 0010:[] > [] pci_iov_release+0x57/0x60 > > Call Trace: > [] pci_release_dev+0x26/0x70 > [] device_release+0x3e/0xb0 > [] kobject_cleanup+0x67/0x180 > [] kobject_put+0x2d/0x60 > [] put_device+0x17/0x20 > [] pci_dev_put+0x1a/0x20 > [] pci_get_dev_by_id+0x5b/0x90 > [] pci_get_subsys+0x35/0x40 > [] pci_get_device+0x18/0x20 > [] pci_get_domain_bus_and_slot+0x2b/0x60 > [] pci_iov_remove_virtfn+0x57/0x180 > [] pci_disable_sriov+0x65/0x140 > [] ixgbe_disable_sriov+0xc7/0x1d0 [ixgbe] > [] ixgbe_pci_sriov_configure+0x3d/0x170 [ixgbe] > [] sriov_numvfs_store+0xdc/0x130 > ... > RIP [] pci_iov_release+0x57/0x60 > > Use the existing mutex lock to protect each enable/disable operation. > > -v2: move the existing lock from protecting the config of the IOV bus > to protecting the writes to sriov_numvfs in sysfs without maintaining > a "locked" version of pci_iov_add/remove_virtfn(). > As suggested by Gavin Shan > > CC: Alexander Duyck > Signed-off-by: Emil Tantilov > --- > drivers/pci/iov.c |7 --- > drivers/pci/pci-sysfs.c | 23 --- > drivers/pci/pci.h |2 +- > 3 files changed, 17 insertions(+), 15 deletions(-) > > diff --git a/drivers/pci/iov.c b/drivers/pci/iov.c > index 4722782..2479ae8 100644 > --- a/drivers/pci/iov.c > +++ b/drivers/pci/iov.c > @@ -124,7 +124,6 @@ int pci_iov_add_virtfn(struct pci_dev *dev, int id, int > reset) > struct pci_sriov *iov = dev->sriov; > struct pci_bus *bus; > > - mutex_lock(&iov->dev->sriov->lock); > bus = virtfn_add_bus(dev->bus, pci_iov_virtfn_bus(dev, id)); > if (!bus) > goto failed; > @@ -162,7 +161,6 @@ int pci_iov_add_virtfn(struct pci_dev *dev, int id, int > reset) > __pci_reset_function(virtfn); > > pci_device_add(virtfn, virtfn->bus); > - mutex_unlock(&iov->dev->sriov->lock); > > pci_bus_add_device(virtfn); > sprintf(buf, "virtfn%u", id); > @@ -181,12 +179,10 @@ int pci_iov_add_virtfn(struct pci_dev *dev, int id, int > reset) > sysfs_remove_link(&dev->dev.kobj, buf); > failed1: > pci_dev_put(dev); > - mutex_lock(&iov->dev->sriov->lock); > pci_stop_and_remove_bus_device(virtfn); > failed0: > virtfn_remove_bus(dev->bus, bus); > failed: > - mutex_unlock(&iov->dev->sriov->lock); > > return rc; > } > @@ -195,7 +191,6 @@ void pci_iov_remove_virtfn(struct pci_dev *dev, int id, > int reset) > { > char buf[VIRTFN_ID_LEN]; > struct pci_dev *virtfn; > - struct pci_sriov *iov = dev->sriov; > > virtfn = pci_get_domain_bus_and_slot(pci_domain_nr(dev->bus), >pci_iov_virtfn_bus(dev, id), > @@ -218,10 +213,8 @@ void pci_iov_remove_virtfn(struct pci_dev *dev, int id, > int reset) > if (virtfn->dev.kobj.sd) > sysfs_remove_link(&virtfn->dev.kobj, "physfn"); > > - mutex_lock(&iov->dev->sriov->lock); > pci_stop_and_remove_bus_device(virtfn); > virtfn_remove_bus(dev->bus, virtfn->bus); > - mutex_unlock(&iov->dev->sriov->lock); > > /* balance pci_get_domain_bus_and_slot() */ > pci_dev_put(virtfn); > diff --git a/drivers/pci/pci-sysfs.c b/drivers/pci/pci-sysfs.c > index 0666287..25d010d 100644 > --- a/drivers/pci/pci-sysfs.c > +++ b/drivers/pci/pci-sysfs.c > @@ -472,6 +472,7 @@ static ssize_t sriov_numvfs_store(struct device *dev, > const char *buf, size_t count) > { > struct pci_dev *pdev = to_pci_dev(dev); > + struct pci_sriov *iov = pdev->sriov; > int ret; > u16 num_vfs; > > @@ -482,38 +483,46 @@ static ssize_t sriov_numvfs_store(struct device *dev, > if (num_vfs > pci_sriov_get_totalvfs(pdev)) > return -ERANGE; > > + mutex_lock(&iov->dev->sriov->lock); > + > if (num_vfs == pdev->sriov->num_VFs) > - return count; /* no change */ > + goto exit; > > /* is PF driver loaded w/callback */ > if (!pdev->driver || !pdev->driver->sriov_configure) { > dev_info(&pdev->dev, "Driver doesn't support SRIOV > configuration via sysfs\n"); > - return -ENOSYS; > + ret = -ENOENT; > + goto exit; Hi Emil, Generally the patch looks fine to me - but I am wondering why the change from -ENOSYS TO -ENOENT? Thanks, - Greg > } > > if (num_vfs == 0) {
Re: [PATCHv1 7/7] IPVTAP: IP-VLAN based tap driver
On Fri, 2017-01-06 at 14:33 -0800, Sainath Grandhi wrote: > This patch adds a tap character device driver that is based on the > IP-VLAN network interface, called ipvtap. An ipvtap device can be created > in the same way as an ipvlan device, using 'type ipvtap', and then accessed > using the tap user space interface. > > Signed-off-by: Sainath Grandhi > Tested-by: Sainath Grandhi > --- > +module_exit(ipvtap_exit); > +MODULE_ALIAS_RTNL_LINK("ipvtap"); > +MODULE_AUTHOR("Arnd Bergmann "); > +MODULE_LICENSE("GPL"); Who wrote this driver exactly ???
Re: [PATCHv1 1/7] TAP: Refactoring macvtap.c
On Sat, Jan 7, 2017 at 12:33 AM, Sainath Grandhi wrote: > macvtap module has code for tap/queue management and link management. This > patch splits > the code into macvtap_main.c for link management and tap.c for tap/queue > management. > Functionality in tap.c can be re-used for implementing tap on other virtual > interfaces. > > Signed-off-by: Sainath Grandhi > Tested-by: Sainath Grandhi > --- > drivers/net/Makefile |2 + > drivers/net/macvtap.c | 1374 > > drivers/net/macvtap_main.c | 218 +++ > drivers/net/tap.c | 1186 ++ > include/linux/if_macvtap.h | 10 + > 5 files changed, 1416 insertions(+), 1374 deletions(-) > delete mode 100644 drivers/net/macvtap.c > create mode 100644 drivers/net/macvtap_main.c > create mode 100644 drivers/net/tap.c > create mode 100644 include/linux/if_macvtap.h Can you use -M -C for better view of this change? It's really hard to review. -- With Best Regards, Andy Shevchenko
Re: [PATCH 2/2] ARM: dts: dra72-evm-revc: enable irqs for dp83867 eth phys
* Grygorii Strashko [170106 12:56]: > TI DRA72-EVM Rev C has two DP83867 ethernet phys which support IRQ > generation in case of phy/link status changes. The INT/PWDN lines from both > DP83867 phys are wired to DRA7 gpio6.16, so reflect the same in DT. Hmm not seeing the patch 1/2 here.. Can this one be queued separately? Is it for v4.11 or a fix? Regards, Tony > Signed-off-by: Grygorii Strashko > --- > arch/arm/boot/dts/dra72-evm-revc.dts | 6 +- > 1 file changed, 5 insertions(+), 1 deletion(-) > > diff --git a/arch/arm/boot/dts/dra72-evm-revc.dts > b/arch/arm/boot/dts/dra72-evm-revc.dts > index c3d939c..3ecac56 100644 > --- a/arch/arm/boot/dts/dra72-evm-revc.dts > +++ b/arch/arm/boot/dts/dra72-evm-revc.dts > @@ -68,6 +68,8 @@ > ti,tx-internal-delay = ; > ti,fifo-depth = ; > ti,min-output-impedance; > + interrupt-parent = <&gpio6>; > + interrupts = <16 IRQ_TYPE_EDGE_FALLING>; > }; > > dp83867_1: ethernet-phy@3 { > @@ -75,6 +77,8 @@ > ti,rx-internal-delay = ; > ti,tx-internal-delay = ; > ti,fifo-depth = ; > - ti,min-output-imepdance; > + ti,min-output-impedance; > + interrupt-parent = <&gpio6>; > + interrupts = <16 IRQ_TYPE_EDGE_FALLING>; > }; > }; > -- > 2.10.1.dirty >
Re: [PATCH net-next 1/2] net: dsa: make "label" property optional for dsa2
On 01/06/2017 02:20 PM, Andrew Lunn wrote: >> If one wants to rename an interface, udev rules can be used as usual. > > Hi Vivien > > Do you have some examples? > > A quick look at udevadm info suggests we can use > > ATTR{phys_port_id} and ATTR{phys_switch_id} > > Humm, it would be nice to know why the second switch has a > phys_switch_id of 0100. Well, that's a combination of being on a little endian system and using %*phN as a printk formatter, and the type being 32-bit long (int). I agree this does not feel natural, but since this is sysfs (so ABI in a way), it's going to be though to change now. -- Florian
Re: [PATCH net-next 2/2] arm: dts: vf610-zii-dev-rev-b: remove ports label
On Fri, Jan 06, 2017 at 05:00:43PM -0500, Vivien Didelot wrote: > Now that the "label" property is optional for Ethernet switch ports, > remove them in the ZII Dev Rev B board DTS. > > On a Rev B board, once eth1 is up, this DTS now exposes to userspace: > > # ip link | grep ': ' | cut -d: -f2 > lo > eth0 > eth1 > eth2@eth1 > eth3@eth1 > eth4@eth1 > eth5@eth1 > eth6@eth1 > eth7@eth1 > eth8@eth1 > eth9@eth1 > eth10@eth1 > eth11@eth1 > eth12@eth1 It exposes this, this time. Next time, it could be: eth0 eth1@eth0 eth2@eth0 eth3@eth0 eth4@eth0 eth5@eth0 eth6@eth0 eth7@eth0 eth8@eth0 eth9@eth0 eth10@eth0 eth11@eth0 eth12 depending on how the base interfaces enumerate. We have gone from deterministic names to non-deterministic names for the switch ports. We now must have udev rules, if we want deterministic names. If the names where not deterministic before, i would of agreed to this. But they are deterministic, set by device tree, and set to match some physical property of the hardware, generally the label on the case/PCB. If somebody were to produce a switch on a PCIe card, or a USB bus, things then are non-deterministic, and leaving the kernel to assign a name is O.K. So i think the first patch is O.K, but i don't like this patch. Andrew
Re: [PATCH 2/3] xen: modify xenstore watch event interface
On 01/06/2017 10:05 AM, Juergen Gross wrote: > Today a Xenstore watch event is delivered via a callback function > declared as: > > void (*callback)(struct xenbus_watch *, > const char **vec, unsigned int len); > > As all watch events only ever come with two parameters (path and token) > changing the prototype to: > > void (*callback)(struct xenbus_watch *, > const char *path, const char *token); > > is the natural thing to do. > > Apply this change and adapt all users. > > Cc: konrad.w...@oracle.com > Cc: roger@citrix.com > Cc: wei.l...@citrix.com > Cc: paul.durr...@citrix.com > Cc: netdev@vger.kernel.org > > Signed-off-by: Juergen Gross > > @@ -903,24 +902,24 @@ static int process_msg(void) > body[msg->hdr.len] = '\0'; > > if (msg->hdr.type == XS_WATCH_EVENT) { > - msg->u.watch.vec = split(body, msg->hdr.len, > - &msg->u.watch.vec_size); > - if (IS_ERR(msg->u.watch.vec)) { > - err = PTR_ERR(msg->u.watch.vec); > + if (count_strings(body, msg->hdr.len) != 2) { > + err = -EINVAL; xenbus_write_watch() returns -EILSEQ when this type of error is encountered so perhaps for we should return the same error here. Either way Reviewed-by: Boris Ostrovsky
[PATCHv1 1/7] TAP: Refactoring macvtap.c
macvtap module has code for tap/queue management and link management. This patch splits the code into macvtap_main.c for link management and tap.c for tap/queue management. Functionality in tap.c can be re-used for implementing tap on other virtual interfaces. Signed-off-by: Sainath Grandhi Tested-by: Sainath Grandhi --- drivers/net/Makefile |2 + drivers/net/macvtap.c | 1374 drivers/net/macvtap_main.c | 218 +++ drivers/net/tap.c | 1186 ++ include/linux/if_macvtap.h | 10 + 5 files changed, 1416 insertions(+), 1374 deletions(-) delete mode 100644 drivers/net/macvtap.c create mode 100644 drivers/net/macvtap_main.c create mode 100644 drivers/net/tap.c create mode 100644 include/linux/if_macvtap.h diff --git a/drivers/net/Makefile b/drivers/net/Makefile index 7336cbd..19b03a9 100644 --- a/drivers/net/Makefile +++ b/drivers/net/Makefile @@ -29,6 +29,8 @@ obj-$(CONFIG_GTP) += gtp.o obj-$(CONFIG_NLMON) += nlmon.o obj-$(CONFIG_NET_VRF) += vrf.o +macvtap-objs := macvtap_main.o tap.o + # # Networking Drivers # diff --git a/drivers/net/macvtap.c b/drivers/net/macvtap.c deleted file mode 100644 index 5c26653..000 --- a/drivers/net/macvtap.c +++ /dev/null @@ -1,1374 +0,0 @@ -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include -#include -#include -#include -#include - -/* - * A macvtap queue is the central object of this driver, it connects - * an open character device to a macvlan interface. There can be - * multiple queues on one interface, which map back to queues - * implemented in hardware on the underlying device. - * - * macvtap_proto is used to allocate queues through the sock allocation - * mechanism. - * - */ -struct macvtap_queue { - struct sock sk; - struct socket sock; - struct socket_wq wq; - int vnet_hdr_sz; - struct macvlan_dev __rcu *vlan; - struct file *file; - unsigned int flags; - u16 queue_index; - bool enabled; - struct list_head next; - struct skb_array skb_array; -}; - -#define MACVTAP_FEATURES (IFF_VNET_HDR | IFF_MULTI_QUEUE) - -#define MACVTAP_VNET_LE 0x8000 -#define MACVTAP_VNET_BE 0x4000 - -#ifdef CONFIG_TUN_VNET_CROSS_LE -static inline bool macvtap_legacy_is_little_endian(struct macvtap_queue *q) -{ - return q->flags & MACVTAP_VNET_BE ? false : - virtio_legacy_is_little_endian(); -} - -static long macvtap_get_vnet_be(struct macvtap_queue *q, int __user *sp) -{ - int s = !!(q->flags & MACVTAP_VNET_BE); - - if (put_user(s, sp)) - return -EFAULT; - - return 0; -} - -static long macvtap_set_vnet_be(struct macvtap_queue *q, int __user *sp) -{ - int s; - - if (get_user(s, sp)) - return -EFAULT; - - if (s) - q->flags |= MACVTAP_VNET_BE; - else - q->flags &= ~MACVTAP_VNET_BE; - - return 0; -} -#else -static inline bool macvtap_legacy_is_little_endian(struct macvtap_queue *q) -{ - return virtio_legacy_is_little_endian(); -} - -static long macvtap_get_vnet_be(struct macvtap_queue *q, int __user *argp) -{ - return -EINVAL; -} - -static long macvtap_set_vnet_be(struct macvtap_queue *q, int __user *argp) -{ - return -EINVAL; -} -#endif /* CONFIG_TUN_VNET_CROSS_LE */ - -static inline bool macvtap_is_little_endian(struct macvtap_queue *q) -{ - return q->flags & MACVTAP_VNET_LE || - macvtap_legacy_is_little_endian(q); -} - -static inline u16 macvtap16_to_cpu(struct macvtap_queue *q, __virtio16 val) -{ - return __virtio16_to_cpu(macvtap_is_little_endian(q), val); -} - -static inline __virtio16 cpu_to_macvtap16(struct macvtap_queue *q, u16 val) -{ - return __cpu_to_virtio16(macvtap_is_little_endian(q), val); -} - -static struct proto macvtap_proto = { - .name = "macvtap", - .owner = THIS_MODULE, - .obj_size = sizeof (struct macvtap_queue), -}; - -/* - * Variables for dealing with macvtaps device numbers. - */ -static dev_t macvtap_major; -#define MACVTAP_NUM_DEVS (1U << MINORBITS) -static DEFINE_MUTEX(minor_lock); -static DEFINE_IDR(minor_idr); - -#define GOODCOPY_LEN 128 -static const void *macvtap_net_namespace(struct device *d) -{ - struct net_device *dev = to_net_dev(d->parent); - return dev_net(dev); -} - -static struct class macvtap_class = { - .name = "macvtap", - .owner = THIS_MODULE, - .ns_type = &net_ns_type_operations, - .namespace = macvtap_net_namespace, -}; -static struct cdev macvtap_cdev; - -static const struct proto_ops macvtap_socket_ops; - -#define TUN_OFFLOADS (NETIF_F_HW_CSUM | NETIF_F_TSO_ECN | NETIF_F_TSO | \ - NETIF_F_TSO6 | NETIF_F_UFO) -#define RX_OFFLOADS (NETIF_F_GRO | N
[PATCHv1 4/7] TAP: Abstract type of virtual interface from tap implementation
macvlan object is re-structured to hold tap related elements in a separate entity, tap_dev. Upon NETDEV_REGISTER device_event, tap_dev is registered with idr and fetched again on tap_open. Few of the tap functions are modified to accepted tap_dev as argument. tap_dev object includes callbacks to be used by underlying virtual interface to take care of tx and rx accounting. Signed-off-by: Sainath Grandhi Tested-by: Sainath Grandhi --- drivers/net/macvlan.c | 2 +- drivers/net/macvtap_main.c | 68 +--- drivers/net/tap.c | 264 - include/linux/if_tap.h | 59 +- 4 files changed, 227 insertions(+), 166 deletions(-) diff --git a/drivers/net/macvlan.c b/drivers/net/macvlan.c index 20b3fdf2..79383f9 100644 --- a/drivers/net/macvlan.c +++ b/drivers/net/macvlan.c @@ -1526,7 +1526,6 @@ static const struct nla_policy macvlan_policy[IFLA_MACVLAN_MAX + 1] = { int macvlan_link_register(struct rtnl_link_ops *ops) { /* common fields */ - ops->priv_size = sizeof(struct macvlan_dev); ops->validate = macvlan_validate; ops->maxtype= IFLA_MACVLAN_MAX; ops->policy = macvlan_policy; @@ -1549,6 +1548,7 @@ static struct rtnl_link_ops macvlan_link_ops = { .newlink= macvlan_newlink, .dellink= macvlan_dellink, .get_link_net = macvlan_get_link_net, + .priv_size = sizeof(struct macvlan_dev), }; static int macvlan_device_event(struct notifier_block *unused, diff --git a/drivers/net/macvtap_main.c b/drivers/net/macvtap_main.c index 32ad560..6326a82 100644 --- a/drivers/net/macvtap_main.c +++ b/drivers/net/macvtap_main.c @@ -24,6 +24,11 @@ #include #include +struct macvtap_dev { + struct macvlan_dev vlan; + struct tap_devtap; +}; + /* * Variables for dealing with macvtaps device numbers. */ @@ -46,22 +51,52 @@ static struct cdev macvtap_cdev; #define TUN_OFFLOADS (NETIF_F_HW_CSUM | NETIF_F_TSO_ECN | NETIF_F_TSO | \ NETIF_F_TSO6 | NETIF_F_UFO) +static void macvtap_count_tx_dropped(struct tap_dev *tap) +{ + struct macvlan_dev *vlan = (struct macvlan_dev *)container_of(tap, struct macvtap_dev, tap); + + this_cpu_inc(vlan->pcpu_stats->tx_dropped); +} + +static void macvtap_count_rx_dropped(struct tap_dev *tap) +{ + struct macvlan_dev *vlan = (struct macvlan_dev *)container_of(tap, struct macvtap_dev, tap); + + macvlan_count_rx(vlan, 0, 0, 0); +} + +static void macvtap_update_features(struct tap_dev *tap, + netdev_features_t features) +{ + struct macvlan_dev *vlan = (struct macvlan_dev *)container_of(tap, struct macvtap_dev, tap); + + vlan->set_features = features; + netdev_update_features(vlan->dev); +} + static int macvtap_newlink(struct net *src_net, struct net_device *dev, struct nlattr *tb[], struct nlattr *data[]) { - struct macvlan_dev *vlan = netdev_priv(dev); + struct macvtap_dev *vlantap = netdev_priv(dev); int err; - INIT_LIST_HEAD(&vlan->queue_list); + INIT_LIST_HEAD(&vlantap->tap.queue_list); /* Since macvlan supports all offloads by default, make * tap support all offloads also. */ - vlan->tap_features = TUN_OFFLOADS; + vlantap->tap.tap_features = TUN_OFFLOADS; - err = netdev_rx_handler_register(dev, tap_handle_frame, vlan); + /* Register callbacks for rx/tx drops accounting and updating +* net_device features +*/ + vlantap->tap.count_tx_dropped = macvtap_count_tx_dropped; + vlantap->tap.count_rx_dropped = macvtap_count_rx_dropped; + vlantap->tap.update_features = macvtap_update_features; + + err = netdev_rx_handler_register(dev, tap_handle_frame, &vlantap->tap); if (err) return err; @@ -74,14 +109,18 @@ static int macvtap_newlink(struct net *src_net, return err; } + vlantap->tap.dev = vlantap->vlan.dev; + return 0; } static void macvtap_dellink(struct net_device *dev, struct list_head *head) { + struct macvtap_dev *vlantap = netdev_priv(dev); + netdev_rx_handler_unregister(dev); - tap_del_queues(dev); + tap_del_queues(&vlantap->tap); macvlan_dellink(dev, head); } @@ -96,13 +135,14 @@ static struct rtnl_link_ops macvtap_link_ops __read_mostly = { .setup = macvtap_setup, .newlink= macvtap_newlink, .dellink= macvtap_dellink, + .priv_size = sizeof(struct macvtap_dev), }; static int macvtap_device_event(struct notifier_block *unused, unsigned long event, void *ptr) { struct net_device *dev = netdev_notifier_info_to_dev(ptr); - struc
[PATCHv1 0/7] Refactor macvtap to re-use tap functionality by other virtual intefaces
Tap character devices can be implemented on other virtual interfaces like ipvlan, similar to macvtap. Source code for tap functionality in macvtap can be re-used for this purpose. This patch series splits macvtap source into two modules, macvtap and tap. This patch series also includes a patch for implementing tap character device driver based on the IP-VLAN network interface, called ipvtap. Sainath Grandhi (7): TAP: Refactoring macvtap.c TAP: Renaming tap related APIs, data structures, macros TAP: Tap character device creation/destroy API TAP: Abstract type of virtual interface from tap implementation TAP: Extending tap device create/destroy APIs TAP: tap as an independent module IPVTAP: IP-VLAN based tap driver drivers/net/Kconfig | 26 + drivers/net/Makefile |2 + drivers/net/ipvlan/Makefile |1 + drivers/net/ipvlan/ipvlan.h |7 + drivers/net/ipvlan/ipvlan_core.c |5 +- drivers/net/ipvlan/ipvlan_main.c | 37 +- drivers/net/ipvlan/ipvtap.c | 238 +++ drivers/net/macvlan.c|2 +- drivers/net/macvtap.c| 1227 ++-- drivers/net/tap.c| 1276 ++ drivers/vhost/net.c |3 +- include/linux/if_macvlan.h |4 +- include/linux/if_tap.h | 63 ++ 13 files changed, 1691 insertions(+), 1200 deletions(-) create mode 100644 drivers/net/ipvlan/ipvtap.c create mode 100644 drivers/net/tap.c create mode 100644 include/linux/if_tap.h -- 2.7.4
[PATCHv1 2/7] TAP: Renaming tap related APIs, data structures, macros
Renaming tap related APIs, data structures and macros in tap.c from macvtap_.* to tap_.* Signed-off-by: Sainath Grandhi Tested-by: Sainath Grandhi --- drivers/net/macvtap_main.c | 18 +-- drivers/net/tap.c | 332 ++--- drivers/vhost/net.c| 3 +- include/linux/if_macvlan.h | 4 +- include/linux/if_macvtap.h | 10 -- include/linux/if_tap.h | 11 ++ 6 files changed, 190 insertions(+), 188 deletions(-) delete mode 100644 include/linux/if_macvtap.h create mode 100644 include/linux/if_tap.h diff --git a/drivers/net/macvtap_main.c b/drivers/net/macvtap_main.c index 96ffa60..548f339 100644 --- a/drivers/net/macvtap_main.c +++ b/drivers/net/macvtap_main.c @@ -1,6 +1,6 @@ #include #include -#include +#include #include #include #include @@ -62,7 +62,7 @@ static int macvtap_newlink(struct net *src_net, */ vlan->tap_features = TUN_OFFLOADS; - err = netdev_rx_handler_register(dev, macvtap_handle_frame, vlan); + err = netdev_rx_handler_register(dev, tap_handle_frame, vlan); if (err) return err; @@ -82,7 +82,7 @@ static void macvtap_dellink(struct net_device *dev, struct list_head *head) { netdev_rx_handler_unregister(dev); - macvtap_del_queues(dev); + tap_del_queues(dev); macvlan_dellink(dev, head); } @@ -121,7 +121,7 @@ static int macvtap_device_event(struct notifier_block *unused, * been registered but before register_netdevice has * finished running. */ - err = macvtap_get_minor(vlan); + err = tap_get_minor(vlan); if (err) return notifier_from_errno(err); @@ -129,7 +129,7 @@ static int macvtap_device_event(struct notifier_block *unused, classdev = device_create(&macvtap_class, &dev->dev, devt, dev, tap_name); if (IS_ERR(classdev)) { - macvtap_free_minor(vlan); + tap_free_minor(vlan); return notifier_from_errno(PTR_ERR(classdev)); } err = sysfs_create_link(&dev->dev.kobj, &classdev->kobj, @@ -144,10 +144,10 @@ static int macvtap_device_event(struct notifier_block *unused, sysfs_remove_link(&dev->dev.kobj, tap_name); devt = MKDEV(MAJOR(macvtap_major), vlan->minor); device_destroy(&macvtap_class, devt); - macvtap_free_minor(vlan); + tap_free_minor(vlan); break; case NETDEV_CHANGE_TX_QUEUE_LEN: - if (macvtap_queue_resize(vlan)) + if (tap_queue_resize(vlan)) return NOTIFY_BAD; break; } @@ -159,7 +159,7 @@ static struct notifier_block macvtap_notifier_block __read_mostly = { .notifier_call = macvtap_device_event, }; -extern struct file_operations macvtap_fops; +extern struct file_operations tap_fops; static int macvtap_init(void) { int err; @@ -169,7 +169,7 @@ static int macvtap_init(void) if (err) goto out1; - cdev_init(&macvtap_cdev, &macvtap_fops); + cdev_init(&macvtap_cdev, &tap_fops); err = cdev_add(&macvtap_cdev, macvtap_major, MACVTAP_NUM_DEVS); if (err) goto out2; diff --git a/drivers/net/tap.c b/drivers/net/tap.c index 8f12a39..d0807c2 100644 --- a/drivers/net/tap.c +++ b/drivers/net/tap.c @@ -24,16 +24,16 @@ #include /* - * A macvtap queue is the central object of this driver, it connects + * A tap queue is the central object of this driver, it connects * an open character device to a macvlan interface. There can be * multiple queues on one interface, which map back to queues * implemented in hardware on the underlying device. * - * macvtap_proto is used to allocate queues through the sock allocation + * tap_proto is used to allocate queues through the sock allocation * mechanism. * */ -struct macvtap_queue { +struct tap_queue { struct sock sk; struct socket sock; struct socket_wq wq; @@ -47,21 +47,21 @@ struct macvtap_queue { struct skb_array skb_array; }; -#define MACVTAP_FEATURES (IFF_VNET_HDR | IFF_MULTI_QUEUE) +#define TAP_IFFEATURES (IFF_VNET_HDR | IFF_MULTI_QUEUE) -#define MACVTAP_VNET_LE 0x8000 -#define MACVTAP_VNET_BE 0x4000 +#define TAP_VNET_LE 0x8000 +#define TAP_VNET_BE 0x4000 #ifdef CONFIG_TUN_VNET_CROSS_LE -static inline bool macvtap_legacy_is_little_endian(struct macvtap_queue *q) +static inline bool tap_legacy_is_little_endian(struct tap_queue *q) { - return q->flags & MACVTAP_VNET_BE ? false : + return q->flags & TAP_VNET_BE ? false : virtio_legacy_is_little_endian(); } -static long macvtap_get_vnet_be(struct macvtap_queue *q, int __use
[PATCHv1 3/7] TAP: Tap character device creation/destroy API
This patch provides tap device create/destroy APIs in tap.c. Signed-off-by: Sainath Grandhi Tested-by: Sainath Grandhi --- drivers/net/macvtap_main.c | 29 +++-- drivers/net/tap.c | 64 ++ include/linux/if_tap.h | 3 +++ 3 files changed, 65 insertions(+), 31 deletions(-) diff --git a/drivers/net/macvtap_main.c b/drivers/net/macvtap_main.c index 548f339..32ad560 100644 --- a/drivers/net/macvtap_main.c +++ b/drivers/net/macvtap_main.c @@ -28,7 +28,6 @@ * Variables for dealing with macvtaps device numbers. */ static dev_t macvtap_major; -#define MACVTAP_NUM_DEVS (1U << MINORBITS) static const void *macvtap_net_namespace(struct device *d) { @@ -159,43 +158,35 @@ static struct notifier_block macvtap_notifier_block __read_mostly = { .notifier_call = macvtap_device_event, }; -extern struct file_operations tap_fops; static int macvtap_init(void) { int err; - err = alloc_chrdev_region(&macvtap_major, 0, - MACVTAP_NUM_DEVS, "macvtap"); - if (err) - goto out1; + err = tap_create_cdev(&macvtap_cdev, &macvtap_major, "macvtap"); - cdev_init(&macvtap_cdev, &tap_fops); - err = cdev_add(&macvtap_cdev, macvtap_major, MACVTAP_NUM_DEVS); if (err) - goto out2; + goto out1; err = class_register(&macvtap_class); if (err) - goto out3; + goto out2; err = register_netdevice_notifier(&macvtap_notifier_block); if (err) - goto out4; + goto out3; err = macvlan_link_register(&macvtap_link_ops); if (err) - goto out5; + goto out4; return 0; -out5: - unregister_netdevice_notifier(&macvtap_notifier_block); out4: - class_unregister(&macvtap_class); + unregister_netdevice_notifier(&macvtap_notifier_block); out3: - cdev_del(&macvtap_cdev); + class_unregister(&macvtap_class); out2: - unregister_chrdev_region(macvtap_major, MACVTAP_NUM_DEVS); + cdev_del(&macvtap_cdev); out1: return err; } @@ -207,9 +198,7 @@ static void macvtap_exit(void) rtnl_link_unregister(&macvtap_link_ops); unregister_netdevice_notifier(&macvtap_notifier_block); class_unregister(&macvtap_class); - cdev_del(&macvtap_cdev); - unregister_chrdev_region(macvtap_major, MACVTAP_NUM_DEVS); - idr_destroy(&minor_idr); + tap_destroy_cdev(macvtap_major, &macvtap_cdev); } module_exit(macvtap_exit); diff --git a/drivers/net/tap.c b/drivers/net/tap.c index d0807c2..52692d2 100644 --- a/drivers/net/tap.c +++ b/drivers/net/tap.c @@ -123,8 +123,12 @@ static struct proto tap_proto = { }; #define TAP_NUM_DEVS (1U << MINORBITS) -static DEFINE_MUTEX(minor_lock); -DEFINE_IDR(minor_idr); +struct major_info { + dev_t major; + struct idr minor_idr; + struct mutex minor_lock; + const char *device_name; +} macvtap_major; #define GOODCOPY_LEN 128 @@ -413,26 +417,26 @@ int tap_get_minor(struct macvlan_dev *vlan) { int retval = -ENOMEM; - mutex_lock(&minor_lock); - retval = idr_alloc(&minor_idr, vlan, 1, TAP_NUM_DEVS, GFP_KERNEL); + mutex_lock(&macvtap_major.minor_lock); + retval = idr_alloc(&macvtap_major.minor_idr, vlan, 1, TAP_NUM_DEVS, GFP_KERNEL); if (retval >= 0) { vlan->minor = retval; } else if (retval == -ENOSPC) { netdev_err(vlan->dev, "Too many tap devices\n"); retval = -EINVAL; } - mutex_unlock(&minor_lock); + mutex_unlock(&macvtap_major.minor_lock); return retval < 0 ? retval : 0; } void tap_free_minor(struct macvlan_dev *vlan) { - mutex_lock(&minor_lock); + mutex_lock(&macvtap_major.minor_lock); if (vlan->minor) { - idr_remove(&minor_idr, vlan->minor); + idr_remove(&macvtap_major.minor_idr, vlan->minor); vlan->minor = 0; } - mutex_unlock(&minor_lock); + mutex_unlock(&macvtap_major.minor_lock); } static struct net_device *dev_get_by_tap_minor(int minor) @@ -440,13 +444,13 @@ static struct net_device *dev_get_by_tap_minor(int minor) struct net_device *dev = NULL; struct macvlan_dev *vlan; - mutex_lock(&minor_lock); - vlan = idr_find(&minor_idr, minor); + mutex_lock(&macvtap_major.minor_lock); + vlan = idr_find(&macvtap_major.minor_idr, minor); if (vlan) { dev = vlan->dev; dev_hold(dev); } - mutex_unlock(&minor_lock); + mutex_unlock(&macvtap_major.minor_lock); return dev; } @@ -1184,3 +1188,41 @@ int tap_queue_resize(struct macvlan_dev *vlan) kfree(arrays); return ret; } + +int tap_create_cdev(struct cdev *tap_cdev, + dev_t *t
[PATCHv1 7/7] IPVTAP: IP-VLAN based tap driver
This patch adds a tap character device driver that is based on the IP-VLAN network interface, called ipvtap. An ipvtap device can be created in the same way as an ipvlan device, using 'type ipvtap', and then accessed using the tap user space interface. Signed-off-by: Sainath Grandhi Tested-by: Sainath Grandhi --- drivers/net/Kconfig | 12 ++ drivers/net/Makefile | 1 + drivers/net/ipvlan/Makefile | 1 + drivers/net/ipvlan/ipvlan.h | 7 ++ drivers/net/ipvlan/ipvlan_core.c | 5 +- drivers/net/ipvlan/ipvlan_main.c | 37 +++--- drivers/net/ipvlan/ipvtap.c | 238 +++ 7 files changed, 282 insertions(+), 19 deletions(-) create mode 100644 drivers/net/ipvlan/ipvtap.c diff --git a/drivers/net/Kconfig b/drivers/net/Kconfig index 280380d..ddfb30a 100644 --- a/drivers/net/Kconfig +++ b/drivers/net/Kconfig @@ -165,6 +165,18 @@ config IPVLAN To compile this driver as a module, choose M here: the module will be called ipvlan. +config IPVTAP +tristate "IP-VLAN based tap driver" +depends on IPVLAN +depends on INET +help + This adds a specialized tap character device driver that is based + on the IP-VLAN network interface, called ipvtap. An ipvtap device + can be added in the same way as a ipvlan device, using 'type + ipvtap', and then be accessed through the tap user space interface. + + To compile this driver as a module, choose M here: the module + will be called macvtap. config VXLAN tristate "Virtual eXtensible Local Area Network (VXLAN)" diff --git a/drivers/net/Makefile b/drivers/net/Makefile index 7dd86ca..98ed4d9 100644 --- a/drivers/net/Makefile +++ b/drivers/net/Makefile @@ -7,6 +7,7 @@ # obj-$(CONFIG_BONDING) += bonding/ obj-$(CONFIG_IPVLAN) += ipvlan/ +obj-$(CONFIG_IPVTAP) += ipvlan/ obj-$(CONFIG_DUMMY) += dummy.o obj-$(CONFIG_EQUALIZER) += eql.o obj-$(CONFIG_IFB) += ifb.o diff --git a/drivers/net/ipvlan/Makefile b/drivers/net/ipvlan/Makefile index df79910..8a2c64d 100644 --- a/drivers/net/ipvlan/Makefile +++ b/drivers/net/ipvlan/Makefile @@ -3,5 +3,6 @@ # obj-$(CONFIG_IPVLAN) += ipvlan.o +obj-$(CONFIG_IPVTAP) += ipvtap.o ipvlan-objs := ipvlan_core.o ipvlan_main.o diff --git a/drivers/net/ipvlan/ipvlan.h b/drivers/net/ipvlan/ipvlan.h index dbfbb33..4362d88 100644 --- a/drivers/net/ipvlan/ipvlan.h +++ b/drivers/net/ipvlan/ipvlan.h @@ -133,4 +133,11 @@ struct sk_buff *ipvlan_l3_rcv(struct net_device *dev, struct sk_buff *skb, u16 proto); unsigned int ipvlan_nf_input(void *priv, struct sk_buff *skb, const struct nf_hook_state *state); +void ipvlan_count_rx(const struct ipvl_dev *ipvlan, +unsigned int len, bool success, bool mcast); +int ipvlan_link_new(struct net *src_net, struct net_device *dev, + struct nlattr *tb[], struct nlattr *data[]); +void ipvlan_link_delete(struct net_device *dev, struct list_head *head); +void ipvlan_link_setup(struct net_device *dev); +int ipvlan_link_register(struct rtnl_link_ops *ops); #endif /* __IPVLAN_H */ diff --git a/drivers/net/ipvlan/ipvlan_core.c b/drivers/net/ipvlan/ipvlan_core.c index 83ce74a..9af16ab 100644 --- a/drivers/net/ipvlan/ipvlan_core.c +++ b/drivers/net/ipvlan/ipvlan_core.c @@ -16,8 +16,8 @@ void ipvlan_init_secret(void) net_get_random_once(&ipvlan_jhash_secret, sizeof(ipvlan_jhash_secret)); } -static void ipvlan_count_rx(const struct ipvl_dev *ipvlan, - unsigned int len, bool success, bool mcast) +void ipvlan_count_rx(const struct ipvl_dev *ipvlan, +unsigned int len, bool success, bool mcast) { if (!ipvlan) return; @@ -36,6 +36,7 @@ static void ipvlan_count_rx(const struct ipvl_dev *ipvlan, this_cpu_inc(ipvlan->pcpu_stats->rx_errs); } } +EXPORT_SYMBOL_GPL(ipvlan_count_rx); static u8 ipvlan_get_v6_hash(const void *iaddr) { diff --git a/drivers/net/ipvlan/ipvlan_main.c b/drivers/net/ipvlan/ipvlan_main.c index 8b0f993..666a05d 100644 --- a/drivers/net/ipvlan/ipvlan_main.c +++ b/drivers/net/ipvlan/ipvlan_main.c @@ -13,14 +13,14 @@ static u32 ipvl_nf_hook_refcnt = 0; static struct nf_hook_ops ipvl_nfops[] __read_mostly = { { - .hook = ipvlan_nf_input, - .pf = NFPROTO_IPV4, + .hook = ipvlan_nf_input, + .pf = NFPROTO_IPV4, .hooknum = NF_INET_LOCAL_IN, .priority = INT_MAX, }, { - .hook = ipvlan_nf_input, - .pf = NFPROTO_IPV6, + .hook = ipvlan_nf_input, + .pf = NFPROTO_IPV6, .hooknum = NF_INET_LOCAL_IN, .priority = INT_MAX, }, @@ -398,7 +398,7 @@ static int ipvlan_hard_header(struct sk_buff *skb, struc
[PATCHv1 6/7] TAP: tap as an independent module
This patch makes tap a separate module for other types of virtual interfaces, for example, ipvlan to use. Signed-off-by: Sainath Grandhi Tested-by: Sainath Grandhi --- drivers/net/Kconfig| 14 +++ drivers/net/Makefile | 3 +- drivers/net/macvtap.c | 247 + drivers/net/macvtap_main.c | 247 - drivers/net/tap.c | 10 ++ 5 files changed, 272 insertions(+), 249 deletions(-) create mode 100644 drivers/net/macvtap.c delete mode 100644 drivers/net/macvtap_main.c diff --git a/drivers/net/Kconfig b/drivers/net/Kconfig index 95c32f2..280380d 100644 --- a/drivers/net/Kconfig +++ b/drivers/net/Kconfig @@ -284,6 +284,20 @@ config TUN If you don't know what to use this for, you don't need it. +config TAP +tristate "TAP module support for virtual interfaces" +---help--- + TAP module serves two purposes. This can be used as library of functions + for virtual interfaces to implement tap functionality. + + This module also includes character device file and socket operations + that can be used by virtual interface implementing tap. + + To compile this driver as a module, choose M here: the module + will be called tap. + + If you don't know what to use this for, you don't need it. + config TUN_VNET_CROSS_LE bool "Support for cross-endian vnet headers on little-endian kernels" default n diff --git a/drivers/net/Makefile b/drivers/net/Makefile index 19b03a9..7dd86ca 100644 --- a/drivers/net/Makefile +++ b/drivers/net/Makefile @@ -21,6 +21,7 @@ obj-$(CONFIG_PHYLIB) += phy/ obj-$(CONFIG_RIONET) += rionet.o obj-$(CONFIG_NET_TEAM) += team/ obj-$(CONFIG_TUN) += tun.o +obj-$(CONFIG_TAP) += tap.o obj-$(CONFIG_VETH) += veth.o obj-$(CONFIG_VIRTIO_NET) += virtio_net.o obj-$(CONFIG_VXLAN) += vxlan.o @@ -29,8 +30,6 @@ obj-$(CONFIG_GTP) += gtp.o obj-$(CONFIG_NLMON) += nlmon.o obj-$(CONFIG_NET_VRF) += vrf.o -macvtap-objs := macvtap_main.o tap.o - # # Networking Drivers # diff --git a/drivers/net/macvtap.c b/drivers/net/macvtap.c new file mode 100644 index 000..3f047b4 --- /dev/null +++ b/drivers/net/macvtap.c @@ -0,0 +1,247 @@ +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include + +struct macvtap_dev { + struct macvlan_dev vlan; + struct tap_devtap; +}; + +/* + * Variables for dealing with macvtaps device numbers. + */ +static dev_t macvtap_major; + +static const void *macvtap_net_namespace(struct device *d) +{ + struct net_device *dev = to_net_dev(d->parent); + return dev_net(dev); +} + +static struct class macvtap_class = { + .name = "macvtap", + .owner = THIS_MODULE, + .ns_type = &net_ns_type_operations, + .namespace = macvtap_net_namespace, +}; +static struct cdev macvtap_cdev; + +#define TUN_OFFLOADS (NETIF_F_HW_CSUM | NETIF_F_TSO_ECN | NETIF_F_TSO | \ + NETIF_F_TSO6 | NETIF_F_UFO) + +static void macvtap_count_tx_dropped(struct tap_dev *tap) +{ + struct macvlan_dev *vlan = (struct macvlan_dev *)container_of(tap, struct macvtap_dev, tap); + + this_cpu_inc(vlan->pcpu_stats->tx_dropped); +} + +static void macvtap_count_rx_dropped(struct tap_dev *tap) +{ + struct macvlan_dev *vlan = (struct macvlan_dev *)container_of(tap, struct macvtap_dev, tap); + + macvlan_count_rx(vlan, 0, 0, 0); +} + +static void macvtap_update_features(struct tap_dev *tap, + netdev_features_t features) +{ + struct macvlan_dev *vlan = (struct macvlan_dev *)container_of(tap, struct macvtap_dev, tap); + + vlan->set_features = features; + netdev_update_features(vlan->dev); +} + +static int macvtap_newlink(struct net *src_net, + struct net_device *dev, + struct nlattr *tb[], + struct nlattr *data[]) +{ + struct macvtap_dev *vlantap = netdev_priv(dev); + int err; + + INIT_LIST_HEAD(&vlantap->tap.queue_list); + + /* Since macvlan supports all offloads by default, make +* tap support all offloads also. +*/ + vlantap->tap.tap_features = TUN_OFFLOADS; + + /* Register callbacks for rx/tx drops accounting and updating +* net_device features +*/ + vlantap->tap.count_tx_dropped = macvtap_count_tx_dropped; + vlantap->tap.count_rx_dropped = macvtap_count_rx_dropped; + vlantap->tap.update_features = macvtap_update_features; + + err = netdev_rx_handler_register(dev, tap_handle_frame, &vlantap->tap); + if (err) + return err; + + /* Don't put anything that may fail after macvlan_common_ne
[PATCHv1 5/7] TAP: Extending tap device create/destroy APIs
Extending tap APIs get/free_minor and create/destroy_cdev to handle more than one type of virtual interface. Signed-off-by: Sainath Grandhi Tested-by: Sainath Grandhi --- drivers/net/macvtap_main.c | 6 +-- drivers/net/tap.c | 110 - include/linux/if_tap.h | 4 +- 3 files changed, 93 insertions(+), 27 deletions(-) diff --git a/drivers/net/macvtap_main.c b/drivers/net/macvtap_main.c index 6326a82..3f047b4 100644 --- a/drivers/net/macvtap_main.c +++ b/drivers/net/macvtap_main.c @@ -160,7 +160,7 @@ static int macvtap_device_event(struct notifier_block *unused, * been registered but before register_netdevice has * finished running. */ - err = tap_get_minor(&vlantap->tap); + err = tap_get_minor(macvtap_major, &vlantap->tap); if (err) return notifier_from_errno(err); @@ -168,7 +168,7 @@ static int macvtap_device_event(struct notifier_block *unused, classdev = device_create(&macvtap_class, &dev->dev, devt, dev, tap_name); if (IS_ERR(classdev)) { - tap_free_minor(&vlantap->tap); + tap_free_minor(macvtap_major, &vlantap->tap); return notifier_from_errno(PTR_ERR(classdev)); } err = sysfs_create_link(&dev->dev.kobj, &classdev->kobj, @@ -183,7 +183,7 @@ static int macvtap_device_event(struct notifier_block *unused, sysfs_remove_link(&dev->dev.kobj, tap_name); devt = MKDEV(MAJOR(macvtap_major), vlantap->tap.minor); device_destroy(&macvtap_class, devt); - tap_free_minor(&vlantap->tap); + tap_free_minor(macvtap_major, &vlantap->tap); break; case NETDEV_CHANGE_TX_QUEUE_LEN: if (tap_queue_resize(&vlantap->tap)) diff --git a/drivers/net/tap.c b/drivers/net/tap.c index 6306ab9..1d5bcf3 100644 --- a/drivers/net/tap.c +++ b/drivers/net/tap.c @@ -99,12 +99,16 @@ static struct proto tap_proto = { }; #define TAP_NUM_DEVS (1U << MINORBITS) + +LIST_HEAD(major_list); + struct major_info { dev_t major; struct idr minor_idr; struct mutex minor_lock; const char *device_name; -} macvtap_major; + struct list_head next; +}; #define GOODCOPY_LEN 128 @@ -385,44 +389,81 @@ rx_handler_result_t tap_handle_frame(struct sk_buff **pskb) return RX_HANDLER_CONSUMED; } -int tap_get_minor(struct tap_dev *tap) +int tap_get_minor(dev_t major, struct tap_dev *tap) { int retval = -ENOMEM; + struct major_info *tap_major, *tmp; + bool found = false; - mutex_lock(&macvtap_major.minor_lock); - retval = idr_alloc(&macvtap_major.minor_idr, tap, 1, TAP_NUM_DEVS, GFP_KERNEL); + list_for_each_entry_safe(tap_major, tmp, &major_list, next) { + if (tap_major->major == MAJOR(major)) { + found = true; + break; + } + } + + if (!found) + return -EINVAL; + + mutex_lock(&tap_major->minor_lock); + retval = idr_alloc(&tap_major->minor_idr, tap, 1, TAP_NUM_DEVS, GFP_KERNEL); if (retval >= 0) { tap->minor = retval; } else if (retval == -ENOSPC) { netdev_err(tap->dev, "Too many tap devices\n"); retval = -EINVAL; } - mutex_unlock(&macvtap_major.minor_lock); + mutex_unlock(&tap_major->minor_lock); return retval < 0 ? retval : 0; } -void tap_free_minor(struct tap_dev *tap) +void tap_free_minor(dev_t major, struct tap_dev *tap) { - mutex_lock(&macvtap_major.minor_lock); + struct major_info *tap_major, *tmp; + bool found = false; + + list_for_each_entry_safe(tap_major, tmp, &major_list, next) { + if (tap_major->major == MAJOR(major)) { + found = true; + break; + } + } + + if (!found) + return; + + mutex_lock(&tap_major->minor_lock); if (tap->minor) { - idr_remove(&macvtap_major.minor_idr, tap->minor); + idr_remove(&tap_major->minor_idr, tap->minor); tap->minor = 0; } - mutex_unlock(&macvtap_major.minor_lock); + mutex_unlock(&tap_major->minor_lock); } -static struct tap_dev *dev_get_by_tap_minor(int minor) +static struct tap_dev *dev_get_by_tap_file(int major, int minor) { struct net_device *dev = NULL; struct tap_dev *tap; + struct major_info *tap_major, *tmp; + bool found = false; - mutex_lock(&macvtap_major.minor_lock); - tap = idr_find(&macvtap_major.minor_idr, minor); + list_for_each_entry_safe(tap_major, tmp, &major_list, next) { + if (tap_ma
Re: [PATCH net-next] net: dsa: move HWMON support to its own file
On Fri, Jan 06, 2017 at 04:42:00PM -0500, Vivien Didelot wrote: > Isolate the HWMON support in DSA in its own file. Currently only the > legacy DSA code is concerned. > > Signed-off-by: Vivien Didelot Seems like a good step towards removing it completely and letting the PHY do it all. Reviewed-by: Andrew Lunn Andrew
Re: [PATCH v2 00/12] net: ethernet: aquantia: Add AQtion 2.5/5 GB NIC driver
On 01/06/2017 01:02 PM, David Miller wrote: From: Alexander Loktionov Date: Fri, 6 Jan 2017 00:06:01 -0800 This series introduced the AQtion NIC driver for the aQuantia AQC107/AQC108 network devices. v1: Initial version v2: o Make necessary drivers/net/ethernet changes to integrate software o Drop intermediate atlantic directory o Remove Makefile things only appropriate to out of tree module builidng Every patch series must be fully bisectable, this means that at each step of the series, the kernel tree must fully build and work properly. You break that already at the first patch, which makes the Kconfig options available, which if enabled will cause a build failure. make[4]: *** No rule to make target 'drivers/net/ethernet/aquantia/aq_main.o', needed by 'drivers/net/ethernet/aquantia/atlantic.o'. Stop. make[4]: *** Waiting for unfinished jobs scripts/Makefile.build:551: recipe for target 'drivers/net/ethernet/aquantia' failed make[3]: *** [drivers/net/ethernet/aquantia] Error 2 make[3]: *** Waiting for unfinished jobs scripts/Makefile.build:551: recipe for target 'drivers/net/ethernet' failed make[2]: *** [drivers/net/ethernet] Error 2 scripts/Makefile.build:551: recipe for target 'drivers/net' failed make[1]: *** [drivers/net] Error 2 make[1]: *** Waiting for unfinished jobs Makefile:988: recipe for target 'drivers' failed make: *** [drivers] Error 2 The way to do this, is to add the pieces of source code infrastrucutre, one piece at a time. And then at the very very end, enable the code into the build. Thanks, will fix shortly. -- David VL
Re: [PATCH net-next] net: dsa: move HWMON support to its own file
On 01/06/2017 01:42 PM, Vivien Didelot wrote: > Isolate the HWMON support in DSA in its own file. Currently only the > legacy DSA code is concerned. > > Signed-off-by: Vivien Didelot Reviewed-by: Florian Fainelli -- Florian
[PATCH net-next 1/2] net: dsa: make "label" property optional for dsa2
In the new DTS bindings for DSA (dsa2), the "ethernet" and "link" phandles are respectively mandatory and exclusive to CPU port and DSA link device tree nodes. Simplify dsa2.c a bit by checking the presence of such phandle instead of checking the redundant "label" property. Then the Linux philosophy for Ethernet switch ports is to expose them to userspace as standard NICs by default. Thus use the standard enumerated "eth%d" device name if no "label" property is provided for a user port. This allows to save DTS files from subjective net device names. If one wants to rename an interface, udev rules can be used as usual. The sysfs phys_port_id and phys_switch_id also provide physical data. Of course the current behavior is unchanged, and the optional "label" property for user ports has precedence over the enumerated name. Signed-off-by: Vivien Didelot --- Documentation/devicetree/bindings/net/dsa/dsa.txt | 20 --- net/dsa/dsa2.c| 24 --- 2 files changed, 12 insertions(+), 32 deletions(-) diff --git a/Documentation/devicetree/bindings/net/dsa/dsa.txt b/Documentation/devicetree/bindings/net/dsa/dsa.txt index a4a570fb2494..cfe8f64eca4f 100644 --- a/Documentation/devicetree/bindings/net/dsa/dsa.txt +++ b/Documentation/devicetree/bindings/net/dsa/dsa.txt @@ -34,13 +34,9 @@ Required properties: Each port children node must have the following mandatory properties: - reg : Describes the port address in the switch -- label: Describes the label associated with this port, which - will become the netdev name. Special labels are - "cpu" to indicate a CPU port and "dsa" to - indicate an uplink/downlink port between switches in - the cluster. -A port labelled "dsa" has the following mandatory property: +An uplink/downlink port between switches in the cluster has the following +mandatory property: - link : Should be a list of phandles to other switch's DSA port. This port is used as the outgoing port @@ -48,12 +44,17 @@ A port labelled "dsa" has the following mandatory property: information must be given, not just the one hop routes to neighbouring switches. -A port labelled "cpu" has the following mandatory property: +A CPU port has the following mandatory property: - ethernet : Should be a phandle to a valid Ethernet device node. This host device is what the switch port is connected to. +A user port has the following optional property: + +- label: Describes the label associated with this port, which + will become the netdev name. + Port child nodes may also contain the following optional standardised properties, described in binding documents: @@ -107,7 +108,6 @@ linked into one DSA cluster. switch0port5: port@5 { reg = <5>; - label = "dsa"; phy-mode = "rgmii-txid"; link = <&switch1port6 &switch2port9>; @@ -119,7 +119,6 @@ linked into one DSA cluster. port@6 { reg = <6>; - label = "cpu"; ethernet = <&fec1>; fixed-link { speed = <100>; @@ -165,7 +164,6 @@ linked into one DSA cluster. switch1port5: port@5 { reg = <5>; - label = "dsa"; link = <&switch2port9>; phy-mode = "rgmii-txid"; fixed-link { @@ -176,7 +174,6 @@ linked into one DSA cluster. switch1port6: port@6 { reg = <6>; - label = "dsa"; phy-mode = "rgmii-txid"; link = <&switch0port5>; fixed-link { @@ -255,7 +252,6 @@ linked into one DSA cluster. switch2port9: port@9 { reg = <9>; - label = "dsa"; phy-mode = "rgmii-txid"; link = <&switch1port5 &switch0port5>; diff --git a/net/dsa/dsa2.c b/net/dsa/dsa2.c index bad119cee2a3..9526bdf2a34a 100644 --- a/net/dsa/dsa2.c +++ b/net/dsa/dsa2.c @@ -81,30 +81,12 @@ static void dsa_dst_del_ds(struct dsa_switch_tree *dst, static bool dsa_port_is_dsa(struct device_n
[PATCH net-next 0/2] net: dsa: make "label" property optional
Patch 1/2 makes the "label" property in new DSA bindings optional. This doesn't change the current behavior with existing DTS files. As Linux considers the Ethernet switch ports as normal NICs by default, not providing a "label" property for user ports results in using the standard "ethX" network device name. Giving a "label" overwrites this. Patch 2/2 removes the labels for the ZII Rev B board as an example. Vivien Didelot (2): net: dsa: make "label" property optional for dsa2 arm: dts: vf610-zii-dev-rev-b: remove ports label Documentation/devicetree/bindings/net/dsa/dsa.txt | 20 --- arch/arm/boot/dts/vf610-zii-dev-rev-b.dts | 16 --- net/dsa/dsa2.c| 24 --- 3 files changed, 12 insertions(+), 48 deletions(-) -- 2.11.0
[PATCH net-next 2/2] arm: dts: vf610-zii-dev-rev-b: remove ports label
Now that the "label" property is optional for Ethernet switch ports, remove them in the ZII Dev Rev B board DTS. On a Rev B board, once eth1 is up, this DTS now exposes to userspace: # ip link | grep ': ' | cut -d: -f2 lo eth0 eth1 eth2@eth1 eth3@eth1 eth4@eth1 eth5@eth1 eth6@eth1 eth7@eth1 eth8@eth1 eth9@eth1 eth10@eth1 eth11@eth1 eth12@eth1 Signed-off-by: Vivien Didelot --- arch/arm/boot/dts/vf610-zii-dev-rev-b.dts | 16 1 file changed, 16 deletions(-) diff --git a/arch/arm/boot/dts/vf610-zii-dev-rev-b.dts b/arch/arm/boot/dts/vf610-zii-dev-rev-b.dts index 7ea617e47fe4..f9c8810aed7c 100644 --- a/arch/arm/boot/dts/vf610-zii-dev-rev-b.dts +++ b/arch/arm/boot/dts/vf610-zii-dev-rev-b.dts @@ -104,25 +104,21 @@ #size-cells = <0>; port@0 { reg = <0>; - label = "lan0"; phy-handle = <&switch0phy0>; }; port@1 { reg = <1>; - label = "lan1"; phy-handle = <&switch0phy1>; }; port@2 { reg = <2>; - label = "lan2"; phy-handle = <&switch0phy2>; }; switch0port5: port@5 { reg = <5>; - label = "dsa"; phy-mode = "rgmii-txid"; link = <&switch1port6 &switch2port9>; @@ -134,7 +130,6 @@ port@6 { reg = <6>; - label = "cpu"; ethernet = <&fec1>; fixed-link { speed = <100>; @@ -186,25 +181,21 @@ #size-cells = <0>; port@0 { reg = <0>; - label = "lan3"; phy-handle = <&switch1phy0>; }; port@1 { reg = <1>; - label = "lan4"; phy-handle = <&switch1phy1>; }; port@2 { reg = <2>; - label = "lan5"; phy-handle = <&switch1phy2>; }; switch1port5: port@5 { reg = <5>; - label = "dsa"; link = <&switch2port9>; phy-mode = "rgmii-txid"; fixed-link { @@ -215,7 +206,6 @@ switch1port6: port@6 { reg = <6>; - label = "dsa"; phy-mode = "rgmii-txid"; link = <&switch0port5>; fixed-link { @@ -263,22 +253,18 @@ #size-cells = <0>; port@0 { reg = <0>; - label = "lan6"; }; port@1 { reg = <1>; - label = "lan7"; }; port@2 { reg = <2>; - label = "lan8
Re: [PATCH net-next 1/2] net: dsa: make "label" property optional for dsa2
> If one wants to rename an interface, udev rules can be used as usual. Hi Vivien Do you have some examples? A quick look at udevadm info suggests we can use ATTR{phys_port_id} and ATTR{phys_switch_id} Humm, it would be nice to know why the second switch has a phys_switch_id of 0100. How is systemd naming them without udev rules? Andrew
[PATCH v2] PCI: lock each enable/disable num_vfs operation in sysfs
Enabling/disabling SRIOV via sysfs by echo-ing multiple values simultaneously: echo 63 > /sys/class/net/ethX/device/sriov_numvfs& echo 63 > /sys/class/net/ethX/device/sriov_numvfs sleep 5 echo 0 > /sys/class/net/ethX/device/sriov_numvfs& echo 0 > /sys/class/net/ethX/device/sriov_numvfs Results in the following bug: kernel BUG at drivers/pci/iov.c:495! invalid opcode: [#1] SMP CPU: 1 PID: 8050 Comm: bash Tainted: G W 4.9.0-rc7-net-next #2092 RIP: 0010:[] [] pci_iov_release+0x57/0x60 Call Trace: [] pci_release_dev+0x26/0x70 [] device_release+0x3e/0xb0 [] kobject_cleanup+0x67/0x180 [] kobject_put+0x2d/0x60 [] put_device+0x17/0x20 [] pci_dev_put+0x1a/0x20 [] pci_get_dev_by_id+0x5b/0x90 [] pci_get_subsys+0x35/0x40 [] pci_get_device+0x18/0x20 [] pci_get_domain_bus_and_slot+0x2b/0x60 [] pci_iov_remove_virtfn+0x57/0x180 [] pci_disable_sriov+0x65/0x140 [] ixgbe_disable_sriov+0xc7/0x1d0 [ixgbe] [] ixgbe_pci_sriov_configure+0x3d/0x170 [ixgbe] [] sriov_numvfs_store+0xdc/0x130 ... RIP [] pci_iov_release+0x57/0x60 Use the existing mutex lock to protect each enable/disable operation. -v2: move the existing lock from protecting the config of the IOV bus to protecting the writes to sriov_numvfs in sysfs without maintaining a "locked" version of pci_iov_add/remove_virtfn(). As suggested by Gavin Shan CC: Alexander Duyck Signed-off-by: Emil Tantilov --- drivers/pci/iov.c |7 --- drivers/pci/pci-sysfs.c | 23 --- drivers/pci/pci.h |2 +- 3 files changed, 17 insertions(+), 15 deletions(-) diff --git a/drivers/pci/iov.c b/drivers/pci/iov.c index 4722782..2479ae8 100644 --- a/drivers/pci/iov.c +++ b/drivers/pci/iov.c @@ -124,7 +124,6 @@ int pci_iov_add_virtfn(struct pci_dev *dev, int id, int reset) struct pci_sriov *iov = dev->sriov; struct pci_bus *bus; - mutex_lock(&iov->dev->sriov->lock); bus = virtfn_add_bus(dev->bus, pci_iov_virtfn_bus(dev, id)); if (!bus) goto failed; @@ -162,7 +161,6 @@ int pci_iov_add_virtfn(struct pci_dev *dev, int id, int reset) __pci_reset_function(virtfn); pci_device_add(virtfn, virtfn->bus); - mutex_unlock(&iov->dev->sriov->lock); pci_bus_add_device(virtfn); sprintf(buf, "virtfn%u", id); @@ -181,12 +179,10 @@ int pci_iov_add_virtfn(struct pci_dev *dev, int id, int reset) sysfs_remove_link(&dev->dev.kobj, buf); failed1: pci_dev_put(dev); - mutex_lock(&iov->dev->sriov->lock); pci_stop_and_remove_bus_device(virtfn); failed0: virtfn_remove_bus(dev->bus, bus); failed: - mutex_unlock(&iov->dev->sriov->lock); return rc; } @@ -195,7 +191,6 @@ void pci_iov_remove_virtfn(struct pci_dev *dev, int id, int reset) { char buf[VIRTFN_ID_LEN]; struct pci_dev *virtfn; - struct pci_sriov *iov = dev->sriov; virtfn = pci_get_domain_bus_and_slot(pci_domain_nr(dev->bus), pci_iov_virtfn_bus(dev, id), @@ -218,10 +213,8 @@ void pci_iov_remove_virtfn(struct pci_dev *dev, int id, int reset) if (virtfn->dev.kobj.sd) sysfs_remove_link(&virtfn->dev.kobj, "physfn"); - mutex_lock(&iov->dev->sriov->lock); pci_stop_and_remove_bus_device(virtfn); virtfn_remove_bus(dev->bus, virtfn->bus); - mutex_unlock(&iov->dev->sriov->lock); /* balance pci_get_domain_bus_and_slot() */ pci_dev_put(virtfn); diff --git a/drivers/pci/pci-sysfs.c b/drivers/pci/pci-sysfs.c index 0666287..25d010d 100644 --- a/drivers/pci/pci-sysfs.c +++ b/drivers/pci/pci-sysfs.c @@ -472,6 +472,7 @@ static ssize_t sriov_numvfs_store(struct device *dev, const char *buf, size_t count) { struct pci_dev *pdev = to_pci_dev(dev); + struct pci_sriov *iov = pdev->sriov; int ret; u16 num_vfs; @@ -482,38 +483,46 @@ static ssize_t sriov_numvfs_store(struct device *dev, if (num_vfs > pci_sriov_get_totalvfs(pdev)) return -ERANGE; + mutex_lock(&iov->dev->sriov->lock); + if (num_vfs == pdev->sriov->num_VFs) - return count; /* no change */ + goto exit; /* is PF driver loaded w/callback */ if (!pdev->driver || !pdev->driver->sriov_configure) { dev_info(&pdev->dev, "Driver doesn't support SRIOV configuration via sysfs\n"); - return -ENOSYS; + ret = -ENOENT; + goto exit; } if (num_vfs == 0) { /* disable VFs */ ret = pdev->driver->sriov_configure(pdev, 0); - if (ret < 0) - return ret; - return count; + goto exit; } /* enable VFs */ if (pdev->sriov->num_VFs) { dev_warn(&pdev->dev, "%d VFs already enabled. Disable befo
Re: [net-next PATCH] net: reduce cycles spend on ICMP replies that gets rate limited
On Fri, 2017-01-06 at 11:40 -0800, Eric Dumazet wrote: > On Fri, 2017-01-06 at 18:39 +0100, Jesper Dangaard Brouer wrote: > > > > @@ -648,13 +668,17 @@ void icmp_send(struct sk_buff *skb_in, int type, int > > code, __be32 info) > > } > > } > > > > - icmp_param = kmalloc(sizeof(*icmp_param), GFP_ATOMIC); > > - if (!icmp_param) > > - return; > > - > > sk = icmp_xmit_lock(net); > > if (!sk) > > - goto out_free; > > + goto out; > > + > > + /* Check global sysctl_icmp_msgs_per_sec ratelimit */ > > + if (!icmpv4_global_allow(net, type, code)) > > + goto out_unlock; > > + > > + icmp_param = kmalloc(sizeof(*icmp_param), GFP_ATOMIC); > > + if (!icmp_param) > > + goto out_unlock; > You could call icmp_xmit_lock() _after_ checking global limit perhaps. That would remove one atomic op. if (!icmpv4_global_allow(net, type, code)) goto out; sk = icmp_xmit_lock(net); if (!sk) goto out;
[PATCH] [v2] net: qcom/emac: add ethtool support
Add support for some ethtool methods: get/set link settings, get/set message level, get statistics, get link status, get ring params, get pause params, and restart autonegotiation. The code to collect the hardware statistics is moved into its own function so that it can be used by "get statistics" method. Signed-off-by: Timur Tabi --- Notes: I don't trust my implementation of emac_get_pauseparam. I feel like I'm missing something. v2: added emac_get_pauseparam and emac_get_ringparam drivers/net/ethernet/qualcomm/emac/Makefile | 2 +- drivers/net/ethernet/qualcomm/emac/emac-ethtool.c | 185 ++ drivers/net/ethernet/qualcomm/emac/emac.c | 51 +++--- drivers/net/ethernet/qualcomm/emac/emac.h | 3 + 4 files changed, 220 insertions(+), 21 deletions(-) create mode 100644 drivers/net/ethernet/qualcomm/emac/emac-ethtool.c diff --git a/drivers/net/ethernet/qualcomm/emac/Makefile b/drivers/net/ethernet/qualcomm/emac/Makefile index 7a66879..fc57ced 100644 --- a/drivers/net/ethernet/qualcomm/emac/Makefile +++ b/drivers/net/ethernet/qualcomm/emac/Makefile @@ -4,6 +4,6 @@ obj-$(CONFIG_QCOM_EMAC) += qcom-emac.o -qcom-emac-objs := emac.o emac-mac.o emac-phy.o emac-sgmii.o \ +qcom-emac-objs := emac.o emac-mac.o emac-phy.o emac-sgmii.o emac-ethtool.o \ emac-sgmii-fsm9900.o emac-sgmii-qdf2432.o \ emac-sgmii-qdf2400.o diff --git a/drivers/net/ethernet/qualcomm/emac/emac-ethtool.c b/drivers/net/ethernet/qualcomm/emac/emac-ethtool.c new file mode 100644 index 000..cfc57d2 --- /dev/null +++ b/drivers/net/ethernet/qualcomm/emac/emac-ethtool.c @@ -0,0 +1,185 @@ +/* Copyright (c) 2016, The Linux Foundation. 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 version 2 and + * only version 2 as published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + */ + +#include +#include + +#include "emac.h" + +static const char * const emac_ethtool_stat_strings[] = { + "rx_ok", + "rx_bcast", + "rx_mcast", + "rx_pause", + "rx_ctrl", + "rx_fcs_err", + "rx_len_err", + "rx_byte_cnt", + "rx_runt", + "rx_frag", + "rx_sz_64", + "rx_sz_65_127", + "rx_sz_128_255", + "rx_sz_256_511", + "rx_sz_512_1023", + "rx_sz_1024_1518", + "rx_sz_1519_max", + "rx_sz_ov", + "rx_rxf_ov", + "rx_align_err", + "rx_bcast_byte_cnt", + "rx_mcast_byte_cnt", + "rx_err_addr", + "rx_crc_align", + "rx_jabbers", + "tx_ok", + "tx_bcast", + "tx_mcast", + "tx_pause", + "tx_exc_defer", + "tx_ctrl", + "tx_defer", + "tx_byte_cnt", + "tx_sz_64", + "tx_sz_65_127", + "tx_sz_128_255", + "tx_sz_256_511", + "tx_sz_512_1023", + "tx_sz_1024_1518", + "tx_sz_1519_max", + "tx_1_col", + "tx_2_col", + "tx_late_col", + "tx_abort_col", + "tx_underrun", + "tx_rd_eop", + "tx_len_err", + "tx_trunc", + "tx_bcast_byte", + "tx_mcast_byte", + "tx_col", +}; + +#define EMAC_STATS_LEN ARRAY_SIZE(emac_ethtool_stat_strings) + +static u32 emac_get_msglevel(struct net_device *netdev) +{ + struct emac_adapter *adpt = netdev_priv(netdev); + + return adpt->msg_enable; +} + +static void emac_set_msglevel(struct net_device *netdev, u32 data) +{ + struct emac_adapter *adpt = netdev_priv(netdev); + + adpt->msg_enable = data; +} + +static int emac_get_sset_count(struct net_device *netdev, int sset) +{ + switch (sset) { + case ETH_SS_STATS: + return EMAC_STATS_LEN; + default: + return -EOPNOTSUPP; + } +} + +static void emac_get_strings(struct net_device *netdev, u32 stringset, u8 *data) +{ + unsigned int i; + + switch (stringset) { + case ETH_SS_STATS: + for (i = 0; i < EMAC_STATS_LEN; i++) { + strlcpy(data, emac_ethtool_stat_strings[i], + ETH_GSTRING_LEN); + data += ETH_GSTRING_LEN; + } + break; + } +} + +static void emac_get_ethtool_stats(struct net_device *netdev, + struct ethtool_stats *stats, + u64 *data) +{ + struct emac_adapter *adpt = netdev_priv(netdev); + + spin_lock(&adpt->stats.lock); + + emac_update_hw_stats(adpt); + memcpy(data, &adpt->stats, EMAC_STATS_LEN * sizeof(u64)); + + spin_unlock(&adpt->stats.lock); +} + +static int emac_nway_reset(struct
[PATCH net-next] net: dsa: move HWMON support to its own file
Isolate the HWMON support in DSA in its own file. Currently only the legacy DSA code is concerned. Signed-off-by: Vivien Didelot --- net/dsa/Makefile | 1 + net/dsa/dsa.c | 131 +-- net/dsa/dsa_priv.h | 9 net/dsa/hwmon.c| 147 + 4 files changed, 159 insertions(+), 129 deletions(-) create mode 100644 net/dsa/hwmon.c diff --git a/net/dsa/Makefile b/net/dsa/Makefile index a3380ed0e0be..560b6747c276 100644 --- a/net/dsa/Makefile +++ b/net/dsa/Makefile @@ -1,6 +1,7 @@ # the core obj-$(CONFIG_NET_DSA) += dsa_core.o dsa_core-y += dsa.o slave.o dsa2.o +dsa_core-$(CONFIG_NET_DSA_HWMON) += hwmon.o # tagging formats dsa_core-$(CONFIG_NET_DSA_TAG_BRCM) += tag_brcm.o diff --git a/net/dsa/dsa.c b/net/dsa/dsa.c index 3f85be0aae34..cda787ebad15 100644 --- a/net/dsa/dsa.c +++ b/net/dsa/dsa.c @@ -9,9 +9,7 @@ * (at your option) any later version. */ -#include #include -#include #include #include #include @@ -108,105 +106,6 @@ dsa_switch_probe(struct device *parent, struct device *host_dev, int sw_addr, return ret; } -/* hwmon support / - -#ifdef CONFIG_NET_DSA_HWMON - -static ssize_t temp1_input_show(struct device *dev, - struct device_attribute *attr, char *buf) -{ - struct dsa_switch *ds = dev_get_drvdata(dev); - int temp, ret; - - ret = ds->ops->get_temp(ds, &temp); - if (ret < 0) - return ret; - - return sprintf(buf, "%d\n", temp * 1000); -} -static DEVICE_ATTR_RO(temp1_input); - -static ssize_t temp1_max_show(struct device *dev, - struct device_attribute *attr, char *buf) -{ - struct dsa_switch *ds = dev_get_drvdata(dev); - int temp, ret; - - ret = ds->ops->get_temp_limit(ds, &temp); - if (ret < 0) - return ret; - - return sprintf(buf, "%d\n", temp * 1000); -} - -static ssize_t temp1_max_store(struct device *dev, - struct device_attribute *attr, const char *buf, - size_t count) -{ - struct dsa_switch *ds = dev_get_drvdata(dev); - int temp, ret; - - ret = kstrtoint(buf, 0, &temp); - if (ret < 0) - return ret; - - ret = ds->ops->set_temp_limit(ds, DIV_ROUND_CLOSEST(temp, 1000)); - if (ret < 0) - return ret; - - return count; -} -static DEVICE_ATTR_RW(temp1_max); - -static ssize_t temp1_max_alarm_show(struct device *dev, - struct device_attribute *attr, char *buf) -{ - struct dsa_switch *ds = dev_get_drvdata(dev); - bool alarm; - int ret; - - ret = ds->ops->get_temp_alarm(ds, &alarm); - if (ret < 0) - return ret; - - return sprintf(buf, "%d\n", alarm); -} -static DEVICE_ATTR_RO(temp1_max_alarm); - -static struct attribute *dsa_hwmon_attrs[] = { - &dev_attr_temp1_input.attr, /* 0 */ - &dev_attr_temp1_max.attr, /* 1 */ - &dev_attr_temp1_max_alarm.attr, /* 2 */ - NULL -}; - -static umode_t dsa_hwmon_attrs_visible(struct kobject *kobj, - struct attribute *attr, int index) -{ - struct device *dev = container_of(kobj, struct device, kobj); - struct dsa_switch *ds = dev_get_drvdata(dev); - struct dsa_switch_ops *ops = ds->ops; - umode_t mode = attr->mode; - - if (index == 1) { - if (!ops->get_temp_limit) - mode = 0; - else if (!ops->set_temp_limit) - mode &= ~S_IWUSR; - } else if (index == 2 && !ops->get_temp_alarm) { - mode = 0; - } - return mode; -} - -static const struct attribute_group dsa_hwmon_group = { - .attrs = dsa_hwmon_attrs, - .is_visible = dsa_hwmon_attrs_visible, -}; -__ATTRIBUTE_GROUPS(dsa_hwmon); - -#endif /* CONFIG_NET_DSA_HWMON */ - /* basic switch operations **/ int dsa_cpu_dsa_setup(struct dsa_switch *ds, struct device *dev, struct device_node *port_dn, int port) @@ -415,30 +314,7 @@ static int dsa_switch_setup_one(struct dsa_switch *ds, struct device *parent) if (ret) return ret; -#ifdef CONFIG_NET_DSA_HWMON - /* If the switch provides a temperature sensor, -* register with hardware monitoring subsystem. -* Treat registration error as non-fatal and ignore it. -*/ - if (ops->get_temp) { - const char *netname = netdev_name(dst->master_netdev); - char hname[IFNAMSIZ + 1]; - int i, j; - - /* Create valid hwmon 'name' attribute */ - for (i = j = 0; i < IFNAMSIZ && netname[i]; i++) { - if (isalnum(netname[i])) -
Re: [next PATCH 00/11] ixgbe: Add support for writable pages and build_skb
From: Alexander Duyck Date: Fri, 06 Jan 2017 08:06:16 -0800 > The testing matrix for all of these patches is going to be pretty > extensive. Basically we want to test these patches on as many platforms > and architectures as possible with as many features being toggled as > possible including RSC, FCoE, SR-IOV, and Jumbo Frames all while receiving > traffic. Overall looks very nice to me. I am assuming that I will get a formal submission once the necessary amount of testing is performed.
Re: pull-request: mac80211 2017-01-06
From: Johannes Berg Date: Fri, 6 Jan 2017 13:37:20 +0100 > Here's another fix for something I noticed while reviewing the code in > a new suggested patch that added another netlink socket destroy path. > > Since the new patch would otherwise cause conflicts, it might be good > to pull net or Linus's next RC containing it into net-next, if you can. > > Please pull and let me know if there's any problem. Pulled, I'll try to get this moving into net-next over the weekend. Remind me about this early next week if that ends up slipping through the cracks. Thanks.
[PATCH net] tg3: Fix race condition in tg3_get_stats64().
The driver's ndo_get_stats64() method is not always called under RTNL. So it can race with driver close or ethtool reconfigurations. Fix the race condition by taking tp->lock spinlock in tg3_free_consistent() when freeing the tp->hw_stats memory block. tg3_get_stats64() is already taking tp->lock. Reported-by: Wang Yufen Signed-off-by: Michael Chan --- drivers/net/ethernet/broadcom/tg3.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/drivers/net/ethernet/broadcom/tg3.c b/drivers/net/ethernet/broadcom/tg3.c index 185e9e0..ae42de4 100644 --- a/drivers/net/ethernet/broadcom/tg3.c +++ b/drivers/net/ethernet/broadcom/tg3.c @@ -8720,11 +8720,14 @@ static void tg3_free_consistent(struct tg3 *tp) tg3_mem_rx_release(tp); tg3_mem_tx_release(tp); + /* Protect tg3_get_stats64() from reading freed tp->hw_stats. */ + tg3_full_lock(tp, 0); if (tp->hw_stats) { dma_free_coherent(&tp->pdev->dev, sizeof(struct tg3_hw_stats), tp->hw_stats, tp->stats_mapping); tp->hw_stats = NULL; } + tg3_full_unlock(tp); } /* -- 1.8.3.1
Re: [PATCH net-next] cxgb4: Add port description for new cards.
From: Ganesh Goudar Date: Fri, 6 Jan 2017 16:52:10 +0530 > Add port description for 25G and 100G cards, and also > change few port descriptions in compliance with the new > naming convention. > > Signed-off-by: Ganesh Goudar Applied.
Re: [PATCH net-next] cxgb4/cxgb4vf: Display 25G and 100G link speed
From: Ganesh Goudar Date: Fri, 6 Jan 2017 16:51:46 +0530 > Add support to report 25G and 100G links, which was missed > as part of commit "eb97ad99f9ed". > > Signed-off-by: Ganesh Goudar Applied.
Re: [PATCH v2 00/12] net: ethernet: aquantia: Add AQtion 2.5/5 GB NIC driver
From: Alexander Loktionov Date: Fri, 6 Jan 2017 00:06:01 -0800 > This series introduced the AQtion NIC driver for the aQuantia > AQC107/AQC108 network devices. > > v1: Initial version > v2: o Make necessary drivers/net/ethernet changes to integrate software > o Drop intermediate atlantic directory > o Remove Makefile things only appropriate to out of tree module builidng Every patch series must be fully bisectable, this means that at each step of the series, the kernel tree must fully build and work properly. You break that already at the first patch, which makes the Kconfig options available, which if enabled will cause a build failure. make[4]: *** No rule to make target 'drivers/net/ethernet/aquantia/aq_main.o', needed by 'drivers/net/ethernet/aquantia/atlantic.o'. Stop. make[4]: *** Waiting for unfinished jobs scripts/Makefile.build:551: recipe for target 'drivers/net/ethernet/aquantia' failed make[3]: *** [drivers/net/ethernet/aquantia] Error 2 make[3]: *** Waiting for unfinished jobs scripts/Makefile.build:551: recipe for target 'drivers/net/ethernet' failed make[2]: *** [drivers/net/ethernet] Error 2 scripts/Makefile.build:551: recipe for target 'drivers/net' failed make[1]: *** [drivers/net] Error 2 make[1]: *** Waiting for unfinished jobs Makefile:988: recipe for target 'drivers' failed make: *** [drivers] Error 2 The way to do this, is to add the pieces of source code infrastrucutre, one piece at a time. And then at the very very end, enable the code into the build.
Re: [PATCH] vti6: fix device register to report IFLA_INFO_KIND
From: David Forster Date: Fri, 6 Jan 2017 10:27:59 + > vti6 interface is registered before the rtnl_link_ops block > is attached. As a result the resulting RTM_NEWLINK is missing > IFLA_INFO_KIND. Re-order attachment of rtnl_link_ops block to fix. > > Signed-off-by: Dave Forster Applied, thanks.
Re: [net-next 00/10][pull request] 1GbE Intel Wired LAN Driver Updates 2017-01-06
From: Jeff Kirsher Date: Fri, 6 Jan 2017 02:48:42 -0800 > This series contains updates/fixes to igb and e1000e. Pulled, thanks Jeff.
[PATCH 1/2] sh_eth: get rid of 'sh_eth_cpu_data::shift_rd0'
After checking all the available manuals, I have enough information to conclude that the 'shift_rd0' flag is only relevant for the Ether cores supporting so called "intelligent checksum" (and hence having CSMR) which is indicated by the 'hw_crc' flag. Since all the relevant SoCs now have both these flags set, we can at last get rid of the former flag... Signed-off-by: Sergei Shtylyov --- drivers/net/ethernet/renesas/sh_eth.c |5 + drivers/net/ethernet/renesas/sh_eth.h |1 - 2 files changed, 1 insertion(+), 5 deletions(-) Index: net/drivers/net/ethernet/renesas/sh_eth.c === --- net.orig/drivers/net/ethernet/renesas/sh_eth.c +++ net/drivers/net/ethernet/renesas/sh_eth.c @@ -537,7 +537,6 @@ static struct sh_eth_cpu_data r7s72100_d .no_ade = 1, .hw_crc = 1, .tsu= 1, - .shift_rd0 = 1, }; static void sh_eth_chip_reset_r8a7740(struct net_device *ndev) @@ -577,7 +576,6 @@ static struct sh_eth_cpu_data r8a7740_da .hw_crc = 1, .tsu= 1, .select_mii = 1, - .shift_rd0 = 1, }; /* There is CPU dependent code */ @@ -820,7 +818,6 @@ static struct sh_eth_cpu_data sh7734_dat .tsu= 1, .hw_crc = 1, .select_mii = 1, - .shift_rd0 = 1, }; /* SH7763 */ @@ -1421,7 +1418,7 @@ static int sh_eth_rx(struct net_device * * the RFS bits are from bit 25 to bit 16. So, the * driver needs right shifting by 16. */ - if (mdp->cd->shift_rd0) + if (mdp->cd->hw_crc) desc_status >>= 16; skb = mdp->rx_skbuff[entry]; Index: net/drivers/net/ethernet/renesas/sh_eth.h === --- net.orig/drivers/net/ethernet/renesas/sh_eth.h +++ net/drivers/net/ethernet/renesas/sh_eth.h @@ -490,7 +490,6 @@ struct sh_eth_cpu_data { unsigned no_ade:1; /* E-DMAC DO NOT have ADE bit in EESR */ unsigned hw_crc:1; /* E-DMAC have CSMR */ unsigned select_mii:1; /* EtherC have RMII_MII (MII select register) */ - unsigned shift_rd0:1; /* shift Rx descriptor word 0 right by 16 */ unsigned rmiimode:1;/* EtherC has RMIIMODE register */ unsigned rtrate:1; /* EtherC has RTRATE register */ };
[PATCH 2/2] sh_eth: rename 'sh_eth_cpu_data::hw_crc'
The 'struct sh_eth_cpu_data' field indicating the "intelligent checksum" support was misnamed 'hw_crc' -- rename it to 'hw_checksum'. Signed-off-by: Sergei Shtylyov --- drivers/net/ethernet/renesas/sh_eth.c | 12 ++-- drivers/net/ethernet/renesas/sh_eth.h |2 +- 2 files changed, 7 insertions(+), 7 deletions(-) Index: net/drivers/net/ethernet/renesas/sh_eth.c === --- net.orig/drivers/net/ethernet/renesas/sh_eth.c +++ net/drivers/net/ethernet/renesas/sh_eth.c @@ -535,7 +535,7 @@ static struct sh_eth_cpu_data r7s72100_d .rpadir_value = 2 << 16, .no_trimd = 1, .no_ade = 1, - .hw_crc = 1, + .hw_checksum= 1, .tsu= 1, }; @@ -573,7 +573,7 @@ static struct sh_eth_cpu_data r8a7740_da .rpadir_value = 2 << 16, .no_trimd = 1, .no_ade = 1, - .hw_crc = 1, + .hw_checksum= 1, .tsu= 1, .select_mii = 1, }; @@ -816,7 +816,7 @@ static struct sh_eth_cpu_data sh7734_dat .no_trimd = 1, .no_ade = 1, .tsu= 1, - .hw_crc = 1, + .hw_checksum= 1, .select_mii = 1, }; @@ -933,7 +933,7 @@ static int sh_eth_reset(struct net_devic sh_eth_write(ndev, 0x0, RDFFR); /* Reset HW CRC register */ - if (mdp->cd->hw_crc) + if (mdp->cd->hw_checksum) sh_eth_write(ndev, 0x0, CSMR); /* Select MII mode */ @@ -1418,7 +1418,7 @@ static int sh_eth_rx(struct net_device * * the RFS bits are from bit 25 to bit 16. So, the * driver needs right shifting by 16. */ - if (mdp->cd->hw_crc) + if (mdp->cd->hw_checksum) desc_status >>= 16; skb = mdp->rx_skbuff[entry]; @@ -1986,7 +1986,7 @@ static size_t __sh_eth_get_regs(struct n add_reg(MAFCR); if (cd->rtrate) add_reg(RTRATE); - if (cd->hw_crc) + if (cd->hw_checksum) add_reg(CSMR); if (cd->select_mii) add_reg(RMII_MII); Index: net/drivers/net/ethernet/renesas/sh_eth.h === --- net.orig/drivers/net/ethernet/renesas/sh_eth.h +++ net/drivers/net/ethernet/renesas/sh_eth.h @@ -488,7 +488,7 @@ struct sh_eth_cpu_data { unsigned rpadir:1; /* E-DMAC have RPADIR */ unsigned no_trimd:1;/* E-DMAC DO NOT have TRIMD */ unsigned no_ade:1; /* E-DMAC DO NOT have ADE bit in EESR */ - unsigned hw_crc:1; /* E-DMAC have CSMR */ + unsigned hw_checksum:1; /* E-DMAC has CSMR */ unsigned select_mii:1; /* EtherC have RMII_MII (MII select register) */ unsigned rmiimode:1;/* EtherC has RMIIMODE register */ unsigned rtrate:1; /* EtherC has RTRATE register */
[PATCH 0/2] sh_eth: "intgelligent checksum" related cleanups
Hello. Here's a set of 2 patches against DaveM's 'net.git' repo, as they are based on a couple patches merged there recently; however, the patches are destined for 'net-next.git' (once 'net.git' gets merged there next time). I'm cleaning up the "intelligent checksum" related code (however, the driver only disables this feature for now, theres's no proper offload supprt yet). [1/2] sh_eth: get rid of 'sh_eth_cpu_data::shift_rd0' [2/2] sh_eth: rename 'sh_eth_cpu_data::hw_crc' MBR, Sergei
[PATCH net] be2net: fix unicast list filling
The adapter->pmac_id[0] item is used for primary MAC address but this is not true for adapter->uc_list[0] as is assumed in be_set_uc_list(). There are N UC addresses copied first from net_device to adapter->uc_list[1..N] and then N UC addresses from adapter->uc_list[0..N-1] are sent to HW. So the last UC address is never stored into HW and address 00:00:00:00;00:00 (from uc_list[0]) is used instead. Cc: Sathya Perla Cc: Ajit Khaparde Cc: Sriharsha Basavapatna Cc: Somnath Kotur Fixes: b717241 be2net: replace polling with sleeping in the FW completion path Signed-off-by: Ivan Vecera --- drivers/net/ethernet/emulex/benet/be_main.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/drivers/net/ethernet/emulex/benet/be_main.c b/drivers/net/ethernet/emulex/benet/be_main.c index 3510352..ec010ce 100644 --- a/drivers/net/ethernet/emulex/benet/be_main.c +++ b/drivers/net/ethernet/emulex/benet/be_main.c @@ -1695,9 +1695,8 @@ static void be_set_uc_list(struct be_adapter *adapter) } if (adapter->update_uc_list) { - i = 1; /* First slot is claimed by the Primary MAC */ - /* cache the uc-list in adapter array */ + i = 0; netdev_for_each_uc_addr(ha, netdev) { ether_addr_copy(adapter->uc_list[i].mac, ha->addr); i++; -- 2.10.2
Re: [PATCH 1/2] net: ipv4: Simplify rt_fill_info
From: David Ahern Date: Thu, 5 Jan 2017 19:32:46 -0800 > rt_fill_info has only 1 caller and both of the last 2 args -- nowait > and flags -- are hardcoded to 0. Given that remove them as input arguments > and simplify rt_fill_info accordingly. > > Signed-off-by: David Ahern Applied.
Re: [PATCH net-next] net: ipv4: make fib_select_default static
From: David Ahern Date: Thu, 5 Jan 2017 19:33:59 -0800 > fib_select_default has a single caller within the same file. > Make it static. > > Signed-off-by: David Ahern Also applied, thanks David.
[PATCH 2/2] ARM: dts: dra72-evm-revc: enable irqs for dp83867 eth phys
TI DRA72-EVM Rev C has two DP83867 ethernet phys which support IRQ generation in case of phy/link status changes. The INT/PWDN lines from both DP83867 phys are wired to DRA7 gpio6.16, so reflect the same in DT. Signed-off-by: Grygorii Strashko --- arch/arm/boot/dts/dra72-evm-revc.dts | 6 +- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/arch/arm/boot/dts/dra72-evm-revc.dts b/arch/arm/boot/dts/dra72-evm-revc.dts index c3d939c..3ecac56 100644 --- a/arch/arm/boot/dts/dra72-evm-revc.dts +++ b/arch/arm/boot/dts/dra72-evm-revc.dts @@ -68,6 +68,8 @@ ti,tx-internal-delay = ; ti,fifo-depth = ; ti,min-output-impedance; + interrupt-parent = <&gpio6>; + interrupts = <16 IRQ_TYPE_EDGE_FALLING>; }; dp83867_1: ethernet-phy@3 { @@ -75,6 +77,8 @@ ti,rx-internal-delay = ; ti,tx-internal-delay = ; ti,fifo-depth = ; - ti,min-output-imepdance; + ti,min-output-impedance; + interrupt-parent = <&gpio6>; + interrupts = <16 IRQ_TYPE_EDGE_FALLING>; }; }; -- 2.10.1.dirty
Re: [PATCHv2 net-next] cxgb4: Synchronize access to mailbox
From: Hariprasad Shenai Date: Fri, 6 Jan 2017 08:47:20 +0530 > The issue comes when there are multiple threads attempting to use > the mailbox facility at the same time. > When DCB operations and interface up/down is run in a loop for every > 0.1 sec, we observed mailbox collisions. And out of the two commands > one would fail with the present code, since we don't queue the second > command. > > To overcome the above issue, added a queue to access the mailbox. > Whenever a mailbox command is issued add it to the queue. If its at > the head issue the mailbox command, else wait for the existing command > to complete. Usually command takes less than a milli-second to > complete. > > Also timeout from the loop, if the command under execution takes > long time to run. > > In reality, the number of mailbox access collisions is going to be > very rare since no one runs such abusive script. > > Signed-off-by: Hariprasad Shenai Applied.
Re: [PATCH] net: phy: dp83867: fix irq generation
From: Grygorii Strashko Date: Thu, 5 Jan 2017 14:48:07 -0600 > For proper IRQ generation by DP83867 phy the INT/PWDN pin has to be > programmed as an interrupt output instead of a Powerdown input in > Configuration Register 3 (CFG3), Address 0x001E, bit 7 INT_OE = 1. The > current driver doesn't do this and as result IRQs will not be generated by > DP83867 phy even if they are properly configured in DT. > > Hence, fix IRQ generation by properly configuring CFG3.INT_OE bit and > ensure that Link Status Change (LINK_STATUS_CHNG_INT) and Auto-Negotiation > Complete (AUTONEG_COMP_INT) interrupt are enabled. After this the DP83867 > driver will work properly in interrupt enabled mode. > > Signed-off-by: Grygorii Strashko Applied.
Re: [PATCH net-next v2] net: dsa: b53: Utilize common helpers for u64/MAC
From: Florian Fainelli Date: Thu, 5 Jan 2017 11:08:58 -0800 > Utilize the two functions recently introduced: u64_to_ether() and > ether_to_u64() instead of our own versions. > > Reviewed-by: Andrew Lunn > Signed-off-by: Florian Fainelli Applied.
Re: [PATCH v2 4/7] x86: put msr-index.h in uapi
On Fri, Jan 6, 2017 at 11:43 AM, Nicolas Dichtel wrote: > This header file is exported, thus move it to uapi. Just hint for the future: -M (move) -C (copy) -D (delete) [though this is NOT for applying] -- With Best Regards, Andy Shevchenko
Re: [PATCH net-next] net: dsa: remove version string
From: Vivien Didelot Date: Thu, 5 Jan 2017 12:28:41 -0500 > The dsa_driver_version string is irrelevant and has not been bumped > since its introduction about 9 years ago. Kill it. > > Signed-off-by: Vivien Didelot Applied, thanks.
Re: [PATCH net-next] liquidio: fix wrong information about channels reported to ethtool
From: Felix Manlunas Date: Wed, 4 Jan 2017 16:18:50 -0800 > From: Weilin Chang > > Information reported to ethtool about channels is sometimes wrong for PF, > and always wrong for VF. Fix them by getting the information from the > right fields from the right structs. > > Signed-off-by: Weilin Chang > Signed-off-by: Felix Manlunas > Signed-off-by: Derek Chickles > Signed-off-by: Satanand Burla Applied.
[net-next v1 3/8] net: netcp: store network statistics in 64 bits
From: Michael Scherban Previously the network statistics were stored in 32 bit variable which can cause some stats to roll over after several minutes of high traffic. This implements 64 bit storage so larger numbers can be stored. Signed-off-by: Michael Scherban Signed-off-by: Murali Karicheri Signed-off-by: Sekhar Nori --- drivers/net/ethernet/ti/netcp.h | 18 ++ drivers/net/ethernet/ti/netcp_core.c | 68 +--- 2 files changed, 74 insertions(+), 12 deletions(-) diff --git a/drivers/net/ethernet/ti/netcp.h b/drivers/net/ethernet/ti/netcp.h index a92abd6..d243c5d 100644 --- a/drivers/net/ethernet/ti/netcp.h +++ b/drivers/net/ethernet/ti/netcp.h @@ -23,6 +23,7 @@ #include #include +#include /* Maximum Ethernet frame size supported by Keystone switch */ #define NETCP_MAX_FRAME_SIZE 9504 @@ -68,6 +69,20 @@ struct netcp_addr { struct list_headnode; }; +struct netcp_stats { + struct u64_stats_sync syncp_rx cacheline_aligned_in_smp; + u64 rx_packets; + u64 rx_bytes; + u32 rx_errors; + u32 rx_dropped; + + struct u64_stats_sync syncp_tx cacheline_aligned_in_smp; + u64 tx_packets; + u64 tx_bytes; + u32 tx_errors; + u32 tx_dropped; +}; + struct netcp_intf { struct device *dev; struct device *ndev_dev; @@ -88,6 +103,9 @@ struct netcp_intf { struct napi_struct rx_napi; struct napi_struct tx_napi; + /* 64-bit netcp stats */ + struct netcp_stats stats; + void*rx_channel; const char *dma_chan_name; u32 rx_pool_size; diff --git a/drivers/net/ethernet/ti/netcp_core.c b/drivers/net/ethernet/ti/netcp_core.c index 286fd8d..b077ed4 100644 --- a/drivers/net/ethernet/ti/netcp_core.c +++ b/drivers/net/ethernet/ti/netcp_core.c @@ -629,6 +629,7 @@ static void netcp_free_rx_desc_chain(struct netcp_intf *netcp, static void netcp_empty_rx_queue(struct netcp_intf *netcp) { + struct netcp_stats *rx_stats = &netcp->stats; struct knav_dma_desc *desc; unsigned int dma_sz; dma_addr_t dma; @@ -642,16 +643,17 @@ static void netcp_empty_rx_queue(struct netcp_intf *netcp) if (unlikely(!desc)) { dev_err(netcp->ndev_dev, "%s: failed to unmap Rx desc\n", __func__); - netcp->ndev->stats.rx_errors++; + rx_stats->rx_errors++; continue; } netcp_free_rx_desc_chain(netcp, desc); - netcp->ndev->stats.rx_dropped++; + rx_stats->rx_dropped++; } } static int netcp_process_one_rx_packet(struct netcp_intf *netcp) { + struct netcp_stats *rx_stats = &netcp->stats; unsigned int dma_sz, buf_len, org_buf_len; struct knav_dma_desc *desc, *ndesc; unsigned int pkt_sz = 0, accum_sz; @@ -757,8 +759,8 @@ static int netcp_process_one_rx_packet(struct netcp_intf *netcp) if (unlikely(ret)) { dev_err(netcp->ndev_dev, "RX hook %d failed: %d\n", rx_hook->order, ret); - netcp->ndev->stats.rx_errors++; /* Free the primary descriptor */ + rx_stats->rx_dropped++; knav_pool_desc_put(netcp->rx_pool, desc); dev_kfree_skb(skb); return 0; @@ -767,8 +769,10 @@ static int netcp_process_one_rx_packet(struct netcp_intf *netcp) /* Free the primary descriptor */ knav_pool_desc_put(netcp->rx_pool, desc); - netcp->ndev->stats.rx_packets++; - netcp->ndev->stats.rx_bytes += skb->len; + u64_stats_update_begin(&rx_stats->syncp_rx); + rx_stats->rx_packets++; + rx_stats->rx_bytes += skb->len; + u64_stats_update_end(&rx_stats->syncp_rx); /* push skb up the stack */ skb->protocol = eth_type_trans(skb, netcp->ndev); @@ -777,7 +781,7 @@ static int netcp_process_one_rx_packet(struct netcp_intf *netcp) free_desc: netcp_free_rx_desc_chain(netcp, desc); - netcp->ndev->stats.rx_errors++; + rx_stats->rx_errors++; return 0; } @@ -1008,6 +1012,7 @@ static void netcp_free_tx_desc_chain(struct netcp_intf *netcp, static int netcp_process_tx_compl_packets(struct netcp_intf *netcp, unsigned int budget) { + struct netcp_stats *tx_stats = &netcp->stats; struct knav_dma_desc *desc; struct netcp_tx_cb *tx_cb; struct sk_buff *skb; @@ -1022,7 +1027,7 @@ static int netcp_process_tx_compl
Re: [PATCH net-next 1/4] siphash: add cryptographically secure PRF
Please do not quote an entire large patch, just to make a small comment or annotation. This makes it so that every reader of your posting has to scroll down a lot just to see a small amount of new content. Simply edit down the quoted material to the actually required context, and then add the content you wish. I do realize that a lot of email clients make this difficult, but that is no excuse for not maintaining this basic level of consideration for the other people on this mailing list. Thanks.
[net-next v1 6/8] net: netcp: ale: update to support unknown vlan controls for NU switch
In NU Ethernet switch used on some of the Keystone SoCs, there is separate UNKNOWNVLAN register for membership, unreg mcast flood, reg mcast flood and force untag egress bits in ALE. So control for these fields require different address offset, shift and size of field. As this ALE has the same version number as ALE in CPSW found on other SoCs, customization based on version number is not possible. So use a configuration parameter, nu_switch_ale, to identify the ALE ALE found in NU Switch. Different treatment is needed for NU Switch ALE due to difference in the ale table bits, separate unknown vlan registers etc. The register information available in ale_controls, needs to be updated to support the netcp NU switch h/w. So it is not constant array any more since it needs to be updated based on ALE type. The header of the file is also updated to indicate it supports N port switch ALE, not just 3 port. The version mask is 3 bits in NU Switch ALE vs 8 bits on other ALE types. While at it, change the debug print to info print so that ALE version gets displayed in boot log. Signed-off-by: Murali Karicheri Signed-off-by: Sekhar Nori --- drivers/net/ethernet/ti/cpsw_ale.c| 50 +++ drivers/net/ethernet/ti/cpsw_ale.h| 13 - drivers/net/ethernet/ti/netcp_ethss.c | 5 +++- 3 files changed, 61 insertions(+), 7 deletions(-) diff --git a/drivers/net/ethernet/ti/cpsw_ale.c b/drivers/net/ethernet/ti/cpsw_ale.c index 43b061b..e15db39 100644 --- a/drivers/net/ethernet/ti/cpsw_ale.c +++ b/drivers/net/ethernet/ti/cpsw_ale.c @@ -1,5 +1,5 @@ /* - * Texas Instruments 3-Port Ethernet Switch Address Lookup Engine + * Texas Instruments N-Port Ethernet Switch Address Lookup Engine * * Copyright (C) 2012 Texas Instruments * @@ -27,8 +27,9 @@ #define BITMASK(bits) (BIT(bits) - 1) -#define ALE_VERSION_MAJOR(rev) ((rev >> 8) & 0xff) +#define ALE_VERSION_MAJOR(rev, mask) (((rev) >> 8) & (mask)) #define ALE_VERSION_MINOR(rev) (rev & 0xff) +#define ALE_VERSION_1R40x0104 /* ALE Registers */ #define ALE_IDVER 0x00 @@ -39,6 +40,12 @@ #define ALE_TABLE 0x34 #define ALE_PORTCTL0x40 +/* ALE NetCP NU switch specific Registers */ +#define ALE_UNKNOWNVLAN_MEMBER 0x90 +#define ALE_UNKNOWNVLAN_UNREG_MCAST_FLOOD 0x94 +#define ALE_UNKNOWNVLAN_REG_MCAST_FLOOD0x98 +#define ALE_UNKNOWNVLAN_FORCE_UNTAG_EGRESS 0x9C + #define ALE_TABLE_WRITEBIT(31) #define ALE_TYPE_FREE 0 @@ -464,7 +471,7 @@ struct ale_control_info { int bits; }; -static const struct ale_control_info ale_controls[ALE_NUM_CONTROLS] = { +static struct ale_control_info ale_controls[ALE_NUM_CONTROLS] = { [ALE_ENABLE]= { .name = "enable", .offset = ALE_CONTROL, @@ -724,8 +731,41 @@ void cpsw_ale_start(struct cpsw_ale *ale) u32 rev; rev = __raw_readl(ale->params.ale_regs + ALE_IDVER); - dev_dbg(ale->params.dev, "initialized cpsw ale revision %d.%d\n", - ALE_VERSION_MAJOR(rev), ALE_VERSION_MINOR(rev)); + if (!ale->params.major_ver_mask) + ale->params.major_ver_mask = 0xff; + ale->version = + (ALE_VERSION_MAJOR(rev, ale->params.major_ver_mask) << 8) | +ALE_VERSION_MINOR(rev); + dev_info(ale->params.dev, "initialized cpsw ale version %d.%d\n", +ALE_VERSION_MAJOR(rev, ale->params.major_ver_mask), +ALE_VERSION_MINOR(rev)); + + if (ale->params.nu_switch_ale) { + /* Separate registers for unknown vlan configuration. +* Also there are N bits, where N is number of ale +* ports and shift value should be 0 +*/ + ale_controls[ALE_PORT_UNKNOWN_VLAN_MEMBER].bits = + ale->params.ale_ports; + ale_controls[ALE_PORT_UNKNOWN_VLAN_MEMBER].offset = + ALE_UNKNOWNVLAN_MEMBER; + ale_controls[ALE_PORT_UNKNOWN_MCAST_FLOOD].bits = + ale->params.ale_ports; + ale_controls[ALE_PORT_UNKNOWN_MCAST_FLOOD].shift = 0; + ale_controls[ALE_PORT_UNKNOWN_MCAST_FLOOD].offset = + ALE_UNKNOWNVLAN_UNREG_MCAST_FLOOD; + ale_controls[ALE_PORT_UNKNOWN_REG_MCAST_FLOOD].bits = + ale->params.ale_ports; + ale_controls[ALE_PORT_UNKNOWN_REG_MCAST_FLOOD].shift = 0; + ale_controls[ALE_PORT_UNKNOWN_REG_MCAST_FLOOD].offset = + ALE_UNKNOWNVLAN_REG_MCAST_FLOOD; + ale_controls[ALE_PORT_UNTAGGED_EGRESS].bits = + ale->params.ale_ports; + ale_controls[ALE_PORT_UN
Re: [RFC PATCH next] ipv6: do not send RTM_DELADDR for tentative addresses
From: Mahesh Bandewar Date: Wed, 4 Jan 2017 15:01:01 -0800 > From: Mahesh Bandewar > > RTM_NEWADDR notification is sent when IFA_F_TENTATIVE is cleared from > the address. So if the address is added and deleted before DAD probes > completes, the RTM_DELADDR will be sent for which there was no > RTM_NEWADDR causing asymmetry in notification. However if the same > logic is used while sending RTM_DELADDR notification, this asymmetry > can be avoided. > > Signed-off-by: Mahesh Bandewar This makes a lot of sense, applied, thanks!
[net-next v1 1/8] net: netcp: extract eflag from desc for rx_hook handling
Extract the eflag bits from the received desc and pass it down the rx_hook chain to be available for netcp modules. Also the psdata and epib data has to be inspected by the netcp modules. So the desc can be freed only after returning from the rx_hook. So move knav_pool_desc_put() after the rx_hook processing. Signed-off-by: Murali Karicheri --- drivers/net/ethernet/ti/netcp.h | 1 + drivers/net/ethernet/ti/netcp_core.c | 20 +--- include/linux/soc/ti/knav_dma.h | 2 ++ 3 files changed, 20 insertions(+), 3 deletions(-) diff --git a/drivers/net/ethernet/ti/netcp.h b/drivers/net/ethernet/ti/netcp.h index 0f58c58..a92abd6 100644 --- a/drivers/net/ethernet/ti/netcp.h +++ b/drivers/net/ethernet/ti/netcp.h @@ -115,6 +115,7 @@ struct netcp_packet { struct sk_buff *skb; __le32 *epib; u32 *psdata; + u32 eflags; unsigned intpsdata_len; struct netcp_intf *netcp; struct netcp_tx_pipe*tx_pipe; diff --git a/drivers/net/ethernet/ti/netcp_core.c b/drivers/net/ethernet/ti/netcp_core.c index c243335..a136c56 100644 --- a/drivers/net/ethernet/ti/netcp_core.c +++ b/drivers/net/ethernet/ti/netcp_core.c @@ -122,6 +122,13 @@ static void get_pkt_info(dma_addr_t *buff, u32 *buff_len, dma_addr_t *ndesc, *ndesc = le32_to_cpu(desc->next_desc); } +static void get_desc_info(u32 *desc_info, u32 *pkt_info, + struct knav_dma_desc *desc) +{ + *desc_info = le32_to_cpu(desc->desc_info); + *pkt_info = le32_to_cpu(desc->packet_info); +} + static u32 get_sw_data(int index, struct knav_dma_desc *desc) { /* No Endian conversion needed as this data is untouched by hw */ @@ -653,6 +660,7 @@ static int netcp_process_one_rx_packet(struct netcp_intf *netcp) struct netcp_packet p_info; struct sk_buff *skb; void *org_buf_ptr; + u32 tmp; dma_desc = knav_queue_pop(netcp->rx_queue, &dma_sz); if (!dma_desc) @@ -724,9 +732,6 @@ static int netcp_process_one_rx_packet(struct netcp_intf *netcp) knav_pool_desc_put(netcp->rx_pool, ndesc); } - /* Free the primary descriptor */ - knav_pool_desc_put(netcp->rx_pool, desc); - /* check for packet len and warn */ if (unlikely(pkt_sz != accum_sz)) dev_dbg(netcp->ndev_dev, "mismatch in packet size(%d) & sum of fragments(%d)\n", @@ -739,6 +744,11 @@ static int netcp_process_one_rx_packet(struct netcp_intf *netcp) p_info.skb = skb; skb->dev = netcp->ndev; p_info.rxtstamp_complete = false; + get_desc_info(&tmp, &p_info.eflags, desc); + p_info.epib = desc->epib; + p_info.psdata = (u32 __force *)desc->psdata; + p_info.eflags = ((p_info.eflags >> KNAV_DMA_DESC_EFLAGS_SHIFT) & +KNAV_DMA_DESC_EFLAGS_MASK); list_for_each_entry(rx_hook, &netcp->rxhook_list_head, list) { int ret; @@ -748,10 +758,14 @@ static int netcp_process_one_rx_packet(struct netcp_intf *netcp) dev_err(netcp->ndev_dev, "RX hook %d failed: %d\n", rx_hook->order, ret); netcp->ndev->stats.rx_errors++; + /* Free the primary descriptor */ + knav_pool_desc_put(netcp->rx_pool, desc); dev_kfree_skb(skb); return 0; } } + /* Free the primary descriptor */ + knav_pool_desc_put(netcp->rx_pool, desc); netcp->ndev->stats.rx_packets++; netcp->ndev->stats.rx_bytes += skb->len; diff --git a/include/linux/soc/ti/knav_dma.h b/include/linux/soc/ti/knav_dma.h index 35cb926..2b78826 100644 --- a/include/linux/soc/ti/knav_dma.h +++ b/include/linux/soc/ti/knav_dma.h @@ -41,6 +41,8 @@ #define KNAV_DMA_DESC_RETQ_SHIFT 0 #define KNAV_DMA_DESC_RETQ_MASKMASK(14) #define KNAV_DMA_DESC_BUF_LEN_MASK MASK(22) +#define KNAV_DMA_DESC_EFLAGS_MASK MASK(4) +#define KNAV_DMA_DESC_EFLAGS_SHIFT 20 #define KNAV_DMA_NUM_EPIB_WORDS4 #define KNAV_DMA_NUM_PS_WORDS 16 -- 1.9.1
[net-next v1 5/8] net: netcp: use hw capability to remove FCS word from rx packets
Some of the newer Ethernet switch hw (such as that on k2e/l/g) can strip the Etherenet FCS from packet at the port 0 egress of the switch. So use this capability instead of doing it in software. Signed-off-by: Murali Karicheri Signed-off-by: Sekhar Nori --- drivers/net/ethernet/ti/netcp.h | 2 ++ drivers/net/ethernet/ti/netcp_core.c | 8 ++-- drivers/net/ethernet/ti/netcp_ethss.c | 10 -- 3 files changed, 16 insertions(+), 4 deletions(-) diff --git a/drivers/net/ethernet/ti/netcp.h b/drivers/net/ethernet/ti/netcp.h index d243c5d..8900a6f 100644 --- a/drivers/net/ethernet/ti/netcp.h +++ b/drivers/net/ethernet/ti/netcp.h @@ -102,6 +102,8 @@ struct netcp_intf { void*rx_fdq[KNAV_DMA_FDQ_PER_CHAN]; struct napi_struct rx_napi; struct napi_struct tx_napi; +#define ETH_SW_CAN_REMOVE_ETH_FCS BIT(0) + u32 hw_cap; /* 64-bit netcp stats */ struct netcp_stats stats; diff --git a/drivers/net/ethernet/ti/netcp_core.c b/drivers/net/ethernet/ti/netcp_core.c index b077ed4..68a75cc 100644 --- a/drivers/net/ethernet/ti/netcp_core.c +++ b/drivers/net/ethernet/ti/netcp_core.c @@ -739,8 +739,12 @@ static int netcp_process_one_rx_packet(struct netcp_intf *netcp) dev_dbg(netcp->ndev_dev, "mismatch in packet size(%d) & sum of fragments(%d)\n", pkt_sz, accum_sz); - /* Remove ethernet FCS from the packet */ - __pskb_trim(skb, skb->len - ETH_FCS_LEN); + /* Newer version of the Ethernet switch can trim the Ethernet FCS +* from the packet and is indicated in hw_cap. So trim it only for +* older h/w +*/ + if (!(netcp->hw_cap & ETH_SW_CAN_REMOVE_ETH_FCS)) + __pskb_trim(skb, skb->len - ETH_FCS_LEN); /* Call each of the RX hooks */ p_info.skb = skb; diff --git a/drivers/net/ethernet/ti/netcp_ethss.c b/drivers/net/ethernet/ti/netcp_ethss.c index 4a64b3e..6bb8e26 100644 --- a/drivers/net/ethernet/ti/netcp_ethss.c +++ b/drivers/net/ethernet/ti/netcp_ethss.c @@ -122,6 +122,7 @@ #define MACSL_FULLDUPLEX BIT(0) #define GBE_CTL_P0_ENABLE BIT(2) +#define ETH_SW_CTL_P0_TX_CRC_REMOVEBIT(13) #define GBE13_REG_VAL_STAT_ENABLE_ALL 0xff #define XGBE_REG_VAL_STAT_ENABLE_ALL 0xf #define GBE_STATS_CD_SEL BIT(28) @@ -2821,7 +2822,7 @@ static int gbe_open(void *intf_priv, struct net_device *ndev) struct netcp_intf *netcp = netdev_priv(ndev); struct gbe_slave *slave = gbe_intf->slave; int port_num = slave->port_num; - u32 reg; + u32 reg, val; int ret; reg = readl(GBE_REG_ADDR(gbe_dev, switch_regs, id_ver)); @@ -2851,7 +2852,12 @@ static int gbe_open(void *intf_priv, struct net_device *ndev) writel(0, GBE_REG_ADDR(gbe_dev, switch_regs, ptype)); /* Control register */ - writel(GBE_CTL_P0_ENABLE, GBE_REG_ADDR(gbe_dev, switch_regs, control)); + val = GBE_CTL_P0_ENABLE; + if (IS_SS_ID_MU(gbe_dev)) { + val |= ETH_SW_CTL_P0_TX_CRC_REMOVE; + netcp->hw_cap = ETH_SW_CAN_REMOVE_ETH_FCS; + } + writel(val, GBE_REG_ADDR(gbe_dev, switch_regs, control)); /* All statistics enabled and STAT AB visible by default */ writel(gbe_dev->stats_en_mask, GBE_REG_ADDR(gbe_dev, switch_regs, -- 1.9.1
[net-next v1 8/8] net: netcp: ale: add proper ale entry mask bits for netcp switch ALE
For NetCP NU Switch ALE, some of the mask bits are different than defaults used in the driver. Add a new macro DEFINE_ALE_FIELD1 that use a configurable mask bits and use it in the driver. These bits are set to correct values by using the new variables added to cpsw_ale structure and re-used in the macros. The parameter nu_switch_ale is configured by the caller driver to indicate the ALE is for that switch and is used in the ALE driver to do customization as needed. Signed-off-by: Murali Karicheri Signed-off-by: Sekhar Nori --- drivers/net/ethernet/ti/cpsw_ale.c | 99 ++ drivers/net/ethernet/ti/cpsw_ale.h | 4 ++ 2 files changed, 84 insertions(+), 19 deletions(-) diff --git a/drivers/net/ethernet/ti/cpsw_ale.c b/drivers/net/ethernet/ti/cpsw_ale.c index 62a18d6..ddd43e0 100644 --- a/drivers/net/ethernet/ti/cpsw_ale.c +++ b/drivers/net/ethernet/ti/cpsw_ale.c @@ -29,6 +29,7 @@ #define ALE_VERSION_MAJOR(rev, mask) (((rev) >> 8) & (mask)) #define ALE_VERSION_MINOR(rev) (rev & 0xff) +#define ALE_VERSION_1R30x0103 #define ALE_VERSION_1R40x0104 /* ALE Registers */ @@ -46,6 +47,7 @@ #define ALE_UNKNOWNVLAN_UNREG_MCAST_FLOOD 0x94 #define ALE_UNKNOWNVLAN_REG_MCAST_FLOOD0x98 #define ALE_UNKNOWNVLAN_FORCE_UNTAG_EGRESS 0x9C +#define ALE_VLAN_MASK_MUX(reg) (0xc0 + (0x4 * (reg))) #define ALE_TABLE_WRITEBIT(31) @@ -96,20 +98,34 @@ static inline void cpsw_ale_set_field(u32 *ale_entry, u32 start, u32 bits, cpsw_ale_set_field(ale_entry, start, bits, value); \ } +#define DEFINE_ALE_FIELD1(name, start) \ +static inline int cpsw_ale_get_##name(u32 *ale_entry, u32 bits) \ +{ \ + return cpsw_ale_get_field(ale_entry, start, bits); \ +} \ +static inline void cpsw_ale_set_##name(u32 *ale_entry, u32 value, \ + u32 bits) \ +{ \ + cpsw_ale_set_field(ale_entry, start, bits, value); \ +} + DEFINE_ALE_FIELD(entry_type, 60, 2) DEFINE_ALE_FIELD(vlan_id, 48, 12) DEFINE_ALE_FIELD(mcast_state, 62, 2) -DEFINE_ALE_FIELD(port_mask,66, 3) +DEFINE_ALE_FIELD1(port_mask, 66) DEFINE_ALE_FIELD(super,65, 1) DEFINE_ALE_FIELD(ucast_type, 62, 2) -DEFINE_ALE_FIELD(port_num, 66, 2) +DEFINE_ALE_FIELD1(port_num,66) DEFINE_ALE_FIELD(blocked, 65, 1) DEFINE_ALE_FIELD(secure, 64, 1) -DEFINE_ALE_FIELD(vlan_untag_force, 24, 3) -DEFINE_ALE_FIELD(vlan_reg_mcast, 16, 3) -DEFINE_ALE_FIELD(vlan_unreg_mcast, 8, 3) -DEFINE_ALE_FIELD(vlan_member_list, 0, 3) +DEFINE_ALE_FIELD1(vlan_untag_force,24) +DEFINE_ALE_FIELD1(vlan_reg_mcast, 16) +DEFINE_ALE_FIELD1(vlan_unreg_mcast,8) +DEFINE_ALE_FIELD1(vlan_member_list,0) DEFINE_ALE_FIELD(mcast,40, 1) +/* ALE NetCP nu switch specific */ +DEFINE_ALE_FIELD(vlan_unreg_mcast_idx, 20, 3) +DEFINE_ALE_FIELD(vlan_reg_mcast_idx, 44, 3) /* The MAC address field in the ALE entry cannot be macroized as above */ static inline void cpsw_ale_get_addr(u32 *ale_entry, u8 *addr) @@ -235,14 +251,16 @@ static void cpsw_ale_flush_mcast(struct cpsw_ale *ale, u32 *ale_entry, { int mask; - mask = cpsw_ale_get_port_mask(ale_entry); + mask = cpsw_ale_get_port_mask(ale_entry, + ale->port_mask_bits); if ((mask & port_mask) == 0) return; /* ports dont intersect, not interested */ mask &= ~port_mask; /* free if only remaining port is host port */ if (mask) - cpsw_ale_set_port_mask(ale_entry, mask); + cpsw_ale_set_port_mask(ale_entry, mask, + ale->port_mask_bits); else cpsw_ale_set_entry_type(ale_entry, ALE_TYPE_FREE); } @@ -303,7 +321,7 @@ int cpsw_ale_add_ucast(struct cpsw_ale *ale, u8 *addr, int port, cpsw_ale_set_ucast_type(ale_entry, ALE_UCAST_PERSISTANT); cpsw_ale_set_secure(ale_entry, (flags & ALE_SECURE) ? 1 : 0); cpsw_ale_set_blocked(ale_entry, (flags & ALE_BLOCKED) ? 1 : 0); - cpsw_ale_set_port_num(ale_entry, port); + cpsw_ale_set_port_num(ale_entry, port, ale->port_num_bits); idx = cpsw_ale_match_addr(ale, addr, (flags & ALE_VLAN) ? vid : 0); if (idx < 0) @@ -350,9 +368,11 @@ int cpsw_ale_add_mcast(struct cpsw_ale *ale, u8 *addr, int port_mask, cpsw_ale_set_super(ale_entry, (flags & ALE_BLOCKED) ? 1 : 0
[net-next v1 2/8] net: netcp: remove the redundant memmov()
The psdata is populated with command data by netcp modules to the tail of the buffer and set_words() copy the same to the front of the psdata. So remove the redundant memmov function call. Signed-off-by: Murali Karicheri --- drivers/net/ethernet/ti/netcp_core.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/drivers/net/ethernet/ti/netcp_core.c b/drivers/net/ethernet/ti/netcp_core.c index a136c56..286fd8d 100644 --- a/drivers/net/ethernet/ti/netcp_core.c +++ b/drivers/net/ethernet/ti/netcp_core.c @@ -1226,9 +1226,9 @@ static int netcp_tx_submit_skb(struct netcp_intf *netcp, /* psdata points to both native-endian and device-endian data */ __le32 *psdata = (void __force *)p_info.psdata; - memmove(p_info.psdata, p_info.psdata + p_info.psdata_len, - p_info.psdata_len); - set_words(p_info.psdata, p_info.psdata_len, psdata); + set_words((u32 *)psdata + + (KNAV_DMA_NUM_PS_WORDS - p_info.psdata_len), + p_info.psdata_len, psdata); tmp |= (p_info.psdata_len & KNAV_DMA_DESC_PSLEN_MASK) << KNAV_DMA_DESC_PSLEN_SHIFT; } -- 1.9.1
[net-next v1 4/8] net: netcp: ethss: get phy-handle only if link interface is MAC-to-PHY
Currently to parse phy-handle, driver doesn't check if the interface is MAC to PHY. This patch add this check for all MAC to PHY interface types supported by the driver. Signed-off-by: Murali Karicheri Signed-off-by: Sekhar Nori --- drivers/net/ethernet/ti/netcp_ethss.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/drivers/net/ethernet/ti/netcp_ethss.c b/drivers/net/ethernet/ti/netcp_ethss.c index 7d9e36f..4a64b3e 100644 --- a/drivers/net/ethernet/ti/netcp_ethss.c +++ b/drivers/net/ethernet/ti/netcp_ethss.c @@ -2930,7 +2930,9 @@ static int init_slave(struct gbe_priv *gbe_dev, struct gbe_slave *slave, } slave->open = false; - slave->phy_node = of_parse_phandle(node, "phy-handle", 0); + if ((slave->link_interface == SGMII_LINK_MAC_PHY) || + (slave->link_interface == XGMII_LINK_MAC_PHY)) + slave->phy_node = of_parse_phandle(node, "phy-handle", 0); slave->port_num = gbe_get_slave_port(gbe_dev, slave->slave_num); if (slave->link_interface >= XGMII_LINK_MAC_PHY) -- 1.9.1
[net-next v1 7/8] net: netcp: ale: use ale_status to size the ale table
ALE h/w on newer version of NetCP (K2E/L/G) does provide a ALE_STATUS register for the size of the ALE Table implemented in h/w. Currently for example we set ALE Table size to 1024 for NetCP ALE on K2E even though the ALE Status/Documentation shows it has 8192 entries. So take advantage of this register to read the size of ALE table supported and use that value in the driver for the newer version of NetCP ALE. For NetCP lite, ALE Table size is much less (64) and indicated by a size of zero in ALE_STATUS. So use that as a default for now. While at it, also fix the ale table size on 10G switch to 2048 per User guide http://www.ti.com/lit/ug/spruhj5/spruhj5.pdf Signed-off-by: Murali Karicheri Signed-off-by: Sekhar Nori --- drivers/net/ethernet/ti/cpsw_ale.c| 31 ++- drivers/net/ethernet/ti/netcp_ethss.c | 4 +--- 2 files changed, 31 insertions(+), 4 deletions(-) diff --git a/drivers/net/ethernet/ti/cpsw_ale.c b/drivers/net/ethernet/ti/cpsw_ale.c index e15db39..62a18d6 100644 --- a/drivers/net/ethernet/ti/cpsw_ale.c +++ b/drivers/net/ethernet/ti/cpsw_ale.c @@ -33,6 +33,7 @@ /* ALE Registers */ #define ALE_IDVER 0x00 +#define ALE_STATUS 0x04 #define ALE_CONTROL0x08 #define ALE_PRESCALE 0x10 #define ALE_UNKNOWNVLAN0x18 @@ -58,6 +59,10 @@ #define ALE_UCAST_OUI 2 #define ALE_UCAST_TOUCHED 3 +#define ALE_TABLE_SIZE_MULTIPLIER 1024 +#define ALE_STATUS_SIZE_MASK 0x1f +#define ALE_TABLE_SIZE_DEFAULT 64 + static inline int cpsw_ale_get_field(u32 *ale_entry, u32 start, u32 bits) { int idx; @@ -728,7 +733,7 @@ static void cpsw_ale_timer(unsigned long arg) void cpsw_ale_start(struct cpsw_ale *ale) { - u32 rev; + u32 rev, ale_entries; rev = __raw_readl(ale->params.ale_regs + ALE_IDVER); if (!ale->params.major_ver_mask) @@ -740,6 +745,30 @@ void cpsw_ale_start(struct cpsw_ale *ale) ALE_VERSION_MAJOR(rev, ale->params.major_ver_mask), ALE_VERSION_MINOR(rev)); + if (!ale->params.ale_entries) { + ale_entries = + __raw_readl(ale->params.ale_regs + ALE_STATUS) & + ALE_STATUS_SIZE_MASK; + /* ALE available on newer NetCP switches has introduced +* a register, ALE_STATUS, to indicate the size of ALE +* table which shows the size as a multiple of 1024 entries. +* For these, params.ale_entries will be set to zero. So +* read the register and update the value of ale_entries. +* ALE table on NetCP lite, is much smaller and is indicated +* by a value of zero in ALE_STATUS. So use a default value +* of ALE_TABLE_SIZE_DEFAULT for this. Caller is expected +* to set the value of ale_entries for all other versions +* of ALE. +*/ + if (!ale_entries) + ale_entries = ALE_TABLE_SIZE_DEFAULT; + else + ale_entries *= ALE_TABLE_SIZE_MULTIPLIER; + ale->params.ale_entries = ale_entries; + } + dev_info(ale->params.dev, +"ALE Table size %ld\n", ale->params.ale_entries); + if (ale->params.nu_switch_ale) { /* Separate registers for unknown vlan configuration. * Also there are N bits, where N is number of ale diff --git a/drivers/net/ethernet/ti/netcp_ethss.c b/drivers/net/ethernet/ti/netcp_ethss.c index e4a1862..f7bb241 100644 --- a/drivers/net/ethernet/ti/netcp_ethss.c +++ b/drivers/net/ethernet/ti/netcp_ethss.c @@ -81,7 +81,6 @@ #define GBENU_CPTS_OFFSET 0x1d000 #define GBENU_ALE_OFFSET 0x1e000 #define GBENU_HOST_PORT_NUM0 -#define GBENU_NUM_ALE_ENTRIES 1024 #define GBENU_SGMII_MODULE_SIZE0x100 /* 10G Ethernet SS defines */ @@ -103,7 +102,7 @@ #define XGBE10_ALE_OFFSET 0x700 #define XGBE10_HW_STATS_OFFSET 0x800 #define XGBE10_HOST_PORT_NUM 0 -#define XGBE10_NUM_ALE_ENTRIES 1024 +#define XGBE10_NUM_ALE_ENTRIES 2048 #defineGBE_TIMER_INTERVAL (HZ / 2) @@ -3441,7 +3440,6 @@ static int set_gbenu_ethss_priv(struct gbe_priv *gbe_dev, gbe_dev->ale_reg = gbe_dev->switch_regs + GBENU_ALE_OFFSET; gbe_dev->ale_ports = gbe_dev->max_num_ports; gbe_dev->host_port = GBENU_HOST_PORT_NUM; - gbe_dev->ale_entries = GBE13_NUM_ALE_ENTRIES; gbe_dev->stats_en_mask = (1 << (gbe_dev->max_num_ports)) - 1; /* Subsystem registers */ -- 1.9.1