Re: wcn36xx: Fix error handling
Christophe Jaillet wrote: > Reorder 'out_free_dxe_pool' and 'out_free_dxe_ctl' error handling labels > in order to match the way resources have been allocated. > > Signed-off-by: Christophe JAILLET Patch applied to ath-next branch of ath.git, thanks. 4aa2d31f5df8 wcn36xx: Fix error handling -- https://patchwork.kernel.org/patch/9581709/ Documentation about submitting wireless patches and checking status from patchwork: https://wireless.wiki.kernel.org/en/developers/documentation/submittingpatches
[PATCH net] rxrpc: rxrpc_kernel_send_data() needs to handle failed call better
If rxrpc_kernel_send_data() is asked to send data through a call that has already failed (due to a remote abort, received protocol error or network error), then return the associated error code saved in the call rather than ESHUTDOWN. This allows the caller to work out whether to ask for the abort code or not based on this. Signed-off-by: David Howells --- net/rxrpc/sendmsg.c |5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/net/rxrpc/sendmsg.c b/net/rxrpc/sendmsg.c index 47ccfeacc1c6..97ab214ca411 100644 --- a/net/rxrpc/sendmsg.c +++ b/net/rxrpc/sendmsg.c @@ -618,8 +618,9 @@ int rxrpc_kernel_send_data(struct socket *sock, struct rxrpc_call *call, ret = rxrpc_send_data(rxrpc_sk(sock->sk), call, msg, len); break; case RXRPC_CALL_COMPLETE: - /* It's too late for this call */ - ret = -ESHUTDOWN; + read_lock_bh(&call->state_lock); + ret = -call->error; + read_unlock_bh(&call->state_lock); break; default: /* Request phase complete for this client call */
[PATCH net] net: Work around lockdep limitation in sockets that use sockets
Lockdep issues a circular dependency warning when AFS issues an operation through AF_RXRPC from a context in which the VFS/VM holds the mmap_sem. The theory lockdep comes up with is as follows: (1) If the pagefault handler decides it needs to read pages from AFS, it calls AFS with mmap_sem held and AFS begins an AF_RXRPC call, but creating a call requires the socket lock: mmap_sem must be taken before sk_lock-AF_RXRPC (2) afs_open_socket() opens an AF_RXRPC socket and binds it. rxrpc_bind() binds the underlying UDP socket whilst holding its socket lock. inet_bind() takes its own socket lock: sk_lock-AF_RXRPC must be taken before sk_lock-AF_INET (3) Reading from a TCP socket into a userspace buffer might cause a fault and thus cause the kernel to take the mmap_sem, but the TCP socket is locked whilst doing this: sk_lock-AF_INET must be taken before mmap_sem However, lockdep's theory is wrong in this instance because it deals only with lock classes and not individual locks. The AF_INET lock in (2) isn't really equivalent to the AF_INET lock in (3) as the former deals with a socket entirely internal to the kernel that never sees userspace. This is a limitation in the design of lockdep. Fix the general case by: (1) Double up all the locking keys used in sockets so that one set are used if the socket is created by userspace and the other set is used if the socket is created by the kernel. (2) Store the kern parameter passed to sk_alloc() in a variable in the sock struct (sk_kern_sock). This informs sock_lock_init(), sock_init_data() and sk_clone_lock() as to the lock keys to be used. Note that the child created by sk_clone_lock() inherits the parent's kern setting. (3) Add a 'kern' parameter to ->accept() that is analogous to the one passed in to ->create() that distinguishes whether kernel_accept() or sys_accept4() was the caller and can be passed to sk_alloc(). Note that a lot of accept functions merely dequeue an already allocated socket. I haven't touched these as the new socket already exists before we get the parameter. Note also that there are a couple of places where I've made the accepted socket unconditionally kernel-based: irda_accept() rds_rcp_accept_one() tcp_accept_from_sock() because they follow a sock_create_kern() and accept off of that. Whilst creating this, I noticed that lustre and ocfs don't create sockets through sock_create_kern() and thus they aren't marked as for-kernel, though they appear to be internal. I wonder if these should do that so that they use the new set of lock keys. Signed-off-by: David Howells --- crypto/af_alg.c |9 +- crypto/algif_hash.c |9 +- drivers/staging/lustre/lnet/lnet/lib-socket.c |4 - fs/dlm/lowcomms.c |2 fs/ocfs2/cluster/tcp.c|2 include/crypto/if_alg.h |2 include/linux/net.h |2 include/net/inet_common.h |3 - include/net/inet_connection_sock.h|2 include/net/sctp/structs.h|3 - include/net/sock.h|9 +- net/atm/svc.c |5 + net/ax25/af_ax25.c|3 - net/bluetooth/l2cap_sock.c|2 net/bluetooth/rfcomm/sock.c |3 - net/bluetooth/sco.c |2 net/core/sock.c | 106 + net/decnet/af_decnet.c|5 + net/ipv4/af_inet.c|5 + net/ipv4/inet_connection_sock.c |2 net/irda/af_irda.c|5 + net/iucv/af_iucv.c|2 net/llc/af_llc.c |4 + net/netrom/af_netrom.c|3 - net/nfc/llcp_sock.c |2 net/phonet/pep.c |6 + net/phonet/socket.c |4 - net/rds/tcp_listen.c |2 net/rose/af_rose.c|3 - net/sctp/ipv6.c |5 + net/sctp/protocol.c |5 + net/sctp/socket.c |4 - net/smc/af_smc.c |2 net/socket.c |4 - net/tipc/socket.c |8 +- net/unix/af_unix.c|5 + net/vmw_vsock/af_vsock.c |3 - net/x25/af_x25.c |3 - 38 files changed, 142 insertions(+), 108 deletions(-) diff --git a/crypto/af_alg.c b/crypto/af
Re: [PATCH 3/5] rds: ib: remove redundant ib_dealloc_fmr
On 03/09/2017 08:26 AM, Zhu Yanjun wrote: > The function ib_dealloc_fmr will never be called. As such, it should > be removed. > > Cc: Joe Jin > Cc: Junxiao Bi > Signed-off-by: Zhu Yanjun > --- > net/rds/ib_fmr.c | 6 ++ > 1 file changed, 2 insertions(+), 4 deletions(-) > > diff --git a/net/rds/ib_fmr.c b/net/rds/ib_fmr.c > index 4fe8f4f..b807df6 100644 > --- a/net/rds/ib_fmr.c > +++ b/net/rds/ib_fmr.c > @@ -78,12 +78,10 @@ struct rds_ib_mr *rds_ib_alloc_fmr(struct rds_ib_device > *rds_ibdev, int npages) > return ibmr; > > out_no_cigar: > - if (ibmr) { > - if (fmr->fmr) > - ib_dealloc_fmr(fmr->fmr); > + if (ibmr) > kfree(ibmr); kfree() already does a NULL check (see http://lxr.free-electrons.com/source/mm/slab.c#L3811) so no need to do it here. -- Johannes Thumshirn Storage jthumsh...@suse.de+49 911 74053 689 SUSE LINUX GmbH, Maxfeldstr. 5, 90409 Nürnberg GF: Felix Imendörffer, Jane Smithard, Graham Norton HRB 21284 (AG Nürnberg) Key fingerprint = EC38 9CAB C2C4 F25D 8600 D0D0 0393 969D 2D76 0850
[patch net-next 0/2] mlxsw: spectrum: Add support for VLAN offload for cls_flower
From: Jiri Pirko This patchset adds support to offload VLAN modify TC action and adds support to offload cls_flower rules that include VID and PCP matching. Petr Machata (2): mlxsw: spectrum: Add support for vlan modify TC action mlxsw: spectrum: Add support for flower matches on VLAN ID, PCP .../mellanox/mlxsw/core_acl_flex_actions.c | 83 ++ .../mellanox/mlxsw/core_acl_flex_actions.h | 2 + .../ethernet/mellanox/mlxsw/core_acl_flex_keys.h | 6 +- drivers/net/ethernet/mellanox/mlxsw/spectrum.h | 3 + drivers/net/ethernet/mellanox/mlxsw/spectrum_acl.c | 29 .../mellanox/mlxsw/spectrum_acl_flex_keys.h| 6 ++ .../ethernet/mellanox/mlxsw/spectrum_acl_tcam.c| 2 + .../net/ethernet/mellanox/mlxsw/spectrum_flower.c | 34 - include/net/tc_act/tc_vlan.h | 5 ++ 9 files changed, 168 insertions(+), 2 deletions(-) -- 2.7.4
[patch net-next 1/2] mlxsw: spectrum: Add support for vlan modify TC action
From: Petr Machata Add VLAN action offloading. Invoke it from Spectrum flower handler for "vlan modify" actions. Signed-off-by: Petr Machata Reviewed-by: Ido Schimmel Signed-off-by: Jiri Pirko --- .../mellanox/mlxsw/core_acl_flex_actions.c | 83 ++ .../mellanox/mlxsw/core_acl_flex_actions.h | 2 + drivers/net/ethernet/mellanox/mlxsw/spectrum.h | 3 + drivers/net/ethernet/mellanox/mlxsw/spectrum_acl.c | 29 .../net/ethernet/mellanox/mlxsw/spectrum_flower.c | 10 +++ include/net/tc_act/tc_vlan.h | 5 ++ 6 files changed, 132 insertions(+) diff --git a/drivers/net/ethernet/mellanox/mlxsw/core_acl_flex_actions.c b/drivers/net/ethernet/mellanox/mlxsw/core_acl_flex_actions.c index 5f337715..fe3c6ea1 100644 --- a/drivers/net/ethernet/mellanox/mlxsw/core_acl_flex_actions.c +++ b/drivers/net/ethernet/mellanox/mlxsw/core_acl_flex_actions.c @@ -567,6 +567,89 @@ static char *mlxsw_afa_block_append_action(struct mlxsw_afa_block *block, return oneact + MLXSW_AFA_PAYLOAD_OFFSET; } +/* VLAN Action + * --- + * VLAN action is used for manipulating VLANs. It can be used to implement QinQ, + * VLAN translation, change of PCP bits of the VLAN tag, push, pop as swap VLANs + * and more. + */ + +#define MLXSW_AFA_VLAN_CODE 0x02 +#define MLXSW_AFA_VLAN_SIZE 1 + +enum mlxsw_afa_vlan_vlan_tag_cmd { + MLXSW_AFA_VLAN_VLAN_TAG_CMD_NOP, + MLXSW_AFA_VLAN_VLAN_TAG_CMD_PUSH_TAG, + MLXSW_AFA_VLAN_VLAN_TAG_CMD_POP_TAG, +}; + +enum mlxsw_afa_vlan_cmd { + MLXSW_AFA_VLAN_CMD_NOP, + MLXSW_AFA_VLAN_CMD_SET_OUTER, + MLXSW_AFA_VLAN_CMD_SET_INNER, + MLXSW_AFA_VLAN_CMD_COPY_OUTER_TO_INNER, + MLXSW_AFA_VLAN_CMD_COPY_INNER_TO_OUTER, + MLXSW_AFA_VLAN_CMD_SWAP, +}; + +/* afa_vlan_vlan_tag_cmd + * Tag command: push, pop, nop VLAN header. + */ +MLXSW_ITEM32(afa, vlan, vlan_tag_cmd, 0x00, 29, 3); + +/* afa_vlan_vid_cmd */ +MLXSW_ITEM32(afa, vlan, vid_cmd, 0x04, 29, 3); + +/* afa_vlan_vid */ +MLXSW_ITEM32(afa, vlan, vid, 0x04, 0, 12); + +/* afa_vlan_ethertype_cmd */ +MLXSW_ITEM32(afa, vlan, ethertype_cmd, 0x08, 29, 3); + +/* afa_vlan_ethertype + * Index to EtherTypes in Switch VLAN EtherType Register (SVER). + */ +MLXSW_ITEM32(afa, vlan, ethertype, 0x08, 24, 3); + +/* afa_vlan_pcp_cmd */ +MLXSW_ITEM32(afa, vlan, pcp_cmd, 0x08, 13, 3); + +/* afa_vlan_pcp */ +MLXSW_ITEM32(afa, vlan, pcp, 0x08, 8, 3); + +static inline void +mlxsw_afa_vlan_pack(char *payload, + enum mlxsw_afa_vlan_vlan_tag_cmd vlan_tag_cmd, + enum mlxsw_afa_vlan_cmd vid_cmd, u16 vid, + enum mlxsw_afa_vlan_cmd pcp_cmd, u8 pcp, + enum mlxsw_afa_vlan_cmd ethertype_cmd, u8 ethertype) +{ + mlxsw_afa_vlan_vlan_tag_cmd_set(payload, vlan_tag_cmd); + mlxsw_afa_vlan_vid_cmd_set(payload, vid_cmd); + mlxsw_afa_vlan_vid_set(payload, vid); + mlxsw_afa_vlan_pcp_cmd_set(payload, pcp_cmd); + mlxsw_afa_vlan_pcp_set(payload, pcp); + mlxsw_afa_vlan_ethertype_cmd_set(payload, ethertype_cmd); + mlxsw_afa_vlan_ethertype_set(payload, ethertype); +} + +int mlxsw_afa_block_append_vlan_modify(struct mlxsw_afa_block *block, + u16 vid, u8 pcp, u8 et) +{ + char *act = mlxsw_afa_block_append_action(block, + MLXSW_AFA_VLAN_CODE, + MLXSW_AFA_VLAN_SIZE); + + if (!act) + return -ENOBUFS; + mlxsw_afa_vlan_pack(act, MLXSW_AFA_VLAN_VLAN_TAG_CMD_NOP, + MLXSW_AFA_VLAN_CMD_SET_OUTER, vid, + MLXSW_AFA_VLAN_CMD_SET_OUTER, pcp, + MLXSW_AFA_VLAN_CMD_SET_OUTER, et); + return 0; +} +EXPORT_SYMBOL(mlxsw_afa_block_append_vlan_modify); + /* Trap / Discard Action * - * The Trap / Discard action enables trapping / mirroring packets to the CPU diff --git a/drivers/net/ethernet/mellanox/mlxsw/core_acl_flex_actions.h b/drivers/net/ethernet/mellanox/mlxsw/core_acl_flex_actions.h index 43f78dc..6e103ac 100644 --- a/drivers/net/ethernet/mellanox/mlxsw/core_acl_flex_actions.h +++ b/drivers/net/ethernet/mellanox/mlxsw/core_acl_flex_actions.h @@ -62,5 +62,7 @@ void mlxsw_afa_block_jump(struct mlxsw_afa_block *block, u16 group_id); int mlxsw_afa_block_append_drop(struct mlxsw_afa_block *block); int mlxsw_afa_block_append_fwd(struct mlxsw_afa_block *block, u8 local_port, bool in_port); +int mlxsw_afa_block_append_vlan_modify(struct mlxsw_afa_block *block, + u16 vid, u8 pcp, u8 et); #endif diff --git a/drivers/net/ethernet/mellanox/mlxsw/spectrum.h b/drivers/net/ethernet/mellanox/mlxsw/spectrum.h index 13ec85e..ac445d8 100644 --- a/drivers/net/ethernet/mellanox/mlxsw/spectrum.h +++ b/drivers/net/ethernet/mellanox/mlxsw/spectrum.h @@ -679,6 +679,9
[patch net-next 2/2] mlxsw: spectrum: Add support for flower matches on VLAN ID, PCP
From: Petr Machata Introduce MLXSW_AFK_ELEMENT_VID, PCP and declare them in afk_element infos that contain them. Use the elements when VLAD ID or priority are used in the flow. Also add MLXSW_AFK_ELEMENT_VID, PCP to mlxsw_sp_acl_tcam_pattern_ipv4. Both items are included in mlxsw_sp_afk_element_info_l2_dmac, resp. _smac, and both MLXSW_AFK_ELEMENT_SMAC and _DMAC are already in the pattern. Signed-off-by: Petr Machata Reviewed-by: Ido Schimmel Signed-off-by: Jiri Pirko --- .../ethernet/mellanox/mlxsw/core_acl_flex_keys.h | 6 +- .../mellanox/mlxsw/spectrum_acl_flex_keys.h| 6 ++ .../ethernet/mellanox/mlxsw/spectrum_acl_tcam.c| 2 ++ .../net/ethernet/mellanox/mlxsw/spectrum_flower.c | 24 +- 4 files changed, 36 insertions(+), 2 deletions(-) diff --git a/drivers/net/ethernet/mellanox/mlxsw/core_acl_flex_keys.h b/drivers/net/ethernet/mellanox/mlxsw/core_acl_flex_keys.h index e4fcba7..c75e914 100644 --- a/drivers/net/ethernet/mellanox/mlxsw/core_acl_flex_keys.h +++ b/drivers/net/ethernet/mellanox/mlxsw/core_acl_flex_keys.h @@ -54,6 +54,8 @@ enum mlxsw_afk_element { MLXSW_AFK_ELEMENT_DST_IP6_LO, MLXSW_AFK_ELEMENT_DST_L4_PORT, MLXSW_AFK_ELEMENT_SRC_L4_PORT, + MLXSW_AFK_ELEMENT_VID, + MLXSW_AFK_ELEMENT_PCP, MLXSW_AFK_ELEMENT_MAX, }; @@ -88,7 +90,7 @@ struct mlxsw_afk_element_info { MLXSW_AFK_ELEMENT_INFO(MLXSW_AFK_ELEMENT_TYPE_BUF, \ _element, _offset, 0, _size) -/* For the purpose of the driver, define a internal storage scratchpad +/* For the purpose of the driver, define an internal storage scratchpad * that will be used to store key/mask values. For each defined element type * define an internal storage geometry. */ @@ -98,6 +100,8 @@ static const struct mlxsw_afk_element_info mlxsw_afk_element_infos[] = { MLXSW_AFK_ELEMENT_INFO_BUF(SMAC, 0x0A, 6), MLXSW_AFK_ELEMENT_INFO_U32(ETHERTYPE, 0x00, 0, 16), MLXSW_AFK_ELEMENT_INFO_U32(IP_PROTO, 0x10, 0, 8), + MLXSW_AFK_ELEMENT_INFO_U32(VID, 0x10, 8, 12), + MLXSW_AFK_ELEMENT_INFO_U32(PCP, 0x10, 20, 3), MLXSW_AFK_ELEMENT_INFO_U32(SRC_IP4, 0x18, 0, 32), MLXSW_AFK_ELEMENT_INFO_U32(DST_IP4, 0x1C, 0, 32), MLXSW_AFK_ELEMENT_INFO_BUF(SRC_IP6_HI, 0x18, 8), diff --git a/drivers/net/ethernet/mellanox/mlxsw/spectrum_acl_flex_keys.h b/drivers/net/ethernet/mellanox/mlxsw/spectrum_acl_flex_keys.h index 82b81cf..af7b7ba 100644 --- a/drivers/net/ethernet/mellanox/mlxsw/spectrum_acl_flex_keys.h +++ b/drivers/net/ethernet/mellanox/mlxsw/spectrum_acl_flex_keys.h @@ -39,11 +39,15 @@ static struct mlxsw_afk_element_inst mlxsw_sp_afk_element_info_l2_dmac[] = { MLXSW_AFK_ELEMENT_INST_BUF(DMAC, 0x00, 6), + MLXSW_AFK_ELEMENT_INST_U32(PCP, 0x08, 13, 3), + MLXSW_AFK_ELEMENT_INST_U32(VID, 0x08, 0, 12), MLXSW_AFK_ELEMENT_INST_U32(SRC_SYS_PORT, 0x0C, 0, 16), }; static struct mlxsw_afk_element_inst mlxsw_sp_afk_element_info_l2_smac[] = { MLXSW_AFK_ELEMENT_INST_BUF(SMAC, 0x00, 6), + MLXSW_AFK_ELEMENT_INST_U32(PCP, 0x08, 13, 3), + MLXSW_AFK_ELEMENT_INST_U32(VID, 0x08, 0, 12), MLXSW_AFK_ELEMENT_INST_U32(SRC_SYS_PORT, 0x0C, 0, 16), }; @@ -65,6 +69,8 @@ static struct mlxsw_afk_element_inst mlxsw_sp_afk_element_info_ipv4_dip[] = { }; static struct mlxsw_afk_element_inst mlxsw_sp_afk_element_info_ipv4_ex[] = { + MLXSW_AFK_ELEMENT_INST_U32(VID, 0x00, 0, 12), + MLXSW_AFK_ELEMENT_INST_U32(PCP, 0x08, 29, 3), MLXSW_AFK_ELEMENT_INST_U32(SRC_L4_PORT, 0x08, 0, 16), MLXSW_AFK_ELEMENT_INST_U32(DST_L4_PORT, 0x0C, 0, 16), }; diff --git a/drivers/net/ethernet/mellanox/mlxsw/spectrum_acl_tcam.c b/drivers/net/ethernet/mellanox/mlxsw/spectrum_acl_tcam.c index 7382832..6858439 100644 --- a/drivers/net/ethernet/mellanox/mlxsw/spectrum_acl_tcam.c +++ b/drivers/net/ethernet/mellanox/mlxsw/spectrum_acl_tcam.c @@ -950,6 +950,8 @@ static const enum mlxsw_afk_element mlxsw_sp_acl_tcam_pattern_ipv4[] = { MLXSW_AFK_ELEMENT_DST_IP4, MLXSW_AFK_ELEMENT_DST_L4_PORT, MLXSW_AFK_ELEMENT_SRC_L4_PORT, + MLXSW_AFK_ELEMENT_VID, + MLXSW_AFK_ELEMENT_PCP, }; static const enum mlxsw_afk_element mlxsw_sp_acl_tcam_pattern_ipv6[] = { diff --git a/drivers/net/ethernet/mellanox/mlxsw/spectrum_flower.c b/drivers/net/ethernet/mellanox/mlxsw/spectrum_flower.c index d898407..f2ed0b3 100644 --- a/drivers/net/ethernet/mellanox/mlxsw/spectrum_flower.c +++ b/drivers/net/ethernet/mellanox/mlxsw/spectrum_flower.c @@ -183,7 +183,8 @@ static int mlxsw_sp_flower_parse(struct mlxsw_sp *mlxsw_sp, BIT(FLOW_DISSECTOR_KEY_ETH_ADDRS) | BIT(FLOW_DISSECTOR_KEY_IPV4_ADDRS) | BIT(FLOW_DISSECTOR_KEY_IPV6_ADDRS) | - BIT(FLOW_DISSECTOR_KEY_PORTS))) { + BIT(FLOW_DISSECTOR_KEY_PORTS) | + BIT(FLOW_DISSECTOR_KEY_VLAN))) {
stmmac still supporting spear600 ?
Hello, I'm porting Linux to an old spear600 based platform, and therefore trying to use the stmmac driver on this SoC. Unfortunately, it doesn't work quite well and I'm wondering if the stmmac driver still properly supports the old version of the IP that is used in this SoC. I'm testing with v4.11-rc1. First, the logs: Linux version 4.11.0-rc1 (thomas@skate) (gcc version 5.4.0 20160609 (Ubuntu/Linaro 5.4.0-6ubuntu1~16.04.4) ) #18 Thu Mar 9 09:18:01 CET 2017 [...] libphy: Fixed MDIO Bus: probed stmmaceth e080.ethernet: no reset control found stmmac - user ID: 0x10, Synopsys ID: 0x32 stmmaceth e080.ethernet: Ring mode enabled stmmaceth e080.ethernet: DMA HW capability register supported stmmaceth e080.ethernet: Normal descriptors libphy: stmmac: probed stmmaceth e080.ethernet (unnamed net_device) (uninitialized): PHY ID 0007c0c4 at 31 IRQ POLL (stmmac-0:1f) active [...] # ifconfig eth0 192.168.1.89 stmmaceth e080.ethernet eth0: device MAC address 00:30:d3:21:22:60 Generic PHY stmmac-0:1f: attached PHY driver [Generic PHY] (mii_bus:phy_addr=stmmac-0:1f, irq=-1) stmmaceth e080.ethernet: Failed to reset the dma stmmaceth e080.ethernet eth0: stmmac_hw_setup: DMA engine initialization failed stmmaceth e080.ethernet eth0: stmmac_open: Hw setup failed ifconfig: SIOCSIFFLAGS: Device or resource busy So the reason why it fails to reset the DMA is because dwmac_dma_reset() sets bit DMA_BUS_MODE_SFT_RESET in register DMA_BUS_MODE and waits for this bit to clear, but that never happens. The reason why I'm not sure if this IP is still supported is because dwmac1000_get_hw_feature() reads the DMA_HW_FEATURE register (offset 0x1058), and my spear600 datasheet doesn't mention this register at all. It is worth mentioning that: - Ethernet is working fine under U-Boot (it's an old 2010.03 U-Boot version, with a good number of patches), so I'm sure the HW is working. - Setting bit 1 in the DMA_BUS_MODE register from U-Boot also leaves this bit set forever, it apparently never clears (unless my tests were wrong, which is very possible). In terms of Device Tree, I'm simply using spear600.dtsi, and enabling the gmac node, nothing else. Has the stmmac driver been recently used/tested on spear600 ? Thanks, Thomas Petazzoni -- Thomas Petazzoni, CTO, Free Electrons Embedded Linux and Kernel engineering http://free-electrons.com
Re: [PATCH 22/29] drivers, scsi: convert iscsi_task.refcount from atomic_t to refcount_t
On 03/09/2017 08:18 AM, Reshetova, Elena wrote: >> On Mon, Mar 06, 2017 at 04:21:09PM +0200, Elena Reshetova wrote: >>> refcount_t type and corresponding API should be >>> used instead of atomic_t when the variable is used as >>> a reference counter. This allows to avoid accidental >>> refcounter overflows that might lead to use-after-free >>> situations. >>> >>> Signed-off-by: Elena Reshetova >>> Signed-off-by: Hans Liljestrand >>> Signed-off-by: Kees Cook >>> Signed-off-by: David Windsor >> >> This looks OK to me. >> >> Acked-by: Chris Leech > > Thank you for review! Do you have a tree that can take this change? Hi Elena, iscsi like fcoe should go via the SCSI tree. Byte, Johannes -- Johannes Thumshirn Storage jthumsh...@suse.de+49 911 74053 689 SUSE LINUX GmbH, Maxfeldstr. 5, 90409 Nürnberg GF: Felix Imendörffer, Jane Smithard, Graham Norton HRB 21284 (AG Nürnberg) Key fingerprint = EC38 9CAB C2C4 F25D 8600 D0D0 0393 969D 2D76 0850
[PATCH] net: phy: ks8995: Fix bug while selecting sysfs node size
From: Lev Urusov The driver will not be able to take into account the correct number of device SPI registers if it is not equal to 128. Signed-off-by: Lev Urusov --- drivers/net/phy/spi_ks8995.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/net/phy/spi_ks8995.c b/drivers/net/phy/spi_ks8995.c index 93ffedf..f084725 100644 --- a/drivers/net/phy/spi_ks8995.c +++ b/drivers/net/phy/spi_ks8995.c @@ -491,8 +491,8 @@ static int ks8995_probe(struct spi_device *spi) if (err) return err; - ks->regs_attr.size = ks->chip->regs_size; memcpy(&ks->regs_attr, &ks8995_registers_attr, sizeof(ks->regs_attr)); + ks->regs_attr.size = ks->chip->regs_size; err = ks8995_reset(ks); if (err) -- 1.9.1
Re: stmmac still supporting spear600 ?
Hello We do not test stmmac on this spear board since many years and I guess you have to provide parameters from the platform. In fact, stmmac is recently tested with DT. IIRC, the mac on spear600 could not have the HW cap register so it is mandatory to provide all the right parameters and configurations for this HW. Regards Peppe On 3/9/2017 9:34 AM, Thomas Petazzoni wrote: Hello, I'm porting Linux to an old spear600 based platform, and therefore trying to use the stmmac driver on this SoC. Unfortunately, it doesn't work quite well and I'm wondering if the stmmac driver still properly supports the old version of the IP that is used in this SoC. I'm testing with v4.11-rc1. First, the logs: Linux version 4.11.0-rc1 (thomas@skate) (gcc version 5.4.0 20160609 (Ubuntu/Linaro 5.4.0-6ubuntu1~16.04.4) ) #18 Thu Mar 9 09:18:01 CET 2017 [...] libphy: Fixed MDIO Bus: probed stmmaceth e080.ethernet: no reset control found stmmac - user ID: 0x10, Synopsys ID: 0x32 stmmaceth e080.ethernet: Ring mode enabled stmmaceth e080.ethernet: DMA HW capability register supported stmmaceth e080.ethernet: Normal descriptors libphy: stmmac: probed stmmaceth e080.ethernet (unnamed net_device) (uninitialized): PHY ID 0007c0c4 at 31 IRQ POLL (stmmac-0:1f) active [...] # ifconfig eth0 192.168.1.89 stmmaceth e080.ethernet eth0: device MAC address 00:30:d3:21:22:60 Generic PHY stmmac-0:1f: attached PHY driver [Generic PHY] (mii_bus:phy_addr=stmmac-0:1f, irq=-1) stmmaceth e080.ethernet: Failed to reset the dma stmmaceth e080.ethernet eth0: stmmac_hw_setup: DMA engine initialization failed stmmaceth e080.ethernet eth0: stmmac_open: Hw setup failed ifconfig: SIOCSIFFLAGS: Device or resource busy So the reason why it fails to reset the DMA is because dwmac_dma_reset() sets bit DMA_BUS_MODE_SFT_RESET in register DMA_BUS_MODE and waits for this bit to clear, but that never happens. The reason why I'm not sure if this IP is still supported is because dwmac1000_get_hw_feature() reads the DMA_HW_FEATURE register (offset 0x1058), and my spear600 datasheet doesn't mention this register at all. It is worth mentioning that: - Ethernet is working fine under U-Boot (it's an old 2010.03 U-Boot version, with a good number of patches), so I'm sure the HW is working. - Setting bit 1 in the DMA_BUS_MODE register from U-Boot also leaves this bit set forever, it apparently never clears (unless my tests were wrong, which is very possible). In terms of Device Tree, I'm simply using spear600.dtsi, and enabling the gmac node, nothing else. Has the stmmac driver been recently used/tested on spear600 ? Thanks, Thomas Petazzoni
[PATCHv2 3/5] rds: ib: remove redundant ib_dealloc_fmr
The function ib_dealloc_fmr will never be called. As such, it should be removed. Cc: Joe Jin Cc: Junxiao Bi Signed-off-by: Zhu Yanjun --- Change from v1 to v2: remove ibmr NULL test. net/rds/ib_fmr.c | 7 ++- 1 file changed, 2 insertions(+), 5 deletions(-) diff --git a/net/rds/ib_fmr.c b/net/rds/ib_fmr.c index 4fe8f4f..249ae1c 100644 --- a/net/rds/ib_fmr.c +++ b/net/rds/ib_fmr.c @@ -78,12 +78,9 @@ struct rds_ib_mr *rds_ib_alloc_fmr(struct rds_ib_device *rds_ibdev, int npages) return ibmr; out_no_cigar: - if (ibmr) { - if (fmr->fmr) - ib_dealloc_fmr(fmr->fmr); - kfree(ibmr); - } + kfree(ibmr); atomic_dec(&pool->item_count); + return ERR_PTR(err); } -- 2.7.4
RE: [PATCH 22/29] drivers, scsi: convert iscsi_task.refcount from atomic_t to refcount_t
> On 03/09/2017 08:18 AM, Reshetova, Elena wrote: > >> On Mon, Mar 06, 2017 at 04:21:09PM +0200, Elena Reshetova wrote: > >>> refcount_t type and corresponding API should be > >>> used instead of atomic_t when the variable is used as > >>> a reference counter. This allows to avoid accidental > >>> refcounter overflows that might lead to use-after-free > >>> situations. > >>> > >>> Signed-off-by: Elena Reshetova > >>> Signed-off-by: Hans Liljestrand > >>> Signed-off-by: Kees Cook > >>> Signed-off-by: David Windsor > >> > >> This looks OK to me. > >> > >> Acked-by: Chris Leech > > > > Thank you for review! Do you have a tree that can take this change? > > Hi Elena, > > iscsi like fcoe should go via the SCSI tree. Thanks Johannes! Should I resend with "Acked-by" added in order for it to be picked up? Best Regards, Elena. > > Byte, > Johannes > > -- > Johannes Thumshirn Storage > jthumsh...@suse.de+49 911 74053 689 > SUSE LINUX GmbH, Maxfeldstr. 5, 90409 Nürnberg > GF: Felix Imendörffer, Jane Smithard, Graham Norton > HRB 21284 (AG Nürnberg) > Key fingerprint = EC38 9CAB C2C4 F25D 8600 D0D0 0393 969D 2D76 0850
Re: stmmac still supporting spear600 ?
On 09-03-17, 10:09, Giuseppe CAVALLARO wrote: > Hello > > We do not test stmmac on this spear board since many years > and I guess you have to provide parameters from the platform. > In fact, stmmac is recently tested with DT. > IIRC, the mac on spear600 could not have the HW cap register > so it is mandatory to provide all the right parameters and > configurations for this HW. Same here, I haven't tested it since many years and trust whatever Giuseppe has said. -- viresh
Re: stmmac still supporting spear600 ?
Hello Giuseppe, Thanks for your answer. On Thu, 9 Mar 2017 10:09:02 +0100, Giuseppe CAVALLARO wrote: > We do not test stmmac on this spear board since many years > and I guess you have to provide parameters from the platform. Ok, that's what I was afraid of :-/ > In fact, stmmac is recently tested with DT. I'm also using the DT, so this is definitely not the problem. > IIRC, the mac on spear600 could not have the HW cap register Correct. > so it is mandatory to provide all the right parameters and > configurations for this HW. OK, I'll have a look. However, I'm still confused by this DMA_RESET bit that never clears, contrary to what the datasheet says. Are there some erratas? Best regards, Thomas -- Thomas Petazzoni, CTO, Free Electrons Embedded Linux and Kernel engineering http://free-electrons.com
Re: [PATCH 22/29] drivers, scsi: convert iscsi_task.refcount from atomic_t to refcount_t
On 03/09/2017 10:26 AM, Reshetova, Elena wrote: > >> On 03/09/2017 08:18 AM, Reshetova, Elena wrote: On Mon, Mar 06, 2017 at 04:21:09PM +0200, Elena Reshetova wrote: > refcount_t type and corresponding API should be > used instead of atomic_t when the variable is used as > a reference counter. This allows to avoid accidental > refcounter overflows that might lead to use-after-free > situations. > > Signed-off-by: Elena Reshetova > Signed-off-by: Hans Liljestrand > Signed-off-by: Kees Cook > Signed-off-by: David Windsor This looks OK to me. Acked-by: Chris Leech >>> >>> Thank you for review! Do you have a tree that can take this change? >> >> Hi Elena, >> >> iscsi like fcoe should go via the SCSI tree. > > Thanks Johannes! Should I resend with "Acked-by" added in order for it to be > picked up? Yes I think this would be a good way to go. Byte, Johannes -- Johannes Thumshirn Storage jthumsh...@suse.de+49 911 74053 689 SUSE LINUX GmbH, Maxfeldstr. 5, 90409 Nürnberg GF: Felix Imendörffer, Jane Smithard, Graham Norton HRB 21284 (AG Nürnberg) Key fingerprint = EC38 9CAB C2C4 F25D 8600 D0D0 0393 969D 2D76 0850
Re: [PATCH v2 net-next 2/8] net: stmicro: configure mtl rx and tx algorithms
On 03/08/2017 05:48 PM, Joao Pinto wrote: > Às 4:45 PM de 3/8/2017, Niklas Cassel escreveu: >> On 03/08/2017 01:22 PM, Joao Pinto wrote: >>> This patch adds the RX and TX scheduling algorithms programming. >>> It introduces the multiple queues configuration function >>> (stmmac_mtl_configuration) in stmmac_main. >>> >>> Signed-off-by: Joao Pinto >>> --- >>> changes v1->v2: >>> - Just to keep up with patch-set version >>> >>> drivers/net/ethernet/stmicro/stmmac/common.h | 4 ++ >>> drivers/net/ethernet/stmicro/stmmac/dwmac4.h | 10 + >>> drivers/net/ethernet/stmicro/stmmac/dwmac4_core.c | 48 >>> +++ >>> drivers/net/ethernet/stmicro/stmmac/stmmac_main.c | 31 +-- >>> 4 files changed, 90 insertions(+), 3 deletions(-) >>> >>> diff --git a/drivers/net/ethernet/stmicro/stmmac/common.h >>> b/drivers/net/ethernet/stmicro/stmmac/common.h >>> index 04d9245..5a0a781 100644 >>> --- a/drivers/net/ethernet/stmicro/stmmac/common.h >>> +++ b/drivers/net/ethernet/stmicro/stmmac/common.h >>> @@ -455,6 +455,10 @@ struct stmmac_ops { >>> int (*rx_ipc)(struct mac_device_info *hw); >>> /* Enable RX Queues */ >>> void (*rx_queue_enable)(struct mac_device_info *hw, u32 queue); >>> + /* Program RX Algorithms */ >>> + void (*prog_mtl_rx_algorithms)(struct mac_device_info *hw, u32 rx_alg); >>> + /* Program TX Algorithms */ >>> + void (*prog_mtl_tx_algorithms)(struct mac_device_info *hw, u32 tx_alg); >>> /* Dump MAC registers */ >>> void (*dump_regs)(struct mac_device_info *hw, u32 *reg_space); >>> /* Handle extra events on specific interrupts hw dependent */ >>> diff --git a/drivers/net/ethernet/stmicro/stmmac/dwmac4.h >>> b/drivers/net/ethernet/stmicro/stmmac/dwmac4.h >>> index db45134..748ab6f 100644 >>> --- a/drivers/net/ethernet/stmicro/stmmac/dwmac4.h >>> +++ b/drivers/net/ethernet/stmicro/stmmac/dwmac4.h >>> @@ -161,6 +161,16 @@ enum power_event { >>> #define GMAC_HI_REG_AE BIT(31) >>> >>> /* MTL registers */ >>> +#define MTL_OPERATION_MODE 0x0c00 >>> +#define MTL_OPERATION_SCHALG_MASK GENMASK(6, 5) >>> +#define MTL_OPERATION_SCHALG_WRR (0x0 << 5) >>> +#define MTL_OPERATION_SCHALG_WFQ (0x1 << 5) >>> +#define MTL_OPERATION_SCHALG_DWRR (0x2 << 5) >>> +#define MTL_OPERATION_SCHALG_SP(0x3 << 5) >>> +#define MTL_OPERATION_RAA BIT(2) >>> +#define MTL_OPERATION_RAA_SP (0x0 << 2) >>> +#define MTL_OPERATION_RAA_WSP (0x1 << 2) >>> + >>> #define MTL_INT_STATUS 0x0c20 >>> #define MTL_INT_Q0 BIT(0) >>> >>> diff --git a/drivers/net/ethernet/stmicro/stmmac/dwmac4_core.c >>> b/drivers/net/ethernet/stmicro/stmmac/dwmac4_core.c >>> index 1e79e65..7503b8e 100644 >>> --- a/drivers/net/ethernet/stmicro/stmmac/dwmac4_core.c >>> +++ b/drivers/net/ethernet/stmicro/stmmac/dwmac4_core.c >>> @@ -70,6 +70,52 @@ static void dwmac4_rx_queue_enable(struct >>> mac_device_info *hw, u32 queue) >>> writel(value, ioaddr + GMAC_RXQ_CTRL0); >>> } >>> >>> +static void dwmac4_prog_mtl_rx_algorithms(struct mac_device_info *hw, >>> + u32 rx_alg) >>> +{ >>> + void __iomem *ioaddr = hw->pcsr; >>> + u32 value = readl(ioaddr + MTL_OPERATION_MODE); >>> + >>> + value &= ~MTL_OPERATION_RAA; >>> + switch (rx_alg) { >>> + case MTL_RX_ALGORITHM_SP: >>> + value |= MTL_OPERATION_RAA_SP; >>> + break; >>> + case MTL_RX_ALGORITHM_WSP: >>> + value |= MTL_OPERATION_RAA_WSP; >>> + break; >>> + default: >>> + break; >>> + } >>> + >>> + writel(value, ioaddr + MTL_OPERATION_MODE); >>> +} >>> + >>> +static void dwmac4_prog_mtl_tx_algorithms(struct mac_device_info *hw, >>> + u32 tx_alg) >>> +{ >>> + void __iomem *ioaddr = hw->pcsr; >>> + u32 value = readl(ioaddr + MTL_OPERATION_MODE); >>> + >>> + value &= ~MTL_OPERATION_SCHALG_MASK; >>> + switch (tx_alg) { >>> + case MTL_TX_ALGORITHM_WRR: >>> + value |= MTL_OPERATION_SCHALG_WRR; >>> + break; >>> + case MTL_TX_ALGORITHM_WFQ: >>> + value |= MTL_OPERATION_SCHALG_WFQ; >>> + break; >>> + case MTL_TX_ALGORITHM_DWRR: >>> + value |= MTL_OPERATION_SCHALG_DWRR; >>> + break; >>> + case MTL_TX_ALGORITHM_SP: >>> + value |= MTL_OPERATION_SCHALG_SP; >>> + break; >>> + default: >>> + break; >>> + } >>> +} >>> + >>> static void dwmac4_dump_regs(struct mac_device_info *hw, u32 *reg_space) >>> { >>> void __iomem *ioaddr = hw->pcsr; >>> @@ -457,6 +503,8 @@ static const struct stmmac_ops dwmac4_ops = { >>> .core_init = dwmac4_core_init, >>> .rx_ipc = dwmac4_rx_ipc_enable, >>> .rx_queue_enable = dwmac4_rx_queue_enable, >>> + .prog_mtl_rx_algorithms = dwmac4_prog_mtl_rx_algorithms, >>> + .prog_mtl_tx_algorithms = dwmac4_prog_mtl_tx_algorithms, >>> .dump_regs = dwmac4_dump_regs, >>> .host_irq_status = dwmac4_irq_status, >>> .flow_ctrl = dwmac4_flow_ctrl, >>> diff --git a
Re: [PATCHv2 3/5] rds: ib: remove redundant ib_dealloc_fmr
On 03/09/2017 10:20 AM, Zhu Yanjun wrote: > The function ib_dealloc_fmr will never be called. As such, it should > be removed. > > Cc: Joe Jin > Cc: Junxiao Bi > Signed-off-by: Zhu Yanjun > --- Reviewed-by: Johannes Thumshirn -- Johannes Thumshirn Storage jthumsh...@suse.de+49 911 74053 689 SUSE LINUX GmbH, Maxfeldstr. 5, 90409 Nürnberg GF: Felix Imendörffer, Jane Smithard, Graham Norton HRB 21284 (AG Nürnberg) Key fingerprint = EC38 9CAB C2C4 F25D 8600 D0D0 0393 969D 2D76 0850
[PATCH] mac80211: Use setup_timer instead of init_timer
From: Ondřej Lysoněk Use setup_timer() and setup_deferrable_timer() to set the data and function timer fields. It makes the code cleaner and will allow for easier change of the timer struct internals. Signed-off-by: Ondřej Lysoněk Cc: Jiri Slaby Cc: Johannes Berg Cc: "David S. Miller" Cc: Cc: --- net/mac80211/mesh_pathtbl.c | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/net/mac80211/mesh_pathtbl.c b/net/mac80211/mesh_pathtbl.c index f0e6175..64c6174 100644 --- a/net/mac80211/mesh_pathtbl.c +++ b/net/mac80211/mesh_pathtbl.c @@ -397,11 +397,10 @@ struct mesh_path *mesh_path_new(struct ieee80211_sub_if_data *sdata, new_mpath->sdata = sdata; new_mpath->flags = 0; skb_queue_head_init(&new_mpath->frame_queue); - new_mpath->timer.data = (unsigned long) new_mpath; - new_mpath->timer.function = mesh_path_timer; new_mpath->exp_time = jiffies; spin_lock_init(&new_mpath->state_lock); - init_timer(&new_mpath->timer); + setup_timer(&new_mpath->timer, mesh_path_timer, + (unsigned long) new_mpath); return new_mpath; } -- 2.9.3
Re: [PATCH v2 net-next 2/8] net: stmicro: configure mtl rx and tx algorithms
Às 9:37 AM de 3/9/2017, Niklas Cassel escreveu: > On 03/08/2017 05:48 PM, Joao Pinto wrote: >> Às 4:45 PM de 3/8/2017, Niklas Cassel escreveu: >>> On 03/08/2017 01:22 PM, Joao Pinto wrote: This patch adds the RX and TX scheduling algorithms programming. It introduces the multiple queues configuration function (stmmac_mtl_configuration) in stmmac_main. (snip...) + stmmac_mac_enable_rx_queues(priv); >>> Hello Joao >>> >>> Since you are now enabling RX queues here, >>> perhaps we should move the enabling of TX queue(s) here as well? >> Hi Niklas, >> TX enable operation is different, it is part of the DMA Operation Mode >> configuration. In a later patch I will be updating the DMA Operation Mode >> configuration and this op will be placed here. >> >> As indicated by David Miller, this patch-set is focused in MAC ops only. DMA >> focused patch-set will follow after this one gets accepted. > > Not sure that I agree 100% since: > > "23.2 Initializing MTL Registers" > > 1. Program the Tx Scheduling algorithm. (Which you now do in > stmmac_mtl_configuration.) > > [snip] > > 3. Program the following fields to initialize the mode of operation in the > MTL_TxQ0_Operation_Mode > a. Transmit Store And Forward (TSF) or Transmit Threshold Control (TTC) in > case of threshold mode > b. Transmit Queue Enable (TXQEN) to value 2‘b10 to enable Transmit Queue0 > c. Transmit Queue Size (TQS) > > > Note that "Initializing DMA" is a separate chapter. > > However, since you are planning on moving the MTL_TxQ0_Operation_Mode > initialization > to stmmac_mtl_configuration in a later patch, I don't think that you have to > rework this > patch just because of this simple remark. Sorry, I misleaded you. What I was trying to say was that the TX Operation Mode is going to be moved here in a later patch. Thanks for the help. > > Nice to see some work done on multiqueues for stmmac :) > > >> >> Thanks! >> >>> +} + +/** * stmmac_hw_setup - setup mac in a usable state. * @dev : pointer to the device structure. * Description: @@ -1688,9 +1713,9 @@ static int stmmac_hw_setup(struct net_device *dev, bool init_ptp) /* Initialize the MAC Core */ priv->hw->mac->core_init(priv->hw, dev->mtu); - /* Initialize MAC RX Queues */ - if (priv->hw->mac->rx_queue_enable) - stmmac_mac_enable_rx_queues(priv); + /* Initialize MTL*/ + if (priv->synopsys_id >= DWMAC_CORE_4_00) + stmmac_mtl_configuration(priv); ret = priv->hw->mac->rx_ipc(priv->hw); if (!ret) { >
Re: [PATCH v5 04/19] net: e100: Replace PCI pool old API
Hello, Le 09/03/2017 à 08:01, Peter Senna Tschudin a écrit : > On Wed, Mar 08, 2017 at 02:40:25PM -0800, Jeff Kirsher wrote: >> On Wed, 2017-03-08 at 17:19 +0100, Romain Perier wrote: >>> The PCI pool API is deprecated. This commit replaces the PCI pool old >>> API by the appropriate function with the DMA pool API. >>> >>> Signed-off-by: Romain Perier >>> Acked-by: Peter Senna Tschudin >>> Tested-by: Peter Senna Tschudin >>> --- >>> drivers/net/ethernet/intel/e100.c | 12 ++-- >>> 1 file changed, 6 insertions(+), 6 deletions(-) >> Acked-by: Jeff Kirsher >> >> My only concern is: >> - what hardware did this get tested with? Since this affects all e100 >> parts, it would be hard to believe that all the affected hardware was >> used in testing. > This was tested by compilation only(See > https://lkml.org/lkml/2017/2/8/661). However this series removes macro > definitions of the old pci_pool interface and replace call sites by what > the macra was calling. > > Here are the macros that this series removes from include/pci.h: > > #define pci_pool dma_pool > #define pci_pool_create(name, pdev, size, align, allocation) \ > dma_pool_create(name, &pdev->dev, size, align, allocation) > #define pci_pool_destroy(pool) dma_pool_destroy(pool) > #define pci_pool_alloc(pool, flags, handle) dma_pool_alloc(pool, flags, > handle) > #define pci_pool_zalloc(pool, flags, handle) \ > dma_pool_zalloc(pool, flags, handle) > #define pci_pool_free(pool, vaddr, addr) dma_pool_free(pool, vaddr, add > > So this should not affect run time. We cannot test a patch like this one on all affected platforms/drivers (at runtime). Simply because we have not the hw. As Peter said, we tested this by compilation only for now via make allyesconfig. That's up to the maintainer of the subsystem to test and ack this, imho. I agree with Peter, this should not affect runtime (as semantically it's compatible and have been validated statically and semantically by your compiler) Regards, Romain
Re: [PATCH v2 2/2] can: spi: hi311x: Add Holt HI-311x CAN driver
Hello Akshay, unfortunately there are not many CAN controllers for the SPI bus. I just know the MPC251x, which behaves badly (message losses) under Linux, especially at hight bit-rates due to insufficient RX buffering. What is your experience with that driver for the HI-311x? Thanks, Wolfgang. Am 07.03.2017 um 16:31 schrieb Akshay Bhat: On 01/17/2017 02:22 PM, Akshay Bhat wrote: This patch adds support for the Holt HI-311x CAN controller. The HI311x CAN controller is capable of transmitting and receiving standard data frames, extended data frames and remote frames. The HI311x interfaces with the host over SPI. Datasheet: www.holtic.com/documents/371-hi-3110_v-rev-jpdf.do Signed-off-by: Akshay Bhat --- Hi Marc, Wanted to check if this patch can be included in the next kernel release (4.12). Thanks, Akshay -- To unsubscribe from this list: send the line "unsubscribe linux-can" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCH v2] udp: avoid ufo handling on IP payload compression packets
commit c146066ab802 ("ipv4: Don't use ufo handling on later transformed packets") and commit f89c56ce710a ("ipv6: Don't use ufo handling on later transformed packets") added a check that 'rt->dst.header_len' isn't zero in order to skip UFO, but it doesn't include IPcomp in transport mode where it equals zero. Packets, after payload compression, may not require further fragmentation, and if original length exceeds MTU, later compressed packets will be transmitted incorrectly. This can be reproduced with LTP udp_ipsec.sh test on veth device with enabled UFO, MTU is 1500 and UDP payload is 2000: * IPv4 case, offset is wrong + unnecessary fragmentation udp_ipsec.sh -p comp -m transport -s 2000 & tcpdump -ni ltp_ns_veth2 ... IP (tos 0x0, ttl 64, id 45203, offset 0, flags [+], proto Compressed IP (108), length 49) 10.0.0.2 > 10.0.0.1: IPComp(cpi=0x1000) IP (tos 0x0, ttl 64, id 45203, offset 1480, flags [none], proto UDP (17), length 21) 10.0.0.2 > 10.0.0.1: ip-proto-17 * IPv6 case, sending small fragments udp_ipsec.sh -6 -p comp -m transport -s 2000 & tcpdump -ni ltp_ns_veth2 ... IP6 (flowlabel 0x6b9ba, hlim 64, next-header Compressed IP (108) payload length: 37) fd00::2 > fd00::1: IPComp(cpi=0x1000) IP6 (flowlabel 0x6b9ba, hlim 64, next-header Compressed IP (108) payload length: 21) fd00::2 > fd00::1: IPComp(cpi=0x1000) Fix it by checking 'rt->dst.xfrm' pointer to 'xfrm_state' struct, skip UFO if xfrm is set. So the new check will include both cases: IPcomp and IPsec. Fixes: c146066ab802 ("ipv4: Don't use ufo handling on later transformed packets") Fixes: f89c56ce710a ("ipv6: Don't use ufo handling on later transformed packets") Signed-off-by: Alexey Kodanev --- v2: use dst_xfrm() to access xfrm_state net/ipv4/ip_output.c |2 +- net/ipv6/ip6_output.c |2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/net/ipv4/ip_output.c b/net/ipv4/ip_output.c index 737ce82..7a3fd25 100644 --- a/net/ipv4/ip_output.c +++ b/net/ipv4/ip_output.c @@ -966,7 +966,7 @@ static int __ip_append_data(struct sock *sk, cork->length += length; if length + fragheaderlen) > mtu) || (skb && skb_is_gso(skb))) && (sk->sk_protocol == IPPROTO_UDP) && - (rt->dst.dev->features & NETIF_F_UFO) && !rt->dst.header_len && + (rt->dst.dev->features & NETIF_F_UFO) && !dst_xfrm(&rt->dst) && (sk->sk_type == SOCK_DGRAM) && !sk->sk_no_check_tx) { err = ip_ufo_append_data(sk, queue, getfrag, from, length, hh_len, fragheaderlen, transhdrlen, diff --git a/net/ipv6/ip6_output.c b/net/ipv6/ip6_output.c index 528b3c1..df42096 100644 --- a/net/ipv6/ip6_output.c +++ b/net/ipv6/ip6_output.c @@ -1385,7 +1385,7 @@ static int __ip6_append_data(struct sock *sk, if length + fragheaderlen) > mtu) || (skb && skb_is_gso(skb))) && (sk->sk_protocol == IPPROTO_UDP) && - (rt->dst.dev->features & NETIF_F_UFO) && !rt->dst.header_len && + (rt->dst.dev->features & NETIF_F_UFO) && !dst_xfrm(&rt->dst) && (sk->sk_type == SOCK_DGRAM) && !udp_get_no_check6_tx(sk)) { err = ip6_ufo_append_data(sk, queue, getfrag, from, length, hh_len, fragheaderlen, exthdrlen, -- 1.7.1
[PATCH net-next] tcp: rename *_sequence_number() to *_seq_and_tsoff()
The functions that are returning tcp sequence number also setup TS offset value, so rename them to better describe their purpose. No functional changes in this patch. Suggested-by: Eric Dumazet Signed-off-by: Alexey Kodanev --- include/net/secure_seq.h |6 +++--- include/net/tcp.h|2 +- net/core/secure_seq.c| 13 ++--- net/ipv4/tcp_input.c |4 ++-- net/ipv4/tcp_ipv4.c | 22 +++--- net/ipv6/tcp_ipv6.c | 22 +++--- 6 files changed, 34 insertions(+), 35 deletions(-) diff --git a/include/net/secure_seq.h b/include/net/secure_seq.h index 0caee63..fe236b3 100644 --- a/include/net/secure_seq.h +++ b/include/net/secure_seq.h @@ -6,10 +6,10 @@ u32 secure_ipv4_port_ephemeral(__be32 saddr, __be32 daddr, __be16 dport); u32 secure_ipv6_port_ephemeral(const __be32 *saddr, const __be32 *daddr, __be16 dport); -u32 secure_tcp_sequence_number(__be32 saddr, __be32 daddr, +u32 secure_tcp_seq_and_tsoff(__be32 saddr, __be32 daddr, +__be16 sport, __be16 dport, u32 *tsoff); +u32 secure_tcpv6_seq_and_tsoff(const __be32 *saddr, const __be32 *daddr, __be16 sport, __be16 dport, u32 *tsoff); -u32 secure_tcpv6_sequence_number(const __be32 *saddr, const __be32 *daddr, -__be16 sport, __be16 dport, u32 *tsoff); u64 secure_dccp_sequence_number(__be32 saddr, __be32 daddr, __be16 sport, __be16 dport); u64 secure_dccpv6_sequence_number(__be32 *saddr, __be32 *daddr, diff --git a/include/net/tcp.h b/include/net/tcp.h index 6ec4ea6..bede8f7 100644 --- a/include/net/tcp.h +++ b/include/net/tcp.h @@ -1816,7 +1816,7 @@ struct tcp_request_sock_ops { struct dst_entry *(*route_req)(const struct sock *sk, struct flowi *fl, const struct request_sock *req, bool *strict); - __u32 (*init_seq)(const struct sk_buff *skb, u32 *tsoff); + __u32 (*init_seq_tsoff)(const struct sk_buff *skb, u32 *tsoff); int (*send_synack)(const struct sock *sk, struct dst_entry *dst, struct flowi *fl, struct request_sock *req, struct tcp_fastopen_cookie *foc, diff --git a/net/core/secure_seq.c b/net/core/secure_seq.c index 758f140..fb87e78 100644 --- a/net/core/secure_seq.c +++ b/net/core/secure_seq.c @@ -45,8 +45,8 @@ static u32 seq_scale(u32 seq) #endif #if IS_ENABLED(CONFIG_IPV6) -u32 secure_tcpv6_sequence_number(const __be32 *saddr, const __be32 *daddr, -__be16 sport, __be16 dport, u32 *tsoff) +u32 secure_tcpv6_seq_and_tsoff(const __be32 *saddr, const __be32 *daddr, + __be16 sport, __be16 dport, u32 *tsoff) { const struct { struct in6_addr saddr; @@ -66,7 +66,7 @@ u32 secure_tcpv6_sequence_number(const __be32 *saddr, const __be32 *daddr, *tsoff = sysctl_tcp_timestamps == 1 ? (hash >> 32) : 0; return seq_scale(hash); } -EXPORT_SYMBOL(secure_tcpv6_sequence_number); +EXPORT_SYMBOL(secure_tcpv6_seq_and_tsoff); u32 secure_ipv6_port_ephemeral(const __be32 *saddr, const __be32 *daddr, __be16 dport) @@ -89,14 +89,13 @@ u32 secure_ipv6_port_ephemeral(const __be32 *saddr, const __be32 *daddr, #ifdef CONFIG_INET -/* secure_tcp_sequence_number(a, b, 0, d) == secure_ipv4_port_ephemeral(a, b, d), +/* secure_tcp_seq_and_tsoff(a, b, 0, d) == secure_ipv4_port_ephemeral(a, b, d), * but fortunately, `sport' cannot be 0 in any circumstances. If this changes, * it would be easy enough to have the former function use siphash_4u32, passing * the arguments as separate u32. */ - -u32 secure_tcp_sequence_number(__be32 saddr, __be32 daddr, - __be16 sport, __be16 dport, u32 *tsoff) +u32 secure_tcp_seq_and_tsoff(__be32 saddr, __be32 daddr, +__be16 sport, __be16 dport, u32 *tsoff) { u64 hash; net_secret_init(); diff --git a/net/ipv4/tcp_input.c b/net/ipv4/tcp_input.c index 39c393c..96b67a8 100644 --- a/net/ipv4/tcp_input.c +++ b/net/ipv4/tcp_input.c @@ -6324,7 +6324,7 @@ int tcp_conn_request(struct request_sock_ops *rsk_ops, goto drop_and_free; if (isn && tmp_opt.tstamp_ok) - af_ops->init_seq(skb, &tcp_rsk(req)->ts_off); + af_ops->init_seq_tsoff(skb, &tcp_rsk(req)->ts_off); if (!want_cookie && !isn) { /* VJ's idea. We save last timestamp seen @@ -6366,7 +6366,7 @@ int tcp_conn_request(struct request_sock_ops *rsk_ops, goto drop_and_release; } - isn = af_ops->init_seq(skb, &tcp_rsk(req)->ts_off); + isn = af_ops->init_seq_tsoff(skb, &tcp_rsk(req)->ts_off); } if (!dst) { dst = af_ops->route_req(sk, &fl
Re: please add some examples to the ip man page
On Wed, Mar 08, 2017 at 03:17:02PM +0800, 積丹尼 Dan Jacobson wrote: > I see. > Perhaps on the man page add > EXAMPLES >See https://www.kernel.org/doc/Documentation/networking/vrf.txt >https://www.google.com/search?q=ip+linux+command+usage+examples > (I thought the latter would be hopeless, but actually found lots!) > Actual examples in the page would better than links IMO. git has some nice examples in gittutorial(7) and giteveryday(7). Maybe that can be good inspiration? -- Mit freundlichen Grüßen Alexander Alemayhu
[PATCH v3 net-next 0/9] prepare mac operations for multiple queues
As agreed with David Miller, this patch-set is the first of 3 to enable multiple queues in stmmac. This first one concentrates on mac operations adding functionalities as: a) Configuration through DT b) RX and TX scheduling algorithms programming b) TX queues weight programming (essential in weightes algorithms) c) RX enable as DCB or AVB (preparing for future AVB support) d) Mapping RX queue to DMA channel e) IRQ treatment prepared for multiple queues f) Debug dump prepared for multiple queues g) CBS configuration In this v3 patch-set version I included a new patch to enable CBS configuration (Patch 9). Joao Pinto (9): net: stmicro: multiple queues dt configuration net: stmicro: configure mtl rx and tx algorithms net: stmicro: configure tx queue weight net: stmicro: mtl rx queue enabled as dcb or avb net: stmicro: mapping mtl rx to dma channel net: stmicro: flow_ctrl functions adapted to mtl net: stmicro: prepare irq_status for mtl net: stmicro: mac debug prepared for multiple queues net: stmicro: configuration of CBS in case of a TX AVB queue Documentation/devicetree/bindings/net/stmmac.txt | 58 +- drivers/net/ethernet/stmicro/stmmac/common.h | 22 ++- .../net/ethernet/stmicro/stmmac/dwmac1000_core.c | 6 +- .../net/ethernet/stmicro/stmmac/dwmac100_core.c| 3 +- drivers/net/ethernet/stmicro/stmmac/dwmac4.h | 59 +- drivers/net/ethernet/stmicro/stmmac/dwmac4_core.c | 204 ++--- .../net/ethernet/stmicro/stmmac/stmmac_ethtool.c | 7 +- drivers/net/ethernet/stmicro/stmmac/stmmac_main.c | 140 -- .../net/ethernet/stmicro/stmmac/stmmac_platform.c | 114 include/linux/stmmac.h | 36 10 files changed, 592 insertions(+), 57 deletions(-) -- 2.9.3
[PATCH v3 net-next 1/9] net: stmicro: multiple queues dt configuration
This patch adds the multiple queues configuration in the Device Tree. It was also created a set of structures to keep the RX and TX queues configurations to be used in the driver. Signed-off-by: Joao Pinto --- Changes v2->v3: - Just to keep up with patch-set version Changes v1->v2: - RX and TX queues child nodes had bad handle Documentation/devicetree/bindings/net/stmmac.txt | 40 ++ .../net/ethernet/stmicro/stmmac/stmmac_platform.c | 91 ++ include/linux/stmmac.h | 30 +++ 3 files changed, 161 insertions(+) diff --git a/Documentation/devicetree/bindings/net/stmmac.txt b/Documentation/devicetree/bindings/net/stmmac.txt index d3bfc2b..4107e67 100644 --- a/Documentation/devicetree/bindings/net/stmmac.txt +++ b/Documentation/devicetree/bindings/net/stmmac.txt @@ -72,6 +72,27 @@ Optional properties: - snps,mb: mixed-burst - snps,rb: rebuild INCRx Burst - mdio: with compatible = "snps,dwmac-mdio", create and register mdio bus. +- Multiple RX Queues parameters: below the list of all the parameters to +configure the multiple RX queues: + - snps,rx-queues-to-use: number of RX queues to be used in the driver + - Choose one of these RX scheduling algorithms: + - snps,rx-sched-sp: Strict priority + - snps,rx-sched-wsp: Weighted Strict priority + - For each RX queue + - Choose one of these modes: + - snps,dcb-algorithm: Queue to be enabled as DCB + - snps,avb-algorithm: Queue to be enabled as AVB + - snps,map-to-dma-channel: Channel to map +- Multiple TX Queues parameters: below the list of all the parameters to +configure the multiple TX queues: + - snps,tx-queues-to-use: number of TX queues to be used in the driver + - Choose one of these TX scheduling algorithms: + - snps,tx-sched-wrr: Weighted Round Robin + - snps,tx-sched-wfq: Weighted Fair Queuing + - snps,tx-sched-dwrr: Deficit Weighted Round Robin + - snps,tx-sched-sp: Strict priority + - For each TX queue + - snps,weight: TX queue weight (if using a weighted algorithm) Examples: @@ -81,6 +102,23 @@ Examples: snps,blen = <256 128 64 32 0 0 0>; }; + mtl_rx_setup: rx-queues-config { + snps,rx-queues-to-use = <1>; + snps,rx-sched-sp; + queue0 { + snps,dcb-algorithm; + snps,map-to-dma-channel = <0x0>; + }; + }; + + mtl_tx_setup: tx-queues-config { + snps,tx-queues-to-use = <1>; + snps,tx-sched-wrr; + queue0 { + snps,weight = <0x10>; + }; + }; + gmac0: ethernet@e080 { compatible = "st,spear600-gmac"; reg = <0xe080 0x8000>; @@ -104,4 +142,6 @@ Examples: phy1: ethernet-phy@0 { }; }; + snps,mtl-rx-config = <&mtl_rx_setup>; + snps,mtl-tx-config = <&mtl_tx_setup>; }; diff --git a/drivers/net/ethernet/stmicro/stmmac/stmmac_platform.c b/drivers/net/ethernet/stmicro/stmmac/stmmac_platform.c index 433a842..ff6af8d 100644 --- a/drivers/net/ethernet/stmicro/stmmac/stmmac_platform.c +++ b/drivers/net/ethernet/stmicro/stmmac/stmmac_platform.c @@ -132,6 +132,95 @@ static struct stmmac_axi *stmmac_axi_setup(struct platform_device *pdev) } /** + * stmmac_mtl_setup - parse DT parameters for multiple queues configuration + * @pdev: platform device + */ +static void stmmac_mtl_setup(struct platform_device *pdev, +struct plat_stmmacenet_data *plat) +{ + struct device_node *q_node; + struct device_node *rx_node; + struct device_node *tx_node; + u8 queue = 0; + + rx_node = of_parse_phandle(pdev->dev.of_node, "snps,mtl-rx-config", 0); + if (!rx_node) + return; + + tx_node = of_parse_phandle(pdev->dev.of_node, "snps,mtl-tx-config", 0); + if (!tx_node) { + of_node_put(rx_node); + return; + } + + /* Processing RX queues common config */ + if (of_property_read_u8(rx_node, "snps,rx-queues-to-use", + &plat->rx_queues_to_use)) + plat->rx_queues_to_use = 1; + + if (of_property_read_bool(rx_node, "snps,rx-sched-sp")) + plat->rx_sched_algorithm = MTL_RX_ALGORITHM_SP; + else if (of_property_read_bool(rx_node, "snps,rx-sched-wsp")) + plat->rx_sched_algorithm = MTL_RX_ALGORITHM_WSP; + else + plat->rx_sched_algorithm = MTL_RX_ALGORITHM_SP; + + /* Processing individual RX queue config */ + for_each_child_of_node(rx_node, q_nod
[PATCH v3 net-next 3/9] net: stmicro: configure tx queue weight
This patch adds TX queues weight programming. Signed-off-by: Joao Pinto --- changes v2->v3: - local variable declarations from longest to shortest line changes v1->v2: - Just to keep up with patch-set version drivers/net/ethernet/stmicro/stmmac/common.h | 3 +++ drivers/net/ethernet/stmicro/stmmac/dwmac4.h | 7 +++ drivers/net/ethernet/stmicro/stmmac/dwmac4_core.c | 13 + drivers/net/ethernet/stmicro/stmmac/stmmac_main.c | 20 4 files changed, 43 insertions(+) diff --git a/drivers/net/ethernet/stmicro/stmmac/common.h b/drivers/net/ethernet/stmicro/stmmac/common.h index 5a0a781..a25b2f8 100644 --- a/drivers/net/ethernet/stmicro/stmmac/common.h +++ b/drivers/net/ethernet/stmicro/stmmac/common.h @@ -459,6 +459,9 @@ struct stmmac_ops { void (*prog_mtl_rx_algorithms)(struct mac_device_info *hw, u32 rx_alg); /* Program TX Algorithms */ void (*prog_mtl_tx_algorithms)(struct mac_device_info *hw, u32 tx_alg); + /* Set MTL TX queues weight */ + void (*set_mtl_tx_queue_weight)(struct mac_device_info *hw, + u32 weight, u32 queue); /* Dump MAC registers */ void (*dump_regs)(struct mac_device_info *hw, u32 *reg_space); /* Handle extra events on specific interrupts hw dependent */ diff --git a/drivers/net/ethernet/stmicro/stmmac/dwmac4.h b/drivers/net/ethernet/stmicro/stmmac/dwmac4.h index 748ab6f..7d77e78 100644 --- a/drivers/net/ethernet/stmicro/stmmac/dwmac4.h +++ b/drivers/net/ethernet/stmicro/stmmac/dwmac4.h @@ -211,6 +211,13 @@ enum power_event { #define MTL_OP_MODE_RTC_96 (2 << MTL_OP_MODE_RTC_SHIFT) #define MTL_OP_MODE_RTC_128(3 << MTL_OP_MODE_RTC_SHIFT) +/* MTL Queue Quantum Weight */ +#define MTL_TXQ_WEIGHT_BASE_ADDR 0x0d18 +#define MTL_TXQ_WEIGHT_BASE_OFFSET 0x40 +#define MTL_TXQX_WEIGHT_BASE_ADDR(x) (MTL_TXQ_WEIGHT_BASE_ADDR + \ + ((x) * MTL_TXQ_WEIGHT_BASE_OFFSET)) +#define MTL_TXQ_WEIGHT_ISCQW_MASK GENMASK(20, 0) + /* MTL debug */ #define MTL_DEBUG_TXSTSFSTSBIT(5) #define MTL_DEBUG_TXFSTS BIT(4) diff --git a/drivers/net/ethernet/stmicro/stmmac/dwmac4_core.c b/drivers/net/ethernet/stmicro/stmmac/dwmac4_core.c index 0fb5c8a..6f59751 100644 --- a/drivers/net/ethernet/stmicro/stmmac/dwmac4_core.c +++ b/drivers/net/ethernet/stmicro/stmmac/dwmac4_core.c @@ -116,6 +116,18 @@ static void dwmac4_prog_mtl_tx_algorithms(struct mac_device_info *hw, } } +static void dwmac4_set_mtl_tx_queue_weight(struct mac_device_info *hw, + u32 weight, u32 queue) +{ + void __iomem *ioaddr = hw->pcsr; + u32 value = 0; + + value = readl(ioaddr + MTL_TXQX_WEIGHT_BASE_ADDR(queue)); + value &= ~MTL_TXQ_WEIGHT_ISCQW_MASK; + value |= weight & MTL_TXQ_WEIGHT_ISCQW_MASK; + writel(value, ioaddr + MTL_TXQX_WEIGHT_BASE_ADDR(queue)); +} + static void dwmac4_dump_regs(struct mac_device_info *hw, u32 *reg_space) { void __iomem *ioaddr = hw->pcsr; @@ -505,6 +517,7 @@ static const struct stmmac_ops dwmac4_ops = { .rx_queue_enable = dwmac4_rx_queue_enable, .prog_mtl_rx_algorithms = dwmac4_prog_mtl_rx_algorithms, .prog_mtl_tx_algorithms = dwmac4_prog_mtl_tx_algorithms, + .set_mtl_tx_queue_weight = dwmac4_set_mtl_tx_queue_weight, .dump_regs = dwmac4_dump_regs, .host_irq_status = dwmac4_irq_status, .flow_ctrl = dwmac4_flow_ctrl, diff --git a/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c b/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c index af57f8d..1ad6957 100644 --- a/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c +++ b/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c @@ -1645,6 +1645,23 @@ static void stmmac_init_tx_coalesce(struct stmmac_priv *priv) } /** + * stmmac_set_tx_queue_weight - Set TX queue weight + * @priv: driver private structure + * Description: It is used for setting TX queues weight + */ +static void stmmac_set_tx_queue_weight(struct stmmac_priv *priv) +{ + u32 tx_queues_count = priv->plat->tx_queues_to_use; + u32 weight = 0; + u32 queue = 0; + + for (queue = 0; queue < tx_queues_count; queue++) { + weight = priv->plat->tx_queues_cfg[queue].weight; + priv->hw->mac->set_mtl_tx_queue_weight(priv->hw, weight, queue); + } +} + +/** * stmmac_mtl_configuration - Configure MTL * @priv: driver private structure * Description: It is used for configurring MTL @@ -1654,6 +1671,9 @@ static void stmmac_mtl_configuration(struct stmmac_priv *priv) u32 rx_queues_count = priv->plat->rx_queues_to_use; u32 tx_queues_count = priv->plat->tx_queues_to_use; + if (tx_queues_count > 1 && priv->hw->mac->set_mtl_tx_queue_weight) + stmmac_set_tx_queue_weight(priv); + /* Configure MTL RX algorithms */ if (rx
[PATCH v3 net-next 4/9] net: stmicro: mtl rx queue enabled as dcb or avb
This patch introduces the enabling of RX queues as DCB or as AVB based on configuration. Signed-off-by: Joao Pinto --- changes v1->v3: - Just to keep up with patch-set version drivers/net/ethernet/stmicro/stmmac/common.h | 2 +- drivers/net/ethernet/stmicro/stmmac/dwmac4_core.c | 8 ++-- drivers/net/ethernet/stmicro/stmmac/stmmac_main.c | 17 ++--- 3 files changed, 13 insertions(+), 14 deletions(-) diff --git a/drivers/net/ethernet/stmicro/stmmac/common.h b/drivers/net/ethernet/stmicro/stmmac/common.h index a25b2f8..ad89c47 100644 --- a/drivers/net/ethernet/stmicro/stmmac/common.h +++ b/drivers/net/ethernet/stmicro/stmmac/common.h @@ -454,7 +454,7 @@ struct stmmac_ops { /* Enable and verify that the IPC module is supported */ int (*rx_ipc)(struct mac_device_info *hw); /* Enable RX Queues */ - void (*rx_queue_enable)(struct mac_device_info *hw, u32 queue); + void (*rx_queue_enable)(struct mac_device_info *hw, u8 mode, u32 queue); /* Program RX Algorithms */ void (*prog_mtl_rx_algorithms)(struct mac_device_info *hw, u32 rx_alg); /* Program TX Algorithms */ diff --git a/drivers/net/ethernet/stmicro/stmmac/dwmac4_core.c b/drivers/net/ethernet/stmicro/stmmac/dwmac4_core.c index 6f59751..04d0fa3 100644 --- a/drivers/net/ethernet/stmicro/stmmac/dwmac4_core.c +++ b/drivers/net/ethernet/stmicro/stmmac/dwmac4_core.c @@ -59,13 +59,17 @@ static void dwmac4_core_init(struct mac_device_info *hw, int mtu) writel(value, ioaddr + GMAC_INT_EN); } -static void dwmac4_rx_queue_enable(struct mac_device_info *hw, u32 queue) +static void dwmac4_rx_queue_enable(struct mac_device_info *hw, + u8 mode, u32 queue) { void __iomem *ioaddr = hw->pcsr; u32 value = readl(ioaddr + GMAC_RXQ_CTRL0); value &= GMAC_RX_QUEUE_CLEAR(queue); - value |= GMAC_RX_AV_QUEUE_ENABLE(queue); + if (mode == MTL_RX_AVB) + value |= GMAC_RX_AV_QUEUE_ENABLE(queue); + else if (mode == MTL_RX_DCB) + value |= GMAC_RX_DCB_QUEUE_ENABLE(queue); writel(value, ioaddr + GMAC_RXQ_CTRL0); } diff --git a/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c b/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c index 1ad6957..17faa1f 100644 --- a/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c +++ b/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c @@ -1256,19 +1256,14 @@ static void free_dma_desc_resources(struct stmmac_priv *priv) */ static void stmmac_mac_enable_rx_queues(struct stmmac_priv *priv) { - int rx_count = priv->dma_cap.number_rx_queues; + u32 rx_queues_count = priv->plat->rx_queues_to_use; int queue = 0; + u8 mode = 0; - /* If GMAC does not have multiple queues, then this is not necessary*/ - if (rx_count == 1) - return; - - /** -* If the core is synthesized with multiple rx queues / multiple -* dma channels, then rx queues will be disabled by default. -* For now only rx queue 0 is enabled. -*/ - priv->hw->mac->rx_queue_enable(priv->hw, queue); + for (queue = 0; queue < rx_queues_count; queue++) { + mode = priv->plat->rx_queues_cfg[queue].mode_to_use; + priv->hw->mac->rx_queue_enable(priv->hw, mode, queue); + } } /** -- 2.9.3
[PATCH v3 net-next 8/9] net: stmicro: mac debug prepared for multiple queues
This patch prepares mac debug dump for multiple queues. Signed-off-by: Joao Pinto --- changes v1->v3: - Just to keep up with patch-set version drivers/net/ethernet/stmicro/stmmac/common.h | 3 ++- drivers/net/ethernet/stmicro/stmmac/dwmac1000_core.c | 3 ++- drivers/net/ethernet/stmicro/stmmac/dwmac4_core.c| 10 -- drivers/net/ethernet/stmicro/stmmac/stmmac_ethtool.c | 4 +++- 4 files changed, 11 insertions(+), 9 deletions(-) diff --git a/drivers/net/ethernet/stmicro/stmmac/common.h b/drivers/net/ethernet/stmicro/stmmac/common.h index 6a348d3..d7bb498 100644 --- a/drivers/net/ethernet/stmicro/stmmac/common.h +++ b/drivers/net/ethernet/stmicro/stmmac/common.h @@ -488,7 +488,8 @@ struct stmmac_ops { void (*reset_eee_mode)(struct mac_device_info *hw); void (*set_eee_timer)(struct mac_device_info *hw, int ls, int tw); void (*set_eee_pls)(struct mac_device_info *hw, int link); - void (*debug)(void __iomem *ioaddr, struct stmmac_extra_stats *x); + void (*debug)(void __iomem *ioaddr, struct stmmac_extra_stats *x, + u32 queue); /* PCS calls */ void (*pcs_ctrl_ane)(void __iomem *ioaddr, bool ane, bool srgmi_ral, bool loopback); diff --git a/drivers/net/ethernet/stmicro/stmmac/dwmac1000_core.c b/drivers/net/ethernet/stmicro/stmmac/dwmac1000_core.c index 3a95ad9..0ebb69f 100644 --- a/drivers/net/ethernet/stmicro/stmmac/dwmac1000_core.c +++ b/drivers/net/ethernet/stmicro/stmmac/dwmac1000_core.c @@ -413,7 +413,8 @@ static void dwmac1000_get_adv_lp(void __iomem *ioaddr, struct rgmii_adv *adv) dwmac_get_adv_lp(ioaddr, GMAC_PCS_BASE, adv); } -static void dwmac1000_debug(void __iomem *ioaddr, struct stmmac_extra_stats *x) +static void dwmac1000_debug(void __iomem *ioaddr, struct stmmac_extra_stats *x, + u32 queue) { u32 value = readl(ioaddr + GMAC_DEBUG); diff --git a/drivers/net/ethernet/stmicro/stmmac/dwmac4_core.c b/drivers/net/ethernet/stmicro/stmmac/dwmac4_core.c index be83602..7f0631c 100644 --- a/drivers/net/ethernet/stmicro/stmmac/dwmac4_core.c +++ b/drivers/net/ethernet/stmicro/stmmac/dwmac4_core.c @@ -468,12 +468,10 @@ static int dwmac4_irq_status(struct mac_device_info *hw, return ret; } -static void dwmac4_debug(void __iomem *ioaddr, struct stmmac_extra_stats *x) +static void dwmac4_debug(void __iomem *ioaddr, struct stmmac_extra_stats *x, +u32 queue) { - u32 value; - - /* Currently only channel 0 is supported */ - value = readl(ioaddr + MTL_CHAN_TX_DEBUG(STMMAC_CHAN0)); + u32 value = readl(ioaddr + MTL_CHAN_TX_DEBUG(queue)); if (value & MTL_DEBUG_TXSTSFSTS) x->mtl_tx_status_fifo_full++; @@ -496,7 +494,7 @@ static void dwmac4_debug(void __iomem *ioaddr, struct stmmac_extra_stats *x) if (value & MTL_DEBUG_TXPAUSED) x->mac_tx_in_pause++; - value = readl(ioaddr + MTL_CHAN_RX_DEBUG(STMMAC_CHAN0)); + value = readl(ioaddr + MTL_CHAN_RX_DEBUG(queue)); if (value & MTL_DEBUG_RXFSTS_MASK) { u32 rxfsts = (value & MTL_DEBUG_RXFSTS_MASK) diff --git a/drivers/net/ethernet/stmicro/stmmac/stmmac_ethtool.c b/drivers/net/ethernet/stmicro/stmmac/stmmac_ethtool.c index 4a5dc89..09a714b 100644 --- a/drivers/net/ethernet/stmicro/stmmac/stmmac_ethtool.c +++ b/drivers/net/ethernet/stmicro/stmmac/stmmac_ethtool.c @@ -520,6 +520,7 @@ static void stmmac_get_ethtool_stats(struct net_device *dev, struct ethtool_stats *dummy, u64 *data) { struct stmmac_priv *priv = netdev_priv(dev); + u32 queue = 0; int i, j = 0; /* Update the DMA HW counters for dwmac10/100 */ @@ -550,7 +551,8 @@ static void stmmac_get_ethtool_stats(struct net_device *dev, if ((priv->hw->mac->debug) && (priv->synopsys_id >= DWMAC_CORE_3_50)) priv->hw->mac->debug(priv->ioaddr, -(void *)&priv->xstats); +(void *)&priv->xstats, +queue); } for (i = 0; i < STMMAC_STATS_LEN; i++) { char *p = (char *)priv + stmmac_gstrings_stats[i].stat_offset; -- 2.9.3
[PATCH v3 net-next 6/9] net: stmicro: flow_ctrl functions adapted to mtl
This patch adapts flow_ctrl function to prepare it for multiple queues. Signed-off-by: Joao Pinto --- changes v1->v3: - Just to keep up with patch-set version drivers/net/ethernet/stmicro/stmmac/common.h | 2 +- drivers/net/ethernet/stmicro/stmmac/dwmac1000_core.c | 3 ++- drivers/net/ethernet/stmicro/stmmac/dwmac100_core.c | 3 ++- drivers/net/ethernet/stmicro/stmmac/dwmac4_core.c| 20 +--- drivers/net/ethernet/stmicro/stmmac/stmmac_ethtool.c | 3 ++- drivers/net/ethernet/stmicro/stmmac/stmmac_main.c| 17 ++--- 6 files changed, 34 insertions(+), 14 deletions(-) diff --git a/drivers/net/ethernet/stmicro/stmmac/common.h b/drivers/net/ethernet/stmicro/stmmac/common.h index 32f5f25..5532633 100644 --- a/drivers/net/ethernet/stmicro/stmmac/common.h +++ b/drivers/net/ethernet/stmicro/stmmac/common.h @@ -473,7 +473,7 @@ struct stmmac_ops { void (*set_filter)(struct mac_device_info *hw, struct net_device *dev); /* Flow control setting */ void (*flow_ctrl)(struct mac_device_info *hw, unsigned int duplex, - unsigned int fc, unsigned int pause_time); + unsigned int fc, unsigned int pause_time, u32 tx_cnt); /* Set power management mode (e.g. magic frame) */ void (*pmt)(struct mac_device_info *hw, unsigned long mode); /* Set/Get Unicast MAC addresses */ diff --git a/drivers/net/ethernet/stmicro/stmmac/dwmac1000_core.c b/drivers/net/ethernet/stmicro/stmmac/dwmac1000_core.c index 19b9b30..3a95ad9 100644 --- a/drivers/net/ethernet/stmicro/stmmac/dwmac1000_core.c +++ b/drivers/net/ethernet/stmicro/stmmac/dwmac1000_core.c @@ -216,7 +216,8 @@ static void dwmac1000_set_filter(struct mac_device_info *hw, static void dwmac1000_flow_ctrl(struct mac_device_info *hw, unsigned int duplex, - unsigned int fc, unsigned int pause_time) + unsigned int fc, unsigned int pause_time, + u32 tx_cnt) { void __iomem *ioaddr = hw->pcsr; /* Set flow such that DZPQ in Mac Register 6 is 0, diff --git a/drivers/net/ethernet/stmicro/stmmac/dwmac100_core.c b/drivers/net/ethernet/stmicro/stmmac/dwmac100_core.c index e370cce..524135e 100644 --- a/drivers/net/ethernet/stmicro/stmmac/dwmac100_core.c +++ b/drivers/net/ethernet/stmicro/stmmac/dwmac100_core.c @@ -131,7 +131,8 @@ static void dwmac100_set_filter(struct mac_device_info *hw, } static void dwmac100_flow_ctrl(struct mac_device_info *hw, unsigned int duplex, - unsigned int fc, unsigned int pause_time) + unsigned int fc, unsigned int pause_time, + u32 tx_cnt) { void __iomem *ioaddr = hw->pcsr; unsigned int flow = MAC_FLOW_CTRL_ENABLE; diff --git a/drivers/net/ethernet/stmicro/stmmac/dwmac4_core.c b/drivers/net/ethernet/stmicro/stmmac/dwmac4_core.c index 3eed2c8..5caed2a 100644 --- a/drivers/net/ethernet/stmicro/stmmac/dwmac4_core.c +++ b/drivers/net/ethernet/stmicro/stmmac/dwmac4_core.c @@ -337,11 +337,12 @@ static void dwmac4_set_filter(struct mac_device_info *hw, } static void dwmac4_flow_ctrl(struct mac_device_info *hw, unsigned int duplex, -unsigned int fc, unsigned int pause_time) +unsigned int fc, unsigned int pause_time, +u32 tx_cnt) { void __iomem *ioaddr = hw->pcsr; - u32 channel = STMMAC_CHAN0; /* FIXME */ unsigned int flow = 0; + u32 queue = 0; pr_debug("GMAC Flow-Control:\n"); if (fc & FLOW_RX) { @@ -351,13 +352,18 @@ static void dwmac4_flow_ctrl(struct mac_device_info *hw, unsigned int duplex, } if (fc & FLOW_TX) { pr_debug("\tTransmit Flow-Control ON\n"); - flow |= GMAC_TX_FLOW_CTRL_TFE; - writel(flow, ioaddr + GMAC_QX_TX_FLOW_CTRL(channel)); - if (duplex) { + if (duplex) pr_debug("\tduplex mode: PAUSE %d\n", pause_time); - flow |= (pause_time << GMAC_TX_FLOW_CTRL_PT_SHIFT); - writel(flow, ioaddr + GMAC_QX_TX_FLOW_CTRL(channel)); + + for (queue = 0; queue < tx_cnt; queue++) { + flow |= GMAC_TX_FLOW_CTRL_TFE; + + if (duplex) + flow |= + (pause_time << GMAC_TX_FLOW_CTRL_PT_SHIFT); + + writel(flow, ioaddr + GMAC_QX_TX_FLOW_CTRL(queue)); } } } diff --git a/drivers/net/ethernet/stmicro/stmmac/stmmac_ethtool.c b/drivers/net/ethernet/stmicro/stmmac/stmmac_ethtool.c index 85d6411..4a5dc89 100644 --- a/drivers/net/ethernet/stmicro/stmmac/stmmac_ethtool.c +++ b/drivers/net/ethernet/stmicro/stmmac/stmmac_ethtool.c @@ -481,6 +481,7 @@ stmmac_set_pauseparam(struct net_device
[PATCH v3 net-next 5/9] net: stmicro: mapping mtl rx to dma channel
This patch adds the functionality of RX queue to dma channel mapping based on configuration. Signed-off-by: Joao Pinto --- changes v1->v3: - Just to keep up with patch-set version drivers/net/ethernet/stmicro/stmmac/common.h | 2 ++ drivers/net/ethernet/stmicro/stmmac/dwmac4.h | 7 +++ drivers/net/ethernet/stmicro/stmmac/dwmac4_core.c | 25 +++ drivers/net/ethernet/stmicro/stmmac/stmmac_main.c | 21 +++ 4 files changed, 55 insertions(+) diff --git a/drivers/net/ethernet/stmicro/stmmac/common.h b/drivers/net/ethernet/stmicro/stmmac/common.h index ad89c47..32f5f25 100644 --- a/drivers/net/ethernet/stmicro/stmmac/common.h +++ b/drivers/net/ethernet/stmicro/stmmac/common.h @@ -462,6 +462,8 @@ struct stmmac_ops { /* Set MTL TX queues weight */ void (*set_mtl_tx_queue_weight)(struct mac_device_info *hw, u32 weight, u32 queue); + /* RX MTL queue to RX dma mapping */ + void (*map_mtl_to_dma)(struct mac_device_info *hw, u32 queue, u32 chan); /* Dump MAC registers */ void (*dump_regs)(struct mac_device_info *hw, u32 *reg_space); /* Handle extra events on specific interrupts hw dependent */ diff --git a/drivers/net/ethernet/stmicro/stmmac/dwmac4.h b/drivers/net/ethernet/stmicro/stmmac/dwmac4.h index 7d77e78..9dd8ac1 100644 --- a/drivers/net/ethernet/stmicro/stmmac/dwmac4.h +++ b/drivers/net/ethernet/stmicro/stmmac/dwmac4.h @@ -174,6 +174,13 @@ enum power_event { #define MTL_INT_STATUS 0x0c20 #define MTL_INT_Q0 BIT(0) +#define MTL_RXQ_DMA_MAP0 0x0c30 /* queue 0 to 3 */ +#define MTL_RXQ_DMA_MAP1 0x0c34 /* queue 4 to 7 */ +#define MTL_RXQ_DMA_Q04MDMACH_MASK GENMASK(3, 0) +#define MTL_RXQ_DMA_Q04MDMACH(x) ((x) << 0) +#define MTL_RXQ_DMA_QXMDMACH_MASK(x) GENMASK(11 + (8 * ((x) - 1)), 8 * (x)) +#define MTL_RXQ_DMA_QXMDMACH(chan, q) ((chan) << (8 * (q))) + #define MTL_CHAN_BASE_ADDR 0x0d00 #define MTL_CHAN_BASE_OFFSET 0x40 #define MTL_CHANX_BASE_ADDR(x) (MTL_CHAN_BASE_ADDR + \ diff --git a/drivers/net/ethernet/stmicro/stmmac/dwmac4_core.c b/drivers/net/ethernet/stmicro/stmmac/dwmac4_core.c index 04d0fa3..3eed2c8 100644 --- a/drivers/net/ethernet/stmicro/stmmac/dwmac4_core.c +++ b/drivers/net/ethernet/stmicro/stmmac/dwmac4_core.c @@ -132,6 +132,30 @@ static void dwmac4_set_mtl_tx_queue_weight(struct mac_device_info *hw, writel(value, ioaddr + MTL_TXQX_WEIGHT_BASE_ADDR(queue)); } +static void dwmac4_map_mtl_dma(struct mac_device_info *hw, u32 queue, u32 chan) +{ + void __iomem *ioaddr = hw->pcsr; + u32 value = 0; + + if (queue < 4) + value = readl(ioaddr + MTL_RXQ_DMA_MAP0); + else + value = readl(ioaddr + MTL_RXQ_DMA_MAP1); + + if (queue == 0 || queue == 4) { + value &= ~MTL_RXQ_DMA_Q04MDMACH_MASK; + value |= MTL_RXQ_DMA_Q04MDMACH(chan); + } else { + value &= ~MTL_RXQ_DMA_QXMDMACH_MASK(queue); + value |= MTL_RXQ_DMA_QXMDMACH(chan, queue); + } + + if (queue < 4) + writel(value, ioaddr + MTL_RXQ_DMA_MAP0); + else + writel(value, ioaddr + MTL_RXQ_DMA_MAP1); +} + static void dwmac4_dump_regs(struct mac_device_info *hw, u32 *reg_space) { void __iomem *ioaddr = hw->pcsr; @@ -522,6 +546,7 @@ static const struct stmmac_ops dwmac4_ops = { .prog_mtl_rx_algorithms = dwmac4_prog_mtl_rx_algorithms, .prog_mtl_tx_algorithms = dwmac4_prog_mtl_tx_algorithms, .set_mtl_tx_queue_weight = dwmac4_set_mtl_tx_queue_weight, + .map_mtl_to_dma = dwmac4_map_mtl_dma, .dump_regs = dwmac4_dump_regs, .host_irq_status = dwmac4_irq_status, .flow_ctrl = dwmac4_flow_ctrl, diff --git a/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c b/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c index 17faa1f..610e7fd 100644 --- a/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c +++ b/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c @@ -1657,6 +1657,23 @@ static void stmmac_set_tx_queue_weight(struct stmmac_priv *priv) } /** + * stmmac_rx_queue_dma_chan_map - Map RX queue to RX dma channel + * @priv: driver private structure + * Description: It is used for mapping RX queues to RX dma channels + */ +static void stmmac_rx_queue_dma_chan_map(struct stmmac_priv *priv) +{ + u32 rx_queues_count = priv->plat->rx_queues_to_use; + u32 queue = 0; + u32 chan = 0; + + for (queue = 0; queue < rx_queues_count; queue++) { + chan = priv->plat->rx_queues_cfg[queue].chan; + priv->hw->mac->map_mtl_to_dma(priv->hw, queue, chan); + } +} + +/** * stmmac_mtl_configuration - Configure MTL * @priv: driver private structure * Description: It is used for configurring MTL @@ -1679,6 +1696,10 @@ static void s
[PATCH v3 net-next 7/9] net: stmicro: prepare irq_status for mtl
This patch prepares mac irq status treatment for multiple queues. Signed-off-by: Joao Pinto --- changes v2->v3: - local variable declarations from longest to shortest line changes v1->v2: - Just to keep up with patch-set version drivers/net/ethernet/stmicro/stmmac/common.h | 2 ++ drivers/net/ethernet/stmicro/stmmac/dwmac4.h | 2 +- drivers/net/ethernet/stmicro/stmmac/dwmac4_core.c | 38 ++- drivers/net/ethernet/stmicro/stmmac/stmmac_main.c | 5 +++ 4 files changed, 31 insertions(+), 16 deletions(-) diff --git a/drivers/net/ethernet/stmicro/stmmac/common.h b/drivers/net/ethernet/stmicro/stmmac/common.h index 5532633..6a348d3 100644 --- a/drivers/net/ethernet/stmicro/stmmac/common.h +++ b/drivers/net/ethernet/stmicro/stmmac/common.h @@ -469,6 +469,8 @@ struct stmmac_ops { /* Handle extra events on specific interrupts hw dependent */ int (*host_irq_status)(struct mac_device_info *hw, struct stmmac_extra_stats *x); + /* Handle MTL interrupts */ + int (*host_mtl_irq_status)(struct mac_device_info *hw, u32 chan); /* Multicast filter setting */ void (*set_filter)(struct mac_device_info *hw, struct net_device *dev); /* Flow control setting */ diff --git a/drivers/net/ethernet/stmicro/stmmac/dwmac4.h b/drivers/net/ethernet/stmicro/stmmac/dwmac4.h index 9dd8ac1..5ca4d64 100644 --- a/drivers/net/ethernet/stmicro/stmmac/dwmac4.h +++ b/drivers/net/ethernet/stmicro/stmmac/dwmac4.h @@ -172,7 +172,7 @@ enum power_event { #define MTL_OPERATION_RAA_WSP (0x1 << 2) #define MTL_INT_STATUS 0x0c20 -#define MTL_INT_Q0 BIT(0) +#define MTL_INT_QX(x) BIT(x) #define MTL_RXQ_DMA_MAP0 0x0c30 /* queue 0 to 3 */ #define MTL_RXQ_DMA_MAP1 0x0c34 /* queue 4 to 7 */ diff --git a/drivers/net/ethernet/stmicro/stmmac/dwmac4_core.c b/drivers/net/ethernet/stmicro/stmmac/dwmac4_core.c index 5caed2a..be83602 100644 --- a/drivers/net/ethernet/stmicro/stmmac/dwmac4_core.c +++ b/drivers/net/ethernet/stmicro/stmmac/dwmac4_core.c @@ -417,11 +417,32 @@ static void dwmac4_phystatus(void __iomem *ioaddr, struct stmmac_extra_stats *x) } } +static int dwmac4_irq_mtl_status(struct mac_device_info *hw, u32 chan) +{ + u32 mtl_int_qx_status = readl(ioaddr + MTL_INT_STATUS); + void __iomem *ioaddr = hw->pcsr; + int ret = 0; + + /* Check MTL Interrupt */ + if (mtl_int_qx_status & MTL_INT_QX(chan)) { + /* read Queue x Interrupt status */ + u32 status = readl(ioaddr + MTL_CHAN_INT_CTRL(chan)); + + if (status & MTL_RX_OVERFLOW_INT) { + /* clear Interrupt */ + writel(status | MTL_RX_OVERFLOW_INT, + ioaddr + MTL_CHAN_INT_CTRL(chan)); + ret = CORE_IRQ_MTL_RX_OVERFLOW; + } + } + + return ret; +} + static int dwmac4_irq_status(struct mac_device_info *hw, struct stmmac_extra_stats *x) { void __iomem *ioaddr = hw->pcsr; - u32 mtl_int_qx_status; u32 intr_status; int ret = 0; @@ -440,20 +461,6 @@ static int dwmac4_irq_status(struct mac_device_info *hw, x->irq_receive_pmt_irq_n++; } - mtl_int_qx_status = readl(ioaddr + MTL_INT_STATUS); - /* Check MTL Interrupt: Currently only one queue is used: Q0. */ - if (mtl_int_qx_status & MTL_INT_Q0) { - /* read Queue 0 Interrupt status */ - u32 status = readl(ioaddr + MTL_CHAN_INT_CTRL(STMMAC_CHAN0)); - - if (status & MTL_RX_OVERFLOW_INT) { - /* clear Interrupt */ - writel(status | MTL_RX_OVERFLOW_INT, - ioaddr + MTL_CHAN_INT_CTRL(STMMAC_CHAN0)); - ret = CORE_IRQ_MTL_RX_OVERFLOW; - } - } - dwmac_pcs_isr(ioaddr, GMAC_PCS_BASE, intr_status, x); if (intr_status & PCS_RGSMIIIS_IRQ) dwmac4_phystatus(ioaddr, x); @@ -555,6 +562,7 @@ static const struct stmmac_ops dwmac4_ops = { .map_mtl_to_dma = dwmac4_map_mtl_dma, .dump_regs = dwmac4_dump_regs, .host_irq_status = dwmac4_irq_status, + .host_mtl_irq_status = dwmac4_irq_mtl_status, .flow_ctrl = dwmac4_flow_ctrl, .pmt = dwmac4_pmt, .set_umac_addr = dwmac4_set_umac_addr, diff --git a/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c b/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c index d6c7b036..09380a2 100644 --- a/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c +++ b/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c @@ -2880,6 +2880,11 @@ static irqreturn_t stmmac_interrupt(int irq, void *dev_id) if ((priv->plat->has_gmac) || (priv->plat->has_gmac4)) { int status = priv->hw->mac->host_irq
[PATCH v3 net-next 9/9] net: stmicro: configuration of CBS in case of a TX AVB queue
This patch adds the configuration of the AVB Credit-Based Shaper. Signed-off-by: Joao Pinto --- changes v1->v3: - Added in v3 Documentation/devicetree/bindings/net/stmmac.txt | 22 +-- drivers/net/ethernet/stmicro/stmmac/common.h | 4 ++ drivers/net/ethernet/stmicro/stmmac/dwmac4.h | 33 drivers/net/ethernet/stmicro/stmmac/dwmac4_core.c | 46 +- drivers/net/ethernet/stmicro/stmmac/stmmac_main.c | 29 ++ .../net/ethernet/stmicro/stmmac/stmmac_platform.c | 29 -- include/linux/stmmac.h | 12 -- 7 files changed, 164 insertions(+), 11 deletions(-) diff --git a/Documentation/devicetree/bindings/net/stmmac.txt b/Documentation/devicetree/bindings/net/stmmac.txt index 4107e67..9b4d5dd 100644 --- a/Documentation/devicetree/bindings/net/stmmac.txt +++ b/Documentation/devicetree/bindings/net/stmmac.txt @@ -92,8 +92,15 @@ Optional properties: - snps,tx-sched-dwrr: Deficit Weighted Round Robin - snps,tx-sched-sp: Strict priority - For each TX queue - - snps,weight: TX queue weight (if using a weighted algorithm) - + - snps,weight: TX queue weight (if using a DCB weight algorithm) + - Choose one of these modes: + - snps,dcb-algorithm: TX queue will be working in DCB + - snps,avb-algorithm: TX queue will be working in AVB + - Configure Credit Base Shaper (if AVB Mode selected): + - snps,send_slope: enable Low Power Interface + - snps,idle_slope: unlock on WoL + - snps,high_credit: max write outstanding req. limit + - snps,low_credit: max read outstanding req. limit Examples: stmmac_axi_setup: stmmac-axi-config { @@ -112,10 +119,19 @@ Examples: }; mtl_tx_setup: tx-queues-config { - snps,tx-queues-to-use = <1>; + snps,tx-queues-to-use = <2>; snps,tx-sched-wrr; queue0 { snps,weight = <0x10>; + snps,dcb-algorithm; + }; + + queue1 { + snps,avb-algorithm; + snps,send_slope = <0x1000>; + snps,idle_slope = <0x1000>; + snps,high_credit = <0x3E800>; + snps,low_credit = <0xFFC18000>; }; }; diff --git a/drivers/net/ethernet/stmicro/stmmac/common.h b/drivers/net/ethernet/stmicro/stmmac/common.h index d7bb498..62449b0 100644 --- a/drivers/net/ethernet/stmicro/stmmac/common.h +++ b/drivers/net/ethernet/stmicro/stmmac/common.h @@ -464,6 +464,10 @@ struct stmmac_ops { u32 weight, u32 queue); /* RX MTL queue to RX dma mapping */ void (*map_mtl_to_dma)(struct mac_device_info *hw, u32 queue, u32 chan); + /* Configure AV Algorithm */ + void (*config_cbs)(struct mac_device_info *hw, u32 send_slope, + u32 idle_slope, u32 high_credit, u32 low_credit, + u32 queue); /* Dump MAC registers */ void (*dump_regs)(struct mac_device_info *hw, u32 *reg_space); /* Handle extra events on specific interrupts hw dependent */ diff --git a/drivers/net/ethernet/stmicro/stmmac/dwmac4.h b/drivers/net/ethernet/stmicro/stmmac/dwmac4.h index 5ca4d64..cf0e602 100644 --- a/drivers/net/ethernet/stmicro/stmmac/dwmac4.h +++ b/drivers/net/ethernet/stmicro/stmmac/dwmac4.h @@ -218,6 +218,15 @@ enum power_event { #define MTL_OP_MODE_RTC_96 (2 << MTL_OP_MODE_RTC_SHIFT) #define MTL_OP_MODE_RTC_128(3 << MTL_OP_MODE_RTC_SHIFT) +/* MTL ETS Control register */ +#define MTL_ETS_CTRL_BASE_ADDR 0x0d10 +#define MTL_ETS_CTRL_BASE_OFFSET 0x40 +#define MTL_ETSX_CTRL_BASE_ADDR(x) (MTL_ETS_CTRL_BASE_ADDR + \ + ((x) * MTL_ETS_CTRL_BASE_OFFSET)) + +#define MTL_ETS_CTRL_CCBIT(3) +#define MTL_ETS_CTRL_AVALG BIT(2) + /* MTL Queue Quantum Weight */ #define MTL_TXQ_WEIGHT_BASE_ADDR 0x0d18 #define MTL_TXQ_WEIGHT_BASE_OFFSET 0x40 @@ -225,6 +234,30 @@ enum power_event { ((x) * MTL_TXQ_WEIGHT_BASE_OFFSET)) #define MTL_TXQ_WEIGHT_ISCQW_MASK GENMASK(20, 0) +/* MTL sendSlopeCredit register */ +#define MTL_SEND_SLP_CRED_BASE_ADDR0x0d1c +#define MTL_SEND_SLP_CRED_OFFSET 0x40 +#define MTL_SEND_SLP_CREDX_BASE_ADDR(x)(MTL_SEND_SLP_CRED_BASE_ADDR + \ + ((x) * MTL_SEND_SLP_CRED_OFFSET)) + +#define MTL_SEND_SLP_CRED_SSC_MASK GENMASK(13, 0) + +/* MTL hiCredit register */ +#define MTL_HIGH_CRED_BASE_ADDR0x0d20 +#define MTL_HIGH_CRED_OFFSET 0x40 +#define M
[PATCH v3 net-next 2/9] net: stmicro: configure mtl rx and tx algorithms
This patch adds the RX and TX scheduling algorithms programming. It introduces the multiple queues configuration function (stmmac_mtl_configuration) in stmmac_main. Signed-off-by: Joao Pinto --- Changes v2->v3: - Switch statements with a tab Changes v1->v2: - Just to keep up with patch-set version drivers/net/ethernet/stmicro/stmmac/common.h | 4 ++ drivers/net/ethernet/stmicro/stmmac/dwmac4.h | 10 + drivers/net/ethernet/stmicro/stmmac/dwmac4_core.c | 48 +++ drivers/net/ethernet/stmicro/stmmac/stmmac_main.c | 31 +-- 4 files changed, 90 insertions(+), 3 deletions(-) diff --git a/drivers/net/ethernet/stmicro/stmmac/common.h b/drivers/net/ethernet/stmicro/stmmac/common.h index 04d9245..5a0a781 100644 --- a/drivers/net/ethernet/stmicro/stmmac/common.h +++ b/drivers/net/ethernet/stmicro/stmmac/common.h @@ -455,6 +455,10 @@ struct stmmac_ops { int (*rx_ipc)(struct mac_device_info *hw); /* Enable RX Queues */ void (*rx_queue_enable)(struct mac_device_info *hw, u32 queue); + /* Program RX Algorithms */ + void (*prog_mtl_rx_algorithms)(struct mac_device_info *hw, u32 rx_alg); + /* Program TX Algorithms */ + void (*prog_mtl_tx_algorithms)(struct mac_device_info *hw, u32 tx_alg); /* Dump MAC registers */ void (*dump_regs)(struct mac_device_info *hw, u32 *reg_space); /* Handle extra events on specific interrupts hw dependent */ diff --git a/drivers/net/ethernet/stmicro/stmmac/dwmac4.h b/drivers/net/ethernet/stmicro/stmmac/dwmac4.h index db45134..748ab6f 100644 --- a/drivers/net/ethernet/stmicro/stmmac/dwmac4.h +++ b/drivers/net/ethernet/stmicro/stmmac/dwmac4.h @@ -161,6 +161,16 @@ enum power_event { #define GMAC_HI_REG_AE BIT(31) /* MTL registers */ +#define MTL_OPERATION_MODE 0x0c00 +#define MTL_OPERATION_SCHALG_MASK GENMASK(6, 5) +#define MTL_OPERATION_SCHALG_WRR (0x0 << 5) +#define MTL_OPERATION_SCHALG_WFQ (0x1 << 5) +#define MTL_OPERATION_SCHALG_DWRR (0x2 << 5) +#define MTL_OPERATION_SCHALG_SP(0x3 << 5) +#define MTL_OPERATION_RAA BIT(2) +#define MTL_OPERATION_RAA_SP (0x0 << 2) +#define MTL_OPERATION_RAA_WSP (0x1 << 2) + #define MTL_INT_STATUS 0x0c20 #define MTL_INT_Q0 BIT(0) diff --git a/drivers/net/ethernet/stmicro/stmmac/dwmac4_core.c b/drivers/net/ethernet/stmicro/stmmac/dwmac4_core.c index 1e79e65..0fb5c8a 100644 --- a/drivers/net/ethernet/stmicro/stmmac/dwmac4_core.c +++ b/drivers/net/ethernet/stmicro/stmmac/dwmac4_core.c @@ -70,6 +70,52 @@ static void dwmac4_rx_queue_enable(struct mac_device_info *hw, u32 queue) writel(value, ioaddr + GMAC_RXQ_CTRL0); } +static void dwmac4_prog_mtl_rx_algorithms(struct mac_device_info *hw, + u32 rx_alg) +{ + void __iomem *ioaddr = hw->pcsr; + u32 value = readl(ioaddr + MTL_OPERATION_MODE); + + value &= ~MTL_OPERATION_RAA; + switch (rx_alg) { + case MTL_RX_ALGORITHM_SP: + value |= MTL_OPERATION_RAA_SP; + break; + case MTL_RX_ALGORITHM_WSP: + value |= MTL_OPERATION_RAA_WSP; + break; + default: + break; + } + + writel(value, ioaddr + MTL_OPERATION_MODE); +} + +static void dwmac4_prog_mtl_tx_algorithms(struct mac_device_info *hw, + u32 tx_alg) +{ + void __iomem *ioaddr = hw->pcsr; + u32 value = readl(ioaddr + MTL_OPERATION_MODE); + + value &= ~MTL_OPERATION_SCHALG_MASK; + switch (tx_alg) { + case MTL_TX_ALGORITHM_WRR: + value |= MTL_OPERATION_SCHALG_WRR; + break; + case MTL_TX_ALGORITHM_WFQ: + value |= MTL_OPERATION_SCHALG_WFQ; + break; + case MTL_TX_ALGORITHM_DWRR: + value |= MTL_OPERATION_SCHALG_DWRR; + break; + case MTL_TX_ALGORITHM_SP: + value |= MTL_OPERATION_SCHALG_SP; + break; + default: + break; + } +} + static void dwmac4_dump_regs(struct mac_device_info *hw, u32 *reg_space) { void __iomem *ioaddr = hw->pcsr; @@ -457,6 +503,8 @@ static const struct stmmac_ops dwmac4_ops = { .core_init = dwmac4_core_init, .rx_ipc = dwmac4_rx_ipc_enable, .rx_queue_enable = dwmac4_rx_queue_enable, + .prog_mtl_rx_algorithms = dwmac4_prog_mtl_rx_algorithms, + .prog_mtl_tx_algorithms = dwmac4_prog_mtl_tx_algorithms, .dump_regs = dwmac4_dump_regs, .host_irq_status = dwmac4_irq_status, .flow_ctrl = dwmac4_flow_ctrl, diff --git a/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c b/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c index 4498a38..af57f8d 100644 --- a/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c +++ b/drivers/net/ethernet/stmicro/stmmac/
Re: [PATCH v3 net-next 4/9] net: stmicro: mtl rx queue enabled as dcb or avb
Hello! On 03/09/2017 02:03 PM, Joao Pinto wrote: This patch introduces the enabling of RX queues as DCB or as AVB based on configuration. Signed-off-by: Joao Pinto [...] diff --git a/drivers/net/ethernet/stmicro/stmmac/dwmac4_core.c b/drivers/net/ethernet/stmicro/stmmac/dwmac4_core.c index 6f59751..04d0fa3 100644 --- a/drivers/net/ethernet/stmicro/stmmac/dwmac4_core.c +++ b/drivers/net/ethernet/stmicro/stmmac/dwmac4_core.c @@ -59,13 +59,17 @@ static void dwmac4_core_init(struct mac_device_info *hw, int mtu) writel(value, ioaddr + GMAC_INT_EN); } -static void dwmac4_rx_queue_enable(struct mac_device_info *hw, u32 queue) +static void dwmac4_rx_queue_enable(struct mac_device_info *hw, + u8 mode, u32 queue) { void __iomem *ioaddr = hw->pcsr; u32 value = readl(ioaddr + GMAC_RXQ_CTRL0); value &= GMAC_RX_QUEUE_CLEAR(queue); - value |= GMAC_RX_AV_QUEUE_ENABLE(queue); + if (mode == MTL_RX_AVB) + value |= GMAC_RX_AV_QUEUE_ENABLE(queue); + else if (mode == MTL_RX_DCB) + value |= GMAC_RX_DCB_QUEUE_ENABLE(queue); *switch*, maybe? [...] diff --git a/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c b/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c index 1ad6957..17faa1f 100644 --- a/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c +++ b/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c @@ -1256,19 +1256,14 @@ static void free_dma_desc_resources(struct stmmac_priv *priv) */ static void stmmac_mac_enable_rx_queues(struct stmmac_priv *priv) { - int rx_count = priv->dma_cap.number_rx_queues; + u32 rx_queues_count = priv->plat->rx_queues_to_use; int queue = 0; It's now set to 0 right below, in the *for* statement. So this initializer seems useless. + u8 mode = 0; - /* If GMAC does not have multiple queues, then this is not necessary*/ - if (rx_count == 1) - return; - - /** -* If the core is synthesized with multiple rx queues / multiple -* dma channels, then rx queues will be disabled by default. -* For now only rx queue 0 is enabled. -*/ - priv->hw->mac->rx_queue_enable(priv->hw, queue); + for (queue = 0; queue < rx_queues_count; queue++) { + mode = priv->plat->rx_queues_cfg[queue].mode_to_use; + priv->hw->mac->rx_queue_enable(priv->hw, mode, queue); + } } /** MBR, Sergei
Re: [PATCHv2 3/5] rds: ib: remove redundant ib_dealloc_fmr
On Thu, Mar 09, 2017 at 04:20:43AM -0500, Zhu Yanjun wrote: > The function ib_dealloc_fmr will never be called. As such, it should > be removed. > > Cc: Joe Jin > Cc: Junxiao Bi > Signed-off-by: Zhu Yanjun > --- > Change from v1 to v2: > remove ibmr NULL test. > > net/rds/ib_fmr.c | 7 ++- > 1 file changed, 2 insertions(+), 5 deletions(-) > > diff --git a/net/rds/ib_fmr.c b/net/rds/ib_fmr.c > index 4fe8f4f..249ae1c 100644 > --- a/net/rds/ib_fmr.c > +++ b/net/rds/ib_fmr.c > @@ -78,12 +78,9 @@ struct rds_ib_mr *rds_ib_alloc_fmr(struct rds_ib_device > *rds_ibdev, int npages) > return ibmr; > > out_no_cigar: > - if (ibmr) { > - if (fmr->fmr) > - ib_dealloc_fmr(fmr->fmr); > - kfree(ibmr); > - } > + kfree(ibmr); > atomic_dec(&pool->item_count); > + Reviewed-by: Yuval Shaia > return ERR_PTR(err); > } > > -- > 2.7.4 > > -- > To unsubscribe from this list: send the line "unsubscribe linux-rdma" in > the body of a message to majord...@vger.kernel.org > More majordomo info at http://vger.kernel.org/majordomo-info.html
Re: [PATCH v2 2/2] can: spi: hi311x: Add Holt HI-311x CAN driver
On 03/09/2017 04:59 AM, Wolfgang Grandegger wrote: > Hello Akshay, > > unfortunately there are not many CAN controllers for the SPI bus. I just > know the MPC251x, which behaves badly (message losses) under Linux, > especially at hight bit-rates due to insufficient RX buffering. What is > your experience with that driver for the HI-311x? > Hi Wolfgang, Good question. I have not worked with MPC251x but the HI-311x performs much better because HI-3110 features: 8 message FIFO (as opposed to 2 buffers on MPC2510) 20 MHz SPI interface (as opposed to 2.5 MHz on MPC2510) As for the real world test results: With RT patch applied to the kernel running on a i.MX6 Dual processor (worst case interrupt latency of 50us as reported by cyclictest), there are ZERO packet drops. Tested with Kvaser Leaf sending 100 burst messages (back to back) every 40ms at a 1M CAN bit rate. 10 million messages were sent by the Kvaser leaf and received successfully by the HI-311x driver. Even without the RT patch, I was able to get the packet drop to zero but this was by moving the CAN/SPI IRQ threads to CPU1 instead of CPU0. Hence I feel the driver is a good candidate to be included in the Linux kernel. Below are detailed test results if you like: https://goo.gl/VWgzp7 Ones of particular interest: 10M-msgs-1M-bitrate-100burst-40ms-interval-leaf.png 10M-msgs-1M-bitrate-100burst-40ms-interval-pwc.txt Thanks, Akshay > > Am 07.03.2017 um 16:31 schrieb Akshay Bhat: >> >> >> On 01/17/2017 02:22 PM, Akshay Bhat wrote: >>> This patch adds support for the Holt HI-311x CAN controller. The HI311x >>> CAN controller is capable of transmitting and receiving standard data >>> frames, extended data frames and remote frames. The HI311x interfaces >>> with the host over SPI. >>> >>> Datasheet: www.holtic.com/documents/371-hi-3110_v-rev-jpdf.do >>> >>> Signed-off-by: Akshay Bhat >>> --- >>> >> >> >> Hi Marc, >> >> Wanted to check if this patch can be included in the next kernel release >> (4.12). >> >> Thanks, >> Akshay >> -- >> To unsubscribe from this list: send the line "unsubscribe linux-can" in >> the body of a message to majord...@vger.kernel.org >> More majordomo info at http://vger.kernel.org/majordomo-info.html >> >>
[PATCH iproute2] iplink: add support for afstats subcommand
Add support for new afstats subcommand. This uses the new IFLA_STATS_AF_SPEC attribute of RTM_GETSTATS messages to show per-device, AF-specific stats. At the moment the kernel only supports MPLS AF stats, so that is all that's implemented here. The print_num function is exposed from ipaddress.c to be used for printing the new stats so that the human-readable option, if set, can be respected. Example of use: $ ./ip/ip -f mpls link afstats dev eth1 3: eth1 mpls: RX: bytes packets errors dropped noroute 9016 98 0 00 TX: bytes packets errors dropped 7232 113 0 0 Signed-off-by: Robert Shearman --- ip/ip_common.h| 2 + ip/ipaddress.c| 2 +- ip/iplink.c | 151 ++ man/man8/ip-link.8.in | 12 4 files changed, 166 insertions(+), 1 deletion(-) diff --git a/ip/ip_common.h b/ip/ip_common.h index abb2b8d5d537..5a39623aa21d 100644 --- a/ip/ip_common.h +++ b/ip/ip_common.h @@ -112,3 +112,5 @@ int name_is_vrf(const char *name); #ifndef LABEL_MAX_MASK #define LABEL_MAX_MASK 0xFU #endif + +void print_num(FILE *fp, unsigned int width, uint64_t count); diff --git a/ip/ipaddress.c b/ip/ipaddress.c index 242c6ea0b4b3..b8d9c7d917fe 100644 --- a/ip/ipaddress.c +++ b/ip/ipaddress.c @@ -418,7 +418,7 @@ static void print_vfinfo(FILE *fp, struct rtattr *vfinfo) print_vf_stats64(fp, vf[IFLA_VF_STATS]); } -static void print_num(FILE *fp, unsigned int width, uint64_t count) +void print_num(FILE *fp, unsigned int width, uint64_t count) { const char *prefix = "kMGTPE"; const unsigned int base = use_iec ? 1024 : 1000; diff --git a/ip/iplink.c b/ip/iplink.c index 00fed9006ea6..866ad723f4a2 100644 --- a/ip/iplink.c +++ b/ip/iplink.c @@ -28,6 +28,7 @@ #include #include #include +#include #include "rt_names.h" #include "utils.h" @@ -99,6 +100,7 @@ void iplink_usage(void) " ip link show [ DEVICE | group GROUP ] [up] [master DEV] [vrf NAME] [type TYPE]\n"); fprintf(stderr, "\n ip link xstats type TYPE [ ARGS ]\n"); + fprintf(stderr, "\n ip link afstats [ dev DEVICE ]\n"); if (iplink_have_newlink()) { fprintf(stderr, @@ -1364,6 +1366,150 @@ static int do_set(int argc, char **argv) } #endif /* IPLINK_IOCTL_COMPAT */ +static void print_mpls_stats(FILE *fp, struct rtattr *attr) +{ + struct rtattr *mrtb[MPLS_STATS_MAX+1]; + struct mpls_link_stats *stats; + + parse_rtattr(mrtb, MPLS_STATS_MAX, RTA_DATA(attr), +RTA_PAYLOAD(attr)); + if (!mrtb[MPLS_STATS_LINK]) + return; + + stats = RTA_DATA(mrtb[MPLS_STATS_LINK]); + + fprintf(fp, "mpls:\n"); + fprintf(fp, "RX: bytes packets errors dropped noroute\n"); + fprintf(fp, ""); + print_num(fp, 10, stats->rx_bytes); + print_num(fp, 8, stats->rx_packets); + print_num(fp, 7, stats->rx_errors); + print_num(fp, 8, stats->rx_dropped); + print_num(fp, 7, stats->rx_noroute); + fprintf(fp, "\n"); + fprintf(fp, "TX: bytes packets errors dropped\n"); + fprintf(fp, ""); + print_num(fp, 10, stats->tx_bytes); + print_num(fp, 8, stats->tx_packets); + print_num(fp, 7, stats->tx_errors); + print_num(fp, 7, stats->tx_dropped); + fprintf(fp, "\n"); +} + +static void print_af_stats_attr(FILE *fp, int ifindex, struct rtattr *attr) +{ + bool if_printed = false; + struct rtattr *i; + int rem; + + rem = RTA_PAYLOAD(attr); + for (i = RTA_DATA(attr); RTA_OK(i, rem); i = RTA_NEXT(i, rem)) { + if (preferred_family != AF_UNSPEC && + i->rta_type != preferred_family) + continue; + + if (!if_printed) { + fprintf(fp, "%u: %s\n", ifindex, + ll_index_to_name(ifindex)); + if_printed = true; + } + + switch (i->rta_type) { + case AF_MPLS: + print_mpls_stats(fp, i); + break; + default: + fprintf(fp, "unknown af(%d)\n", i->rta_type); + break; + } + } +} + +struct af_stats_ctx { + FILE *fp; + int ifindex; +}; + +static int print_af_stats(const struct sockaddr_nl *who, + struct nlmsghdr *n, + void *arg) +{ + struct if_stats_msg *ifsm = NLMSG_DATA(n); + struct rtattr *tb[IFLA_STATS_MAX+1]; + int len = n->nlmsg_len; + struct af_stats_ctx *ctx = arg; + FILE *fp = ctx->fp; + + len -= NLMSG_LENGTH(sizeof(*ifsm)); + if (len < 0) { + fprintf(stderr, "BUG: wrong nlmsg
[PATCH v3 3/4] nvme-rdma: use inet_pton_with_scope helper
Both the destination and the host addresses are now parsed using inet_pton_with_scope helper. We also get ipv6 (with address scopes support). Reviewed-by: Christoph Hellwig Signed-off-by: Sagi Grimberg --- drivers/nvme/host/rdma.c | 63 +++- 1 file changed, 19 insertions(+), 44 deletions(-) diff --git a/drivers/nvme/host/rdma.c b/drivers/nvme/host/rdma.c index 779f516e7a4e..7bad791a7fe9 100644 --- a/drivers/nvme/host/rdma.c +++ b/drivers/nvme/host/rdma.c @@ -129,14 +129,8 @@ struct nvme_rdma_ctrl { u64 cap; u32 max_fr_pages; - union { - struct sockaddr addr; - struct sockaddr_in addr_in; - }; - union { - struct sockaddr src_addr; - struct sockaddr_in src_addr_in; - }; + struct sockaddr_storage addr; + struct sockaddr_storage src_addr; struct nvme_ctrlctrl; }; @@ -571,11 +565,12 @@ static int nvme_rdma_init_queue(struct nvme_rdma_ctrl *ctrl, return PTR_ERR(queue->cm_id); } - queue->cm_error = -ETIMEDOUT; if (ctrl->ctrl.opts->mask & NVMF_OPT_HOST_TRADDR) - src_addr = &ctrl->src_addr; + src_addr = (struct sockaddr *)&ctrl->src_addr; - ret = rdma_resolve_addr(queue->cm_id, src_addr, &ctrl->addr, + queue->cm_error = -ETIMEDOUT; + ret = rdma_resolve_addr(queue->cm_id, src_addr, + (struct sockaddr *)&ctrl->addr, NVME_RDMA_CONNECT_TIMEOUT_MS); if (ret) { dev_info(ctrl->ctrl.device, @@ -1857,27 +1852,13 @@ static int nvme_rdma_create_io_queues(struct nvme_rdma_ctrl *ctrl) return ret; } -static int nvme_rdma_parse_ipaddr(struct sockaddr_in *in_addr, char *p) -{ - u8 *addr = (u8 *)&in_addr->sin_addr.s_addr; - size_t buflen = strlen(p); - - /* XXX: handle IPv6 addresses */ - - if (buflen > INET_ADDRSTRLEN) - return -EINVAL; - if (in4_pton(p, buflen, addr, '\0', NULL) == 0) - return -EINVAL; - in_addr->sin_family = AF_INET; - return 0; -} - static struct nvme_ctrl *nvme_rdma_create_ctrl(struct device *dev, struct nvmf_ctrl_options *opts) { struct nvme_rdma_ctrl *ctrl; int ret; bool changed; + char *port; ctrl = kzalloc(sizeof(*ctrl), GFP_KERNEL); if (!ctrl) @@ -1885,34 +1866,28 @@ static struct nvme_ctrl *nvme_rdma_create_ctrl(struct device *dev, ctrl->ctrl.opts = opts; INIT_LIST_HEAD(&ctrl->list); - ret = nvme_rdma_parse_ipaddr(&ctrl->addr_in, opts->traddr); + if (opts->mask & NVMF_OPT_TRSVCID) + port = opts->trsvcid; + else + port = __stringify(NVME_RDMA_IP_PORT); + + ret = inet_pton_with_scope(&init_net, AF_UNSPEC, + opts->traddr, port, &ctrl->addr); if (ret) { - pr_err("malformed IP address passed: %s\n", opts->traddr); + pr_err("malformed address passed: %s:%s\n", opts->traddr, port); goto out_free_ctrl; } if (opts->mask & NVMF_OPT_HOST_TRADDR) { - ret = nvme_rdma_parse_ipaddr(&ctrl->src_addr_in, - opts->host_traddr); + ret = inet_pton_with_scope(&init_net, AF_UNSPEC, + opts->host_traddr, NULL, &ctrl->src_addr); if (ret) { - pr_err("malformed src IP address passed: %s\n", + pr_err("malformed src address passed: %s\n", opts->host_traddr); goto out_free_ctrl; } } - if (opts->mask & NVMF_OPT_TRSVCID) { - u16 port; - - ret = kstrtou16(opts->trsvcid, 0, &port); - if (ret) - goto out_free_ctrl; - - ctrl->addr_in.sin_port = cpu_to_be16(port); - } else { - ctrl->addr_in.sin_port = cpu_to_be16(NVME_RDMA_IP_PORT); - } - ret = nvme_init_ctrl(&ctrl->ctrl, dev, &nvme_rdma_ctrl_ops, 0 /* no quirks, we're perfect! */); if (ret) @@ -1977,7 +1952,7 @@ static struct nvme_ctrl *nvme_rdma_create_ctrl(struct device *dev, changed = nvme_change_ctrl_state(&ctrl->ctrl, NVME_CTRL_LIVE); WARN_ON_ONCE(!changed); - dev_info(ctrl->ctrl.device, "new ctrl: NQN \"%s\", addr %pISp\n", + dev_info(ctrl->ctrl.device, "new ctrl: NQN \"%s\", addr %pISpcs\n", ctrl->ctrl.opts->subsysnqn, &ctrl->addr); kref_get(&ctrl->ctrl.kref); -- 2.7.4
[PATCH v3 4/4] iscsi-target: use generic inet_pton_with_scope
Instead of parsing address strings, use a generic helper. Acked-by: Nicholas Bellinger Signed-off-by: Sagi Grimberg --- drivers/target/iscsi/iscsi_target_configfs.c | 46 1 file changed, 12 insertions(+), 34 deletions(-) diff --git a/drivers/target/iscsi/iscsi_target_configfs.c b/drivers/target/iscsi/iscsi_target_configfs.c index bf40f03755dd..f30c27b83c5e 100644 --- a/drivers/target/iscsi/iscsi_target_configfs.c +++ b/drivers/target/iscsi/iscsi_target_configfs.c @@ -167,10 +167,7 @@ static struct se_tpg_np *lio_target_call_addnptotpg( struct iscsi_portal_group *tpg; struct iscsi_tpg_np *tpg_np; char *str, *str2, *ip_str, *port_str; - struct sockaddr_storage sockaddr; - struct sockaddr_in *sock_in; - struct sockaddr_in6 *sock_in6; - unsigned long port; + struct sockaddr_storage sockaddr = { }; int ret; char buf[MAX_PORTAL_LEN + 1]; @@ -182,21 +179,19 @@ static struct se_tpg_np *lio_target_call_addnptotpg( memset(buf, 0, MAX_PORTAL_LEN + 1); snprintf(buf, MAX_PORTAL_LEN + 1, "%s", name); - memset(&sockaddr, 0, sizeof(struct sockaddr_storage)); - str = strstr(buf, "["); if (str) { - const char *end; - str2 = strstr(str, "]"); if (!str2) { pr_err("Unable to locate trailing \"]\"" " in IPv6 iSCSI network portal address\n"); return ERR_PTR(-EINVAL); } - str++; /* Skip over leading "[" */ + + ip_str = str + 1; /* Skip over leading "[" */ *str2 = '\0'; /* Terminate the unbracketed IPv6 address */ str2++; /* Skip over the \0 */ + port_str = strstr(str2, ":"); if (!port_str) { pr_err("Unable to locate \":port\"" @@ -205,23 +200,8 @@ static struct se_tpg_np *lio_target_call_addnptotpg( } *port_str = '\0'; /* Terminate string for IP */ port_str++; /* Skip over ":" */ - - ret = kstrtoul(port_str, 0, &port); - if (ret < 0) { - pr_err("kstrtoul() failed for port_str: %d\n", ret); - return ERR_PTR(ret); - } - sock_in6 = (struct sockaddr_in6 *)&sockaddr; - sock_in6->sin6_family = AF_INET6; - sock_in6->sin6_port = htons((unsigned short)port); - ret = in6_pton(str, -1, - (void *)&sock_in6->sin6_addr.in6_u, -1, &end); - if (ret <= 0) { - pr_err("in6_pton returned: %d\n", ret); - return ERR_PTR(-EINVAL); - } } else { - str = ip_str = &buf[0]; + ip_str = &buf[0]; port_str = strstr(ip_str, ":"); if (!port_str) { pr_err("Unable to locate \":port\"" @@ -230,17 +210,15 @@ static struct se_tpg_np *lio_target_call_addnptotpg( } *port_str = '\0'; /* Terminate string for IP */ port_str++; /* Skip over ":" */ + } - ret = kstrtoul(port_str, 0, &port); - if (ret < 0) { - pr_err("kstrtoul() failed for port_str: %d\n", ret); - return ERR_PTR(ret); - } - sock_in = (struct sockaddr_in *)&sockaddr; - sock_in->sin_family = AF_INET; - sock_in->sin_port = htons((unsigned short)port); - sock_in->sin_addr.s_addr = in_aton(ip_str); + ret = inet_pton_with_scope(&init_net, AF_UNSPEC, ip_str, + port_str, &sockaddr); + if (ret) { + pr_err("malformed ip/port passed: %s\n", name); + return ERR_PTR(ret); } + tpg = container_of(se_tpg, struct iscsi_portal_group, tpg_se_tpg); ret = iscsit_get_tpg(tpg); if (ret < 0) -- 2.7.4
[PATCH v3 0/4] Introduce a new helper for parsing ipv[4|6]:port to socket address
Changes from v1: - rebased to 4.11-rc1 - improved changelogs Changes from v0: - rebased on 4.10 - splitted inet_pton_with_scope to be a bit saner (from Chrsitoph) - converted nvme-rdma host_traddr to use a generic helper We have some places in the stack that support ipv4 and ipv6. In some cases the user configuration does not reveal which address family is given and needs to be parsed from the input string. Given that the user-input varies between subsystems, some processing is required from the call-site to separate address and port strings. As a side-effect, this set adds ipv6 support for nvme over fabrics. Sagi Grimberg (4): net/utils: generic inet_pton_with_scope helper nvmet-rdma: use generic inet_pton_with_scope nvme-rdma: use inet_pton_with_scope helper iscsi-target: use generic inet_pton_with_scope drivers/nvme/host/rdma.c | 63 +--- drivers/nvme/target/rdma.c | 42 +++ drivers/target/iscsi/iscsi_target_configfs.c | 46 include/linux/inet.h | 6 ++ net/core/utils.c | 103 +++ 5 files changed, 169 insertions(+), 91 deletions(-) -- 2.7.4
[PATCH v3 1/4] net/utils: generic inet_pton_with_scope helper
Several locations in the stack need to handle ipv4/ipv6 (with scope) and port strings conversion to sockaddr. Add a helper that takes either AF_INET, AF_INET6 or AF_UNSPEC (for wildcard) to centralize this handling. Suggested-by: Christoph Hellwig Reviewed-by: Christoph Hellwig Signed-off-by: Sagi Grimberg --- include/linux/inet.h | 6 +++ net/core/utils.c | 103 +++ 2 files changed, 109 insertions(+) diff --git a/include/linux/inet.h b/include/linux/inet.h index 4cca05c9678e..636ebe87e6f8 100644 --- a/include/linux/inet.h +++ b/include/linux/inet.h @@ -43,6 +43,8 @@ #define _LINUX_INET_H #include +#include +#include /* * These mimic similar macros defined in user-space for inet_ntop(3). @@ -54,4 +56,8 @@ extern __be32 in_aton(const char *str); extern int in4_pton(const char *src, int srclen, u8 *dst, int delim, const char **end); extern int in6_pton(const char *src, int srclen, u8 *dst, int delim, const char **end); + +extern int inet_pton_with_scope(struct net *net, unsigned short af, + const char *src, const char *port, struct sockaddr_storage *addr); + #endif /* _LINUX_INET_H */ diff --git a/net/core/utils.c b/net/core/utils.c index 6592d7bbed39..f96cf527bb8f 100644 --- a/net/core/utils.c +++ b/net/core/utils.c @@ -26,9 +26,11 @@ #include #include #include +#include #include #include +#include #include #include @@ -300,6 +302,107 @@ int in6_pton(const char *src, int srclen, } EXPORT_SYMBOL(in6_pton); +static int inet4_pton(const char *src, u16 port_num, + struct sockaddr_storage *addr) +{ + struct sockaddr_in *addr4 = (struct sockaddr_in *)addr; + int srclen = strlen(src); + + if (srclen > INET_ADDRSTRLEN) + return -EINVAL; + + if (in4_pton(src, srclen, (u8 *)&addr4->sin_addr.s_addr, +'\n', NULL) == 0) + return -EINVAL; + + addr4->sin_family = AF_INET; + addr4->sin_port = htons(port_num); + + return 0; +} + +static int inet6_pton(struct net *net, const char *src, u16 port_num, + struct sockaddr_storage *addr) +{ + struct sockaddr_in6 *addr6 = (struct sockaddr_in6 *)addr; + const char *scope_delim; + int srclen = strlen(src); + + if (srclen > INET6_ADDRSTRLEN) + return -EINVAL; + + if (in6_pton(src, srclen, (u8 *)&addr6->sin6_addr.s6_addr, +'%', &scope_delim) == 0) + return -EINVAL; + + if (ipv6_addr_type(&addr6->sin6_addr) & IPV6_ADDR_LINKLOCAL && + src + srclen != scope_delim && *scope_delim == '%') { + struct net_device *dev; + char scope_id[16]; + size_t scope_len = min_t(size_t, sizeof(scope_id), +src + srclen - scope_delim - 1); + + memcpy(scope_id, scope_delim + 1, scope_len); + scope_id[scope_len] = '\0'; + + dev = dev_get_by_name(net, scope_id); + if (dev) { + addr6->sin6_scope_id = dev->ifindex; + dev_put(dev); + } else if (kstrtouint(scope_id, 0, &addr6->sin6_scope_id)) { + return -EINVAL; + } + } + + addr6->sin6_family = AF_INET6; + addr6->sin6_port = htons(port_num); + + return 0; +} + +/** + * inet_pton_with_scope - convert an IPv4/IPv6 and port to socket address + * @net: net namespace (used for scope handling) + * @af: address family, AF_INET, AF_INET6 or AF_UNSPEC for either + * @src: the start of the address string + * @port: the start of the port string (or NULL for none) + * @addr: output socket address + * + * Return zero on success, return errno when any error occurs. + */ +int inet_pton_with_scope(struct net *net, __kernel_sa_family_t af, + const char *src, const char *port, struct sockaddr_storage *addr) +{ + u16 port_num; + int ret = -EINVAL; + + if (port) { + if (kstrtou16(port, 0, &port_num)) + return -EINVAL; + } else { + port_num = 0; + } + + switch (af) { + case AF_INET: + ret = inet4_pton(src, port_num, addr); + break; + case AF_INET6: + ret = inet6_pton(net, src, port_num, addr); + break; + case AF_UNSPEC: + ret = inet4_pton(src, port_num, addr); + if (ret) + ret = inet6_pton(net, src, port_num, addr); + break; + default: + pr_err("unexpected address family %d\n", af); + }; + + return ret; +} +EXPORT_SYMBOL(inet_pton_with_scope); + void inet_proto_csum_replace4(__sum16 *sum, struct sk_buff *skb, __be32 from, __be32 to, bool pseudohdr) { -- 2.7.4
[PATCH v3 2/4] nvmet-rdma: use generic inet_pton_with_scope
Instead of parsing address strings, use a generic helper. This also adds ipv6 (with address scopes) support. Reviewed-by: Christoph Hellwig Signed-off-by: Sagi Grimberg --- drivers/nvme/target/rdma.c | 42 +- 1 file changed, 29 insertions(+), 13 deletions(-) diff --git a/drivers/nvme/target/rdma.c b/drivers/nvme/target/rdma.c index 9aa1da3778b3..973b674ab55b 100644 --- a/drivers/nvme/target/rdma.c +++ b/drivers/nvme/target/rdma.c @@ -1429,12 +1429,16 @@ static void nvmet_rdma_delete_ctrl(struct nvmet_ctrl *ctrl) static int nvmet_rdma_add_port(struct nvmet_port *port) { struct rdma_cm_id *cm_id; - struct sockaddr_in addr_in; - u16 port_in; + struct sockaddr_storage addr = { }; + __kernel_sa_family_t af; int ret; switch (port->disc_addr.adrfam) { case NVMF_ADDR_FAMILY_IP4: + af = AF_INET; + break; + case NVMF_ADDR_FAMILY_IP6: + af = AF_INET6; break; default: pr_err("address family %d not supported\n", @@ -1442,13 +1446,13 @@ static int nvmet_rdma_add_port(struct nvmet_port *port) return -EINVAL; } - ret = kstrtou16(port->disc_addr.trsvcid, 0, &port_in); - if (ret) + ret = inet_pton_with_scope(&init_net, af, port->disc_addr.traddr, + port->disc_addr.trsvcid, &addr); + if (ret) { + pr_err("malformed ip/port passed: %s:%s\n", + port->disc_addr.traddr, port->disc_addr.trsvcid); return ret; - - addr_in.sin_family = AF_INET; - addr_in.sin_addr.s_addr = in_aton(port->disc_addr.traddr); - addr_in.sin_port = htons(port_in); + } cm_id = rdma_create_id(&init_net, nvmet_rdma_cm_handler, port, RDMA_PS_TCP, IB_QPT_RC); @@ -1457,20 +1461,32 @@ static int nvmet_rdma_add_port(struct nvmet_port *port) return PTR_ERR(cm_id); } - ret = rdma_bind_addr(cm_id, (struct sockaddr *)&addr_in); + /* +* Allow both IPv4 and IPv6 sockets to bind a single port +* at the same time. +*/ + ret = rdma_set_afonly(cm_id, 1); + if (ret) { + pr_err("rdma_set_afonly failed (%d)\n", ret); + goto out_destroy_id; + } + + ret = rdma_bind_addr(cm_id, (struct sockaddr *)&addr); if (ret) { - pr_err("binding CM ID to %pISpc failed (%d)\n", &addr_in, ret); + pr_err("binding CM ID to %pISpcs failed (%d)\n", + (struct sockaddr *)&addr, ret); goto out_destroy_id; } ret = rdma_listen(cm_id, 128); if (ret) { - pr_err("listening to %pISpc failed (%d)\n", &addr_in, ret); + pr_err("listening to %pISpcs failed (%d)\n", + (struct sockaddr *)&addr, ret); goto out_destroy_id; } - pr_info("enabling port %d (%pISpc)\n", - le16_to_cpu(port->disc_addr.portid), &addr_in); + pr_info("enabling port %d (%pISpcs)\n", + le16_to_cpu(port->disc_addr.portid), (struct sockaddr *)&addr); port->priv = cm_id; return 0; -- 2.7.4
[PATCH net-next v2] net/socket: use per af lockdep classes for sk queues
Currently the sock queue's spin locks get their lockdep classes by the default init_spin_lock() initializer: all socket families get - usually, see below - a single class for rx, another specific class for tx, etc. This can lead to false positive lockdep splat, as reported by Andrey. Moreover there are two separate initialization points for the sock queues, one in sk_clone_lock() and one in sock_init_data(), so that e.g. the rx queue lock can get one of two possible, different classes, depending on the socket being cloned or not. This change tries to address the above, setting explicitly a per address family lockdep class for each queue's spinlock. Also, move the duplicated initialization code to a single location. v1 -> v2: - renamed the init helper rfc -> v1: - no changes, tested with several different workload Suggested-by: Cong Wang Signed-off-by: Paolo Abeni --- net/core/sock.c | 96 ++--- 1 file changed, 78 insertions(+), 18 deletions(-) diff --git a/net/core/sock.c b/net/core/sock.c index f6fd79f..768aedf 100644 --- a/net/core/sock.c +++ b/net/core/sock.c @@ -258,12 +258,66 @@ static const char *const af_family_clock_key_strings[AF_MAX+1] = { "clock-AF_NFC" , "clock-AF_VSOCK", "clock-AF_KCM" , "clock-AF_QIPCRTR", "clock-AF_SMC" , "clock-AF_MAX" }; +static const char *const af_family_rlock_key_strings[AF_MAX+1] = { + "rlock-AF_UNSPEC", "rlock-AF_UNIX" , "rlock-AF_INET" , + "rlock-AF_AX25" , "rlock-AF_IPX" , "rlock-AF_APPLETALK", + "rlock-AF_NETROM", "rlock-AF_BRIDGE" , "rlock-AF_ATMPVC" , + "rlock-AF_X25" , "rlock-AF_INET6", "rlock-AF_ROSE" , + "rlock-AF_DECnet", "rlock-AF_NETBEUI" , "rlock-AF_SECURITY" , + "rlock-AF_KEY" , "rlock-AF_NETLINK" , "rlock-AF_PACKET" , + "rlock-AF_ASH" , "rlock-AF_ECONET" , "rlock-AF_ATMSVC" , + "rlock-AF_RDS" , "rlock-AF_SNA" , "rlock-AF_IRDA" , + "rlock-AF_PPPOX" , "rlock-AF_WANPIPE" , "rlock-AF_LLC" , + "rlock-27" , "rlock-28" , "rlock-AF_CAN" , + "rlock-AF_TIPC" , "rlock-AF_BLUETOOTH", "rlock-AF_IUCV" , + "rlock-AF_RXRPC" , "rlock-AF_ISDN" , "rlock-AF_PHONET" , + "rlock-AF_IEEE802154", "rlock-AF_CAIF" , "rlock-AF_ALG" , + "rlock-AF_NFC" , "rlock-AF_VSOCK", "rlock-AF_KCM" , + "rlock-AF_QIPCRTR", "rlock-AF_SMC" , "rlock-AF_MAX" +}; +static const char *const af_family_wlock_key_strings[AF_MAX+1] = { + "wlock-AF_UNSPEC", "wlock-AF_UNIX" , "wlock-AF_INET" , + "wlock-AF_AX25" , "wlock-AF_IPX" , "wlock-AF_APPLETALK", + "wlock-AF_NETROM", "wlock-AF_BRIDGE" , "wlock-AF_ATMPVC" , + "wlock-AF_X25" , "wlock-AF_INET6", "wlock-AF_ROSE" , + "wlock-AF_DECnet", "wlock-AF_NETBEUI" , "wlock-AF_SECURITY" , + "wlock-AF_KEY" , "wlock-AF_NETLINK" , "wlock-AF_PACKET" , + "wlock-AF_ASH" , "wlock-AF_ECONET" , "wlock-AF_ATMSVC" , + "wlock-AF_RDS" , "wlock-AF_SNA" , "wlock-AF_IRDA" , + "wlock-AF_PPPOX" , "wlock-AF_WANPIPE" , "wlock-AF_LLC" , + "wlock-27" , "wlock-28" , "wlock-AF_CAN" , + "wlock-AF_TIPC" , "wlock-AF_BLUETOOTH", "wlock-AF_IUCV" , + "wlock-AF_RXRPC" , "wlock-AF_ISDN" , "wlock-AF_PHONET" , + "wlock-AF_IEEE802154", "wlock-AF_CAIF" , "wlock-AF_ALG" , + "wlock-AF_NFC" , "wlock-AF_VSOCK", "wlock-AF_KCM" , + "wlock-AF_QIPCRTR", "wlock-AF_SMC" , "wlock-AF_MAX" +}; +static const char *const af_family_elock_key_strings[AF_MAX+1] = { + "elock-AF_UNSPEC", "elock-AF_UNIX" , "elock-AF_INET" , + "elock-AF_AX25" , "elock-AF_IPX" , "elock-AF_APPLETALK", + "elock-AF_NETROM", "elock-AF_BRIDGE" , "elock-AF_ATMPVC" , + "elock-AF_X25" , "elock-AF_INET6", "elock-AF_ROSE" , + "elock-AF_DECnet", "elock-AF_NETBEUI" , "elock-AF_SECURITY" , + "elock-AF_KEY" , "elock-AF_NETLINK" , "elock-AF_PACKET" , + "elock-AF_ASH" , "elock-AF_ECONET" , "elock-AF_ATMSVC" , + "elock-AF_RDS" , "elock-AF_SNA" , "elock-AF_IRDA" , + "elock-AF_PPPOX" , "elock-AF_WANPIPE" , "elock-AF_LLC" , + "elock-27" , "elock-28" , "elock-AF_CAN" , + "elock-AF_TIPC" , "elock-AF_BLUETOOTH", "elock-AF_IUCV" , + "elock-AF_RXRPC" , "elock-AF_ISDN" , "elock-AF_PHONET" , + "elock-AF_IEEE802154", "elock-AF_CAIF" , "elock-AF_ALG" , + "elock-AF_NFC" , "elock-AF_VSOCK", "elock-AF_KCM" , + "elock-AF_QIPCRTR", "elock-AF_SMC" , "elock-AF_MAX" +}; /* - * sk_callback_lock locking rules are per-address-family, + * sk_callback_lock and sk queues locking rules are per-address-family, * so split the lock classes by using a per-AF key: */ static struct lock_class_key af_callback_keys[AF_MAX]; +static struct lock_class_key af_rlock_keys[AF_MAX]; +static struct lock_class_key af_wlock_keys[AF_MAX]; +static struct lock_class_key af_elock_keys[AF_MAX]; /* Take into consideration the size of the struct sk_buff ove
Re: [net/bpf] 3051bf36c2 BUG: unable to handle kernel paging request at 0000a7cf
On 03/09/2017 06:36 AM, Kees Cook wrote: On Wed, Mar 8, 2017 at 3:55 PM, Laura Abbott wrote: On 03/08/2017 02:36 PM, Kees Cook wrote: On Wed, Mar 8, 2017 at 2:27 PM, Daniel Borkmann wrote: [ 28.474232] rodata_test: test data was not read only [...] In my tests so far, I've never been able to get rodata_test to fail (Qemu 2.5.0, Ubuntu). I'll retry with your .config and see if I can recheck under Qemu 2.7.1. Do you see these failures on real hardware? -Kees FWIW, I'm seeing the same issue with qemu 2.6.2 and 2.8.0 on Fedora 24 and rawhide respectively. I also notice that CONFIG_X86_PAE is turned off in the defconfig. If I set CONFIG_HIGHMEM_64G which turns on CONFIG_X86_PAE the problem goes away. I can't tell if this is an indication of magically hiding the TLB problem or if there is an issue with !X86_PAE invalidation. I found my difference. I normally run qemu with "-cpu host" which makes the failure go away. With "-cpu kvm64", I see the rodata_test failure immediately. Seems like this may be a kvm cpu feature emulation bug? I'll see if I can find the specific cpu feature in the morning... Interesting! Changing to "-cpu host" makes rodata_test succeed plus my test_setmem and the test_bpf suite runs fine as well. Haven't seen a corruption since. Switching back to "-cpu kvm64" I immediately see mentioned issues again. With regard to CPA_FLUSHTLB that Linus mentioned, when I investigated code paths in change_page_attr_set_clr(), I did see that CPA_FLUSHTLB was set each time we switched attrs and a cpa_flush_range() was performed (with the correct number of pages and cache set to 0). That would be a __flush_tlb_all() eventually. Hmm, it indeed might seem likely that this could be an emulation bug. Thanks, Daniel
Re: [net/bpf] 3051bf36c2 BUG: unable to handle kernel paging request at 0000a7cf
On Thu, 9 Mar 2017, Daniel Borkmann wrote: > With regard to CPA_FLUSHTLB that Linus mentioned, when I investigated > code paths in change_page_attr_set_clr(), I did see that CPA_FLUSHTLB > was set each time we switched attrs and a cpa_flush_range() was > performed (with the correct number of pages and cache set to 0). That > would be a __flush_tlb_all() eventually. > > Hmm, it indeed might seem likely that this could be an emulation bug. Which variant of __flush_tlb_all() is used when the test fails? Check for the following flags in /proc/cpuinfo: pge invpcid Thanks, tglx
Re: [net/bpf] 3051bf36c2 BUG: unable to handle kernel paging request at 0000a7cf
On Wed, 8 Mar 2017, Linus Torvalds wrote: > Adding x86 people too, since this seems to be something off about > ARCH_HAS_SET_MEMORY for x86-32. > > The code seems to be shared between x86-32 and 64, I'm not seeing why > set_memory_r[ow]() should fail on one but not the other. Indeed. > Considering that it seems to be flaky even on 32-bit, maybe it's > timing-related, or possibly related to TLB sizes or whatever (ie more > likely hidden by a larger TLB on more modern hardware?) The only difference I can see is the way how __tlb_flush_all() is happening. We have 3 variants: invpcid_flush_all() - depends on X86_FEATURE_INVPCID and X86_FEATURE_PGE cr4 based flush - depends on X86_FEATURE_PGE cr3 based flush No idea which variant is used in that failure case. > Anyway, just looking at change_page_attr_set_clr(), I notice that the > page alias checking treats NX specially: > > /* No alias checking for _NX bit modifications */ > checkalias = (pgprot_val(mask_set) | pgprot_val(mask_clr)) != > _PAGE_NX; > > which seems insane. Why would NX be different from other protection > bits (like _PAGE_RW)? The reason is that the alias mapping should never be executable at all. Thanks, tglx
[PATCH iproute2] man: Fix formatting of vrf parameter of ip-link show command
Add missing opening " [" for the vrf parameter. Signed-off-by: Robert Shearman --- man/man8/ip-link.8.in | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/man/man8/ip-link.8.in b/man/man8/ip-link.8.in index 83ffb6357f7d..3f5d57c28885 100644 --- a/man/man8/ip-link.8.in +++ b/man/man8/ip-link.8.in @@ -164,7 +164,7 @@ ip-link \- network device configuration .B master .IR DEVICE " ] [" .B type -.IR ETYPE " ]" +.IR ETYPE " ] [" .B vrf .IR NAME " ]" -- 2.1.4
Re: [PATCH v4 net-next 00/13] mlx4: order-0 allocations and page recycling
On 08/03/2017 6:17 PM, Eric Dumazet wrote: As mentioned half a year ago, we better switch mlx4 driver to order-0 allocations and page recycling. This reduces vulnerability surface thanks to better skb->truesize tracking and provides better performance in most cases. (33 Gbit for one TCP flow on my lab hosts) I will provide for linux-4.13 a patch on top of this series, trying to improve data locality as described in https://www.spinics.net/lists/netdev/msg422258.html v2 provides an ethtool -S new counter (rx_alloc_pages) and code factorization, plus Tariq fix. v3 includes various fixes based on Tariq tests and feedback from Saeed and Tariq. v4 rebased on net-next for inclusion in linux-4.12, as requested by Tariq. Hi Eric, I was preparing this series for submission as well. You got it done first :) Thanks for re-submitting. I am Acking the patches now. Regards, Tariq Worth noting this patch series deletes ~250 lines of code ;) Eric Dumazet (13): mlx4: dma_dir is a mlx4_en_priv attribute mlx4: remove order field from mlx4_en_frag_info mlx4: get rid of frag_prefix_size mlx4: rx_headroom is a per port attribute mlx4: reduce rx ring page_cache size mlx4: removal of frag_sizes[] mlx4: use order-0 pages for RX mlx4: add page recycling in receive path mlx4: add rx_alloc_pages counter in ethtool -S mlx4: do not access rx_desc from mlx4_en_process_rx_cq() mlx4: factorize page_address() calls mlx4: make validate_loopback() more generic mlx4: remove duplicate code in mlx4_en_process_rx_cq() drivers/net/ethernet/mellanox/mlx4/en_ethtool.c | 2 +- drivers/net/ethernet/mellanox/mlx4/en_port.c | 2 + drivers/net/ethernet/mellanox/mlx4/en_rx.c | 607 +++ drivers/net/ethernet/mellanox/mlx4/en_selftest.c | 6 - drivers/net/ethernet/mellanox/mlx4/en_tx.c | 4 +- drivers/net/ethernet/mellanox/mlx4/mlx4_en.h | 30 +- drivers/net/ethernet/mellanox/mlx4/mlx4_stats.h | 2 +- 7 files changed, 201 insertions(+), 452 deletions(-)
Re: [PATCH v4 net-next 02/13] mlx4: remove order field from mlx4_en_frag_info
On 08/03/2017 6:17 PM, Eric Dumazet wrote: This is really a port attribute, no need to duplicate it per RX queue and per frag. Signed-off-by: Eric Dumazet --- drivers/net/ethernet/mellanox/mlx4/en_rx.c | 6 +++--- drivers/net/ethernet/mellanox/mlx4/mlx4_en.h | 2 +- 2 files changed, 4 insertions(+), 4 deletions(-) Acked-by: Tariq Toukan Thanks.
Re: [PATCH v4 net-next 03/13] mlx4: get rid of frag_prefix_size
On 08/03/2017 6:17 PM, Eric Dumazet wrote: Using per frag storage for frag_prefix_size is really silly. mlx4_en_complete_rx_desc() has all needed info already. Signed-off-by: Eric Dumazet --- drivers/net/ethernet/mellanox/mlx4/en_rx.c | 27 --- drivers/net/ethernet/mellanox/mlx4/mlx4_en.h | 3 +-- 2 files changed, 13 insertions(+), 17 deletions(-) Acked-by: Tariq Toukan Thanks.
Re: [PATCH v4 net-next 04/13] mlx4: rx_headroom is a per port attribute
On 08/03/2017 6:17 PM, Eric Dumazet wrote: No need to duplicate it per RX queue / frags. Signed-off-by: Eric Dumazet --- drivers/net/ethernet/mellanox/mlx4/en_rx.c | 6 +++--- drivers/net/ethernet/mellanox/mlx4/mlx4_en.h | 2 +- 2 files changed, 4 insertions(+), 4 deletions(-) Acked-by: Tariq Toukan Thanks.
Re: [PATCH v4 net-next 05/13] mlx4: reduce rx ring page_cache size
On 08/03/2017 6:17 PM, Eric Dumazet wrote: We only need to store the page and dma address. Signed-off-by: Eric Dumazet --- drivers/net/ethernet/mellanox/mlx4/en_rx.c | 17 ++--- drivers/net/ethernet/mellanox/mlx4/en_tx.c | 2 -- drivers/net/ethernet/mellanox/mlx4/mlx4_en.h | 6 +- 3 files changed, 15 insertions(+), 10 deletions(-) Acked-by: Tariq Toukan Thanks.
Re: [PATCH v4 net-next 06/13] mlx4: removal of frag_sizes[]
On 08/03/2017 6:17 PM, Eric Dumazet wrote: We will soon use order-0 pages, and frag truesize will more precisely match real sizes. In the new model, we prefer to use <= 2048 bytes fragments, so that we can use page-recycle technique on PAGE_SIZE=4096 arches. We will still pack as much frames as possible on arches with big pages, like PowerPC. Signed-off-by: Eric Dumazet --- drivers/net/ethernet/mellanox/mlx4/en_rx.c | 24 ++-- drivers/net/ethernet/mellanox/mlx4/mlx4_en.h | 8 2 files changed, 10 insertions(+), 22 deletions(-) Acked-by: Tariq Toukan Thanks.
Re: [PATCH v4 net-next 07/13] mlx4: use order-0 pages for RX
On 08/03/2017 6:17 PM, Eric Dumazet wrote: Use of order-3 pages is problematic in some cases. This patch might add three kinds of regression : 1) a CPU performance regression, but we will add later page recycling and performance should be back. 2) TCP receiver could grow its receive window slightly slower, because skb->len/skb->truesize ratio will decrease. This is mostly ok, we prefer being conservative to not risk OOM, and eventually tune TCP better in the future. This is consistent with other drivers using 2048 per ethernet frame. 3) Because we allocate one page per RX slot, we consume more memory for the ring buffers. XDP already had this constraint anyway. Signed-off-by: Eric Dumazet --- drivers/net/ethernet/mellanox/mlx4/en_rx.c | 72 +--- drivers/net/ethernet/mellanox/mlx4/mlx4_en.h | 5 -- 2 files changed, 33 insertions(+), 44 deletions(-) Acked-by: Tariq Toukan Thanks.
Re: [PATCH v4 net-next 09/13] mlx4: add rx_alloc_pages counter in ethtool -S
On 08/03/2017 6:17 PM, Eric Dumazet wrote: This new counter tracks number of pages that we allocated for one port. lpaa24:~# ethtool -S eth0 | egrep 'rx_alloc_pages|rx_packets' rx_packets: 306755183 rx_alloc_pages: 932897 Signed-off-by: Eric Dumazet --- drivers/net/ethernet/mellanox/mlx4/en_ethtool.c | 2 +- drivers/net/ethernet/mellanox/mlx4/en_port.c| 2 ++ drivers/net/ethernet/mellanox/mlx4/en_rx.c | 11 +++ drivers/net/ethernet/mellanox/mlx4/mlx4_en.h| 1 + drivers/net/ethernet/mellanox/mlx4/mlx4_stats.h | 2 +- 5 files changed, 12 insertions(+), 6 deletions(-) Acked-by: Tariq Toukan Thanks.
Re: [PATCH v4 net-next 08/13] mlx4: add page recycling in receive path
On 08/03/2017 6:17 PM, Eric Dumazet wrote: Same technique than some Intel drivers, for arches where PAGE_SIZE = 4096 In most cases, pages are reused because they were consumed before we could loop around the RX ring. This brings back performance, and is even better, a single TCP flow reaches 30Gbit on my hosts. v2: added full memset() in mlx4_en_free_frag(), as Tariq found it was needed if we switch to large MTU, as priv->log_rx_info can dynamically be changed. Signed-off-by: Eric Dumazet --- drivers/net/ethernet/mellanox/mlx4/en_rx.c | 258 +-- drivers/net/ethernet/mellanox/mlx4/mlx4_en.h | 1 - 2 files changed, 82 insertions(+), 177 deletions(-) Acked-by: Tariq Toukan Thanks.
Re: [PATCH v4 net-next 10/13] mlx4: do not access rx_desc from mlx4_en_process_rx_cq()
On 08/03/2017 6:17 PM, Eric Dumazet wrote: Instead of fetching dma address from rx_desc->data[0].addr, prefer using frags[0].dma + frags[0].page_offset to avoid a potential cache line miss. Signed-off-by: Eric Dumazet --- drivers/net/ethernet/mellanox/mlx4/en_rx.c | 9 +++-- 1 file changed, 3 insertions(+), 6 deletions(-) Acked-by: Tariq Toukan Thanks.
Re: [PATCH v4 net-next 13/13] mlx4: remove duplicate code in mlx4_en_process_rx_cq()
On 08/03/2017 6:17 PM, Eric Dumazet wrote: We should keep one way to build skbs, regardless of GRO being on or off. Note that I made sure to defer as much as possible the point we need to pull data from the frame, so that future prefetch() we might add are more effective. These skb attributes derive from the CQE or ring : ip_summed, csum hash vlan offload hwtstamps queue_mapping As a bonus, this patch removes mlx4 dependency on eth_get_headlen() which is very often broken enough to give us headaches. Signed-off-by: Eric Dumazet --- drivers/net/ethernet/mellanox/mlx4/en_rx.c | 209 ++--- 1 file changed, 41 insertions(+), 168 deletions(-) Acked-by: Tariq Toukan Thanks.
Re: [net/bpf] 3051bf36c2 BUG: unable to handle kernel paging request at 0000a7cf
On 03/09/2017 02:10 PM, Thomas Gleixner wrote: On Thu, 9 Mar 2017, Daniel Borkmann wrote: With regard to CPA_FLUSHTLB that Linus mentioned, when I investigated code paths in change_page_attr_set_clr(), I did see that CPA_FLUSHTLB was set each time we switched attrs and a cpa_flush_range() was performed (with the correct number of pages and cache set to 0). That would be a __flush_tlb_all() eventually. Hmm, it indeed might seem likely that this could be an emulation bug. Which variant of __flush_tlb_all() is used when the test fails? Check for the following flags in /proc/cpuinfo: pge invpcid I added the following and booted with both variants: printk("X86_FEATURE_PGE:%u\n", static_cpu_has(X86_FEATURE_PGE)); printk("X86_FEATURE_INVPCID:%u\n", static_cpu_has(X86_FEATURE_INVPCID)); "-cpu host" gives: [8.326117] X86_FEATURE_PGE:1 [8.326381] X86_FEATURE_INVPCID:1 "-cpu kvm64" gives: [8.517069] X86_FEATURE_PGE:1 [8.517393] X86_FEATURE_INVPCID:0 Thanks, Daniel
Re: [PATCH v4 net-next 11/13] mlx4: factorize page_address() calls
On 08/03/2017 6:17 PM, Eric Dumazet wrote: We need to compute the frame virtual address at different points. Do it once. Following patch will use the new va address for validate_loopback() Signed-off-by: Eric Dumazet --- drivers/net/ethernet/mellanox/mlx4/en_rx.c | 15 +++ 1 file changed, 7 insertions(+), 8 deletions(-) Acked-by: Tariq Toukan Thanks.
Re: [PATCH v4 net-next 12/13] mlx4: make validate_loopback() more generic
On 08/03/2017 6:17 PM, Eric Dumazet wrote: Testing a boolean in fast path is not worth duplicating the code allocating packets, when GRO is on or off. If this proves to be a problem, we might later use a jump label. Next patch will remove this duplicated code and ease code review. Signed-off-by: Eric Dumazet --- drivers/net/ethernet/mellanox/mlx4/en_rx.c | 23 ++- drivers/net/ethernet/mellanox/mlx4/en_selftest.c | 6 -- 2 files changed, 10 insertions(+), 19 deletions(-) Acked-by: Tariq Toukan Thanks.
Re: [PATCH v4 net-next 01/13] mlx4: dma_dir is a mlx4_en_priv attribute
On 08/03/2017 6:17 PM, Eric Dumazet wrote: No need to duplicate it for all queues and frags. num_frags & log_rx_info become u8 to save space. u8 accesses are a bit faster than u16 anyway. Signed-off-by: Eric Dumazet --- drivers/net/ethernet/mellanox/mlx4/en_rx.c | 16 drivers/net/ethernet/mellanox/mlx4/en_tx.c | 2 +- drivers/net/ethernet/mellanox/mlx4/mlx4_en.h | 6 +++--- 3 files changed, 12 insertions(+), 12 deletions(-) Acked-by: Tariq Toukan Thanks.
[net-next v2 00/10] QorIQ DPAA 1 updates
This patch set introduces a series of fixes and features to the DPAA 1 drivers. Besides activating hardware Rx checksum offloading, four traffic classes are added for Tx traffic prioritisation. The changes are also available on the dpaa_eth-next branch in the git repository at: git://git.freescale.com/ppc/upstream/linux.git changes from v1: added patch to enable context-A stashing Camelia Groza (2): dpaa_eth: add four prioritised Tx traffic classes dpaa_eth: enable multiple Tx traffic classes Madalin Bucur (8): fsl/fman: parse result data is big endian fsl/fman: set HW parser as BMI next engine fsl/fman: remove wrong free fsl/fman: enlarge FIFO to allow for the 5th port dpaa_eth: remove redundant initialization dpaa_eth: enable Rx checksum offload dpaa_eth: do not ignore port api return value dpaa_eth: enable context-A stashing drivers/net/ethernet/freescale/dpaa/dpaa_eth.c | 178 +++- drivers/net/ethernet/freescale/dpaa/dpaa_eth.h | 8 +- drivers/net/ethernet/freescale/fman/fman.c | 23 ++- drivers/net/ethernet/freescale/fman/fman.h | 10 +- drivers/net/ethernet/freescale/fman/fman_port.c | 76 +- 5 files changed, 248 insertions(+), 47 deletions(-) -- 2.1.0
[net-next v2 03/10] fsl/fman: remove wrong free
Reported-by: Dan Carpenter Signed-off-by: Madalin Bucur --- drivers/net/ethernet/freescale/fman/fman_port.c | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/drivers/net/ethernet/freescale/fman/fman_port.c b/drivers/net/ethernet/freescale/fman/fman_port.c index f314348..57bf44f 100644 --- a/drivers/net/ethernet/freescale/fman/fman_port.c +++ b/drivers/net/ethernet/freescale/fman/fman_port.c @@ -1312,7 +1312,7 @@ int fman_port_config(struct fman_port *port, struct fman_port_params *params) /* Allocate the FM driver's parameters structure */ port->cfg = kzalloc(sizeof(*port->cfg), GFP_KERNEL); if (!port->cfg) - goto err_params; + return -EINVAL; /* Initialize FM port parameters which will be kept by the driver */ port->port_type = port->dts_params.type; @@ -1393,8 +1393,6 @@ int fman_port_config(struct fman_port *port, struct fman_port_params *params) err_port_cfg: kfree(port->cfg); -err_params: - kfree(port); return -EINVAL; } EXPORT_SYMBOL(fman_port_config); -- 2.1.0
[net-next v2 02/10] fsl/fman: set HW parser as BMI next engine
Enable the HW parser for all DPAA interfaces. Signed-off-by: Madalin Bucur --- drivers/net/ethernet/freescale/fman/fman.c | 21 drivers/net/ethernet/freescale/fman/fman_port.c | 72 +++-- 2 files changed, 90 insertions(+), 3 deletions(-) diff --git a/drivers/net/ethernet/freescale/fman/fman.c b/drivers/net/ethernet/freescale/fman/fman.c index f60845f..d755930 100644 --- a/drivers/net/ethernet/freescale/fman/fman.c +++ b/drivers/net/ethernet/freescale/fman/fman.c @@ -59,6 +59,7 @@ #define DMA_OFFSET 0x000C2000 #define FPM_OFFSET 0x000C3000 #define IMEM_OFFSET0x000C4000 +#define HWP_OFFSET 0x000C7000 #define CGP_OFFSET 0x000DB000 /* Exceptions bit map */ @@ -218,6 +219,9 @@ #define QMI_GS_HALT_NOT_BUSY 0x0002 +/* HWP defines */ +#define HWP_RPIMAC_PEN 0x0001 + /* IRAM defines */ #define IRAM_IADD_AIE 0x8000 #define IRAM_READY 0x8000 @@ -475,6 +479,12 @@ struct fman_dma_regs { u32 res00e0[0x400 - 56]; }; +struct fman_hwp_regs { + u32 res[0x844 / 4]; /* 0x000..0x843 */ + u32 fmprrpimac; /* FM Parser Internal memory access control */ + u32 res[(0x1000 - 0x848) / 4]; /* 0x848..0xFFF */ +}; + /* Structure that holds current FMan state. * Used for saving run time information. */ @@ -606,6 +616,7 @@ struct fman { struct fman_bmi_regs __iomem *bmi_regs; struct fman_qmi_regs __iomem *qmi_regs; struct fman_dma_regs __iomem *dma_regs; + struct fman_hwp_regs __iomem *hwp_regs; fman_exceptions_cb *exception_cb; fman_bus_error_cb *bus_error_cb; /* Spinlock for FMan use */ @@ -999,6 +1010,12 @@ static void qmi_init(struct fman_qmi_regs __iomem *qmi_rg, iowrite32be(tmp_reg, &qmi_rg->fmqm_ien); } +static void hwp_init(struct fman_hwp_regs __iomem *hwp_rg) +{ + /* enable HW Parser */ + iowrite32be(HWP_RPIMAC_PEN, &hwp_rg->fmprrpimac); +} + static int enable(struct fman *fman, struct fman_cfg *cfg) { u32 cfg_reg = 0; @@ -1793,6 +1810,7 @@ static int fman_config(struct fman *fman) fman->bmi_regs = base_addr + BMI_OFFSET; fman->qmi_regs = base_addr + QMI_OFFSET; fman->dma_regs = base_addr + DMA_OFFSET; + fman->hwp_regs = base_addr + HWP_OFFSET; fman->base_addr = base_addr; spin_lock_init(&fman->spinlock); @@ -2062,6 +2080,9 @@ static int fman_init(struct fman *fman) /* Init QMI Registers */ qmi_init(fman->qmi_regs, fman->cfg); + /* Init HW Parser */ + hwp_init(fman->hwp_regs); + err = enable(fman, cfg); if (err != 0) return err; diff --git a/drivers/net/ethernet/freescale/fman/fman_port.c b/drivers/net/ethernet/freescale/fman/fman_port.c index 9f3bb50..f314348 100644 --- a/drivers/net/ethernet/freescale/fman/fman_port.c +++ b/drivers/net/ethernet/freescale/fman/fman_port.c @@ -62,6 +62,7 @@ #define BMI_PORT_REGS_OFFSET 0 #define QMI_PORT_REGS_OFFSET 0x400 +#define HWP_PORT_REGS_OFFSET 0x800 /* Default values */ #define DFLT_PORT_BUFFER_PREFIX_CONTEXT_DATA_ALIGN \ @@ -182,7 +183,7 @@ #define NIA_ENG_BMI0x0050 #define NIA_ENG_QMI_ENQ0x0054 #define NIA_ENG_QMI_DEQ0x0058 - +#define NIA_ENG_HWP0x0044 #define NIA_BMI_AC_ENQ_FRAME 0x0002 #define NIA_BMI_AC_TX_RELEASE 0x02C0 #define NIA_BMI_AC_RELEASE 0x00C0 @@ -317,6 +318,19 @@ struct fman_port_qmi_regs { u32 fmqm_pndcc; /* PortID n Dequeue Confirm Counter */ }; +#define HWP_HXS_COUNT 16 +#define HWP_HXS_PHE_REPORT 0x0800 +#define HWP_HXS_PCAC_PSTAT 0x0100 +#define HWP_HXS_PCAC_PSTOP 0x0001 +struct fman_port_hwp_regs { + struct { + u32 ssa; /* Soft Sequence Attachment */ + u32 lcv; /* Line-up Enable Confirmation Mask */ + } pmda[HWP_HXS_COUNT]; /* Parse Memory Direct Access Registers */ + u32 reserved080[(0x3f8 - 0x080) / 4]; /* (0x080-0x3f7) */ + u32 fmpr_pcac; /* Configuration Access Control */ +}; + /* QMI dequeue prefetch modes */ enum fman_port_deq_prefetch { FMAN_PORT_DEQ_NO_PREFETCH, /* No prefetch mode */ @@ -436,6 +450,7 @@ struct fman_port { union fman_port_bmi_regs __iomem *bmi_regs; struct fman_port_qmi_regs __iomem *qmi_regs; + struct fman_port_hwp_regs __iomem *hwp_regs; struct fman_sp_buffer_offsets buffer_offsets; @@ -521,9 +536,12 @@ static int init_bmi_rx(struct fman_port *port) /* NIA */ tmp = (u32)cfg->rx_fd_bits << BMI_NEXT_ENG_FD_BITS_S
[net-next v2 01/10] fsl/fman: parse result data is big endian
Signed-off-by: Madalin Bucur --- drivers/net/ethernet/freescale/fman/fman.h | 10 +- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/drivers/net/ethernet/freescale/fman/fman.h b/drivers/net/ethernet/freescale/fman/fman.h index 57aae8d..f53e147 100644 --- a/drivers/net/ethernet/freescale/fman/fman.h +++ b/drivers/net/ethernet/freescale/fman/fman.h @@ -134,14 +134,14 @@ enum fman_exceptions { struct fman_prs_result { u8 lpid;/* Logical port id */ u8 shimr; /* Shim header result */ - u16 l2r;/* Layer 2 result */ - u16 l3r;/* Layer 3 result */ + __be16 l2r; /* Layer 2 result */ + __be16 l3r; /* Layer 3 result */ u8 l4r; /* Layer 4 result */ u8 cplan; /* Classification plan id */ - u16 nxthdr; /* Next Header */ - u16 cksum; /* Running-sum */ + __be16 nxthdr; /* Next Header */ + __be16 cksum; /* Running-sum */ /* Flags&fragment-offset field of the last IP-header */ - u16 flags_frag_off; + __be16 flags_frag_off; /* Routing type field of a IPV6 routing extension header */ u8 route_type; /* Routing Extension Header Present; last bit is IP valid */ -- 2.1.0
Re: [PATCH v4 net-next 00/13] mlx4: order-0 allocations and page recycling
On Thu, Mar 9, 2017 at 5:49 AM, Tariq Toukan wrote: > Hi Eric, > > I was preparing this series for submission as well. > You got it done first :) > > Thanks for re-submitting. > I am Acking the patches now. I believe you also could have added a single Ack on this cover, instead of one ack per element in the series. David can you tell us if this is true ? Thanks Tariq !
Re: [PATCH v2 2/2] can: spi: hi311x: Add Holt HI-311x CAN driver
Hello Akshay, Am 09.03.2017 um 13:34 schrieb Akshay Bhat: On 03/09/2017 04:59 AM, Wolfgang Grandegger wrote: Hello Akshay, unfortunately there are not many CAN controllers for the SPI bus. I just know the MPC251x, which behaves badly (message losses) under Linux, especially at hight bit-rates due to insufficient RX buffering. What is your experience with that driver for the HI-311x? Hi Wolfgang, Good question. I have not worked with MPC251x but the HI-311x performs much better because HI-3110 features: 8 message FIFO (as opposed to 2 buffers on MPC2510) 20 MHz SPI interface (as opposed to 2.5 MHz on MPC2510) As for the real world test results: With RT patch applied to the kernel running on a i.MX6 Dual processor (worst case interrupt latency of 50us as reported by cyclictest), there are ZERO packet drops. Tested with Kvaser Leaf sending 100 burst messages (back to back) every 40ms at a 1M CAN bit rate. 10 million messages were sent by the Kvaser leaf and received successfully by the HI-311x driver. This corresponds to a bus load of approx. 50%, I think? Even without the RT patch, I was able to get the packet drop to zero but this was by moving the CAN/SPI IRQ threads to CPU1 instead of CPU0. Vanilla Linux is more critical here due to higher latencies. With 2500 Messages per sec the RX FIFO (8 Messages) fills up within 3.2 ms... and in a burst even quicker. That's already heavy load. Wolfgang.
Re: [net/bpf] 3051bf36c2 BUG: unable to handle kernel paging request at 0000a7cf
On Thu, 9 Mar 2017, Daniel Borkmann wrote: > On 03/09/2017 02:10 PM, Thomas Gleixner wrote: > > On Thu, 9 Mar 2017, Daniel Borkmann wrote: > > > With regard to CPA_FLUSHTLB that Linus mentioned, when I investigated > > > code paths in change_page_attr_set_clr(), I did see that CPA_FLUSHTLB > > > was set each time we switched attrs and a cpa_flush_range() was > > > performed (with the correct number of pages and cache set to 0). That > > > would be a __flush_tlb_all() eventually. > > > > > > Hmm, it indeed might seem likely that this could be an emulation bug. > > > > Which variant of __flush_tlb_all() is used when the test fails? > > > > Check for the following flags in /proc/cpuinfo: pge invpcid > > I added the following and booted with both variants: > > printk("X86_FEATURE_PGE:%u\n", static_cpu_has(X86_FEATURE_PGE)); > printk("X86_FEATURE_INVPCID:%u\n", static_cpu_has(X86_FEATURE_INVPCID)); > > "-cpu host" gives: > > [8.326117] X86_FEATURE_PGE:1 > [8.326381] X86_FEATURE_INVPCID:1 > > "-cpu kvm64" gives: > > [8.517069] X86_FEATURE_PGE:1 > [8.517393] X86_FEATURE_INVPCID:0 That's the one which fails. So it's using the CR4 based flushing. Just ran a test on a physical system with PGE=1 and INVPCID=0. Works fine. Emulation problem? Thanks, tglx
[net-next v2 05/10] dpaa_eth: remove redundant initialization
Signed-off-by: Madalin Bucur --- drivers/net/ethernet/freescale/dpaa/dpaa_eth.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/net/ethernet/freescale/dpaa/dpaa_eth.c b/drivers/net/ethernet/freescale/dpaa/dpaa_eth.c index e2ca107..e19181f 100644 --- a/drivers/net/ethernet/freescale/dpaa/dpaa_eth.c +++ b/drivers/net/ethernet/freescale/dpaa/dpaa_eth.c @@ -2093,7 +2093,7 @@ static enum qman_cb_dqrr_result rx_default_dqrr(struct qman_portal *portal, dma_addr_t addr = qm_fd_addr(fd); enum qm_fd_format fd_format; struct net_device *net_dev; - u32 fd_status = fd->status; + u32 fd_status; struct dpaa_bp *dpaa_bp; struct dpaa_priv *priv; unsigned int skb_len; -- 2.1.0
Re: stmmac still supporting spear600 ?
Hello Thomas On 3/9/2017 10:32 AM, Thomas Petazzoni wrote: OK, I'll have a look. However, I'm still confused by this DMA_RESET bit that never clears, contrary to what the datasheet says. Are there some erratas? I suggest you to take a look at the tx/rx clocks from PHY. You have to provide these otherwise you cannot reset the engine. Best Regards Peppe Best regards, Thomas
[net-next v2 07/10] dpaa_eth: do not ignore port api return value
Reported-by: Dan Carpenter Signed-off-by: Madalin Bucur --- drivers/net/ethernet/freescale/dpaa/dpaa_eth.c | 65 +- 1 file changed, 43 insertions(+), 22 deletions(-) diff --git a/drivers/net/ethernet/freescale/dpaa/dpaa_eth.c b/drivers/net/ethernet/freescale/dpaa/dpaa_eth.c index a7a595c..ae64cdb 100644 --- a/drivers/net/ethernet/freescale/dpaa/dpaa_eth.c +++ b/drivers/net/ethernet/freescale/dpaa/dpaa_eth.c @@ -1063,9 +1063,9 @@ static int dpaa_fq_free(struct device *dev, struct list_head *list) return err; } -static void dpaa_eth_init_tx_port(struct fman_port *port, struct dpaa_fq *errq, - struct dpaa_fq *defq, - struct dpaa_buffer_layout *buf_layout) +static int dpaa_eth_init_tx_port(struct fman_port *port, struct dpaa_fq *errq, +struct dpaa_fq *defq, +struct dpaa_buffer_layout *buf_layout) { struct fman_buffer_prefix_content buf_prefix_content; struct fman_port_params params; @@ -1084,23 +1084,29 @@ static void dpaa_eth_init_tx_port(struct fman_port *port, struct dpaa_fq *errq, params.specific_params.non_rx_params.dflt_fqid = defq->fqid; err = fman_port_config(port, ¶ms); - if (err) + if (err) { pr_err("%s: fman_port_config failed\n", __func__); + return err; + } err = fman_port_cfg_buf_prefix_content(port, &buf_prefix_content); - if (err) + if (err) { pr_err("%s: fman_port_cfg_buf_prefix_content failed\n", __func__); + return err; + } err = fman_port_init(port); if (err) pr_err("%s: fm_port_init failed\n", __func__); + + return err; } -static void dpaa_eth_init_rx_port(struct fman_port *port, struct dpaa_bp **bps, - size_t count, struct dpaa_fq *errq, - struct dpaa_fq *defq, - struct dpaa_buffer_layout *buf_layout) +static int dpaa_eth_init_rx_port(struct fman_port *port, struct dpaa_bp **bps, +size_t count, struct dpaa_fq *errq, +struct dpaa_fq *defq, +struct dpaa_buffer_layout *buf_layout) { struct fman_buffer_prefix_content buf_prefix_content; struct fman_port_rx_params *rx_p; @@ -1128,32 +1134,44 @@ static void dpaa_eth_init_rx_port(struct fman_port *port, struct dpaa_bp **bps, } err = fman_port_config(port, ¶ms); - if (err) + if (err) { pr_err("%s: fman_port_config failed\n", __func__); + return err; + } err = fman_port_cfg_buf_prefix_content(port, &buf_prefix_content); - if (err) + if (err) { pr_err("%s: fman_port_cfg_buf_prefix_content failed\n", __func__); + return err; + } err = fman_port_init(port); if (err) pr_err("%s: fm_port_init failed\n", __func__); + + return err; } -static void dpaa_eth_init_ports(struct mac_device *mac_dev, - struct dpaa_bp **bps, size_t count, - struct fm_port_fqs *port_fqs, - struct dpaa_buffer_layout *buf_layout, - struct device *dev) +static int dpaa_eth_init_ports(struct mac_device *mac_dev, + struct dpaa_bp **bps, size_t count, + struct fm_port_fqs *port_fqs, + struct dpaa_buffer_layout *buf_layout, + struct device *dev) { struct fman_port *rxport = mac_dev->port[RX]; struct fman_port *txport = mac_dev->port[TX]; + int err; - dpaa_eth_init_tx_port(txport, port_fqs->tx_errq, - port_fqs->tx_defq, &buf_layout[TX]); - dpaa_eth_init_rx_port(rxport, bps, count, port_fqs->rx_errq, - port_fqs->rx_defq, &buf_layout[RX]); + err = dpaa_eth_init_tx_port(txport, port_fqs->tx_errq, + port_fqs->tx_defq, &buf_layout[TX]); + if (err) + return err; + + err = dpaa_eth_init_rx_port(rxport, bps, count, port_fqs->rx_errq, + port_fqs->rx_defq, &buf_layout[RX]); + + return err; } static int dpaa_bman_release(const struct dpaa_bp *dpaa_bp, @@ -2649,8 +2667,10 @@ static int dpaa_eth_probe(struct platform_device *pdev) priv->rx_headroom = dpaa_get_headroom(&priv->buf_layout[RX]); /* All real interfaces need their ports initialized */ - dpaa_eth_init_ports(mac_dev, dpaa_bps, DPAA_BPS_NUM, &port_fqs, - &priv->buf_layout[0], dev); + err = dpaa
[net-next v2 04/10] fsl/fman: enlarge FIFO to allow for the 5th port
Signed-off-by: Madalin Bucur --- drivers/net/ethernet/freescale/fman/fman.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/net/ethernet/freescale/fman/fman.c b/drivers/net/ethernet/freescale/fman/fman.c index d755930..4aefe24 100644 --- a/drivers/net/ethernet/freescale/fman/fman.c +++ b/drivers/net/ethernet/freescale/fman/fman.c @@ -1212,7 +1212,7 @@ static int fill_soc_specific_params(struct fman_state_struct *state) state->max_num_of_open_dmas = 32; state->fm_port_num_of_cg= 256; state->num_of_rx_ports = 6; - state->total_fifo_size = 122 * 1024; + state->total_fifo_size = 136 * 1024; break; case 2: -- 2.1.0
[net-next v2 08/10] dpaa_eth: add four prioritised Tx traffic classes
From: Camelia Groza Each traffic class corresponds to a WQ priority level. The number of Tx netdev queues and frame queues is increased to NR_CPUS queues for each traffic class. In addition, the priority of the Rx, Error and Conf queues is lowered but their order is maintained. By default, only one traffic class is enabled, only the low priority Tx queues are used and only the corresponding netdev queues are advertised. Signed-off-by: Camelia Groza Signed-off-by: Madalin Bucur --- drivers/net/ethernet/freescale/dpaa/dpaa_eth.c | 43 +- drivers/net/ethernet/freescale/dpaa/dpaa_eth.h | 8 - 2 files changed, 42 insertions(+), 9 deletions(-) diff --git a/drivers/net/ethernet/freescale/dpaa/dpaa_eth.c b/drivers/net/ethernet/freescale/dpaa/dpaa_eth.c index ae64cdb..ac75d09 100644 --- a/drivers/net/ethernet/freescale/dpaa/dpaa_eth.c +++ b/drivers/net/ethernet/freescale/dpaa/dpaa_eth.c @@ -565,16 +565,18 @@ static void dpaa_bps_free(struct dpaa_priv *priv) /* Use multiple WQs for FQ assignment: * - Tx Confirmation queues go to WQ1. - * - Rx Error and Tx Error queues go to WQ2 (giving them a better chance - * to be scheduled, in case there are many more FQs in WQ3). - * - Rx Default and Tx queues go to WQ3 (no differentiation between - * Rx and Tx traffic). + * - Rx Error and Tx Error queues go to WQ5 (giving them a better chance + * to be scheduled, in case there are many more FQs in WQ6). + * - Rx Default goes to WQ6. + * - Tx queues go to different WQs depending on their priority. Equal + * chunks of NR_CPUS queues go to WQ6 (lowest priority), WQ2, WQ1 and + * WQ0 (highest priority). * This ensures that Tx-confirmed buffers are timely released. In particular, * it avoids congestion on the Tx Confirm FQs, which can pile up PFDRs if they * are greatly outnumbered by other FQs in the system, while * dequeue scheduling is round-robin. */ -static inline void dpaa_assign_wq(struct dpaa_fq *fq) +static inline void dpaa_assign_wq(struct dpaa_fq *fq, int idx) { switch (fq->fq_type) { case FQ_TYPE_TX_CONFIRM: @@ -583,11 +585,33 @@ static inline void dpaa_assign_wq(struct dpaa_fq *fq) break; case FQ_TYPE_RX_ERROR: case FQ_TYPE_TX_ERROR: - fq->wq = 2; + fq->wq = 5; break; case FQ_TYPE_RX_DEFAULT: + fq->wq = 6; + break; case FQ_TYPE_TX: - fq->wq = 3; + switch (idx / DPAA_TC_TXQ_NUM) { + case 0: + /* Low priority (best effort) */ + fq->wq = 6; + break; + case 1: + /* Medium priority */ + fq->wq = 2; + break; + case 2: + /* High priority */ + fq->wq = 1; + break; + case 3: + /* Very high priority */ + fq->wq = 0; + break; + default: + WARN(1, "Too many TX FQs: more than %d!\n", +DPAA_ETH_TXQ_NUM); + } break; default: WARN(1, "Invalid FQ type %d for FQID %d!\n", @@ -615,7 +639,7 @@ static struct dpaa_fq *dpaa_fq_alloc(struct device *dev, } for (i = 0; i < count; i++) - dpaa_assign_wq(dpaa_fq + i); + dpaa_assign_wq(dpaa_fq + i, i); return dpaa_fq; } @@ -2683,6 +2707,9 @@ static int dpaa_eth_probe(struct platform_device *pdev) memset(percpu_priv, 0, sizeof(*percpu_priv)); } + priv->num_tc = 1; + netif_set_real_num_tx_queues(net_dev, priv->num_tc * DPAA_TC_TXQ_NUM); + /* Initialize NAPI */ err = dpaa_napi_add(net_dev); if (err < 0) diff --git a/drivers/net/ethernet/freescale/dpaa/dpaa_eth.h b/drivers/net/ethernet/freescale/dpaa/dpaa_eth.h index 1f9aebf..9941a78 100644 --- a/drivers/net/ethernet/freescale/dpaa/dpaa_eth.h +++ b/drivers/net/ethernet/freescale/dpaa/dpaa_eth.h @@ -39,7 +39,12 @@ #include "mac.h" #include "dpaa_eth_trace.h" -#define DPAA_ETH_TXQ_NUM NR_CPUS +/* Number of prioritised traffic classes */ +#define DPAA_TC_NUM4 +/* Number of Tx queues per traffic class */ +#define DPAA_TC_TXQ_NUMNR_CPUS +/* Total number of Tx queues */ +#define DPAA_ETH_TXQ_NUM (DPAA_TC_NUM * DPAA_TC_TXQ_NUM) #define DPAA_BPS_NUM 3 /* number of bpools per interface */ @@ -152,6 +157,7 @@ struct dpaa_priv { u16 channel; struct list_head dpaa_fq_list; + u8 num_tc; u32 msg_enable; /* net_device message level */ struct { -- 2.1.0
[net-next v2 10/10] dpaa_eth: enable context-A stashing
Signed-off-by: Madalin Bucur --- drivers/net/ethernet/freescale/dpaa/dpaa_eth.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/drivers/net/ethernet/freescale/dpaa/dpaa_eth.c b/drivers/net/ethernet/freescale/dpaa/dpaa_eth.c index 1b3ea38..aa769cb 100644 --- a/drivers/net/ethernet/freescale/dpaa/dpaa_eth.c +++ b/drivers/net/ethernet/freescale/dpaa/dpaa_eth.c @@ -1052,7 +1052,8 @@ static int dpaa_fq_init(struct dpaa_fq *dpaa_fq, bool td_enable) /* Initialization common to all ingress queues */ if (dpaa_fq->flags & QMAN_FQ_FLAG_NO_ENQUEUE) { initfq.we_mask |= cpu_to_be16(QM_INITFQ_WE_CONTEXTA); - initfq.fqd.fq_ctrl |= cpu_to_be16(QM_FQCTRL_HOLDACTIVE); + initfq.fqd.fq_ctrl |= cpu_to_be16(QM_FQCTRL_HOLDACTIVE | + QM_FQCTRL_CTXASTASHING); initfq.fqd.context_a.stashing.exclusive = QM_STASHING_EXCL_DATA | QM_STASHING_EXCL_CTX | QM_STASHING_EXCL_ANNOTATION; -- 2.1.0
Re: [net/bpf] 3051bf36c2 BUG: unable to handle kernel paging request at 0000a7cf
On 03/09/2017 02:25 PM, Daniel Borkmann wrote: On 03/09/2017 02:10 PM, Thomas Gleixner wrote: On Thu, 9 Mar 2017, Daniel Borkmann wrote: With regard to CPA_FLUSHTLB that Linus mentioned, when I investigated code paths in change_page_attr_set_clr(), I did see that CPA_FLUSHTLB was set each time we switched attrs and a cpa_flush_range() was performed (with the correct number of pages and cache set to 0). That would be a __flush_tlb_all() eventually. Hmm, it indeed might seem likely that this could be an emulation bug. Which variant of __flush_tlb_all() is used when the test fails? Check for the following flags in /proc/cpuinfo: pge invpcid I added the following and booted with both variants: printk("X86_FEATURE_PGE:%u\n", static_cpu_has(X86_FEATURE_PGE)); printk("X86_FEATURE_INVPCID:%u\n", static_cpu_has(X86_FEATURE_INVPCID)); "-cpu host" gives: [8.326117] X86_FEATURE_PGE:1 [8.326381] X86_FEATURE_INVPCID:1 "-cpu kvm64" gives: [8.517069] X86_FEATURE_PGE:1 [8.517393] X86_FEATURE_INVPCID:0 Fwiw, I tried switching from using cr4 (__native_flush_tlb_global_irq_disabled()) to slower cr3 (__native_flush_tlb()) in "-cpu kvm64" mode, and it looks like it also lets all test cases pass (rodata_test, test_setmem, test_bpf), no corruption happening, etc. Test diff used: diff --git a/arch/x86/include/asm/tlbflush.h b/arch/x86/include/asm/tlbflush.h index 6fa8594..34f4582 100644 --- a/arch/x86/include/asm/tlbflush.h +++ b/arch/x86/include/asm/tlbflush.h @@ -188,9 +188,9 @@ static inline void __native_flush_tlb_single(unsigned long addr) static inline void __flush_tlb_all(void) { - if (static_cpu_has(X86_FEATURE_PGE)) - __flush_tlb_global(); - else +// if (static_cpu_has(X86_FEATURE_PGE)) +// __flush_tlb_global(); +// else __flush_tlb(); }
[net-next v2 06/10] dpaa_eth: enable Rx checksum offload
Use the FMan HW parser L4CV flag to offload Rx checksumming. Signed-off-by: Madalin Bucur --- drivers/net/ethernet/freescale/dpaa/dpaa_eth.c | 29 -- 1 file changed, 27 insertions(+), 2 deletions(-) diff --git a/drivers/net/ethernet/freescale/dpaa/dpaa_eth.c b/drivers/net/ethernet/freescale/dpaa/dpaa_eth.c index e19181f..a7a595c 100644 --- a/drivers/net/ethernet/freescale/dpaa/dpaa_eth.c +++ b/drivers/net/ethernet/freescale/dpaa/dpaa_eth.c @@ -137,6 +137,13 @@ MODULE_PARM_DESC(tx_timeout, "The Tx timeout in ms"); /* L4 Type field: TCP */ #define FM_L4_PARSE_RESULT_TCP 0x20 +/* FD status field indicating whether the FM Parser has attempted to validate + * the L4 csum of the frame. + * Note that having this bit set doesn't necessarily imply that the checksum + * is valid. One would have to check the parse results to find that out. + */ +#define FM_FD_STAT_L4CV 0x0004 + #define DPAA_SGT_MAX_ENTRIES 16 /* maximum number of entries in SG Table */ #define DPAA_BUFF_RELEASE_MAX 8 /* maximum number of buffers released at once */ @@ -235,6 +242,7 @@ static int dpaa_netdev_init(struct net_device *net_dev, * For conformity, we'll still declare GSO explicitly. */ net_dev->features |= NETIF_F_GSO; + net_dev->features |= NETIF_F_RXCSUM; net_dev->priv_flags |= IFF_LIVE_ADDR_CHANGE; /* we do not want shared skbs on TX */ @@ -1526,6 +1534,23 @@ static struct sk_buff *dpaa_cleanup_tx_fd(const struct dpaa_priv *priv, return skb; } +static u8 rx_csum_offload(const struct dpaa_priv *priv, const struct qm_fd *fd) +{ + /* The parser has run and performed L4 checksum validation. +* We know there were no parser errors (and implicitly no +* L4 csum error), otherwise we wouldn't be here. +*/ + if ((priv->net_dev->features & NETIF_F_RXCSUM) && + (be32_to_cpu(fd->status) & FM_FD_STAT_L4CV)) + return CHECKSUM_UNNECESSARY; + + /* We're here because either the parser didn't run or the L4 checksum +* was not verified. This may include the case of a UDP frame with +* checksum zero or an L4 proto other than TCP/UDP +*/ + return CHECKSUM_NONE; +} + /* Build a linear skb around the received buffer. * We are guaranteed there is enough room at the end of the data buffer to * accommodate the shared info area of the skb. @@ -1556,7 +1581,7 @@ static struct sk_buff *contig_fd_to_skb(const struct dpaa_priv *priv, skb_reserve(skb, fd_off); skb_put(skb, qm_fd_get_length(fd)); - skb->ip_summed = CHECKSUM_NONE; + skb->ip_summed = rx_csum_offload(priv, fd); return skb; @@ -1616,7 +1641,7 @@ static struct sk_buff *sg_fd_to_skb(const struct dpaa_priv *priv, if (WARN_ON(unlikely(!skb))) goto free_buffers; - skb->ip_summed = CHECKSUM_NONE; + skb->ip_summed = rx_csum_offload(priv, fd); /* Make sure forwarded skbs will have enough space * on Tx, if extra headers are added. -- 2.1.0
Re: please add some examples to the ip man page
On 3/9/17 3:56 AM, Alexander Alemayhu wrote: > On Wed, Mar 08, 2017 at 03:17:02PM +0800, 積丹尼 Dan Jacobson wrote: >> I see. >> Perhaps on the man page add >> EXAMPLES >>See https://www.kernel.org/doc/Documentation/networking/vrf.txt >>https://www.google.com/search?q=ip+linux+command+usage+examples >> (I thought the latter would be hopeless, but actually found lots!) >> > Actual examples in the page would better than links IMO. git has some > nice examples in gittutorial(7) and giteveryday(7). Maybe that can be > good inspiration? excellent opportunity for an aspiring writer / user to make a contribution to improve iproute2. git clone git://git.kernel.org/pub/scm/linux/kernel/git/shemminger/iproute2.git cd iproute2 commit, send to netdev.
Re: [PATCH v4 net-next 00/13] mlx4: order-0 allocations and page recycling
On 09/03/2017 4:26 PM, Eric Dumazet wrote: On Thu, Mar 9, 2017 at 5:49 AM, Tariq Toukan wrote: Hi Eric, I was preparing this series for submission as well. You got it done first :) Thanks for re-submitting. I am Acking the patches now. I believe you also could have added a single Ack on this cover, instead of one ack per element in the series. I wasn't sure this is possible, I think patchworks doesn't recognize it. Dave, does this work? David can you tell us if this is true ? Thanks Tariq ! You're welcome.
[iproute PATCH] man: ss.8: Add missing protocols to description of -A
The list was missing dccp and sctp protocols. Signed-off-by: Phil Sutter --- man/man8/ss.8 | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/man/man8/ss.8 b/man/man8/ss.8 index 4ef11523b4268..81de69de8042e 100644 --- a/man/man8/ss.8 +++ b/man/man8/ss.8 @@ -132,7 +132,7 @@ Currently the following families are supported: unix, inet, inet6, link, netlink .B \-A QUERY, \-\-query=QUERY, \-\-socket=QUERY List of socket tables to dump, separated by commas. The following identifiers are understood: all, inet, tcp, udp, raw, unix, packet, netlink, unix_dgram, -unix_stream, unix_seqpacket, packet_raw, packet_dgram. +unix_stream, unix_seqpacket, packet_raw, packet_dgram, dccp, sctp. .TP .B \-D FILE, \-\-diag=FILE Do not display anything, just dump raw information about TCP sockets to FILE after applying filters. If FILE is - stdout is used. -- 2.11.0
[net-next v2 09/10] dpaa_eth: enable multiple Tx traffic classes
From: Camelia Groza Implement the setup_tc ndo to configure prioritised Tx traffic classes. Priorities range from 0 (lowest) to 3 (highest). The driver assigns NR_CPUS queues to each traffic class. Signed-off-by: Camelia Groza Signed-off-by: Madalin Bucur --- drivers/net/ethernet/freescale/dpaa/dpaa_eth.c | 36 ++ 1 file changed, 36 insertions(+) diff --git a/drivers/net/ethernet/freescale/dpaa/dpaa_eth.c b/drivers/net/ethernet/freescale/dpaa/dpaa_eth.c index ac75d09..1b3ea38 100644 --- a/drivers/net/ethernet/freescale/dpaa/dpaa_eth.c +++ b/drivers/net/ethernet/freescale/dpaa/dpaa_eth.c @@ -342,6 +342,41 @@ static void dpaa_get_stats64(struct net_device *net_dev, } } +static int dpaa_setup_tc(struct net_device *net_dev, u32 handle, __be16 proto, +struct tc_to_netdev *tc) +{ + struct dpaa_priv *priv = netdev_priv(net_dev); + int i; + + if (tc->type != TC_SETUP_MQPRIO) + return -EINVAL; + + if (tc->tc == priv->num_tc) + return 0; + + if (!tc->tc) { + netdev_reset_tc(net_dev); + goto out; + } + + if (tc->tc > DPAA_TC_NUM) { + netdev_err(net_dev, "Too many traffic classes: max %d supported.\n", + DPAA_TC_NUM); + return -EINVAL; + } + + netdev_set_num_tc(net_dev, tc->tc); + + for (i = 0; i < tc->tc; i++) + netdev_set_tc_queue(net_dev, i, DPAA_TC_TXQ_NUM, + i * DPAA_TC_TXQ_NUM); + +out: + priv->num_tc = tc->tc ? tc->tc : 1; + netif_set_real_num_tx_queues(net_dev, priv->num_tc * DPAA_TC_TXQ_NUM); + return 0; +} + static struct mac_device *dpaa_mac_dev_get(struct platform_device *pdev) { struct platform_device *of_dev; @@ -2417,6 +2452,7 @@ static const struct net_device_ops dpaa_ops = { .ndo_validate_addr = eth_validate_addr, .ndo_set_rx_mode = dpaa_set_rx_mode, .ndo_do_ioctl = dpaa_ioctl, + .ndo_setup_tc = dpaa_setup_tc, }; static int dpaa_napi_add(struct net_device *net_dev) -- 2.1.0
Re: [PATCH v2 2/2] can: spi: hi311x: Add Holt HI-311x CAN driver
Hi Wolfgang, On 03/09/2017 09:45 AM, Wolfgang Grandegger wrote: > Hello Akshay, > > Am 09.03.2017 um 13:34 schrieb Akshay Bhat: >> >> Hi Wolfgang, >> >> Good question. I have not worked with MPC251x but the HI-311x performs >> much better because HI-3110 features: >> 8 message FIFO (as opposed to 2 buffers on MPC2510) >> 20 MHz SPI interface (as opposed to 2.5 MHz on MPC2510) >> >> As for the real world test results: >> >> With RT patch applied to the kernel running on a i.MX6 Dual processor >> (worst case interrupt latency of 50us as reported by cyclictest), there >> are ZERO packet drops. >> Tested with Kvaser Leaf sending 100 burst messages (back to back) every >> 40ms at a 1M CAN bit rate. 10 million messages were sent by the Kvaser >> leaf and received successfully by the HI-311x driver. > > This corresponds to a bus load of approx. 50%, I think? The usecase I tested above was more like ~30% (data payload length was randomized) but I did test with 50% bus load as well without any dropped messages. > >> Even without the RT patch, I was able to get the packet drop to zero but >> this was by moving the CAN/SPI IRQ threads to CPU1 instead of CPU0. > > Vanilla Linux is more critical here due to higher latencies. With 2500 > Messages per sec the RX FIFO (8 Messages) fills up within 3.2 ms... and > in a burst even quicker. That's already heavy load. > I agree with Vanilla Linux is more critical due to higher latencies, however if the frequency governor is set to performance and CAN/SPI threads are moved to another CPU (if that is an option) with SCHED_FIFO setting, the driver is able to keep up even at high bit rates / bursts. I understand SPI based CAN controllers are not ideal choice but for users that do not have any other option, I feel this controller/driver meets their need :) Thanks, Akshay
[PATCH net-next v5 3/7] gtp: merge gtp_get_net and gtp_genl_find_dev
Both function are always used together with the final goal to get the gtp_dev. This simplifies the code by merging them together. The netdevice lookup is changed to use the regular dev_get_by_index. The gtp netdevice list is now only used to find the PDP contexts for imcomming packets. It can be completely eliminated Once the TEID hash is moved into the GTP socket. Signed-off-by: Andreas Schultz --- drivers/net/gtp.c | 146 ++ 1 file changed, 69 insertions(+), 77 deletions(-) diff --git a/drivers/net/gtp.c b/drivers/net/gtp.c index 9aa2b35..74018eb 100644 --- a/drivers/net/gtp.c +++ b/drivers/net/gtp.c @@ -744,21 +744,6 @@ static struct rtnl_link_ops gtp_link_ops __read_mostly = { .fill_info = gtp_fill_info, }; -static struct net *gtp_genl_get_net(struct net *src_net, struct nlattr *tb[]) -{ - struct net *net; - - /* Examine the link attributes and figure out which network namespace -* we are talking about. -*/ - if (tb[GTPA_NET_NS_FD]) - net = get_net_ns_by_fd(nla_get_u32(tb[GTPA_NET_NS_FD])); - else - net = get_net(src_net); - - return net; -} - static int gtp_hashtable_new(struct gtp_dev *gtp, int hsize) { int i; @@ -872,16 +857,30 @@ static int gtp_encap_enable(struct gtp_dev *gtp, struct nlattr *data[]) return 0; } -static struct net_device *gtp_find_dev(struct net *net, int ifindex) +static struct gtp_dev *gtp_find_dev(struct net *src_net, struct nlattr *nla[]) { - struct gtp_net *gn = net_generic(net, gtp_net_id); - struct gtp_dev *gtp; - - list_for_each_entry_rcu(gtp, &gn->gtp_dev_list, list) { - if (ifindex == gtp->dev->ifindex) - return gtp->dev; - } - return NULL; + struct gtp_dev *gtp = NULL; + struct net_device *dev; + struct net *net; + + /* Examine the link attributes and figure out which network namespace +* we are talking about. +*/ + if (nla[GTPA_NET_NS_FD]) + net = get_net_ns_by_fd(nla_get_u32(nla[GTPA_NET_NS_FD])); + else + net = get_net(src_net); + + if (IS_ERR(net)) + return NULL; + + /* Check if there's an existing gtpX device to configure */ + dev = dev_get_by_index_rcu(net, nla_get_u32(nla[GTPA_LINK])); + if (dev->netdev_ops == >p_netdev_ops) + gtp = netdev_priv(dev); + + put_net(net); + return gtp; } static void ipv4_pdp_fill(struct pdp_ctx *pctx, struct genl_info *info) @@ -911,9 +910,9 @@ static void ipv4_pdp_fill(struct pdp_ctx *pctx, struct genl_info *info) } } -static int ipv4_pdp_add(struct net_device *dev, struct genl_info *info) +static int ipv4_pdp_add(struct gtp_dev *gtp, struct genl_info *info) { - struct gtp_dev *gtp = netdev_priv(dev); + struct net_device *dev = gtp->dev; u32 hash_ms, hash_tid = 0; struct pdp_ctx *pctx; bool found = false; @@ -990,8 +989,8 @@ static int ipv4_pdp_add(struct net_device *dev, struct genl_info *info) static int gtp_genl_new_pdp(struct sk_buff *skb, struct genl_info *info) { - struct net_device *dev; - struct net *net; + struct gtp_dev *gtp; + int err; if (!info->attrs[GTPA_VERSION] || !info->attrs[GTPA_LINK] || @@ -1015,77 +1014,79 @@ static int gtp_genl_new_pdp(struct sk_buff *skb, struct genl_info *info) return -EINVAL; } - net = gtp_genl_get_net(sock_net(skb->sk), info->attrs); - if (IS_ERR(net)) - return PTR_ERR(net); + rcu_read_lock(); - /* Check if there's an existing gtpX device to configure */ - dev = gtp_find_dev(net, nla_get_u32(info->attrs[GTPA_LINK])); - if (dev == NULL) { - put_net(net); - return -ENODEV; + gtp = gtp_find_dev(sock_net(skb->sk), info->attrs); + if (!gtp) { + err = -ENODEV; + goto out_unlock; } - put_net(net); - return ipv4_pdp_add(dev, info); + err = ipv4_pdp_add(gtp, info); + +out_unlock: + rcu_read_unlock(); + return err; } static int gtp_genl_del_pdp(struct sk_buff *skb, struct genl_info *info) { - struct net_device *dev; struct pdp_ctx *pctx; struct gtp_dev *gtp; - struct net *net; + int err = 0; if (!info->attrs[GTPA_VERSION] || !info->attrs[GTPA_LINK]) return -EINVAL; - net = gtp_genl_get_net(sock_net(skb->sk), info->attrs); - if (IS_ERR(net)) - return PTR_ERR(net); + rcu_read_lock(); - /* Check if there's an existing gtpX device to configure */ - dev = gtp_find_dev(net, nla_get_u32(info->attrs[GTPA_LINK])); - if (dev == NULL) { - put_net(net); - return -ENODEV; + gtp = gtp_find_dev(s
[PATCH net-next v5 5/7] gtp: unify genl_find_pdp and prepare for per socket lookup
This unifies duplicate code into a helper. It also prepares the groundwork to add a lookup version that uses the socket to find attached pdp contexts. Signed-off-by: Andreas Schultz --- drivers/net/gtp.c | 121 ++ 1 file changed, 50 insertions(+), 71 deletions(-) diff --git a/drivers/net/gtp.c b/drivers/net/gtp.c index 0c6707a..bf4b352 100644 --- a/drivers/net/gtp.c +++ b/drivers/net/gtp.c @@ -1037,55 +1037,67 @@ static int gtp_genl_new_pdp(struct sk_buff *skb, struct genl_info *info) return err; } +static struct pdp_ctx *gtp_find_pdp_by_link(struct net *net, + struct nlattr *nla[]) +{ + struct gtp_dev *gtp; + + gtp = gtp_find_dev(net, nla); + if (!gtp) + return ERR_PTR(-ENODEV); + + if (nla[GTPA_MS_ADDRESS]) { + __be32 ip = nla_get_be32(nla[GTPA_MS_ADDRESS]); + + return ipv4_pdp_find(gtp, ip); + } else if (nla[GTPA_VERSION]) { + u32 gtp_version = nla_get_u32(nla[GTPA_VERSION]); + + if (gtp_version == GTP_V0 && nla[GTPA_TID]) + return gtp0_pdp_find(gtp, nla_get_u64(nla[GTPA_TID])); + else if (gtp_version == GTP_V1 && nla[GTPA_I_TEI]) + return gtp1_pdp_find(gtp, nla_get_u32(nla[GTPA_I_TEI])); + } + + return ERR_PTR(-EINVAL); +} + +static struct pdp_ctx *gtp_find_pdp(struct net *net, struct nlattr *nla[]) +{ + struct pdp_ctx *pctx; + + if (nla[GTPA_LINK]) + pctx = gtp_find_pdp_by_link(net, nla); + else + pctx = ERR_PTR(-EINVAL); + + if (!pctx) + pctx = ERR_PTR(-ENOENT); + + return pctx; +} + static int gtp_genl_del_pdp(struct sk_buff *skb, struct genl_info *info) { struct pdp_ctx *pctx; - struct gtp_dev *gtp; int err = 0; - if (!info->attrs[GTPA_VERSION] || - !info->attrs[GTPA_LINK]) + if (!info->attrs[GTPA_VERSION]) return -EINVAL; rcu_read_lock(); - gtp = gtp_find_dev(sock_net(skb->sk), info->attrs); - if (!gtp) { - err = -ENODEV; - goto out_unlock; - } - - switch (nla_get_u32(info->attrs[GTPA_VERSION])) { - case GTP_V0: - if (!info->attrs[GTPA_TID]) { - err = -EINVAL; - goto out_unlock; - } - pctx = gtp0_pdp_find(gtp, nla_get_u64(info->attrs[GTPA_TID])); - break; - case GTP_V1: - if (!info->attrs[GTPA_I_TEI]) { - err = -EINVAL; - goto out_unlock; - } - pctx = gtp1_pdp_find(gtp, nla_get_u64(info->attrs[GTPA_I_TEI])); - break; - - default: - err = -EINVAL; - goto out_unlock; - } - - if (!pctx) { - err = -ENOENT; + pctx = gtp_find_pdp(sock_net(skb->sk), info->attrs); + if (IS_ERR(pctx)) { + err = PTR_ERR(pctx); goto out_unlock; } if (pctx->gtp_version == GTP_V0) - netdev_dbg(gtp->dev, "GTPv0-U: deleting tunnel id = %llx (pdp %p)\n", + netdev_dbg(pctx->dev, "GTPv0-U: deleting tunnel id = %llx (pdp %p)\n", pctx->u.v0.tid, pctx); else if (pctx->gtp_version == GTP_V1) - netdev_dbg(gtp->dev, "GTPv1-U: deleting tunnel id = %x/%x (pdp %p)\n", + netdev_dbg(pctx->dev, "GTPv1-U: deleting tunnel id = %x/%x (pdp %p)\n", pctx->u.v1.i_tei, pctx->u.v1.o_tei, pctx); hlist_del_rcu(&pctx->hlist_tid); @@ -1139,49 +1151,16 @@ static int gtp_genl_get_pdp(struct sk_buff *skb, struct genl_info *info) { struct pdp_ctx *pctx = NULL; struct sk_buff *skb2; - struct gtp_dev *gtp; - u32 gtp_version; int err; - if (!info->attrs[GTPA_VERSION] || - !info->attrs[GTPA_LINK]) + if (!info->attrs[GTPA_VERSION]) return -EINVAL; - gtp_version = nla_get_u32(info->attrs[GTPA_VERSION]); - switch (gtp_version) { - case GTP_V0: - case GTP_V1: - break; - default: - return -EINVAL; - } - rcu_read_lock(); - gtp = gtp_find_dev(sock_net(skb->sk), info->attrs); - if (!gtp) { - err = -ENODEV; - goto err_unlock; - } - - if (gtp_version == GTP_V0 && - info->attrs[GTPA_TID]) { - u64 tid = nla_get_u64(info->attrs[GTPA_TID]); - - pctx = gtp0_pdp_find(gtp, tid); - } else if (gtp_version == GTP_V1 && -info->attrs[GTPA_I_TEI]) { - u32 tid = nla_get_u32(info->attrs[GTPA_I_TEI]); - - pctx = gtp1_pdp_find(gtp, tid); - } else if (info->attrs[GTPA_MS_
[PATCH net-next v5 7/7] gtp: add socket to pdp context
Having the socket present in context simplifies the sending logic. It also fixes the invalid assumption that we have to use the same sending socket for all client IP's on a specific gtp interface. Signed-off-by: Andreas Schultz --- drivers/net/gtp.c | 94 +++ 1 file changed, 47 insertions(+), 47 deletions(-) diff --git a/drivers/net/gtp.c b/drivers/net/gtp.c index d58f46f..3e1854f 100644 --- a/drivers/net/gtp.c +++ b/drivers/net/gtp.c @@ -58,6 +58,7 @@ struct pdp_ctx { struct in_addr ms_addr_ip4; struct in_addr sgsn_addr_ip4; + struct sock *sk; struct net_device *dev; atomic_ttx_seq; @@ -179,8 +180,7 @@ static bool gtp_check_src_ms(struct sk_buff *skb, struct pdp_ctx *pctx, return false; } -static int gtp_rx(struct pdp_ctx *pctx, struct sk_buff *skb, unsigned int hdrlen, - bool xnet) +static int gtp_rx(struct pdp_ctx *pctx, struct sk_buff *skb, unsigned int hdrlen) { struct pcpu_sw_netstats *stats; @@ -190,7 +190,8 @@ static int gtp_rx(struct pdp_ctx *pctx, struct sk_buff *skb, unsigned int hdrlen } /* Get rid of the GTP + UDP headers. */ - if (iptunnel_pull_header(skb, hdrlen, skb->protocol, xnet)) + if (iptunnel_pull_header(skb, hdrlen, skb->protocol, +!net_eq(sock_net(pctx->sk), dev_net(pctx->dev return -1; netdev_dbg(pctx->dev, "forwarding packet from GGSN to uplink\n"); @@ -214,8 +215,7 @@ static int gtp_rx(struct pdp_ctx *pctx, struct sk_buff *skb, unsigned int hdrlen } /* 1 means pass up to the stack, -1 means drop and 0 means decapsulated. */ -static int gtp0_udp_encap_recv(struct gtp_dev *gtp, struct sk_buff *skb, - bool xnet) +static int gtp0_udp_encap_recv(struct gtp_dev *gtp, struct sk_buff *skb) { unsigned int hdrlen = sizeof(struct udphdr) + sizeof(struct gtp0_header); @@ -239,11 +239,10 @@ static int gtp0_udp_encap_recv(struct gtp_dev *gtp, struct sk_buff *skb, return 1; } - return gtp_rx(pctx, skb, hdrlen, xnet); + return gtp_rx(pctx, skb, hdrlen); } -static int gtp1u_udp_encap_recv(struct gtp_dev *gtp, struct sk_buff *skb, - bool xnet) +static int gtp1u_udp_encap_recv(struct gtp_dev *gtp, struct sk_buff *skb) { unsigned int hdrlen = sizeof(struct udphdr) + sizeof(struct gtp1_header); @@ -282,7 +281,7 @@ static int gtp1u_udp_encap_recv(struct gtp_dev *gtp, struct sk_buff *skb, return 1; } - return gtp_rx(pctx, skb, hdrlen, xnet); + return gtp_rx(pctx, skb, hdrlen); } static void gtp_encap_destroy(struct sock *sk) @@ -318,7 +317,6 @@ static int gtp_encap_recv(struct sock *sk, struct sk_buff *skb) { struct gtp_dev *gtp; int ret = 0; - bool xnet; gtp = rcu_dereference_sk_user_data(sk); if (!gtp) @@ -326,16 +324,14 @@ static int gtp_encap_recv(struct sock *sk, struct sk_buff *skb) netdev_dbg(gtp->dev, "encap_recv sk=%p\n", sk); - xnet = !net_eq(sock_net(sk), dev_net(gtp->dev)); - switch (udp_sk(sk)->encap_type) { case UDP_ENCAP_GTP0: netdev_dbg(gtp->dev, "received GTP0 packet\n"); - ret = gtp0_udp_encap_recv(gtp, skb, xnet); + ret = gtp0_udp_encap_recv(gtp, skb); break; case UDP_ENCAP_GTP1U: netdev_dbg(gtp->dev, "received GTP1U packet\n"); - ret = gtp1u_udp_encap_recv(gtp, skb, xnet); + ret = gtp1u_udp_encap_recv(gtp, skb); break; default: ret = -1; /* Shouldn't happen. */ @@ -378,8 +374,9 @@ static void gtp_dev_uninit(struct net_device *dev) free_percpu(dev->tstats); } -static struct rtable *ip4_route_output_gtp(struct net *net, struct flowi4 *fl4, - const struct sock *sk, __be32 daddr) +static struct rtable *ip4_route_output_gtp(struct flowi4 *fl4, + const struct sock *sk, + __be32 daddr) { memset(fl4, 0, sizeof(*fl4)); fl4->flowi4_oif = sk->sk_bound_dev_if; @@ -388,7 +385,7 @@ static struct rtable *ip4_route_output_gtp(struct net *net, struct flowi4 *fl4, fl4->flowi4_tos = RT_CONN_FLAGS(sk); fl4->flowi4_proto = sk->sk_protocol; - return ip_route_output_key(net, fl4); + return ip_route_output_key(sock_net(sk), fl4); } static inline void gtp0_push_header(struct sk_buff *skb, struct pdp_ctx *pctx) @@ -477,7 +474,6 @@ static int gtp_build_skb_ip4(struct sk_buff *skb, struct net_device *dev, struct rtable *rt; struct flowi4 fl4; struct iphdr
[PATCH net-next v5 1/7] gtp: switch from struct socket to struct sock for the GTP sockets
After enabling the UDP encapsulation, only the sk member is used. Holding the socket would prevent user space from closing the socket, but holding a reference to the sk member does not have the same effect. This change will make it simpler to later detach the sockets from the netdevice. Signed-off-by: Andreas Schultz --- drivers/net/gtp.c | 42 +++--- 1 file changed, 23 insertions(+), 19 deletions(-) diff --git a/drivers/net/gtp.c b/drivers/net/gtp.c index 8969874..e1b5af3 100644 --- a/drivers/net/gtp.c +++ b/drivers/net/gtp.c @@ -66,8 +66,8 @@ struct pdp_ctx { struct gtp_dev { struct list_headlist; - struct socket *sock0; - struct socket *sock1u; + struct sock *sk0; + struct sock *sk1u; struct net_device *dev; @@ -261,17 +261,19 @@ static int gtp1u_udp_encap_recv(struct gtp_dev *gtp, struct sk_buff *skb, static void gtp_encap_disable(struct gtp_dev *gtp) { - if (gtp->sock0 && gtp->sock0->sk) { - udp_sk(gtp->sock0->sk)->encap_type = 0; - rcu_assign_sk_user_data(gtp->sock0->sk, NULL); + if (gtp->sk0) { + udp_sk(gtp->sk0)->encap_type = 0; + rcu_assign_sk_user_data(gtp->sk0, NULL); + sock_put(gtp->sk0); } - if (gtp->sock1u && gtp->sock1u->sk) { - udp_sk(gtp->sock1u->sk)->encap_type = 0; - rcu_assign_sk_user_data(gtp->sock1u->sk, NULL); + if (gtp->sk1u) { + udp_sk(gtp->sk1u)->encap_type = 0; + rcu_assign_sk_user_data(gtp->sk1u, NULL); + sock_put(gtp->sk1u); } - gtp->sock0 = NULL; - gtp->sock1u = NULL; + gtp->sk0 = NULL; + gtp->sk1u = NULL; } static void gtp_encap_destroy(struct sock *sk) @@ -484,14 +486,14 @@ static int gtp_build_skb_ip4(struct sk_buff *skb, struct net_device *dev, switch (pctx->gtp_version) { case GTP_V0: - if (gtp->sock0) - sk = gtp->sock0->sk; + if (gtp->sk0) + sk = gtp->sk0; else sk = NULL; break; case GTP_V1: - if (gtp->sock1u) - sk = gtp->sock1u->sk; + if (gtp->sk1u) + sk = gtp->sk1u; else sk = NULL; break; @@ -504,7 +506,7 @@ static int gtp_build_skb_ip4(struct sk_buff *skb, struct net_device *dev, return -ENOENT; } - rt = ip4_route_output_gtp(sock_net(sk), &fl4, gtp->sock0->sk, + rt = ip4_route_output_gtp(sock_net(sk), &fl4, gtp->sk0, pctx->sgsn_addr_ip4.s_addr); if (IS_ERR(rt)) { netdev_dbg(dev, "no route to SSGN %pI4\n", @@ -839,18 +841,20 @@ static int gtp_encap_enable(struct net_device *dev, struct gtp_dev *gtp, netdev_dbg(dev, "enable gtp on %p, %p\n", sock0, sock1u); - gtp->sock0 = sock0; - gtp->sock1u = sock1u; + sock_hold(sock0->sk); + gtp->sk0 = sock0->sk; + sock_hold(sock1u->sk); + gtp->sk1u = sock1u->sk; tuncfg.sk_user_data = gtp; tuncfg.encap_rcv = gtp_encap_recv; tuncfg.encap_destroy = gtp_encap_destroy; tuncfg.encap_type = UDP_ENCAP_GTP0; - setup_udp_tunnel_sock(sock_net(gtp->sock0->sk), gtp->sock0, &tuncfg); + setup_udp_tunnel_sock(sock_net(gtp->sk0), sock0, &tuncfg); tuncfg.encap_type = UDP_ENCAP_GTP1U; - setup_udp_tunnel_sock(sock_net(gtp->sock1u->sk), gtp->sock1u, &tuncfg); + setup_udp_tunnel_sock(sock_net(gtp->sk1u), sock1u, &tuncfg); err = 0; err2: -- 2.10.2
[PATCH net-next v5 0/7] gtp: misc improvements
Hi Pablo, This is a resent of last series that missed the merge window. There are no changes compared to v4. v4: Compared to v3 it contains mostly smallish naming and spelling fixes. It also drops the documentation patch, Harald did a better job with the documentation and the some things I described do not yet match the implementation. I'll readd the relevant parts with a follow up series. This series lays the groundwork for removing the socket references from the GTP netdevice by removing duplicate code and simplifying the logic on some code paths. It slighly changes the GTP genl API by making the socket parameters optional (though one of them is still required). The removal of the socket references will break the 1:1 releation between GTP netdevice and GTP socket that prevents us to support multiple VRFs with overlapping IP addresse spaces attached to the same GTP-U entity (needed for multi APN support, coming a follow up series). Pablo found a socket hold problem in v2. In order to solve that I had to switch the socket references from the struct socket to the internal struct sock. This should have no functionl impact, but we can now hang on to the reference without blocking user space from closing the GTP socket. v4->v5: * resent for new merge window v3->v4: * drop the documentation patch * spelling fixes * pass nlattr instead of genl_info into gtp_find_dev, makes the code slightly more compact and readable v2->v3: * add documentation to explain the goal of all these changes * incorporate review comments * switch from struct socket to struct sock Regards Andreas -- Andreas Schultz (7): gtp: switch from struct socket to struct sock for the GTP sockets gtp: make GTP sockets in gtp_newlink optional gtp: merge gtp_get_net and gtp_genl_find_dev gtp: consolidate gtp socket rx path gtp: unify genl_find_pdp and prepare for per socket lookup gtp: consolidate pdp context destruction into helper gtp: add socket to pdp context drivers/net/gtp.c | 543 +++--- 1 file changed, 269 insertions(+), 274 deletions(-) -- 2.10.2
[PATCH net-next v5 6/7] gtp: consolidate pdp context destruction into helper
Consolidate duplicate code into helper. Signed-off-by: Andreas Schultz --- drivers/net/gtp.c | 24 ++-- 1 file changed, 14 insertions(+), 10 deletions(-) diff --git a/drivers/net/gtp.c b/drivers/net/gtp.c index bf4b352..d58f46f 100644 --- a/drivers/net/gtp.c +++ b/drivers/net/gtp.c @@ -86,6 +86,8 @@ struct gtp_net { static u32 gtp_h_initval; +static void pdp_context_delete(struct pdp_ctx *pctx); + static inline u32 gtp0_hashfn(u64 tid) { u32 *tid32 = (u32 *) &tid; @@ -780,13 +782,10 @@ static void gtp_hashtable_free(struct gtp_dev *gtp) struct pdp_ctx *pctx; int i; - for (i = 0; i < gtp->hash_size; i++) { - hlist_for_each_entry_rcu(pctx, >p->tid_hash[i], hlist_tid) { - hlist_del_rcu(&pctx->hlist_tid); - hlist_del_rcu(&pctx->hlist_addr); - kfree_rcu(pctx, rcu_head); - } - } + for (i = 0; i < gtp->hash_size; i++) + hlist_for_each_entry_rcu(pctx, >p->tid_hash[i], hlist_tid) + pdp_context_delete(pctx); + synchronize_rcu(); kfree(gtp->addr_hash); kfree(gtp->tid_hash); @@ -995,6 +994,13 @@ static int ipv4_pdp_add(struct gtp_dev *gtp, struct genl_info *info) return 0; } +static void pdp_context_delete(struct pdp_ctx *pctx) +{ + hlist_del_rcu(&pctx->hlist_tid); + hlist_del_rcu(&pctx->hlist_addr); + kfree_rcu(pctx, rcu_head); +} + static int gtp_genl_new_pdp(struct sk_buff *skb, struct genl_info *info) { struct gtp_dev *gtp; @@ -1100,9 +1106,7 @@ static int gtp_genl_del_pdp(struct sk_buff *skb, struct genl_info *info) netdev_dbg(pctx->dev, "GTPv1-U: deleting tunnel id = %x/%x (pdp %p)\n", pctx->u.v1.i_tei, pctx->u.v1.o_tei, pctx); - hlist_del_rcu(&pctx->hlist_tid); - hlist_del_rcu(&pctx->hlist_addr); - kfree_rcu(pctx, rcu_head); + pdp_context_delete(pctx); out_unlock: rcu_read_unlock(); -- 2.10.2
[PATCH net-next v5 4/7] gtp: consolidate gtp socket rx path
Add network device to gtp context in preparation for splitting the TEID from the network device. Use this to rework the socker rx path. Move the common RX part of v0 and v1 into a helper. Also move the final rx part into that helper as well. Signed-off-by: Andreas Schultz --- drivers/net/gtp.c | 80 ++- 1 file changed, 44 insertions(+), 36 deletions(-) diff --git a/drivers/net/gtp.c b/drivers/net/gtp.c index 74018eb..0c6707a 100644 --- a/drivers/net/gtp.c +++ b/drivers/net/gtp.c @@ -58,6 +58,8 @@ struct pdp_ctx { struct in_addr ms_addr_ip4; struct in_addr sgsn_addr_ip4; + struct net_device *dev; + atomic_ttx_seq; struct rcu_head rcu_head; }; @@ -175,6 +177,40 @@ static bool gtp_check_src_ms(struct sk_buff *skb, struct pdp_ctx *pctx, return false; } +static int gtp_rx(struct pdp_ctx *pctx, struct sk_buff *skb, unsigned int hdrlen, + bool xnet) +{ + struct pcpu_sw_netstats *stats; + + if (!gtp_check_src_ms(skb, pctx, hdrlen)) { + netdev_dbg(pctx->dev, "No PDP ctx for this MS\n"); + return 1; + } + + /* Get rid of the GTP + UDP headers. */ + if (iptunnel_pull_header(skb, hdrlen, skb->protocol, xnet)) + return -1; + + netdev_dbg(pctx->dev, "forwarding packet from GGSN to uplink\n"); + + /* Now that the UDP and the GTP header have been removed, set up the +* new network header. This is required by the upper layer to +* calculate the transport header. +*/ + skb_reset_network_header(skb); + + skb->dev = pctx->dev; + + stats = this_cpu_ptr(pctx->dev->tstats); + u64_stats_update_begin(&stats->syncp); + stats->rx_packets++; + stats->rx_bytes += skb->len; + u64_stats_update_end(&stats->syncp); + + netif_rx(skb); + return 0; +} + /* 1 means pass up to the stack, -1 means drop and 0 means decapsulated. */ static int gtp0_udp_encap_recv(struct gtp_dev *gtp, struct sk_buff *skb, bool xnet) @@ -201,13 +237,7 @@ static int gtp0_udp_encap_recv(struct gtp_dev *gtp, struct sk_buff *skb, return 1; } - if (!gtp_check_src_ms(skb, pctx, hdrlen)) { - netdev_dbg(gtp->dev, "No PDP ctx for this MS\n"); - return 1; - } - - /* Get rid of the GTP + UDP headers. */ - return iptunnel_pull_header(skb, hdrlen, skb->protocol, xnet); + return gtp_rx(pctx, skb, hdrlen, xnet); } static int gtp1u_udp_encap_recv(struct gtp_dev *gtp, struct sk_buff *skb, @@ -250,13 +280,7 @@ static int gtp1u_udp_encap_recv(struct gtp_dev *gtp, struct sk_buff *skb, return 1; } - if (!gtp_check_src_ms(skb, pctx, hdrlen)) { - netdev_dbg(gtp->dev, "No PDP ctx for this MS\n"); - return 1; - } - - /* Get rid of the GTP + UDP headers. */ - return iptunnel_pull_header(skb, hdrlen, skb->protocol, xnet); + return gtp_rx(pctx, skb, hdrlen, xnet); } static void gtp_encap_destroy(struct sock *sk) @@ -290,10 +314,9 @@ static void gtp_encap_disable(struct gtp_dev *gtp) */ static int gtp_encap_recv(struct sock *sk, struct sk_buff *skb) { - struct pcpu_sw_netstats *stats; struct gtp_dev *gtp; + int ret = 0; bool xnet; - int ret; gtp = rcu_dereference_sk_user_data(sk); if (!gtp) @@ -319,33 +342,17 @@ static int gtp_encap_recv(struct sock *sk, struct sk_buff *skb) switch (ret) { case 1: netdev_dbg(gtp->dev, "pass up to the process\n"); - return 1; + break; case 0: - netdev_dbg(gtp->dev, "forwarding packet from GGSN to uplink\n"); break; case -1: netdev_dbg(gtp->dev, "GTP packet has been dropped\n"); kfree_skb(skb); - return 0; + ret = 0; + break; } - /* Now that the UDP and the GTP header have been removed, set up the -* new network header. This is required by the upper layer to -* calculate the transport header. -*/ - skb_reset_network_header(skb); - - skb->dev = gtp->dev; - - stats = this_cpu_ptr(gtp->dev->tstats); - u64_stats_update_begin(&stats->syncp); - stats->rx_packets++; - stats->rx_bytes += skb->len; - u64_stats_update_end(&stats->syncp); - - netif_rx(skb); - - return 0; + return ret; } static int gtp_dev_init(struct net_device *dev) @@ -951,6 +958,7 @@ static int ipv4_pdp_add(struct gtp_dev *gtp, struct genl_info *info) if (pctx == NULL) return -ENOMEM; + pctx->dev = gtp->dev; ipv4_pdp_fill(pctx, info); atomic_set(&pctx->tx_seq, 0); -- 2.10.2
[PATCH net-next v5 2/7] gtp: make GTP sockets in gtp_newlink optional
Having both GTPv0-U and GTPv1-U is not always desirable. Fallback from GTPv1-U to GTPv0-U was depreciated from 3GPP Rel-8 onwards. Post Rel-8 implementation are discuraged from listening on the v0 port (see 3GPP TS 29.281, Sect. 1). A future change will completely decouple the sockets from the network device. Till then, at least one of the sockets needs to be specified (either v0 or v1), the other is optional. Signed-off-by: Andreas Schultz --- drivers/net/gtp.c | 148 -- 1 file changed, 78 insertions(+), 70 deletions(-) diff --git a/drivers/net/gtp.c b/drivers/net/gtp.c index e1b5af3..9aa2b35 100644 --- a/drivers/net/gtp.c +++ b/drivers/net/gtp.c @@ -259,30 +259,30 @@ static int gtp1u_udp_encap_recv(struct gtp_dev *gtp, struct sk_buff *skb, return iptunnel_pull_header(skb, hdrlen, skb->protocol, xnet); } -static void gtp_encap_disable(struct gtp_dev *gtp) -{ - if (gtp->sk0) { - udp_sk(gtp->sk0)->encap_type = 0; - rcu_assign_sk_user_data(gtp->sk0, NULL); - sock_put(gtp->sk0); - } - if (gtp->sk1u) { - udp_sk(gtp->sk1u)->encap_type = 0; - rcu_assign_sk_user_data(gtp->sk1u, NULL); - sock_put(gtp->sk1u); - } - - gtp->sk0 = NULL; - gtp->sk1u = NULL; -} - static void gtp_encap_destroy(struct sock *sk) { struct gtp_dev *gtp; gtp = rcu_dereference_sk_user_data(sk); - if (gtp) - gtp_encap_disable(gtp); + if (gtp) { + udp_sk(sk)->encap_type = 0; + rcu_assign_sk_user_data(sk, NULL); + sock_put(sk); + } +} + +static void gtp_encap_disable_sock(struct sock *sk) +{ + if (!sk) + return; + + gtp_encap_destroy(sk); +} + +static void gtp_encap_disable(struct gtp_dev *gtp) +{ + gtp_encap_disable_sock(gtp->sk0); + gtp_encap_disable_sock(gtp->sk1u); } /* UDP encapsulation receive handler. See net/ipv4/udp.c. @@ -642,27 +642,23 @@ static void gtp_link_setup(struct net_device *dev) static int gtp_hashtable_new(struct gtp_dev *gtp, int hsize); static void gtp_hashtable_free(struct gtp_dev *gtp); -static int gtp_encap_enable(struct net_device *dev, struct gtp_dev *gtp, - int fd_gtp0, int fd_gtp1); +static int gtp_encap_enable(struct gtp_dev *gtp, struct nlattr *data[]); static int gtp_newlink(struct net *src_net, struct net_device *dev, struct nlattr *tb[], struct nlattr *data[]) { - int hashsize, err, fd0, fd1; struct gtp_dev *gtp; struct gtp_net *gn; + int hashsize, err; - if (!data[IFLA_GTP_FD0] || !data[IFLA_GTP_FD1]) + if (!data[IFLA_GTP_FD0] && !data[IFLA_GTP_FD1]) return -EINVAL; gtp = netdev_priv(dev); - fd0 = nla_get_u32(data[IFLA_GTP_FD0]); - fd1 = nla_get_u32(data[IFLA_GTP_FD1]); - - err = gtp_encap_enable(dev, gtp, fd0, fd1); + err = gtp_encap_enable(gtp, data); if (err < 0) - goto out_err; + return err; if (!data[IFLA_GTP_PDP_HASHSIZE]) hashsize = 1024; @@ -690,7 +686,6 @@ static int gtp_newlink(struct net *src_net, struct net_device *dev, gtp_hashtable_free(gtp); out_encap: gtp_encap_disable(gtp); -out_err: return err; } @@ -805,63 +800,76 @@ static void gtp_hashtable_free(struct gtp_dev *gtp) kfree(gtp->tid_hash); } -static int gtp_encap_enable(struct net_device *dev, struct gtp_dev *gtp, - int fd_gtp0, int fd_gtp1) +static struct sock *gtp_encap_enable_socket(int fd, int type, + struct gtp_dev *gtp) { struct udp_tunnel_sock_cfg tuncfg = {NULL}; - struct socket *sock0, *sock1u; + struct socket *sock; + struct sock *sk; int err; - netdev_dbg(dev, "enable gtp on %d, %d\n", fd_gtp0, fd_gtp1); + pr_debug("enable gtp on %d, %d\n", fd, type); - sock0 = sockfd_lookup(fd_gtp0, &err); - if (sock0 == NULL) { - netdev_dbg(dev, "socket fd=%d not found (gtp0)\n", fd_gtp0); - return -ENOENT; + sock = sockfd_lookup(fd, &err); + if (!sock) { + pr_debug("gtp socket fd=%d not found\n", fd); + return NULL; } - if (sock0->sk->sk_protocol != IPPROTO_UDP) { - netdev_dbg(dev, "socket fd=%d not UDP\n", fd_gtp0); - err = -EINVAL; - goto err1; + if (sock->sk->sk_protocol != IPPROTO_UDP) { + pr_debug("socket fd=%d not UDP\n", fd); + sk = ERR_PTR(-EINVAL); + goto out_sock; } - sock1u = sockfd_lookup(fd_gtp1, &err); - if (sock1u == NULL) { - netdev_dbg(dev, "socket fd=%d not found (gtp1u)\n", fd_gtp1); - err = -ENOENT; -
Re: [PATCH 1/5] rds: ib: drop unnecessary rdma_reject
On 3/8/2017 11:26 PM, Zhu Yanjun wrote: When rdma_accept fails, rdma_reject is called in it. As such, it is not necessary to execute rdma_reject again. Cc: Joe Jin Cc: Junxiao Bi Signed-off-by: Zhu Yanjun --- net/rds/ib_cm.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/net/rds/ib_cm.c b/net/rds/ib_cm.c index ce3775a..eca3d5f 100644 --- a/net/rds/ib_cm.c +++ b/net/rds/ib_cm.c @@ -677,8 +677,7 @@ int rds_ib_cm_handle_connect(struct rdma_cm_id *cm_id, event->param.conn.initiator_depth); /* rdma_accept() calls rdma_reject() internally if it fails */ - err = rdma_accept(cm_id, &conn_param); - if (err) + if (rdma_accept(cm_id, &conn_param)) rds_ib_conn_error(conn, "rdma_accept failed (%d)\n", err); There are couple of consumer reject reasons needs to be conveyed. Current code don't pass them, but downstream code has them and hence I kept the code as is. Its good to avoid the reject on current code so am fine with the change. Acked-by: Santosh Shilimkar
Re: [PATCH 2/5] rds: ib: replace spin_lock_irq with spin_lock_irqsave
On 3/8/2017 11:26 PM, Zhu Yanjun wrote: It is difficult to make sure the state of the interrupt when this function is called. As such, it is safer to use spin_lock_irqsave than spin_lock_irq. There is no reason to hold irqs and as such the code path is safe from irq context. I don't see need of this change unless you have test case which showed some issue. Regards, Santosh
Re: [PATCH 4/5] rds: ib: add the static type to the function
On 3/8/2017 11:26 PM, Zhu Yanjun wrote: The function rds_ib_map_fmr is used only in the ib_fmr.c file. As such, the static type is added to limit it in this file. Cc: Joe Jin Cc: Junxiao Bi Signed-off-by: Zhu Yanjun --- net/rds/ib_fmr.c | 5 +++-- net/rds/ib_mr.h | 2 -- 2 files changed, 3 insertions(+), 4 deletions(-) Acked-by: Santosh Shilimkar
Re: [PATCHv2 3/5] rds: ib: remove redundant ib_dealloc_fmr
On 3/9/2017 1:20 AM, Zhu Yanjun wrote: The function ib_dealloc_fmr will never be called. As such, it should be removed. Cc: Joe Jin Cc: Junxiao Bi Signed-off-by: Zhu Yanjun --- Change from v1 to v2: remove ibmr NULL test. While posting updates, please post entire series and also give some time between two posts. net/rds/ib_fmr.c | 7 ++- 1 file changed, 2 insertions(+), 5 deletions(-) diff --git a/net/rds/ib_fmr.c b/net/rds/ib_fmr.c index 4fe8f4f..249ae1c 100644 --- a/net/rds/ib_fmr.c +++ b/net/rds/ib_fmr.c @@ -78,12 +78,9 @@ struct rds_ib_mr *rds_ib_alloc_fmr(struct rds_ib_device *rds_ibdev, int npages) return ibmr; out_no_cigar: - if (ibmr) { - if (fmr->fmr) - ib_dealloc_fmr(fmr->fmr); - kfree(ibmr); - } + kfree(ibmr); atomic_dec(&pool->item_count); + No need of the extra line here. return ERR_PTR(err); }
Re: [PATCH 5/5] rds: ib: unmap the scatter/gather list when error
On 3/8/2017 11:26 PM, Zhu Yanjun wrote: When some errors occur, the scatter/gather list mapped to DMA addresses should be handled. Cc: Joe Jin Cc: Junxiao Bi Signed-off-by: Zhu Yanjun --- Looks good. Acked-by: Santosh Shilimkar
Re: [PATCH 5/5] rds: ib: unmap the scatter/gather list when error
On 3/8/2017 11:26 PM, Zhu Yanjun wrote: When some errors occur, the scatter/gather list mapped to DMA addresses should be handled. Cc: Joe Jin Cc: Junxiao Bi Signed-off-by: Zhu Yanjun --- Acked-by: Santosh Shilimkar
Re: [PATCH net-next v2] net/socket: use per af lockdep classes for sk queues
On Thu, 2017-03-09 at 13:54 +0100, Paolo Abeni wrote: > Currently the sock queue's spin locks get their lockdep > classes by the default init_spin_lock() initializer: > all socket families get - usually, see below - a single > class for rx, another specific class for tx, etc. > This can lead to false positive lockdep splat, as > reported by Andrey. > Moreover there are two separate initialization points > for the sock queues, one in sk_clone_lock() and one > in sock_init_data(), so that e.g. the rx queue lock > can get one of two possible, different classes, depending > on the socket being cloned or not. > This change tries to address the above, setting explicitly > a per address family lockdep class for each queue's > spinlock. Also, move the duplicated initialization code to a > single location. Acked-by: Eric Dumazet
Re: [PATCH v2 2/2] can: spi: hi311x: Add Holt HI-311x CAN driver
Hello, doing a quick review... I realized a few issues... Am 17.01.2017 um 20:22 schrieb Akshay Bhat: This patch adds support for the Holt HI-311x CAN controller. The HI311x CAN controller is capable of transmitting and receiving standard data frames, extended data frames and remote frames. The HI311x interfaces with the host over SPI. Datasheet: www.holtic.com/documents/371-hi-3110_v-rev-jpdf.do Signed-off-by: Akshay Bhat --- v1 -> v2: Address comments from Marc Kleine-Budde: - use u8 instead of uint8_t - alphabetically sort Makefile and Kconfig - copy over copyright information from mcp251x - use single space after each marco - add missing HI3110_ namespace in defines - remove magic number for IDE & SRR bits - simplify logic to populate extended CAN ID - remove unused parameters in hi3110_setup function - remove redundant frame->can_dlc length check - simplify error handling in hi3110_open function Address comments from Julia Lawall: - remove unnecessary semicolon after while loop in hi3110_can_ist drivers/net/can/spi/Kconfig |6 + drivers/net/can/spi/Makefile |1 + drivers/net/can/spi/hi311x.c | 1069 ++ 3 files changed, 1076 insertions(+) create mode 100644 drivers/net/can/spi/hi311x.c diff --git a/drivers/net/can/spi/Kconfig b/drivers/net/can/spi/Kconfig index 148cae5..8f2e0dd 100644 --- a/drivers/net/can/spi/Kconfig +++ b/drivers/net/can/spi/Kconfig @@ -1,6 +1,12 @@ menu "CAN SPI interfaces" depends on SPI +config CAN_HI311X + tristate "Holt HI311x SPI CAN controllers" + depends on CAN_DEV && SPI && HAS_DMA + ---help--- + Driver for the Holt HI311x SPI CAN controllers. + config CAN_MCP251X tristate "Microchip MCP251x SPI CAN controllers" depends on HAS_DMA diff --git a/drivers/net/can/spi/Makefile b/drivers/net/can/spi/Makefile index 0e86040..f59fa37 100644 --- a/drivers/net/can/spi/Makefile +++ b/drivers/net/can/spi/Makefile @@ -3,4 +3,5 @@ # +obj-$(CONFIG_CAN_HI311X) += hi311x.o obj-$(CONFIG_CAN_MCP251X) += mcp251x.o diff --git a/drivers/net/can/spi/hi311x.c b/drivers/net/can/spi/hi311x.c new file mode 100644 index 000..cccfe2d --- /dev/null +++ b/drivers/net/can/spi/hi311x.c @@ -0,0 +1,1069 @@ +/* CAN bus driver for Holt HI3110 CAN Controller with SPI Interface + * + * Copyright(C) Timesys Corporation 2016 + * + * Based on Microchip 251x CAN Controller (mcp251x) Linux kernel driver + * Copyright 2009 Christian Pellegrin EVOL S.r.l. + * Copyright 2007 Raymarine UK, Ltd. All Rights Reserved. + * Copyright 2006 Arcom Control Systems Ltd. + * + * Based on CAN bus driver for the CCAN controller written by + * - Sascha Hauer, Marc Kleine-Budde, Pengutronix + * - Simon Kallweit, intefo AG + * Copyright 2007 + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#define HI3110_MASTER_RESET 0x56 +#define HI3110_READ_CTRL0 0xD2 +#define HI3110_READ_CTRL1 0xD4 +#define HI3110_READ_STATF 0xE2 +#define HI3110_WRITE_CTRL0 0x14 +#define HI3110_WRITE_CTRL1 0x16 +#define HI3110_WRITE_INTE 0x1C +#define HI3110_WRITE_BTR0 0x18 +#define HI3110_WRITE_BTR1 0x1A +#define HI3110_READ_BTR0 0xD6 +#define HI3110_READ_BTR1 0xD8 +#define HI3110_READ_INTF 0xDE +#define HI3110_READ_ERR 0xDC +#define HI3110_READ_FIFO_WOTIME 0x48 +#define HI3110_WRITE_FIFO 0x12 +#define HI3110_READ_MESSTAT 0xDA +#define HI3110_READ_TEC 0xEC + +#define HI3110_CTRL0_MODE_MASK (7 << 5) +#define HI3110_CTRL0_NORMAL_MODE (0 << 5) +#define HI3110_CTRL0_LOOPBACK_MODE (1 << 5) +#define HI3110_CTRL0_MONITOR_MODE (2 << 5) +#define HI3110_CTRL0_SLEEP_MODE (3 << 5) +#define HI3110_CTRL0_INIT_MODE (4 << 5) + +#define HI3110_CTRL1_TXEN BIT(7) + +#define HI3110_INT_RXTMP BIT(7) +#define HI3110_INT_RXFIFO BIT(6) +#define HI3110_INT_TXCPLT BIT(5) +#define HI3110_INT_BUSERR BIT(4) +#define HI3110_INT_MCHG BIT(3) +#define HI3110_INT_WAKEUP BIT(2) +#define HI3110_INT_F1MESS BIT(1) +#define HI3110_INT_F0MESS BIT(0) + +#define HI3110_ERR_BUSOFF BIT(7) +#define HI3110_ERR_TXERRP BIT(6) +#define HI3110_ERR_RXERRP BIT(5) +#define HI3110_ERR_BITERR BIT(4) +#define HI3110_ERR_FRMERR BIT(3) +#define HI3110_ERR_CRCERR BIT(2) +#define HI3110_ERR_ACKERR BIT(1) +#define HI3110_ERR_STUFERR BIT(0) +#define HI3110_ERR_PROTOCOL_MASK (0x1F) + +#define HI3110_STAT_RXFMTY BIT(1) + +#define HI3110_BTR0_SJW_SHIFT 6 +#define HI3110_BTR0_BRP_SHIFT 0 + +#define HI3110_BTR1_SAMP_3PERBIT (1 << 7) +#define HI3110_BTR1_SAMP_1PERBIT (0 << 7) +#define HI3110_BTR1_TSEG2_SHIFT 4 +#define HI3110_BTR1_TSEG1_SHIFT 0 + +#define HI3110_FIFO_WOTIME_TAG_OFF 0 +#define HI3110_FIFO_WOTIME_ID_OFF 1 +#def