* [PATCH] rxrpc: add IPV6 dependency
From: Arnd Bergmann @ 2018-10-12 12:36 UTC (permalink / raw)
To: David Howells, David S. Miller
Cc: Arnd Bergmann, linux-afs, linux-kernel, netdev
The udpv6_encap_enable() function is part of the ipv6 code, and if that
is configured as a loadable module, rxcpc cannot be built-in any more:
net/rxrpc/local_object.o: In function `rxrpc_lookup_local':
local_object.c:(.text+0x2688): undefined reference to `udpv6_encap_enable'
Add a dependency that allows building rxrpc with or without IPv6, but
that disallows the broken configuration. Since AFS selects RXRPC,
this needs the same dependency.
Fixes: 5271953cad31 ("rxrpc: Use the UDP encap_rcv hook")
Signed-off-by: Arnd Bergmann <arnd@arndb.de>
---
fs/afs/Kconfig | 1 +
net/rxrpc/Kconfig | 1 +
2 files changed, 2 insertions(+)
diff --git a/fs/afs/Kconfig b/fs/afs/Kconfig
index ebba3b18e5da..e2cad2c9d9d8 100644
--- a/fs/afs/Kconfig
+++ b/fs/afs/Kconfig
@@ -1,6 +1,7 @@
config AFS_FS
tristate "Andrew File System support (AFS)"
depends on INET
+ depends on IPV6 || !IPV6
select AF_RXRPC
select DNS_RESOLVER
help
diff --git a/net/rxrpc/Kconfig b/net/rxrpc/Kconfig
index 86f8853a038c..d925be00fc74 100644
--- a/net/rxrpc/Kconfig
+++ b/net/rxrpc/Kconfig
@@ -5,6 +5,7 @@
config AF_RXRPC
tristate "RxRPC session sockets"
depends on INET
+ depends on IPV6 || !IPV6
select CRYPTO
select KEYS
help
--
2.18.0
^ permalink raw reply related
* Probable Spam:
From: Smadar Barber-Tsadik @ 2018-10-12 6:55 UTC (permalink / raw)
--
My name is Smadar Barber-Tsadik, I'm the Chief Executive Officer (C.P.A) of the First International Bank of Israel (FIBI).I'm getting in touch with you in regards to a very important and urgent matter.Kindly respond back at your earliest convenience so I can provide you the details.
Faithfully,Smadar Barber-Tsadik
^ permalink raw reply
* Re: [PATCH net-next V2 6/8] vhost: packed ring support
From: Tiwei Bie @ 2018-10-12 14:32 UTC (permalink / raw)
To: Jason Wang
Cc: mst, kvm, virtualization, netdev, linux-kernel, wexu, jfreimann,
maxime.coquelin
In-Reply-To: <1531711691-6769-7-git-send-email-jasowang@redhat.com>
On Mon, Jul 16, 2018 at 11:28:09AM +0800, Jason Wang wrote:
[...]
> @@ -1367,10 +1397,48 @@ long vhost_vring_ioctl(struct vhost_dev *d, unsigned int ioctl, void __user *arg
> vq->last_avail_idx = s.num;
> /* Forget the cached index value. */
> vq->avail_idx = vq->last_avail_idx;
> + if (vhost_has_feature(vq, VIRTIO_F_RING_PACKED)) {
> + vq->last_avail_wrap_counter = wrap_counter;
> + vq->avail_wrap_counter = vq->last_avail_wrap_counter;
> + }
> break;
> case VHOST_GET_VRING_BASE:
> s.index = idx;
> s.num = vq->last_avail_idx;
> + if (vhost_has_feature(vq, VIRTIO_F_RING_PACKED))
> + s.num |= vq->last_avail_wrap_counter << 31;
> + if (copy_to_user(argp, &s, sizeof(s)))
> + r = -EFAULT;
> + break;
> + case VHOST_SET_VRING_USED_BASE:
> + /* Moving base with an active backend?
> + * You don't want to do that.
> + */
> + if (vq->private_data) {
> + r = -EBUSY;
> + break;
> + }
> + if (copy_from_user(&s, argp, sizeof(s))) {
> + r = -EFAULT;
> + break;
> + }
> + if (vhost_has_feature(vq, VIRTIO_F_RING_PACKED)) {
> + wrap_counter = s.num >> 31;
> + s.num &= ~(1 << 31);
> + }
> + if (s.num > 0xffff) {
> + r = -EINVAL;
> + break;
> + }
Do we want to put wrap_counter at bit 15?
If put wrap_counter at bit 31, the check (s.num > 0xffff)
won't be able to catch the illegal index 0x8000~0xffff for
packed ring.
> + vq->last_used_idx = s.num;
> + if (vhost_has_feature(vq, VIRTIO_F_RING_PACKED))
> + vq->last_used_wrap_counter = wrap_counter;
> + break;
> + case VHOST_GET_VRING_USED_BASE:
Do we need the new VHOST_GET_VRING_USED_BASE and
VHOST_SET_VRING_USED_BASE ops?
We are going to merge below series in DPDK:
http://patches.dpdk.org/patch/45874/
We may need to reach an agreement first.
> + s.index = idx;
> + s.num = vq->last_used_idx;
> + if (vhost_has_feature(vq, VIRTIO_F_RING_PACKED))
> + s.num |= vq->last_used_wrap_counter << 31;
> if (copy_to_user(argp, &s, sizeof s))
> r = -EFAULT;
> break;
[...]
^ permalink raw reply
* [PATCH net-next 1/3] net: hns3: Enable promisc mode when mac vlan table is full
From: Salil Mehta @ 2018-10-12 14:34 UTC (permalink / raw)
To: davem
Cc: salil.mehta, yisen.zhuang, lipeng321, mehta.salil, netdev,
linux-kernel, linuxarm, Jian Shen
In-Reply-To: <20181012143406.22600-1-salil.mehta@huawei.com>
From: Jian Shen <shenjian15@huawei.com>
Currently, the driver does nothing when mac vlan table is full.
In this case, the packet with new mac address will be dropped
by hardware. This patch adds check for the result of sync mac
address, and enable promisc mode when mac vlan table is full.
Furtherly, disable vlan filter when enable promisc by user
command.
Fixes: 46a3df9f9718 ("net: hns3: Add HNS3 Acceleration Engine & Compatibility Layer Support")
Signed-off-by: Jian Shen <shenjian15@huawei.com>
Signed-off-by: Salil Mehta <salil.mehta@huawei.com>
---
drivers/net/ethernet/hisilicon/hns3/hnae3.h | 11 +++
drivers/net/ethernet/hisilicon/hns3/hns3_enet.c | 78 +++++++++++++++++++---
drivers/net/ethernet/hisilicon/hns3/hns3_enet.h | 3 +
.../ethernet/hisilicon/hns3/hns3pf/hclge_main.c | 9 ++-
4 files changed, 89 insertions(+), 12 deletions(-)
diff --git a/drivers/net/ethernet/hisilicon/hns3/hnae3.h b/drivers/net/ethernet/hisilicon/hns3/hnae3.h
index 3df62a5..c3bd2a1 100644
--- a/drivers/net/ethernet/hisilicon/hns3/hnae3.h
+++ b/drivers/net/ethernet/hisilicon/hns3/hnae3.h
@@ -503,6 +503,15 @@ struct hnae3_unic_private_info {
#define HNAE3_SUPPORT_VF BIT(3)
#define HNAE3_SUPPORT_SERDES_PARALLEL_LOOPBACK BIT(4)
+#define HNAE3_USER_UPE BIT(0) /* unicast promisc enabled by user */
+#define HNAE3_USER_MPE BIT(1) /* mulitcast promisc enabled by user */
+#define HNAE3_BPE BIT(2) /* broadcast promisc enable */
+#define HNAE3_OVERFLOW_UPE BIT(3) /* unicast mac vlan overflow */
+#define HNAE3_OVERFLOW_MPE BIT(4) /* multicast mac vlan overflow */
+#define HNAE3_VLAN_FLTR BIT(5) /* enable vlan filter */
+#define HNAE3_UPE (HNAE3_USER_UPE | HNAE3_OVERFLOW_UPE)
+#define HNAE3_MPE (HNAE3_USER_MPE | HNAE3_OVERFLOW_MPE)
+
struct hnae3_handle {
struct hnae3_client *client;
struct pci_dev *pdev;
@@ -521,6 +530,8 @@ struct hnae3_handle {
};
u32 numa_node_mask; /* for multi-chip support */
+
+ u8 netdev_flags;
};
#define hnae3_set_field(origin, mask, shift, val) \
diff --git a/drivers/net/ethernet/hisilicon/hns3/hns3_enet.c b/drivers/net/ethernet/hisilicon/hns3/hns3_enet.c
index 9bbb53c..bbd6197 100644
--- a/drivers/net/ethernet/hisilicon/hns3/hns3_enet.c
+++ b/drivers/net/ethernet/hisilicon/hns3/hns3_enet.c
@@ -459,23 +459,81 @@ static int hns3_nic_mc_unsync(struct net_device *netdev,
return 0;
}
+static u8 hns3_get_netdev_flags(struct net_device *netdev)
+{
+ u8 flags = 0;
+
+ if (netdev->flags & IFF_PROMISC) {
+ flags = HNAE3_USER_UPE | HNAE3_USER_MPE;
+ } else {
+ flags |= HNAE3_VLAN_FLTR;
+ if (netdev->flags & IFF_ALLMULTI)
+ flags |= HNAE3_USER_MPE;
+ }
+
+ return flags;
+}
+
static void hns3_nic_set_rx_mode(struct net_device *netdev)
{
struct hnae3_handle *h = hns3_get_handle(netdev);
+ u8 new_flags;
+ int ret;
- if (h->ae_algo->ops->set_promisc_mode) {
- if (netdev->flags & IFF_PROMISC)
- h->ae_algo->ops->set_promisc_mode(h, true, true);
- else if (netdev->flags & IFF_ALLMULTI)
- h->ae_algo->ops->set_promisc_mode(h, false, true);
- else
- h->ae_algo->ops->set_promisc_mode(h, false, false);
- }
- if (__dev_uc_sync(netdev, hns3_nic_uc_sync, hns3_nic_uc_unsync))
+ new_flags = hns3_get_netdev_flags(netdev);
+
+ ret = __dev_uc_sync(netdev, hns3_nic_uc_sync, hns3_nic_uc_unsync);
+ if (ret) {
netdev_err(netdev, "sync uc address fail\n");
+ if (ret == -ENOSPC)
+ new_flags |= HNAE3_OVERFLOW_UPE;
+ }
+
if (netdev->flags & IFF_MULTICAST) {
- if (__dev_mc_sync(netdev, hns3_nic_mc_sync, hns3_nic_mc_unsync))
+ ret = __dev_mc_sync(netdev, hns3_nic_mc_sync,
+ hns3_nic_mc_unsync);
+ if (ret) {
netdev_err(netdev, "sync mc address fail\n");
+ if (ret == -ENOSPC)
+ new_flags |= HNAE3_OVERFLOW_MPE;
+ }
+ }
+
+ hns3_update_promisc_mode(netdev, new_flags);
+ /* User mode Promisc mode enable and vlan filtering is disabled to
+ * let all packets in. MAC-VLAN Table overflow Promisc enabled and
+ * vlan fitering is enabled
+ */
+ hns3_enable_vlan_filter(netdev, new_flags & HNAE3_VLAN_FLTR);
+ h->netdev_flags = new_flags;
+}
+
+void hns3_update_promisc_mode(struct net_device *netdev, u8 promisc_flags)
+{
+ struct hns3_nic_priv *priv = netdev_priv(netdev);
+ struct hnae3_handle *h = priv->ae_handle;
+
+ if (h->ae_algo->ops->set_promisc_mode) {
+ h->ae_algo->ops->set_promisc_mode(h,
+ promisc_flags & HNAE3_UPE,
+ promisc_flags & HNAE3_MPE);
+ }
+}
+
+void hns3_enable_vlan_filter(struct net_device *netdev, bool enable)
+{
+ struct hns3_nic_priv *priv = netdev_priv(netdev);
+ struct hnae3_handle *h = priv->ae_handle;
+ bool last_state;
+
+ if (h->pdev->revision >= 0x21 && h->ae_algo->ops->enable_vlan_filter) {
+ last_state = h->netdev_flags & HNAE3_VLAN_FLTR ? true : false;
+ if (enable != last_state) {
+ netdev_info(netdev,
+ "%s vlan filter\n",
+ enable ? "enable" : "disable");
+ h->ae_algo->ops->enable_vlan_filter(h, enable);
+ }
}
}
diff --git a/drivers/net/ethernet/hisilicon/hns3/hns3_enet.h b/drivers/net/ethernet/hisilicon/hns3/hns3_enet.h
index ac881e8..f25b281 100644
--- a/drivers/net/ethernet/hisilicon/hns3/hns3_enet.h
+++ b/drivers/net/ethernet/hisilicon/hns3/hns3_enet.h
@@ -640,6 +640,9 @@ void hns3_set_vector_coalesce_tx_gl(struct hns3_enet_tqp_vector *tqp_vector,
void hns3_set_vector_coalesce_rl(struct hns3_enet_tqp_vector *tqp_vector,
u32 rl_value);
+void hns3_enable_vlan_filter(struct net_device *netdev, bool enable);
+void hns3_update_promisc_mode(struct net_device *netdev, u8 promisc_flags);
+
#ifdef CONFIG_HNS3_DCB
void hns3_dcbnl_setup(struct hnae3_handle *handle);
#else
diff --git a/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_main.c b/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_main.c
index db97f6a..1bd83e8 100644
--- a/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_main.c
+++ b/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_main.c
@@ -5606,6 +5606,10 @@ static void hclge_enable_vlan_filter(struct hnae3_handle *handle, bool enable)
hclge_set_vlan_filter_ctrl(hdev, HCLGE_FILTER_TYPE_VF,
HCLGE_FILTER_FE_EGRESS_V1_B, enable);
}
+ if (enable)
+ handle->netdev_flags |= HNAE3_VLAN_FLTR;
+ else
+ handle->netdev_flags &= ~HNAE3_VLAN_FLTR;
}
static int hclge_set_vf_vlan_common(struct hclge_dev *hdev, int vfid,
@@ -5902,7 +5906,7 @@ static int hclge_init_vlan_config(struct hclge_dev *hdev)
{
#define HCLGE_DEF_VLAN_TYPE 0x8100
- struct hnae3_handle *handle;
+ struct hnae3_handle *handle = &hdev->vport[0].nic;
struct hclge_vport *vport;
int ret;
int i;
@@ -5925,6 +5929,8 @@ static int hclge_init_vlan_config(struct hclge_dev *hdev)
return ret;
}
+ handle->netdev_flags |= HNAE3_VLAN_FLTR;
+
hdev->vlan_type_cfg.rx_in_fst_vlan_type = HCLGE_DEF_VLAN_TYPE;
hdev->vlan_type_cfg.rx_in_sec_vlan_type = HCLGE_DEF_VLAN_TYPE;
hdev->vlan_type_cfg.rx_ot_fst_vlan_type = HCLGE_DEF_VLAN_TYPE;
@@ -5969,7 +5975,6 @@ static int hclge_init_vlan_config(struct hclge_dev *hdev)
return ret;
}
- handle = &hdev->vport[0].nic;
return hclge_set_vlan_filter(handle, htons(ETH_P_8021Q), 0, false);
}
--
2.7.4
^ permalink raw reply related
* [PATCH net-next 2/3] net: hns3: Resume promisc mode and vlan filter status after reset
From: Salil Mehta @ 2018-10-12 14:34 UTC (permalink / raw)
To: davem
Cc: salil.mehta, yisen.zhuang, lipeng321, mehta.salil, netdev,
linux-kernel, linuxarm, Jian Shen
In-Reply-To: <20181012143406.22600-1-salil.mehta@huawei.com>
From: Jian Shen <shenjian15@huawei.com>
This patch resumes promisc mode and vlan filter status after reset.
Signed-off-by: Jian Shen <shenjian15@huawei.com>
Signed-off-by: Salil Mehta <salil.mehta@huawei.com>
---
drivers/net/ethernet/hisilicon/hns3/hns3_enet.c | 6 +++++-
1 file changed, 5 insertions(+), 1 deletion(-)
diff --git a/drivers/net/ethernet/hisilicon/hns3/hns3_enet.c b/drivers/net/ethernet/hisilicon/hns3/hns3_enet.c
index bbd6197..ce93fcc 100644
--- a/drivers/net/ethernet/hisilicon/hns3/hns3_enet.c
+++ b/drivers/net/ethernet/hisilicon/hns3/hns3_enet.c
@@ -3665,11 +3665,15 @@ static int hns3_reset_notify_init_enet(struct hnae3_handle *handle)
{
struct net_device *netdev = handle->kinfo.netdev;
struct hns3_nic_priv *priv = netdev_priv(netdev);
+ bool vlan_filter_enable;
int ret;
hns3_init_mac_addr(netdev, false);
- hns3_nic_set_rx_mode(netdev);
hns3_recover_hw_addr(netdev);
+ hns3_update_promisc_mode(netdev, handle->netdev_flags);
+ vlan_filter_enable = netdev->flags & IFF_PROMISC ? false : true;
+ hns3_enable_vlan_filter(netdev, vlan_filter_enable);
+
/* Hardware table is only clear when pf resets */
if (!(handle->flags & HNAE3_SUPPORT_VF))
--
2.7.4
^ permalink raw reply related
* [PATCH net-next 3/3] net: hns3: Resume promisc mode and vlan filter status after loopback test
From: Salil Mehta @ 2018-10-12 14:34 UTC (permalink / raw)
To: davem
Cc: salil.mehta, yisen.zhuang, lipeng321, mehta.salil, netdev,
linux-kernel, linuxarm, Jian Shen
In-Reply-To: <20181012143406.22600-1-salil.mehta@huawei.com>
From: Jian Shen <shenjian15@huawei.com>
This patch resumes promisc mode and vlan filter status after
loopback test.
Fixes: 3b75c3df599d ("net: hns3: net: hns3: Add support for IFF_ALLMULTI flag")
Signed-off-by: Jian Shen <shenjian15@huawei.com>
Signed-off-by: Salil Mehta <salil.mehta@huawei.com>
---
drivers/net/ethernet/hisilicon/hns3/hns3_ethtool.c | 10 +++++++++-
1 file changed, 9 insertions(+), 1 deletion(-)
diff --git a/drivers/net/ethernet/hisilicon/hns3/hns3_ethtool.c b/drivers/net/ethernet/hisilicon/hns3/hns3_ethtool.c
index f1354f6..a4762c2 100644
--- a/drivers/net/ethernet/hisilicon/hns3/hns3_ethtool.c
+++ b/drivers/net/ethernet/hisilicon/hns3/hns3_ethtool.c
@@ -71,6 +71,7 @@ struct hns3_link_mode_mapping {
static int hns3_lp_setup(struct net_device *ndev, enum hnae3_loop loop, bool en)
{
struct hnae3_handle *h = hns3_get_handle(ndev);
+ bool vlan_filter_enable;
int ret;
if (!h->ae_algo->ops->set_loopback ||
@@ -91,7 +92,14 @@ static int hns3_lp_setup(struct net_device *ndev, enum hnae3_loop loop, bool en)
if (ret)
return ret;
- h->ae_algo->ops->set_promisc_mode(h, en, en);
+ if (en) {
+ h->ae_algo->ops->set_promisc_mode(h, true, true);
+ } else {
+ /* recover promisc mode before loopback test */
+ hns3_update_promisc_mode(ndev, h->netdev_flags);
+ vlan_filter_enable = ndev->flags & IFF_PROMISC ? false : true;
+ hns3_enable_vlan_filter(ndev, vlan_filter_enable);
+ }
return ret;
}
--
2.7.4
^ permalink raw reply related
* Re: 9p/RDMA for syzkaller (Was: BUG: corrupted list in p9_read_work)
From: Dmitry Vyukov @ 2018-10-12 14:50 UTC (permalink / raw)
To: Dominique Martinet
Cc: Leon Romanovsky, syzbot, David Miller, Eric Van Hensbergen, LKML,
Latchesar Ionkov, netdev, Ron Minnich, syzkaller-bugs,
v9fs-developer
In-Reply-To: <20181011141928.GB32030@nautica>
On Thu, Oct 11, 2018 at 4:19 PM, Dominique Martinet
<asmadeus@codewreck.org> wrote:
> Dmitry Vyukov wrote on Thu, Oct 11, 2018:
>> But again we don't need to support all of the available hardware.
>
> I agree with that, I just have no idea what the "librxe-rdmav16.so" lib
> could be doing and described something I am slightly more familiar with
> (e.g. libmlx5)
> I talked about a common subset of the verb abi because I didn't want to
> look into what it's doing, but if it's not enough there's always that
> possibility.
>
>
>> For example, we are testing net stack from external side using tun.
>> tun is a very simple, virtual abstraction of a network card. It allows
>> us to test all of generic net stack starting from L2 without messing
>> with any real drivers and their differences entirely. I had impression
>> that we are talking about something similar here too. Or not?
>
> That sounds about right, rxe is a software implementation that should
> work on most network interfaces ; at least from what I tried it worked
> on a VM's virtio net down to my laptop's wifi interface so it's a good
> start... I'm not saying all because I just tried a dummy interface and
> that returned EINVAL.
> The only point I disagree is the 'very simple', even getting that to
> work will be a far cry from a socket() call... :)
>
>
>> Also I am a bit missing context about rdma<->9p interface. Do we need
>> to setup all these ring buffers to satisfy the parts that 9p needs? Is
>> it that 9p actually reads data directly from these ring buffers? Or
>> there is some higher-level rdma interface that 9p uses?
>
> It needs an "RDMA_PS_TCP" connection established, that requires
> everything I described unfortunately...
> Once that's established we need to register some memory to the driver
> and post some recv buffers (even if we won't read it, the client would
> get errors if we aren't ready to receive anything - at least it does
> with real hardware), and also use some registered memory to send data.
>
> Thinking back though I think that my server implementation isn't very
> far from the raw level in what I'm doing, I recall libibverbs fallback
> implementation (e.g. if the driver lib doesn't implement it otherwise)
> of the functions I looked at like ibv_post_send to mostly be just
> serializing the arguments, slapping the command from an enum in front of
> it and sending it to the kernel, so it might be enough to just
> reimplement that shim in or figure a way to generate the binary commands
> once and then use these values; now I'm comparing two runs of strace of
> my test server I definitely see a pattern.
>
> I'll give it a try but don't expect something fast, and it's probably
> not going to be very pretty either...
>
> To give a concrete example, here are all the read/write/fcntl calls
> looking just at /dev/infiniband in a hello world program that just
> establishes connection (server side), receive and send two messages and
> quits:
>
>
> This part apparently sets up the listening connection of the server:
>
> 1430 1539262699.126025 openat(AT_FDCWD, "/dev/infiniband/rdma_cm", O_RDWR|O_CLOEXEC) = 3
> 1430 1539262699.126155 write(3, "\0\0\0\0\30\0\4\0@m'\1\0\0\0\0\344\327\375\271\374\177\0\0?\1\2\0\0\0\0\0", 32) = 32
> 1430 1539262699.126192 write(3, "\24\0\0\0\210\0\0\0\0\0\0\0000\0\0\0\33\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\1\6\0\0\377\377\377\377\377\377\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0", 144) = 144
> 1430 1539262699.126223 write(3, "\23\0\0\0\20\0\20\1 \326\375\271\374\177\0\0\0\0\0\0\0\0\0\0", 24) = 24
> 1430 1539262699.126250 write(3, "\23\0\0\0\20\0\20\1 \326\375\271\374\177\0\0\0\0\0\0\2\0\0\0", 24) = 24
> 1430 1539262699.126274 write(3, "\1\0\0\0\20\0\4\0\324\327\375\271\374\177\0\0\0\0\0\0\0\0\0\0", 24) = 24
> 1430 1539262699.126303 close(3) = 0
> 1430 1539262699.126360 openat(AT_FDCWD, "/dev/infiniband/rdma_cm", O_RDWR|O_CLOEXEC) = 3
> 1430 1539262699.126429 write(3, "\0\0\0\0\30\0\4\0\240\217'\1\0\0\0\0t\330\375\271\374\177\0\0\6\1\2\0\0\0\0\0", 32) = 32
> 1430 1539262699.126472 write(3, "\24\0\0\0\210\0\0\0\0\0\0\0\34\0\0\0\n\0\4\323\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0", 144) = 144
> 1430 1539262699.126501 write(3, "\23\0\0\0\20\0\20\1p\326\375\271\374\177\0\0\0\0\0\0\0\0\0\0", 24) = 24
> 1430 1539262699.126534 write(3, "\23\0\0\0\20\0\20\1p\326\375\271\374\177\0\0\0\0\0\0\2\0\0\0", 24) = 24
> 1430 1539262699.127119 write(3, "\7\0\0\0\10\0\0\0\0\0\0\0@\0\0\0", 16) = 16
> 1430 1539262699.127149 write(3, "\23\0\0\0\20\0\20\1`\327\375\271\374\177\0\0\0\0\0\0\0\0\0\0", 24) = 24
> 1430 1539262699.127319 fcntl(3, F_GETFL) = 0x8002 (flags O_RDWR|O_LARGEFILE)
> 1430 1539262699.127348 fcntl(3, F_SETFL, O_RDWR|O_NONBLOCK|O_LARGEFILE <unfinished ...>
>
> Then the client connects (had some epoll on read on fd 3, but no read?!)
>
> 1446 1539262706.268685 write(3, "\f\0\0\0\10\0H\1\200\307\211\302G\177\0\0", 16) = 16
> 1446 1539262706.268718 write(3, "\23\0\0\0\20\0\20\1\240\304\211\302G\177\0\0\2\0\0\0\0\0\0\0", 24) = 24
> 1446 1539262706.269440 openat(AT_FDCWD, "/dev/infiniband/uverbs0", O_RDWR|O_CLOEXEC) = 5
> 1446 1539262706.269474 write(5, "\0\0\0\0\4\0\2\0H\302\211\302G\177\0\0", 16) = 16
> 1446 1539262706.269503 write(5, "\1\0\0\0\4\0,\0\220\301\211\302G\177\0\0", 16) = 16
> 1446 1539262706.269545 write(5, "\2\0\0\0\6\0\n\0\20\302\211\302G\177\0\0\1\0\0\0\0\0\0\0", 24) = 24
> 1446 1539262706.269571 write(5, "\3\0\0\0\4\0\1\0\314\303\211\302G\177\0\0", 16) = 16
> 1446 1539262706.269596 write(3, "\23\0\0\0\20\0\20\1\240\304\211\302G\177\0\0\2\0\0\0\2\0\0\0", 24) = 24
> 1446 1539262706.269618 write(3, "\23\0\0\0\20\0\270\1\200\303\211\302G\177\0\0\2\0\0\0\1\0\0\0", 24) = 24
> 1430 1539262706.269801 write(5, "\3\0\0\0\4\0\1\0\354\330\375\271\374\177\0\0", 16) = 16
> 1430 1539262706.269944 write(5, "\21\0\0\0\4\0\1\0T\330\375\271\374\177\0\0", 16) = 16
> 1430 1539262706.270000 write(5, "\22\0\0\0\n\0\6\0 \330\375\271\374\177\0\0`\232'\1\0\0\0\0006\0\0\0\0\0\0\0\7\0\0\0\0\0\0\0", 40) = 40
> 1430 1539262706.270203 write(5, "\27\0\0\0\4\0\0\0\2\0\0\0\0\0\0\0", 16) = 16
> 1430 1539262706.270262 write(5, "\30\0\0\0\20\0\20\0000\327\375\271\374\177\0\0\20\233'\1\0\0\0\0\1\0\0\0\2\0\0\0\2\0\0\0\0\0\0\0002\0\0\0\4\0\0\0\1\0\0\0\1\0\0\0\0\0\0\0\1\2\0\0", 64) = 64
> 1430 1539262706.270482 write(3, "\v\0\0\0\20\0\220\0p\326\375\271\374\177\0\0\2\0\0\0\1\0\0\0", 24) = 24
> 1430 1539262706.270546 write(5, "\32\0\0\0\36\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\3\0\0\09\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\16\0\0\0\0\0\0\0\1\0\0\0\0\0\0\0\1\0\0\0\0\0\0\0", 120) = 120
> 1430 1539262706.270677 write(5, "\t\0\0\0\f\0\3\0\224\330\375\271\374\177\0\0\20p)\302G\177\0\0\0\0@\0\0\0\0\0\20p)\302G\177\0\0\1\0\0\0\1\0\0\0", 48) = 48
> 1430 1539262706.271973 write(5, "\t\0\0\0\f\0\3\0D\330\375\271\374\177\0\0\210\362&\1\0\0\0\0\1\0\0\0\0\0\0\0\210\362&\1\0\0\0\0\1\0\0\0\1\0\0\0", 48) = 48
> 1430 1539262706.272060 write(3, "\v\0\0\0\20\0\220\0000\325\375\271\374\177\0\0\2\0\0\0\1\0\0\0", 24) = 24
> 1430 1539262706.272110 write(5, "\32\0\0\0\36\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\3\0\0\09\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\16\0\0\0\0\0\0\0\1\0\0\0\0\0\0\0\1\0\0\0\0\0\0\0", 120) = 120
> 1430 1539262706.272159 write(3, "\v\0\0\0\20\0\220\0000\325\375\271\374\177\0\0\2\0\0\0\2\0\0\0", 24) = 24
> 1430 1539262706.272205 write(5, "\32\0\0\0\36\0\0\0\0\0\0\0\0\0\0\0\0\0\377\377\n*\21f\0\0\0\0\0\0\0\0\1@\0\0\0\7\1\1\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\3\0\0\0\201\221\22\0\0\0\0\0\340\t\351\0\0\0\0\0\23\0\0\0\0\0\0\0\0\0\0\0\2\0\3\0\0\0\1\0\0\0\0\0\0\0\0\0", 120) = 120
> 1430 1539262706.272439 write(3, "\v\0\0\0\20\0\220\0000\325\375\271\374\177\0\0\2\0\0\0\3\0\0\0", 24) = 24
> 1430 1539262706.272496 write(5, "\32\0\0\0\36\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\3\0\0\0\1.\1\0\0\0\0\0\0\0\0\0\364((\0\0\0\0\0\0\0\0\0\0\0\0\0\3\0\0\0\0\1\0\0\0\23\7\7\0\0\0\0", 120) = 120
> 1430 1539262706.272565 write(3, "\10\0\0\0 \1\0\0\220\f\0\274G\177\0\0\24\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\1\1\0\0\n\1\2\0\0\0\0\0\0\0", 296) = 296
> 1446 1539262706.272962 write(3, "\f\0\0\0\10\0H\1\200\307\211\302G\177\0\0", 16) = 16
> 1430 1539262706.274144 write(5, "\t\0\0\0\f\0\3\0D\330\375\271\374\177\0\0`\0\351\301G\177\0\0\0\0 \0\0\0\0\0`\0\351\301G\177\0\0\1\0\0\0\1\0\0\0", 48) = 48
>
>
> Some data is exchanged (we don't see the data as it's in buffers whose
> address was given earlier):
>
> 1464 1539262714.529679 write(5, "\27\0\0\0\4\0\0\0\2\0\0\0\0\0\0\0", 16) = 16
> 1464 1539262714.530059 write(5, "\34\0\0\0\10\0\1\0lT)\302G\177\0\0\3\0\0\0\0\0\0\0\0\0\0\0\200\0\0\0", 32) = 32
> 1464 1539262714.530634 write(5, "\27\0\0\0\4\0\0\0\2\0\0\0\0\0\0\0", 16) = 16
> 1430 1539262719.331307 write(5, "\34\0\0\0\10\0\1\0\374\327\375\271\374\177\0\0\3\0\0\0\0\0\0\0\0\0\0\0\200\0\0\0", 32) = 32
> 1464 1539262719.332113 write(5, "\27\0\0\0\4\0\0\0\2\0\0\0\0\0\0\0", 16) = 16
>
> And disconnect:
>
> 1430 1539262721.192844 write(5, "\r\0\0\0\3\0\0\0\6\0\0\0", 12) = 12
> 1430 1539262721.193186 write(5, "\r\0\0\0\3\0\0\0\5\0\0\0", 12) = 12
> 1430 1539262721.193324 write(5, "\32\0\0\0\36\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\3\0\0\0\1\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\6\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0", 120) = 120
> 1430 1539262721.193567 write(3, "\n\0\0\0\4\0\0\0\2\0\0\0", 12) = 12
> 1446 1539262721.256556 write(3, "\f\0\0\0\10\0H\1\200\307\211\302G\177\0\0", 16) = 16
> 1430 1539262721.257618 write(3, "\1\0\0\0\20\0\4\0\204\327\375\271\374\177\0\0\2\0\0\0\0\0\0\0", 24) = 24
> 1430 1539262721.257769 write(5, "\4\0\0\0\3\0\0\0\0\0\0\0", 12) = 12
> 1430 1539262721.258369 write(5, "\27\0\0\0\4\0\0\0\2\0\0\0\0\0\0\0", 16) = 16
> 1430 1539262721.258667 write(5, "\33\0\0\0\6\0\1\0T\327\375\271\374\177\0\0\3\0\0\0\0\0\0\0", 24) = 24
> 1430 1539262721.259223 write(5, "\24\0\0\0\6\0\2\08\327\375\271\374\177\0\0\2\0\0\0\0\0\0\0", 24) = 24
> 1430 1539262721.260476 write(3, "\1\0\0\0\20\0\4\0D\330\375\271\374\177\0\0\0\0\0\0\0\0\0\0", 24) = 24
> 1430 1539262721.260726 close(3) = 0
> 1430 1539262721.261082 write(5, "\4\0\0\0\3\0\0\0\1\0\0\0", 12) = -1 EBUSY (Device or resource busy)
> 1430 1539262721.358728 write(5, "\r\0\0\0\3\0\0\0\4\0\0\0", 12) = 12
>
>
> I don't see any read on these fd despite epoll being set to wait for
> read events on these so I'm not quite sure where ibverbs knows if the
> commands worked or not, but hopefully that illustrats that it's slightly
> more complex than just socket/bind/listen/accept/write/close! :)
Yes, it seems so.
I guess I am still missing the big picture somewhat.
If we do "echo -n FOO > /sys/module/rdma_rxe/parameters/add" and let's
say FOO is a tun device. Does it mean that we will send/receive
packets from the tun? If yes, that would make things simpler. And do
we still need ring buffers in that case? If not and we still send/recv
via in-memory ring buffers, then why do we need tun at all?
Leon, maybe you know how to setup a stub rdma that we could use as 9p
transport? If we do this, I guess it will also expose lots of
interesting rdma code paths for testing.
^ permalink raw reply
* [PATCH net] rxrpc: Fix incorrect conditional on IPV6
From: David Howells @ 2018-10-12 14:52 UTC (permalink / raw)
Cc: Arnd Bergmann, netdev, dhowells, linux-afs, linux-kernel
The udpv6_encap_enable() function is part of the ipv6 code, and if that is
configured as a loadable module and rxrpc is built in then a build failure
will occur because the conditional check is wrong:
net/rxrpc/local_object.o: In function `rxrpc_lookup_local':
local_object.c:(.text+0x2688): undefined reference to `udpv6_encap_enable'
Use the correct config symbol (CONFIG_AF_RXRPC_IPV6) in the conditional
check rather than CONFIG_IPV6 as that will do the right thing.
Fixes: 5271953cad31 ("rxrpc: Use the UDP encap_rcv hook")
Signed-off-by: David Howells <dhowells@redhat.com>
cc: Arnd Bergmann <arnd@arndb.de>
---
net/rxrpc/local_object.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/net/rxrpc/local_object.c b/net/rxrpc/local_object.c
index cad0691c2bb4..0906e51d3cfb 100644
--- a/net/rxrpc/local_object.c
+++ b/net/rxrpc/local_object.c
@@ -139,7 +139,7 @@ static int rxrpc_open_socket(struct rxrpc_local *local, struct net *net)
udp_sk(usk)->gro_complete = NULL;
udp_encap_enable();
-#if IS_ENABLED(CONFIG_IPV6)
+#if IS_ENABLED(CONFIG_AF_RXRPC_IPV6)
if (local->srx.transport.family == AF_INET6)
udpv6_encap_enable();
#endif
^ permalink raw reply related
* Re: [RFC-resend 1/2] x86/compat: Adjust in_compat_syscall() to generic code under !COMPAT
From: Andy Lutomirski @ 2018-10-12 14:57 UTC (permalink / raw)
To: Dmitry Safonov
Cc: linux-kernel, Dmitry Safonov, Ard Biesheuvel, Andy Lutomirsky,
David S. Miller, Herbert Xu, H. Peter Anvin, Ingo Molnar,
John Stultz, Kirill A. Shutemov, Oleg Nesterov, Steffen Klassert,
Stephen Boyd, Steven Rostedt, Thomas Gleixner, x86, linux-efi,
netdev
In-Reply-To: <20181012134253.23266-2-dima@arista.com>
> On Oct 12, 2018, at 6:42 AM, Dmitry Safonov <dima@arista.com> wrote:
>
> The result of in_compat_syscall() can be pictured as:
>
> x86 platform:
> ---------------------------------------------------
> | Arch\syscall | 64-bit | ia32 | x32 |
> |-------------------------------------------------|
> | x86_64 | false | true | true |
> |-------------------------------------------------|
> | i686 | | <true> | |
> ---------------------------------------------------
>
> Other platforms:
> -------------------------------------------
> | Arch\syscall | 64-bit | compat |
> |-----------------------------------------|
> | 64-bit | false | true |
> |-----------------------------------------|
> | 32-bit(?) | | <false> |
> -------------------------------------------
>
>
Yikes. This is probably even my fault!
Reviewed-by: Andy Lutomirski <luto@kernel.org>
And, if you want:
Apologized-for-by: Andy Lutomirski <luto@kernel.org>
^ permalink raw reply
* Re: 9p/RDMA for syzkaller (Was: BUG: corrupted list in p9_read_work)
From: Dominique Martinet @ 2018-10-12 15:08 UTC (permalink / raw)
To: Dmitry Vyukov
Cc: Leon Romanovsky, syzbot, David Miller, Eric Van Hensbergen, LKML,
Latchesar Ionkov, netdev, Ron Minnich, syzkaller-bugs,
v9fs-developer
In-Reply-To: <CACT4Y+byESz-LuzM07ik6-VVHoD7OhO_BB0qOLNUZ4j-ao9CFA@mail.gmail.com>
Dmitry Vyukov wrote on Fri, Oct 12, 2018:
> > I don't see any read on these fd despite epoll being set to wait for
> > read events on these so I'm not quite sure where ibverbs knows if the
> > commands worked or not, but hopefully that illustrats that it's slightly
> > more complex than just socket/bind/listen/accept/write/close! :)
>
> Yes, it seems so.
>
> I guess I am still missing the big picture somewhat.
> If we do "echo -n FOO > /sys/module/rdma_rxe/parameters/add" and let's
> say FOO is a tun device. Does it mean that we will send/receive
> packets from the tun? If yes, that would make things simpler. And do
> we still need ring buffers in that case? If not and we still send/recv
> via in-memory ring buffers, then why do we need tun at all?
Hmm, good point; I hadn't looked at the network level how this is
emulated.
When I use a single VM I do not see anything with tcpdump on any
interface, so I assume the kernel short-cuts the interface in this case.
When communicating between two machines there obviously is traffic; it
appears to be transported over udp - I see the messages I sent in plain
text in the dump and there is only a handful of packets for the whole
connecting and teardown so it's definitely much simpler.
This might have some knob I am not aware of to force the driver to send
udp in the local setup, if we can it's going to be much easier to
reimplement the rxe emulation protocol with raw syscalls than what I was
describing earlier...
> Leon, maybe you know how to setup a stub rdma that we could use as 9p
> transport? If we do this, I guess it will also expose lots of
> interesting rdma code paths for testing.
I'm doing this on my free time atm so I can't invest too much, would
love some help if you're aware of anything :)
--
Dominique
^ permalink raw reply
* [PATCH 0/2] net: ethernet: ti: cpsw fix mcast packet lost
From: Ivan Khoronzhuk @ 2018-10-12 15:28 UTC (permalink / raw)
To: grygorii.strashko, davem
Cc: linux-omap, netdev, linux-kernel, Ivan Khoronzhuk
The patchset omits redundant refresh of mcast address table and
prevents mcast packet lost.
Based on net-next/master
tested on am572x evm
Ivan Khoronzhuk (2):
net: ethernet: ti: cpsw_ale: use const for API having pointer on mac
address
net: ethernet: ti: cpsw: fix lost of mcast packets while rx_mode
update
drivers/net/ethernet/ti/cpsw.c | 46 ++++++++++++++++++------------
drivers/net/ethernet/ti/cpsw_ale.c | 12 ++++----
drivers/net/ethernet/ti/cpsw_ale.h | 8 +++---
3 files changed, 38 insertions(+), 28 deletions(-)
--
2.17.1
^ permalink raw reply
* [PATCH 1/2] net: ethernet: ti: cpsw_ale: use const for API having pointer on mac address
From: Ivan Khoronzhuk @ 2018-10-12 15:28 UTC (permalink / raw)
To: grygorii.strashko, davem
Cc: linux-omap, netdev, linux-kernel, Ivan Khoronzhuk
In-Reply-To: <20181012152815.31320-1-ivan.khoronzhuk@linaro.org>
It allows to use function under callbacks with same const qualifier of
mac address for farther changes.
Signed-off-by: Ivan Khoronzhuk <ivan.khoronzhuk@linaro.org>
---
drivers/net/ethernet/ti/cpsw_ale.c | 12 ++++++------
drivers/net/ethernet/ti/cpsw_ale.h | 8 ++++----
2 files changed, 10 insertions(+), 10 deletions(-)
diff --git a/drivers/net/ethernet/ti/cpsw_ale.c b/drivers/net/ethernet/ti/cpsw_ale.c
index 5766225a4ce1..798c989d5d93 100644
--- a/drivers/net/ethernet/ti/cpsw_ale.c
+++ b/drivers/net/ethernet/ti/cpsw_ale.c
@@ -136,7 +136,7 @@ static inline void cpsw_ale_get_addr(u32 *ale_entry, u8 *addr)
addr[i] = cpsw_ale_get_field(ale_entry, 40 - 8*i, 8);
}
-static inline void cpsw_ale_set_addr(u32 *ale_entry, u8 *addr)
+static inline void cpsw_ale_set_addr(u32 *ale_entry, const u8 *addr)
{
int i;
@@ -175,7 +175,7 @@ static int cpsw_ale_write(struct cpsw_ale *ale, int idx, u32 *ale_entry)
return idx;
}
-static int cpsw_ale_match_addr(struct cpsw_ale *ale, u8 *addr, u16 vid)
+static int cpsw_ale_match_addr(struct cpsw_ale *ale, const u8 *addr, u16 vid)
{
u32 ale_entry[ALE_ENTRY_WORDS];
int type, idx;
@@ -309,7 +309,7 @@ static inline void cpsw_ale_set_vlan_entry_type(u32 *ale_entry,
}
}
-int cpsw_ale_add_ucast(struct cpsw_ale *ale, u8 *addr, int port,
+int cpsw_ale_add_ucast(struct cpsw_ale *ale, const u8 *addr, int port,
int flags, u16 vid)
{
u32 ale_entry[ALE_ENTRY_WORDS] = {0, 0, 0};
@@ -336,7 +336,7 @@ int cpsw_ale_add_ucast(struct cpsw_ale *ale, u8 *addr, int port,
}
EXPORT_SYMBOL_GPL(cpsw_ale_add_ucast);
-int cpsw_ale_del_ucast(struct cpsw_ale *ale, u8 *addr, int port,
+int cpsw_ale_del_ucast(struct cpsw_ale *ale, const u8 *addr, int port,
int flags, u16 vid)
{
u32 ale_entry[ALE_ENTRY_WORDS] = {0, 0, 0};
@@ -352,7 +352,7 @@ int cpsw_ale_del_ucast(struct cpsw_ale *ale, u8 *addr, int port,
}
EXPORT_SYMBOL_GPL(cpsw_ale_del_ucast);
-int cpsw_ale_add_mcast(struct cpsw_ale *ale, u8 *addr, int port_mask,
+int cpsw_ale_add_mcast(struct cpsw_ale *ale, const u8 *addr, int port_mask,
int flags, u16 vid, int mcast_state)
{
u32 ale_entry[ALE_ENTRY_WORDS] = {0, 0, 0};
@@ -386,7 +386,7 @@ int cpsw_ale_add_mcast(struct cpsw_ale *ale, u8 *addr, int port_mask,
}
EXPORT_SYMBOL_GPL(cpsw_ale_add_mcast);
-int cpsw_ale_del_mcast(struct cpsw_ale *ale, u8 *addr, int port_mask,
+int cpsw_ale_del_mcast(struct cpsw_ale *ale, const u8 *addr, int port_mask,
int flags, u16 vid)
{
u32 ale_entry[ALE_ENTRY_WORDS] = {0, 0, 0};
diff --git a/drivers/net/ethernet/ti/cpsw_ale.h b/drivers/net/ethernet/ti/cpsw_ale.h
index d4fe9016429b..cd07a3e96d57 100644
--- a/drivers/net/ethernet/ti/cpsw_ale.h
+++ b/drivers/net/ethernet/ti/cpsw_ale.h
@@ -105,13 +105,13 @@ void cpsw_ale_start(struct cpsw_ale *ale);
void cpsw_ale_stop(struct cpsw_ale *ale);
int cpsw_ale_flush_multicast(struct cpsw_ale *ale, int port_mask, int vid);
-int cpsw_ale_add_ucast(struct cpsw_ale *ale, u8 *addr, int port,
+int cpsw_ale_add_ucast(struct cpsw_ale *ale, const u8 *addr, int port,
int flags, u16 vid);
-int cpsw_ale_del_ucast(struct cpsw_ale *ale, u8 *addr, int port,
+int cpsw_ale_del_ucast(struct cpsw_ale *ale, const u8 *addr, int port,
int flags, u16 vid);
-int cpsw_ale_add_mcast(struct cpsw_ale *ale, u8 *addr, int port_mask,
+int cpsw_ale_add_mcast(struct cpsw_ale *ale, const u8 *addr, int port_mask,
int flags, u16 vid, int mcast_state);
-int cpsw_ale_del_mcast(struct cpsw_ale *ale, u8 *addr, int port_mask,
+int cpsw_ale_del_mcast(struct cpsw_ale *ale, const u8 *addr, int port_mask,
int flags, u16 vid);
int cpsw_ale_add_vlan(struct cpsw_ale *ale, u16 vid, int port, int untag,
int reg_mcast, int unreg_mcast);
--
2.17.1
^ permalink raw reply related
* [PATCH 2/2] net: ethernet: ti: cpsw: fix lost of mcast packets while rx_mode update
From: Ivan Khoronzhuk @ 2018-10-12 15:28 UTC (permalink / raw)
To: grygorii.strashko, davem
Cc: linux-omap, netdev, linux-kernel, Ivan Khoronzhuk
In-Reply-To: <20181012152815.31320-1-ivan.khoronzhuk@linaro.org>
Whenever kernel or user decides to call rx mode update, it clears
every multicast entry from forwarding table and in some time adds
it again. This time can be enough to drop incoming multicast packets.
That's why clear only staled multicast entries and update or add new
one afterwards.
Signed-off-by: Ivan Khoronzhuk <ivan.khoronzhuk@linaro.org>
---
drivers/net/ethernet/ti/cpsw.c | 46 +++++++++++++++++++++-------------
1 file changed, 28 insertions(+), 18 deletions(-)
diff --git a/drivers/net/ethernet/ti/cpsw.c b/drivers/net/ethernet/ti/cpsw.c
index 832bce07c385..b7a6a2a0f71d 100644
--- a/drivers/net/ethernet/ti/cpsw.c
+++ b/drivers/net/ethernet/ti/cpsw.c
@@ -570,7 +570,7 @@ static inline int cpsw_get_slave_port(u32 slave_num)
return slave_num + 1;
}
-static void cpsw_add_mcast(struct cpsw_priv *priv, u8 *addr)
+static void cpsw_add_mcast(struct cpsw_priv *priv, const u8 *addr)
{
struct cpsw_common *cpsw = priv->cpsw;
@@ -662,16 +662,35 @@ static void cpsw_set_promiscious(struct net_device *ndev, bool enable)
}
}
-static void cpsw_ndo_set_rx_mode(struct net_device *ndev)
+static int cpsw_add_mc_addr(struct net_device *ndev, const u8 *addr)
+{
+ struct cpsw_priv *priv = netdev_priv(ndev);
+
+ cpsw_add_mcast(priv, addr);
+ return 0;
+}
+
+static int cpsw_del_mc_addr(struct net_device *ndev, const u8 *addr)
{
struct cpsw_priv *priv = netdev_priv(ndev);
struct cpsw_common *cpsw = priv->cpsw;
- int vid;
+ int vid, flags;
- if (cpsw->data.dual_emac)
+ if (cpsw->data.dual_emac) {
vid = cpsw->slaves[priv->emac_port].port_vlan;
- else
- vid = cpsw->data.default_vlan;
+ flags = ALE_VLAN;
+ } else {
+ vid = 0;
+ flags = 0;
+ }
+
+ cpsw_ale_del_mcast(cpsw->ale, addr, 0, flags, vid);
+ return 0;
+}
+
+static void cpsw_ndo_set_rx_mode(struct net_device *ndev)
+{
+ struct cpsw_common *cpsw = ndev_to_cpsw(ndev);
if (ndev->flags & IFF_PROMISC) {
/* Enable promiscuous mode */
@@ -684,19 +703,9 @@ static void cpsw_ndo_set_rx_mode(struct net_device *ndev)
}
/* Restore allmulti on vlans if necessary */
- cpsw_ale_set_allmulti(cpsw->ale, priv->ndev->flags & IFF_ALLMULTI);
-
- /* Clear all mcast from ALE */
- cpsw_ale_flush_multicast(cpsw->ale, ALE_ALL_PORTS, vid);
+ cpsw_ale_set_allmulti(cpsw->ale, ndev->flags & IFF_ALLMULTI);
- if (!netdev_mc_empty(ndev)) {
- struct netdev_hw_addr *ha;
-
- /* program multicast address list into ALE register */
- netdev_for_each_mc_addr(ha, ndev) {
- cpsw_add_mcast(priv, ha->addr);
- }
- }
+ __dev_mc_sync(ndev, cpsw_add_mc_addr, cpsw_del_mc_addr);
}
static void cpsw_intr_enable(struct cpsw_common *cpsw)
@@ -1956,6 +1965,7 @@ static int cpsw_ndo_stop(struct net_device *ndev)
struct cpsw_common *cpsw = priv->cpsw;
cpsw_info(priv, ifdown, "shutting down cpsw device\n");
+ __dev_mc_unsync(priv->ndev, cpsw_del_mc_addr);
netif_tx_stop_all_queues(priv->ndev);
netif_carrier_off(priv->ndev);
--
2.17.1
^ permalink raw reply related
* Re: [PATCH] rxrpc: add IPV6 dependency
From: Randy Dunlap @ 2018-10-12 15:33 UTC (permalink / raw)
To: David Howells, Arnd Bergmann
Cc: David S. Miller, linux-afs, linux-kernel, netdev
In-Reply-To: <24845.1539354316@warthog.procyon.org.uk>
On 10/12/18 7:25 AM, David Howells wrote:
> Arnd Bergmann <arnd@arndb.de> wrote:
>
>> + depends on IPV6 || !IPV6
>
> That looks weird. It looks like it always ought to be true.
It's a common idiom in Kconfig.
It prevents AF_RXRPC=y and IPV6=m, resulting in this build error.
--
~Randy
^ permalink raw reply
* [PATCH net] rxrpc: Fix incorrect conditional on IPV6
From: David Howells @ 2018-10-12 15:38 UTC (permalink / raw)
To: netdev
Cc: kbuild-all, Arnd Bergmann, Arnd Bergmann, dhowells, linux-afs,
linux-kernel
The udpv6_encap_enable() function is part of the ipv6 code, and if that is
configured as a loadable module and rxrpc is built in then a build failure
will occur because the conditional check is wrong:
net/rxrpc/local_object.o: In function `rxrpc_lookup_local':
local_object.c:(.text+0x2688): undefined reference to `udpv6_encap_enable'
Use the correct config symbol (CONFIG_AF_RXRPC_IPV6) in the conditional
check rather than CONFIG_IPV6 as that will do the right thing.
Fixes: 5271953cad31 ("rxrpc: Use the UDP encap_rcv hook")
Reported-by: kbuild-all@01.org
Reported-by: Arnd Bergmann <arnd@arndb.de>
Signed-off-by: David Howells <dhowells@redhat.com>
Reviewed-by: Arnd Bergmann <arnd@arndb.de>
---
net/rxrpc/local_object.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/net/rxrpc/local_object.c b/net/rxrpc/local_object.c
index cad0691c2bb4..0906e51d3cfb 100644
--- a/net/rxrpc/local_object.c
+++ b/net/rxrpc/local_object.c
@@ -139,7 +139,7 @@ static int rxrpc_open_socket(struct rxrpc_local *local, struct net *net)
udp_sk(usk)->gro_complete = NULL;
udp_encap_enable();
-#if IS_ENABLED(CONFIG_IPV6)
+#if IS_ENABLED(CONFIG_AF_RXRPC_IPV6)
if (local->srx.transport.family == AF_INET6)
udpv6_encap_enable();
#endif
^ permalink raw reply related
* Re: usbnet private-data accessor functions
From: Oliver Neukum @ 2018-10-12 15:38 UTC (permalink / raw)
To: Ben Dooks, davem, netdev
Cc: gregkh, linux-kernel, bjorn, steve.glendinning, linux-kernel,
linux-usb
In-Reply-To: <20181012091642.21294-1-ben.dooks@codethink.co.uk>
On Fr, 2018-10-12 at 10:16 +0100, Ben Dooks wrote:
> I have been looking at the usbnet drivers and the possibility of some
> code cleanups. One of the things I've found is that changing the way
> the drivers use the private data with the usbnet structure is often
> hand-coded each time is needed.
Where is the improvement? You are just hiding how the data is passed.
It may look more pleasant to you, but that is a subjective impression.
I would suggest that if you want a nicely named way to get at private
data, add a field to the appropriate data structure.
Regards
Oliver
^ permalink raw reply
* [rtnetlink] Potential bug in Linux (rt)netlink code
From: Henning Rogge @ 2018-10-12 7:30 UTC (permalink / raw)
To: netdev
Hi,
I am working on a self-written routing agent
(https://github.com/OLSR/OONF) and am stuck on a problem with netlink
that I cannot explain with an userspace error.
I am using a netlink socket for setting routes
(RTM_NEWROUTE/RTM_DELROUTE), querying the kernel for the current routes
in the database (via a RTM_GETROUTE dump) and for getting multicast
messages for ongoing routing changes.
After a few netlink messages I get to the point where the kernel just
does not responst to a RTM_NEWROUTE. No error, no answer, despite the
NLM_F_ACK flag set)... but sometime when (during shutdown of the routing
agent) the program sends another route command (most times a
RTM_DELROUTE) I get a single netlink packet with a "successful" response
for both the "missing" RTM_NEWROUTE and one for the new RTM DELROUTE
sequence number.
I am testing two routing agents, each of them in a systemd-nspawn based
container connected over a bridge on the host system on a current Debian
Testing (kernel 4.18.0-1-amd64).
I am directly using the netlink sockets, without any other userspace
library in between.
I have checked the hexdumps of a couple of netlink messages (including
the ones just before the bug happens) by hand and they seem to be okay.
When I tried to add a "netlink listener" socket for futher debugging (ip
link add nlmon0 type nlmon) the problem vanished until I removed the
listener socket again.
Any ideas how to debug this problem? Unfortunately I have no short
example program to trigger the bug... I have rarely seen the problem for
years (once every couple of months), but until a few days ago I never
managed to reproduce it.
Henning Rogge
--
Diplom-Informatiker Henning Rogge , Fraunhofer-Institut für
Kommunikation, Informationsverarbeitung und Ergonomie FKIE
Kommunikationssysteme (KOM)
Zanderstrasse 5, 53177 Bonn, Germany
Telefon +49 228 50212-469
mailto:henning.rogge@fkie.fraunhofer.de http://www.fkie.fraunhofer.de
^ permalink raw reply
* Re: Bad MAINTAINERS pattern in section 'VIRTIO AND VHOST VSOCK DRIVER'
From: Stefan Hajnoczi @ 2018-10-12 15:46 UTC (permalink / raw)
To: Joe Perches
Cc: linux-kernel, Stefan Hajnoczi, kvm, virtualization, netdev,
David S . Miller
In-Reply-To: <20180928220527.32038-1-joe@perches.com>
[-- Attachment #1: Type: text/plain, Size: 958 bytes --]
On Fri, Sep 28, 2018 at 03:05:26PM -0700, Joe Perches wrote:
> Please fix this defect appropriately.
>
> linux-next MAINTAINERS section:
>
> 15660 VIRTIO AND VHOST VSOCK DRIVER
> 15661 M: Stefan Hajnoczi <stefanha@redhat.com>
> 15662 L: kvm@vger.kernel.org
> 15663 L: virtualization@lists.linux-foundation.org
> 15664 L: netdev@vger.kernel.org
> 15665 S: Maintained
> 15666 F: include/linux/virtio_vsock.h
> 15667 F: include/uapi/linux/virtio_vsock.h
> 15668 F: include/uapi/linux/vsockmon.h
> 15669 F: include/uapi/linux/vm_sockets_diag.h
> 15670 F: net/vmw_vsock/diag.c
> 15671 F: net/vmw_vsock/af_vsock_tap.c
> 15672 F: net/vmw_vsock/virtio_transport_common.c
> 15673 F: net/vmw_vsock/virtio_transport.c
> 15674 F: drivers/net/vsockmon.c
> 15675 F: drivers/vhost/vsock.c
> --> 15676 F: drivers/vhost/vsock.h
Hi Joe,
Thanks for pointing this out and sorry for the late response. I have
sent a patch.
Stefan
[-- Attachment #2: signature.asc --]
[-- Type: application/pgp-signature, Size: 455 bytes --]
^ permalink raw reply
* [PATCH] fore200e: fix sbus compile
From: Christoph Hellwig @ 2018-10-12 8:17 UTC (permalink / raw)
To: netdev; +Cc: 3chas3
Fix a stupid typo introduced in the refactoring.
Fixes: 0efe5523 ("fore200e: simplify fore200e_bus usage")
Signed-off-by: Christoph Hellwig <hch@lst.de>
---
drivers/atm/fore200e.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/drivers/atm/fore200e.c b/drivers/atm/fore200e.c
index 2b5dc8fe1d85..40d6ddbf1d5e 100644
--- a/drivers/atm/fore200e.c
+++ b/drivers/atm/fore200e.c
@@ -762,7 +762,7 @@ static const struct fore200e_bus fore200e_sbus_ops = {
.model_name = "SBA-200E",
.proc_name = "sba200e",
.descr_alignment = 32,
- .buffer_alignent = 64,
+ .buffer_alignment = 64,
.status_alignment = 32,
.read = fore200e_sba_read,
.write = fore200e_sba_write,
--
2.19.1
^ permalink raw reply related
* [PATCH net-next] net: ethernet: ti: cpsw: use for mcast entries only host port
From: Ivan Khoronzhuk @ 2018-10-12 16:06 UTC (permalink / raw)
To: grygorii.strashko, davem
Cc: linux-omap, netdev, linux-kernel, Ivan Khoronzhuk
In dual-emac mode the cpsw driver sends directed packets, that means
that packets go to the directed port, but an ALE lookup is performed
to determine untagged egress only. It means that on tx side no need
to add port bit for ALE mcast entry mask, and basically ALE entry
for port identification is needed only on rx side.
So, add only host port in dual_emac mode as used directed
transmission, and no need in one more port. For single port boards
and switch mode all ports used, as usual, so no changes for them.
Also it simplifies farther changes.
In other words, mcast entries for dual-emac should behave exactly
like unicast. It also can help avoid leaking packets between ports
with same vlan on h/w level if ports could became members of same vid.
So now, for instance, if mcast address 33:33:00:00:00:01 is added then
entries in ALE table:
vid = 1, addr = 33:33:00:00:00:01, port_mask = 0x1
vid = 2, addr = 33:33:00:00:00:01, port_mask = 0x1
Instead of:
vid = 1, addr = 33:33:00:00:00:01, port_mask = 0x3
vid = 2, addr = 33:33:00:00:00:01, port_mask = 0x5
With the same considerations, set only host port for unregistered
mcast for dual-emac mode in case of IFF_ALLMULTI is set, exactly like
it's done in cpsw_ale_set_allmulti().
Signed-off-by: Ivan Khoronzhuk <ivan.khoronzhuk@linaro.org>
---
Based on net-next/master
drivers/net/ethernet/ti/cpsw.c | 13 +++++++------
1 file changed, 7 insertions(+), 6 deletions(-)
diff --git a/drivers/net/ethernet/ti/cpsw.c b/drivers/net/ethernet/ti/cpsw.c
index 16dcbf36f8cc..7bfb7ee3a261 100644
--- a/drivers/net/ethernet/ti/cpsw.c
+++ b/drivers/net/ethernet/ti/cpsw.c
@@ -576,10 +576,8 @@ static void cpsw_add_mcast(struct cpsw_priv *priv, u8 *addr)
if (cpsw->data.dual_emac) {
struct cpsw_slave *slave = cpsw->slaves + priv->emac_port;
- int slave_port = cpsw_get_slave_port(slave->slave_num);
- cpsw_ale_add_mcast(cpsw->ale, addr,
- 1 << slave_port | ALE_PORT_HOST,
+ cpsw_ale_add_mcast(cpsw->ale, addr, ALE_PORT_HOST,
ALE_VLAN, slave->port_vlan, 0);
return;
}
@@ -1410,7 +1408,7 @@ static inline void cpsw_add_dual_emac_def_ale_entries(
cpsw_ale_add_vlan(cpsw->ale, slave->port_vlan, port_mask,
port_mask, port_mask, 0);
cpsw_ale_add_mcast(cpsw->ale, priv->ndev->broadcast,
- port_mask, ALE_VLAN, slave->port_vlan, 0);
+ ALE_PORT_HOST, ALE_VLAN, slave->port_vlan, 0);
cpsw_ale_add_ucast(cpsw->ale, priv->mac_addr,
HOST_PORT_NUM, ALE_VLAN |
ALE_SECURE, slave->port_vlan);
@@ -2293,16 +2291,19 @@ static inline int cpsw_add_vlan_ale_entry(struct cpsw_priv *priv,
{
int ret;
int unreg_mcast_mask = 0;
+ int mcast_mask;
u32 port_mask;
struct cpsw_common *cpsw = priv->cpsw;
if (cpsw->data.dual_emac) {
port_mask = (1 << (priv->emac_port + 1)) | ALE_PORT_HOST;
+ mcast_mask = ALE_PORT_HOST;
if (priv->ndev->flags & IFF_ALLMULTI)
- unreg_mcast_mask = port_mask;
+ unreg_mcast_mask = mcast_mask;
} else {
port_mask = ALE_ALL_PORTS;
+ mcast_mask = port_mask;
if (priv->ndev->flags & IFF_ALLMULTI)
unreg_mcast_mask = ALE_ALL_PORTS;
@@ -2321,7 +2322,7 @@ static inline int cpsw_add_vlan_ale_entry(struct cpsw_priv *priv,
goto clean_vid;
ret = cpsw_ale_add_mcast(cpsw->ale, priv->ndev->broadcast,
- port_mask, ALE_VLAN, vid, 0);
+ mcast_mask, ALE_VLAN, vid, 0);
if (ret != 0)
goto clean_vlan_ucast;
return 0;
--
2.17.1
^ permalink raw reply related
* Re: [PATCH bpf-next 2/2] bpf, libbpf: simplify perf RB walk and do incremental updates
From: Daniel Borkmann @ 2018-10-12 8:39 UTC (permalink / raw)
To: Jakub Kicinski; +Cc: alexei.starovoitov, netdev
In-Reply-To: <20181011200405.0af4a48b@cakuba.netronome.com>
On 10/12/2018 05:04 AM, Jakub Kicinski wrote:
> On Thu, 11 Oct 2018 16:02:07 +0200, Daniel Borkmann wrote:
>> Clean up and improve bpf_perf_event_read_simple() ring walk a bit
>> to use similar tail update scheme as in perf and bcc allowing the
>> kernel to make forward progress not only after full timely walk.
>
> The extra memory barriers won't impact performance? If I read the code
> correctly we now have:
>
> while (bla) {
> head = HEAD
> rmb()
>
> ...
>
> mb()
> TAIL = tail
> }
>
> Would it make sense to try to piggy back on the mb() for head re-read
> at least? Perhaps that's a non-issue, just wondering.
>From the scheme specified in the comment in prior patch my understanding
would be that they don't pair (see B and C) so there would be no guarantee
that load of head would happen before load of data. Fwiw, I've been using
the exact same semantics as user space perf tool walks the perf mmap'ed
ring buffer (tools/perf/util/mmap.{h,c}) here. Given kernel doesn't stop
pushing into ring buffer while user space walks it and indicates how far
it has consumed data via tail update, it would allow for making room
successively and not only after full run has complete, so we don't make
any assumptions in the generic libbpf library helper on how slow/quick
the callback would be processing resp. how full ring is, etc, and kernel
pushing new data can be processed in the same run if necessary. One thing
we could consider is to batch tail updates, say, every 8 elements and a
final update once we break out walking the ring; probably okay'ish as a
heuristic..
>> Also few other improvements to use realloc() instead of free() and
>> malloc() combination and for the callback use proper perf_event_header
>> instead of void pointer, so that real applications can use container_of()
>> macro with proper type checking.
>
> FWIW the free() + malloc() was to avoid the the needless copy of the
> previous event realloc() may do. It makes sense to use realloc()
> especially if you want to put extra info in front of the buffer, just
> sayin' it wasn't a complete braino ;)
No strong preference from my side, I'd think that it might be sensible in
any case from applications to call the bpf_perf_event_read_simple() with a
already preallocated buffer, depending on the expected max element size from
BPF could e.g. be a buffer of 1 page or so. Given 512 byte stack space from
the BPF prog and MTU 1500 this would more than suffice to avoid new
allocations altogether. Anyway, given we only grow the new memory area I
did some testing on realloc() with an array of pointers to prior malloc()'ed
buffers, running randomly 10M realloc()s to increase size over them and
saw <1% where area had to be moved, so we're hitting corner case of a corner
case, I'm also ok to leave the combination, though. :)
Thanks,
Daniel
^ permalink raw reply
* [PATCH v3 lora-next 1/5] regmap: Add regmap_noinc_write API
From: Ben Whitten @ 2018-10-12 16:26 UTC (permalink / raw)
To: afaerber
Cc: starnight, hasnain.virk, netdev, liuxuenetmail, shess,
Ben Whitten, Mark Brown, Greg Kroah-Hartman, Rafael J. Wysocki,
linux-kernel
In-Reply-To: <1539361567-3602-1-git-send-email-ben.whitten@lairdtech.com>
The regmap API had a noinc_read function added for instances where devices
supported returning data from an internal FIFO in a single read.
This commit adds the noinc_write variant to allow writing to a non
incrementing register, this is used in devices such as the sx1301 for
loading firmware.
Signed-off-by: Ben Whitten <ben.whitten@lairdtech.com>
---
drivers/base/regmap/internal.h | 3 ++
drivers/base/regmap/regmap.c | 77 ++++++++++++++++++++++++++++++++++++++++++
include/linux/regmap.h | 19 +++++++++++
3 files changed, 99 insertions(+)
diff --git a/drivers/base/regmap/internal.h b/drivers/base/regmap/internal.h
index a6bf34d63..404f123 100644
--- a/drivers/base/regmap/internal.h
+++ b/drivers/base/regmap/internal.h
@@ -94,11 +94,13 @@ struct regmap {
bool (*readable_reg)(struct device *dev, unsigned int reg);
bool (*volatile_reg)(struct device *dev, unsigned int reg);
bool (*precious_reg)(struct device *dev, unsigned int reg);
+ bool (*writeable_noinc_reg)(struct device *dev, unsigned int reg);
bool (*readable_noinc_reg)(struct device *dev, unsigned int reg);
const struct regmap_access_table *wr_table;
const struct regmap_access_table *rd_table;
const struct regmap_access_table *volatile_table;
const struct regmap_access_table *precious_table;
+ const struct regmap_access_table *wr_noinc_table;
const struct regmap_access_table *rd_noinc_table;
int (*reg_read)(void *context, unsigned int reg, unsigned int *val);
@@ -183,6 +185,7 @@ bool regmap_writeable(struct regmap *map, unsigned int reg);
bool regmap_readable(struct regmap *map, unsigned int reg);
bool regmap_volatile(struct regmap *map, unsigned int reg);
bool regmap_precious(struct regmap *map, unsigned int reg);
+bool regmap_writeable_noinc(struct regmap *map, unsigned int reg);
bool regmap_readable_noinc(struct regmap *map, unsigned int reg);
int _regmap_write(struct regmap *map, unsigned int reg,
diff --git a/drivers/base/regmap/regmap.c b/drivers/base/regmap/regmap.c
index 0360a90..d4f1fc6 100644
--- a/drivers/base/regmap/regmap.c
+++ b/drivers/base/regmap/regmap.c
@@ -168,6 +168,17 @@ bool regmap_precious(struct regmap *map, unsigned int reg)
return false;
}
+bool regmap_writeable_noinc(struct regmap *map, unsigned int reg)
+{
+ if (map->writeable_noinc_reg)
+ return map->writeable_noinc_reg(map->dev, reg);
+
+ if (map->wr_noinc_table)
+ return regmap_check_range_table(map, reg, map->wr_noinc_table);
+
+ return true;
+}
+
bool regmap_readable_noinc(struct regmap *map, unsigned int reg)
{
if (map->readable_noinc_reg)
@@ -777,11 +788,13 @@ struct regmap *__regmap_init(struct device *dev,
map->rd_table = config->rd_table;
map->volatile_table = config->volatile_table;
map->precious_table = config->precious_table;
+ map->wr_noinc_table = config->wr_noinc_table;
map->rd_noinc_table = config->rd_noinc_table;
map->writeable_reg = config->writeable_reg;
map->readable_reg = config->readable_reg;
map->volatile_reg = config->volatile_reg;
map->precious_reg = config->precious_reg;
+ map->writeable_noinc_reg = config->writeable_noinc_reg;
map->readable_noinc_reg = config->readable_noinc_reg;
map->cache_type = config->cache_type;
@@ -1298,6 +1311,7 @@ int regmap_reinit_cache(struct regmap *map, const struct regmap_config *config)
map->readable_reg = config->readable_reg;
map->volatile_reg = config->volatile_reg;
map->precious_reg = config->precious_reg;
+ map->writeable_noinc_reg = config->writeable_noinc_reg;
map->readable_noinc_reg = config->readable_noinc_reg;
map->cache_type = config->cache_type;
@@ -1898,6 +1912,69 @@ int regmap_raw_write(struct regmap *map, unsigned int reg,
EXPORT_SYMBOL_GPL(regmap_raw_write);
/**
+ * regmap_noinc_write(): Write data from a register without incrementing the
+ * register number
+ *
+ * @map: Register map to write to
+ * @reg: Register to write to
+ * @val: Pointer to data buffer
+ * @val_len: Length of output buffer in bytes.
+ *
+ * The regmap API usually assumes that bulk bus write operations will write a
+ * range of registers. Some devices have certain registers for which a write
+ * operation can write to an internal FIFO.
+ *
+ * The target register must be volatile but registers after it can be
+ * completely unrelated cacheable registers.
+ *
+ * This will attempt multiple writes as required to write val_len bytes.
+ *
+ * A value of zero will be returned on success, a negative errno will be
+ * returned in error cases.
+ */
+int regmap_noinc_write(struct regmap *map, unsigned int reg,
+ const void *val, size_t val_len)
+{
+ size_t write_len;
+ int ret;
+
+ if (!map->bus)
+ return -EINVAL;
+ if (!map->bus->write)
+ return -ENOTSUPP;
+ if (val_len % map->format.val_bytes)
+ return -EINVAL;
+ if (!IS_ALIGNED(reg, map->reg_stride))
+ return -EINVAL;
+ if (val_len == 0)
+ return -EINVAL;
+
+ map->lock(map->lock_arg);
+
+ if (!regmap_volatile(map, reg) || !regmap_writeable_noinc(map, reg)) {
+ ret = -EINVAL;
+ goto out_unlock;
+ }
+
+ while (val_len) {
+ if (map->max_raw_write && map->max_raw_write < val_len)
+ write_len = map->max_raw_write;
+ else
+ write_len = val_len;
+ ret = _regmap_raw_write(map, reg, val, write_len);
+ if (ret)
+ goto out_unlock;
+ val = ((u8 *)val) + write_len;
+ val_len -= write_len;
+ }
+
+out_unlock:
+ map->unlock(map->lock_arg);
+ return ret;
+}
+EXPORT_SYMBOL_GPL(regmap_noinc_write);
+
+/**
* regmap_field_update_bits_base() - Perform a read/modify/write cycle a
* register field.
*
diff --git a/include/linux/regmap.h b/include/linux/regmap.h
index 379505a..de04dc4 100644
--- a/include/linux/regmap.h
+++ b/include/linux/regmap.h
@@ -268,6 +268,13 @@ typedef void (*regmap_unlock)(void *);
* field is NULL but precious_table (see below) is not, the
* check is performed on such table (a register is precious if
* it belongs to one of the ranges specified by precious_table).
+ * @writeable_noinc_reg: Optional callback returning true if the register
+ * supports multiple write operations without incrementing
+ * the register number. If this field is NULL but
+ * wr_noinc_table (see below) is not, the check is
+ * performed on such table (a register is no increment
+ * writeable if it belongs to one of the ranges specified
+ * by wr_noinc_table).
* @readable_noinc_reg: Optional callback returning true if the register
* supports multiple read operations without incrementing
* the register number. If this field is NULL but
@@ -302,6 +309,7 @@ typedef void (*regmap_unlock)(void *);
* @rd_table: As above, for read access.
* @volatile_table: As above, for volatile registers.
* @precious_table: As above, for precious registers.
+ * @wr_noinc_table: As above, for no increment writeable registers.
* @rd_noinc_table: As above, for no increment readable registers.
* @reg_defaults: Power on reset values for registers (for use with
* register cache support).
@@ -352,6 +360,7 @@ struct regmap_config {
bool (*readable_reg)(struct device *dev, unsigned int reg);
bool (*volatile_reg)(struct device *dev, unsigned int reg);
bool (*precious_reg)(struct device *dev, unsigned int reg);
+ bool (*writeable_noinc_reg)(struct device *dev, unsigned int reg);
bool (*readable_noinc_reg)(struct device *dev, unsigned int reg);
bool disable_locking;
@@ -369,6 +378,7 @@ struct regmap_config {
const struct regmap_access_table *rd_table;
const struct regmap_access_table *volatile_table;
const struct regmap_access_table *precious_table;
+ const struct regmap_access_table *wr_noinc_table;
const struct regmap_access_table *rd_noinc_table;
const struct reg_default *reg_defaults;
unsigned int num_reg_defaults;
@@ -979,6 +989,8 @@ int regmap_write(struct regmap *map, unsigned int reg, unsigned int val);
int regmap_write_async(struct regmap *map, unsigned int reg, unsigned int val);
int regmap_raw_write(struct regmap *map, unsigned int reg,
const void *val, size_t val_len);
+int regmap_noinc_write(struct regmap *map, unsigned int reg,
+ const void *val, size_t val_len);
int regmap_bulk_write(struct regmap *map, unsigned int reg, const void *val,
size_t val_count);
int regmap_multi_reg_write(struct regmap *map, const struct reg_sequence *regs,
@@ -1222,6 +1234,13 @@ static inline int regmap_raw_write_async(struct regmap *map, unsigned int reg,
return -EINVAL;
}
+static inline int regmap_noinc_write(struct regmap *map, unsigned int reg,
+ const void *val, size_t val_len)
+{
+ WARN_ONCE(1, "regmap API is disabled");
+ return -EINVAL;
+}
+
static inline int regmap_bulk_write(struct regmap *map, unsigned int reg,
const void *val, size_t val_count)
{
--
2.7.4
^ permalink raw reply related
* [PATCH v3 lora-next 2/5] net: lora: sx1301: replace burst spi functions with regmap_noinc
From: Ben Whitten @ 2018-10-12 16:26 UTC (permalink / raw)
To: afaerber
Cc: starnight, hasnain.virk, netdev, liuxuenetmail, shess,
Ben Whitten, David S. Miller, linux-kernel
In-Reply-To: <1539361567-3602-1-git-send-email-ben.whitten@lairdtech.com>
We can now use to regmap_noinc API to allow reading and writing to
the internal FIFO register which controls processor memory.
We also remove the now defunct spi element from the structure as this
completes the move to regmap.
Signed-off-by: Ben Whitten <ben.whitten@lairdtech.com>
---
drivers/net/lora/sx1301.c | 22 ++--------------------
drivers/net/lora/sx1301.h | 2 --
2 files changed, 2 insertions(+), 22 deletions(-)
diff --git a/drivers/net/lora/sx1301.c b/drivers/net/lora/sx1301.c
index fd29258..9c85fe7 100644
--- a/drivers/net/lora/sx1301.c
+++ b/drivers/net/lora/sx1301.c
@@ -74,23 +74,6 @@ static struct regmap_config sx1301_regmap_config = {
.max_register = SX1301_MAX_REGISTER,
};
-static int sx1301_read_burst(struct sx1301_priv *priv, u8 reg, u8 *val, size_t len)
-{
- u8 addr = reg & 0x7f;
- return spi_write_then_read(priv->spi, &addr, 1, val, len);
-}
-
-static int sx1301_write_burst(struct sx1301_priv *priv, u8 reg, const u8 *val, size_t len)
-{
- u8 addr = reg | BIT(7);
- struct spi_transfer xfr[2] = {
- { .tx_buf = &addr, .len = 1 },
- { .tx_buf = val, .len = len },
- };
-
- return spi_sync_transfer(priv->spi, xfr, 2);
-}
-
static int sx1301_soft_reset(struct sx1301_priv *priv)
{
return regmap_write(priv->regmap, SX1301_PAGE, REG_PAGE_RESET_SOFT_RESET);
@@ -180,7 +163,7 @@ static int sx1301_load_firmware(struct sx1301_priv *priv, int mcu, const struct
return ret;
}
- ret = sx1301_write_burst(priv, SX1301_MPD, fw->data, fw->size);
+ ret = regmap_noinc_write(priv->regmap, SX1301_MPD, fw->data, fw->size);
if (ret) {
dev_err(priv->dev, "MCU prom data write failed\n");
return ret;
@@ -196,7 +179,7 @@ static int sx1301_load_firmware(struct sx1301_priv *priv, int mcu, const struct
if (!buf)
return -ENOMEM;
- ret = sx1301_read_burst(priv, SX1301_MPD, buf, fw->size);
+ ret = regmap_noinc_read(priv->regmap, SX1301_MPD, buf, fw->size);
if (ret) {
dev_err(priv->dev, "MCU prom data read failed\n");
kfree(buf);
@@ -566,7 +549,6 @@ static int sx1301_probe(struct spi_device *spi)
spi_set_drvdata(spi, netdev);
priv->dev = &spi->dev;
- priv->spi = spi;
priv->regmap = devm_regmap_init_spi(spi, &sx1301_regmap_config);
if (IS_ERR(priv->regmap)) {
diff --git a/drivers/net/lora/sx1301.h b/drivers/net/lora/sx1301.h
index e939c02..e6400f8 100644
--- a/drivers/net/lora/sx1301.h
+++ b/drivers/net/lora/sx1301.h
@@ -12,7 +12,6 @@
#include <linux/regmap.h>
#include <linux/gpio/consumer.h>
#include <linux/lora/dev.h>
-#include <linux/spi/spi.h>
#define SX1301_CHIP_VERSION 103
@@ -64,7 +63,6 @@
struct sx1301_priv {
struct lora_dev_priv lora;
struct device *dev;
- struct spi_device *spi;
struct gpio_desc *rst_gpio;
struct regmap *regmap;
};
--
2.7.4
^ permalink raw reply related
* [PATCH v3 lora-next 4/5] net: lora: sx125x: convert to regmap fields
From: Ben Whitten @ 2018-10-12 16:26 UTC (permalink / raw)
To: afaerber
Cc: starnight, hasnain.virk, netdev, liuxuenetmail, shess,
Ben Whitten, David S. Miller, linux-kernel
In-Reply-To: <1539361567-3602-1-git-send-email-ben.whitten@lairdtech.com>
From: Ben Whitten <ben.whitten@gmail.com>
We convert to using regmap fields to allow regmap to take care of read
modify writes and bit shifting for ofset fields.
Signed-off-by: Ben Whitten <ben.whitten@gmail.com>
---
drivers/net/lora/sx125x.c | 59 ++++++++++++++++++++++++++++++++++++++++-------
1 file changed, 51 insertions(+), 8 deletions(-)
diff --git a/drivers/net/lora/sx125x.c b/drivers/net/lora/sx125x.c
index dc13d1a..36b61b1 100644
--- a/drivers/net/lora/sx125x.c
+++ b/drivers/net/lora/sx125x.c
@@ -25,11 +25,25 @@
#include "sx125x.h"
-#define REG_CLK_SELECT_TX_DAC_CLK_SELECT_CLK_IN BIT(0)
-#define REG_CLK_SELECT_CLK_OUT BIT(1)
+enum sx125x_fields {
+ F_CLK_OUT,
+ F_TX_DAC_CLK_SEL,
+ F_SX1257_XOSC_GM_STARTUP,
+ F_SX1257_XOSC_DISABLE_CORE,
+};
+
+static const struct reg_field sx125x_regmap_fields[] = {
+ /* CLK_SELECT */
+ [F_CLK_OUT] = REG_FIELD(SX125X_CLK_SELECT, 1, 1),
+ [F_TX_DAC_CLK_SEL] = REG_FIELD(SX125X_CLK_SELECT, 0, 0),
+ /* XOSC */ /* TODO maybe make this dynamic */
+ [F_SX1257_XOSC_GM_STARTUP] = REG_FIELD(SX1257_XOSC, 0, 3),
+ [F_SX1257_XOSC_DISABLE_CORE] = REG_FIELD(SX1257_XOSC, 5, 5),
+};
struct sx125x_priv {
struct regmap *regmap;
+ struct regmap_field *regmap_fields[ARRAY_SIZE(sx125x_regmap_fields)];
};
static struct regmap_config __maybe_unused sx125x_regmap_config = {
@@ -44,11 +58,18 @@ static struct regmap_config __maybe_unused sx125x_regmap_config = {
.max_register = SX125X_MAX_REGISTER,
};
+static int sx125x_field_write(struct sx125x_priv *priv,
+ enum sx125x_fields field_id, u8 val)
+{
+ return regmap_field_write(priv->regmap_fields[field_id], val);
+}
+
static int __maybe_unused sx125x_regmap_probe(struct device *dev, struct regmap *regmap, unsigned int radio)
{
struct sx125x_priv *priv;
unsigned int val;
int ret;
+ int i;
priv = devm_kzalloc(dev, sizeof(*priv), GFP_KERNEL);
if (!priv)
@@ -56,6 +77,18 @@ static int __maybe_unused sx125x_regmap_probe(struct device *dev, struct regmap
dev_set_drvdata(dev, priv);
priv->regmap = regmap;
+ for (i = 0; i < ARRAY_SIZE(sx125x_regmap_fields); i++) {
+ const struct reg_field *reg_fields = sx125x_regmap_fields;
+
+ priv->regmap_fields[i] = devm_regmap_field_alloc(dev,
+ priv->regmap,
+ reg_fields[i]);
+ if (IS_ERR(priv->regmap_fields[i])) {
+ ret = PTR_ERR(priv->regmap_fields[i]);
+ dev_err(dev, "Cannot allocate regmap field: %d\n", ret);
+ return ret;
+ }
+ }
if (true) {
ret = regmap_read(priv->regmap, SX1255_VERSION, &val);
@@ -66,24 +99,34 @@ static int __maybe_unused sx125x_regmap_probe(struct device *dev, struct regmap
dev_info(dev, "SX125x version: %02x\n", val);
}
- val = REG_CLK_SELECT_TX_DAC_CLK_SELECT_CLK_IN;
if (radio == 1) { /* HACK */
- val |= REG_CLK_SELECT_CLK_OUT;
+ ret = sx125x_field_write(priv, F_CLK_OUT, 1);
+ if (ret) {
+ dev_err(dev, "enabling clock output failed\n");
+ return ret;
+ }
+
dev_info(dev, "enabling clock output\n");
}
- ret = regmap_write(priv->regmap, SX125X_CLK_SELECT, val);
+ ret = sx125x_field_write(priv, F_TX_DAC_CLK_SEL, 1);
if (ret) {
- dev_err(dev, "clk write failed\n");
+ dev_err(dev, "clock select failed\n");
return ret;
}
dev_dbg(dev, "clk written\n");
if (true) {
- ret = regmap_write(priv->regmap, SX1257_XOSC, 13 + 2 * 16);
+ ret = sx125x_field_write(priv, F_SX1257_XOSC_DISABLE_CORE, 1);
+ if (ret) {
+ dev_err(dev, "xosc disable failed\n");
+ return ret;
+ }
+
+ ret = sx125x_field_write(priv, F_SX1257_XOSC_GM_STARTUP, 13);
if (ret) {
- dev_err(dev, "xosc write failed\n");
+ dev_err(dev, "xosc startup adjust failed\n");
return ret;
}
}
--
2.7.4
^ permalink raw reply related
* [PATCH v3 lora-next 5/5] net: lora: sx125x sx1301: allow radio to register as a clk provider
From: Ben Whitten @ 2018-10-12 16:26 UTC (permalink / raw)
To: afaerber
Cc: starnight, hasnain.virk, netdev, liuxuenetmail, shess,
Ben Whitten, David S. Miller, linux-kernel
In-Reply-To: <1539361567-3602-1-git-send-email-ben.whitten@lairdtech.com>
From: Ben Whitten <ben.whitten@gmail.com>
The 32M is run from the radio, before we just enabled it based on
the radio number but now we can use the clk framework to request the
clk is started when we need it.
The 32M clock produced from the radio is really a gated version of
tcxo which is a fixed clock provided by hardware, and isn't captured
in this patch.
The sx1301 brings the clock up prior to calibration once the radios
have probed themselves.
A sample dts showing the clk link:
sx1301: sx1301@0 {
...
clocks = <&radio1 0>;
clock-names = "clk32m";
radio-spi {
radio0: radio-a@0 {
...
};
radio1: radio-b@1 {
#clock-cells = <0>;
clock-output-names = "clk32m";
};
};
};
Signed-off-by: Ben Whitten <ben.whitten@gmail.com>
---
drivers/net/lora/sx125x.c | 112 ++++++++++++++++++++++++++++++++++++++++++----
drivers/net/lora/sx1301.c | 13 ++++++
drivers/net/lora/sx1301.h | 2 +
3 files changed, 119 insertions(+), 8 deletions(-)
diff --git a/drivers/net/lora/sx125x.c b/drivers/net/lora/sx125x.c
index 36b61b1..b7ca782 100644
--- a/drivers/net/lora/sx125x.c
+++ b/drivers/net/lora/sx125x.c
@@ -9,6 +9,8 @@
* Copyright (c) 2013 Semtech-Cycleo
*/
+#include <linux/clk.h>
+#include <linux/clk-provider.h>
#include <linux/module.h>
#include <linux/of.h>
#include <linux/of_device.h>
@@ -42,10 +44,16 @@ static const struct reg_field sx125x_regmap_fields[] = {
};
struct sx125x_priv {
+ struct clk *clkout;
+ struct clk_hw clkout_hw;
+
+ struct device *dev;
struct regmap *regmap;
struct regmap_field *regmap_fields[ARRAY_SIZE(sx125x_regmap_fields)];
};
+#define to_clkout(_hw) container_of(_hw, struct sx125x_priv, clkout_hw)
+
static struct regmap_config __maybe_unused sx125x_regmap_config = {
.reg_bits = 8,
.val_bits = 8,
@@ -64,6 +72,96 @@ static int sx125x_field_write(struct sx125x_priv *priv,
return regmap_field_write(priv->regmap_fields[field_id], val);
}
+static int sx125x_field_read(struct sx125x_priv *priv,
+ enum sx125x_fields field_id, unsigned int *val)
+{
+ return regmap_field_read(priv->regmap_fields[field_id], val);
+}
+
+static int sx125x_clkout_enable(struct clk_hw *hw)
+{
+ struct sx125x_priv *priv = to_clkout(hw);
+
+ dev_info(priv->dev, "enabling clkout\n");
+ return sx125x_field_write(priv, F_CLK_OUT, 1);
+}
+
+static void sx125x_clkout_disable(struct clk_hw *hw)
+{
+ struct sx125x_priv *priv = to_clkout(hw);
+ int ret;
+
+ dev_info(priv->dev, "disabling clkout\n");
+ ret = sx125x_field_write(priv, F_CLK_OUT, 0);
+ if (ret)
+ dev_err(priv->dev, "error disabling clkout\n");
+}
+
+static int sx125x_clkout_is_enabled(struct clk_hw *hw)
+{
+ struct sx125x_priv *priv = to_clkout(hw);
+ unsigned int enabled;
+ int ret;
+
+ ret = sx125x_field_read(priv, F_CLK_OUT, &enabled);
+ if (ret) {
+ dev_err(priv->dev, "error reading clk enable\n");
+ return 0;
+ }
+ return enabled;
+}
+
+static const struct clk_ops sx125x_clkout_ops = {
+ .enable = sx125x_clkout_enable,
+ .disable = sx125x_clkout_disable,
+ .is_enabled = sx125x_clkout_is_enabled,
+};
+
+static int sx125x_register_clock_provider(struct sx125x_priv *priv)
+{
+ struct device *dev = priv->dev;
+ struct clk_init_data init;
+ const char *parent;
+ int ret;
+
+ /* Disable CLKOUT */
+ ret = sx125x_field_write(priv, F_CLK_OUT, 0);
+ if (ret) {
+ dev_err(dev, "unable to disable clkout\n");
+ return ret;
+ }
+
+ /* Register clock provider if expected in DTB */
+ if (!of_find_property(dev->of_node, "#clock-cells", NULL))
+ return 0;
+
+ dev_info(dev, "registering clkout\n");
+
+ parent = of_clk_get_parent_name(dev->of_node, 0);
+ if (!parent) {
+ dev_err(dev, "Unable to find parent clk\n");
+ return -ENODEV;
+ }
+
+ init.ops = &sx125x_clkout_ops;
+ init.flags = CLK_IS_BASIC;
+ init.parent_names = &parent;
+ init.num_parents = 1;
+ priv->clkout_hw.init = &init;
+
+ of_property_read_string_index(dev->of_node, "clock-output-names", 0,
+ &init.name);
+
+ priv->clkout = devm_clk_register(dev, &priv->clkout_hw);
+ if (IS_ERR(priv->clkout)) {
+ dev_err(dev, "failed to register clkout\n");
+ return PTR_ERR(priv->clkout);
+ }
+ ret = of_clk_add_hw_provider(dev->of_node, of_clk_hw_simple_get,
+ &priv->clkout_hw);
+ return ret;
+}
+
static int __maybe_unused sx125x_regmap_probe(struct device *dev, struct regmap *regmap, unsigned int radio)
{
struct sx125x_priv *priv;
@@ -76,6 +174,7 @@ static int __maybe_unused sx125x_regmap_probe(struct device *dev, struct regmap
return -ENOMEM;
dev_set_drvdata(dev, priv);
+ priv->dev = dev;
priv->regmap = regmap;
for (i = 0; i < ARRAY_SIZE(sx125x_regmap_fields); i++) {
const struct reg_field *reg_fields = sx125x_regmap_fields;
@@ -99,16 +198,13 @@ static int __maybe_unused sx125x_regmap_probe(struct device *dev, struct regmap
dev_info(dev, "SX125x version: %02x\n", val);
}
- if (radio == 1) { /* HACK */
- ret = sx125x_field_write(priv, F_CLK_OUT, 1);
- if (ret) {
- dev_err(dev, "enabling clock output failed\n");
- return ret;
- }
-
- dev_info(dev, "enabling clock output\n");
+ ret = sx125x_register_clock_provider(priv);
+ if (ret) {
+ dev_err(dev, "failed to register clkout provider: %d\n", ret);
+ return ret;
}
+ /* TODO Only needs setting on radio on the TX path */
ret = sx125x_field_write(priv, F_TX_DAC_CLK_SEL, 1);
if (ret) {
dev_err(dev, "clock select failed\n");
diff --git a/drivers/net/lora/sx1301.c b/drivers/net/lora/sx1301.c
index 339f8d9..23cbddc3 100644
--- a/drivers/net/lora/sx1301.c
+++ b/drivers/net/lora/sx1301.c
@@ -10,6 +10,7 @@
*/
#include <linux/bitops.h>
+#include <linux/clk.h>
#include <linux/delay.h>
#include <linux/firmware.h>
#include <linux/lora.h>
@@ -378,6 +379,18 @@ static int sx130x_loradev_open(struct net_device *netdev)
return -ENXIO;
}
+ priv->clk32m = devm_clk_get(priv->dev, "clk32m");
+ if (IS_ERR(priv->clk32m)) {
+ dev_err(priv->dev, "failed to get clk32m\n");
+ return PTR_ERR(priv->clk32m);
+ }
+
+ ret = clk_prepare_enable(priv->clk32m);
+ if (ret) {
+ dev_err(priv->dev, "failed to enable clk32m: %d\n", ret);
+ return ret;
+ }
+
ret = sx1301_field_write(priv, F_GLOBAL_EN, 1);
if (ret) {
dev_err(priv->dev, "enable global clocks failed\n");
diff --git a/drivers/net/lora/sx1301.h b/drivers/net/lora/sx1301.h
index 0bbd948..a1a2e38 100644
--- a/drivers/net/lora/sx1301.h
+++ b/drivers/net/lora/sx1301.h
@@ -9,6 +9,7 @@
#ifndef _SX1301_
#define _SX1301_
+#include <linux/clk.h>
#include <linux/regmap.h>
#include <linux/gpio/consumer.h>
#include <linux/lora/dev.h>
@@ -108,6 +109,7 @@ static const struct reg_field sx1301_regmap_fields[] = {
struct sx1301_priv {
struct lora_dev_priv lora;
struct device *dev;
+ struct clk *clk32m;
struct gpio_desc *rst_gpio;
struct regmap *regmap;
struct regmap_field *regmap_fields[ARRAY_SIZE(sx1301_regmap_fields)];
--
2.7.4
^ permalink raw reply related
page: next (older) | prev (newer) | latest
- recent:[subjects (threaded)|topics (new)|topics (active)]
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox