* [PATCH AUTOSEL 4.19 187/258] mac80211: fix radiotap vendor presence bitmap handling
From: Sasha Levin @ 2019-01-28 15:58 UTC (permalink / raw)
To: linux-kernel, stable
Cc: Johannes Berg, Luca Coelho, Sasha Levin, linux-wireless, netdev
In-Reply-To: <20190128155924.51521-1-sashal@kernel.org>
From: Johannes Berg <johannes.berg@intel.com>
[ Upstream commit efc38dd7d5fa5c8cdd0c917c5d00947aa0539443 ]
Due to the alignment handling, it actually matters where in the code
we add the 4 bytes for the presence bitmap to the length; the first
field is the timestamp with 8 byte alignment so we need to add the
space for the extra vendor namespace presence bitmap *before* we do
any alignment for the fields.
Move the presence bitmap length accounting to the right place to fix
the alignment for the data properly.
Signed-off-by: Johannes Berg <johannes.berg@intel.com>
Signed-off-by: Luca Coelho <luciano.coelho@intel.com>
Signed-off-by: Johannes Berg <johannes.berg@intel.com>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
net/mac80211/rx.c | 5 +++--
1 file changed, 3 insertions(+), 2 deletions(-)
diff --git a/net/mac80211/rx.c b/net/mac80211/rx.c
index 5e2b4a41acf1..51ad330bf8e8 100644
--- a/net/mac80211/rx.c
+++ b/net/mac80211/rx.c
@@ -142,6 +142,9 @@ ieee80211_rx_radiotap_hdrlen(struct ieee80211_local *local,
/* allocate extra bitmaps */
if (status->chains)
len += 4 * hweight8(status->chains);
+ /* vendor presence bitmap */
+ if (status->flag & RX_FLAG_RADIOTAP_VENDOR_DATA)
+ len += 4;
if (ieee80211_have_rx_timestamp(status)) {
len = ALIGN(len, 8);
@@ -197,8 +200,6 @@ ieee80211_rx_radiotap_hdrlen(struct ieee80211_local *local,
if (status->flag & RX_FLAG_RADIOTAP_VENDOR_DATA) {
struct ieee80211_vendor_radiotap *rtap = (void *)skb->data;
- /* vendor presence bitmap */
- len += 4;
/* alignment for fixed 6-byte vendor data header */
len = ALIGN(len, 2);
/* vendor data header */
--
2.19.1
^ permalink raw reply related
* [PATCH AUTOSEL 4.19 189/258] mlxsw: spectrum: Properly cleanup LAG uppers when removing port from LAG
From: Sasha Levin @ 2019-01-28 15:58 UTC (permalink / raw)
To: linux-kernel, stable; +Cc: Ido Schimmel, David S . Miller, Sasha Levin, netdev
In-Reply-To: <20190128155924.51521-1-sashal@kernel.org>
From: Ido Schimmel <idosch@mellanox.com>
[ Upstream commit be2d6f421f680e01d58f7cd452646e0d8586d49b ]
When a LAG device or a VLAN device on top of it is enslaved to a bridge,
the driver propagates the CHANGEUPPER event to the LAG's slaves.
This causes each physical port to increase the reference count of the
internal representation of the bridge port by calling
mlxsw_sp_port_bridge_join().
However, when a port is removed from a LAG, the corresponding leave()
function is not called and the reference count is not decremented. This
leads to ugly hacks such as mlxsw_sp_bridge_port_should_destroy() that
try to understand if the bridge port should be destroyed even when its
reference count is not 0.
Instead, make sure that when a port is unlinked from a LAG it would see
the same events as if the LAG (or its uppers) were unlinked from a
bridge.
The above is achieved by walking the LAG's uppers when a port is
unlinked and calling mlxsw_sp_port_bridge_leave() for each upper that is
enslaved to a bridge.
Signed-off-by: Ido Schimmel <idosch@mellanox.com>
Reviewed-by: Petr Machata <petrm@mellanox.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
.../net/ethernet/mellanox/mlxsw/spectrum.c | 23 ++++++++++++++++
.../mellanox/mlxsw/spectrum_switchdev.c | 27 +------------------
2 files changed, 24 insertions(+), 26 deletions(-)
diff --git a/drivers/net/ethernet/mellanox/mlxsw/spectrum.c b/drivers/net/ethernet/mellanox/mlxsw/spectrum.c
index de821a9fdfaf..d64cd8d44d83 100644
--- a/drivers/net/ethernet/mellanox/mlxsw/spectrum.c
+++ b/drivers/net/ethernet/mellanox/mlxsw/spectrum.c
@@ -4235,6 +4235,25 @@ void mlxsw_sp_port_dev_put(struct mlxsw_sp_port *mlxsw_sp_port)
dev_put(mlxsw_sp_port->dev);
}
+static void
+mlxsw_sp_port_lag_uppers_cleanup(struct mlxsw_sp_port *mlxsw_sp_port,
+ struct net_device *lag_dev)
+{
+ struct net_device *br_dev = netdev_master_upper_dev_get(lag_dev);
+ struct net_device *upper_dev;
+ struct list_head *iter;
+
+ if (netif_is_bridge_port(lag_dev))
+ mlxsw_sp_port_bridge_leave(mlxsw_sp_port, lag_dev, br_dev);
+
+ netdev_for_each_upper_dev_rcu(lag_dev, upper_dev, iter) {
+ if (!netif_is_bridge_port(upper_dev))
+ continue;
+ br_dev = netdev_master_upper_dev_get(upper_dev);
+ mlxsw_sp_port_bridge_leave(mlxsw_sp_port, upper_dev, br_dev);
+ }
+}
+
static int mlxsw_sp_lag_create(struct mlxsw_sp *mlxsw_sp, u16 lag_id)
{
char sldr_pl[MLXSW_REG_SLDR_LEN];
@@ -4427,6 +4446,10 @@ static void mlxsw_sp_port_lag_leave(struct mlxsw_sp_port *mlxsw_sp_port,
/* Any VLANs configured on the port are no longer valid */
mlxsw_sp_port_vlan_flush(mlxsw_sp_port);
+ /* Make the LAG and its directly linked uppers leave bridges they
+ * are memeber in
+ */
+ mlxsw_sp_port_lag_uppers_cleanup(mlxsw_sp_port, lag_dev);
if (lag->ref_count == 1)
mlxsw_sp_lag_destroy(mlxsw_sp, lag_id);
diff --git a/drivers/net/ethernet/mellanox/mlxsw/spectrum_switchdev.c b/drivers/net/ethernet/mellanox/mlxsw/spectrum_switchdev.c
index 0d9ea37c5d21..cdec48bcc6ad 100644
--- a/drivers/net/ethernet/mellanox/mlxsw/spectrum_switchdev.c
+++ b/drivers/net/ethernet/mellanox/mlxsw/spectrum_switchdev.c
@@ -282,30 +282,6 @@ mlxsw_sp_bridge_port_destroy(struct mlxsw_sp_bridge_port *bridge_port)
kfree(bridge_port);
}
-static bool
-mlxsw_sp_bridge_port_should_destroy(const struct mlxsw_sp_bridge_port *
- bridge_port)
-{
- struct net_device *dev = bridge_port->dev;
- struct mlxsw_sp *mlxsw_sp;
-
- if (is_vlan_dev(dev))
- mlxsw_sp = mlxsw_sp_lower_get(vlan_dev_real_dev(dev));
- else
- mlxsw_sp = mlxsw_sp_lower_get(dev);
-
- /* In case ports were pulled from out of a bridged LAG, then
- * it's possible the reference count isn't zero, yet the bridge
- * port should be destroyed, as it's no longer an upper of ours.
- */
- if (!mlxsw_sp && list_empty(&bridge_port->vlans_list))
- return true;
- else if (bridge_port->ref_count == 0)
- return true;
- else
- return false;
-}
-
static struct mlxsw_sp_bridge_port *
mlxsw_sp_bridge_port_get(struct mlxsw_sp_bridge *bridge,
struct net_device *brport_dev)
@@ -343,8 +319,7 @@ static void mlxsw_sp_bridge_port_put(struct mlxsw_sp_bridge *bridge,
{
struct mlxsw_sp_bridge_device *bridge_device;
- bridge_port->ref_count--;
- if (!mlxsw_sp_bridge_port_should_destroy(bridge_port))
+ if (--bridge_port->ref_count != 0)
return;
bridge_device = bridge_port->bridge_device;
mlxsw_sp_bridge_port_destroy(bridge_port);
--
2.19.1
^ permalink raw reply related
* [PATCH AUTOSEL 4.19 193/258] cw1200: Fix concurrency use-after-free bugs in cw1200_hw_scan()
From: Sasha Levin @ 2019-01-28 15:58 UTC (permalink / raw)
To: linux-kernel, stable
Cc: Jia-Ju Bai, Kalle Valo, Sasha Levin, linux-wireless, netdev
In-Reply-To: <20190128155924.51521-1-sashal@kernel.org>
From: Jia-Ju Bai <baijiaju1990@gmail.com>
[ Upstream commit 4f68ef64cd7feb1220232bd8f501d8aad340a099 ]
The function cw1200_bss_info_changed() and cw1200_hw_scan() can be
concurrently executed.
The two functions both access a possible shared variable "frame.skb".
This shared variable is freed by dev_kfree_skb() in cw1200_upload_beacon(),
which is called by cw1200_bss_info_changed(). The free operation is
protected by a mutex lock "priv->conf_mutex" in cw1200_bss_info_changed().
In cw1200_hw_scan(), this shared variable is accessed without the
protection of the mutex lock "priv->conf_mutex".
Thus, concurrency use-after-free bugs may occur.
To fix these bugs, the original calls to mutex_lock(&priv->conf_mutex) and
mutex_unlock(&priv->conf_mutex) are moved to the places, which can
protect the accesses to the shared variable.
Signed-off-by: Jia-Ju Bai <baijiaju1990@gmail.com>
Signed-off-by: Kalle Valo <kvalo@codeaurora.org>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
drivers/net/wireless/st/cw1200/scan.c | 13 ++++++-------
1 file changed, 6 insertions(+), 7 deletions(-)
diff --git a/drivers/net/wireless/st/cw1200/scan.c b/drivers/net/wireless/st/cw1200/scan.c
index 67213f11acbd..0a9eac93dd01 100644
--- a/drivers/net/wireless/st/cw1200/scan.c
+++ b/drivers/net/wireless/st/cw1200/scan.c
@@ -78,6 +78,10 @@ int cw1200_hw_scan(struct ieee80211_hw *hw,
if (req->n_ssids > WSM_SCAN_MAX_NUM_OF_SSIDS)
return -EINVAL;
+ /* will be unlocked in cw1200_scan_work() */
+ down(&priv->scan.lock);
+ mutex_lock(&priv->conf_mutex);
+
frame.skb = ieee80211_probereq_get(hw, priv->vif->addr, NULL, 0,
req->ie_len);
if (!frame.skb)
@@ -86,19 +90,15 @@ int cw1200_hw_scan(struct ieee80211_hw *hw,
if (req->ie_len)
skb_put_data(frame.skb, req->ie, req->ie_len);
- /* will be unlocked in cw1200_scan_work() */
- down(&priv->scan.lock);
- mutex_lock(&priv->conf_mutex);
-
ret = wsm_set_template_frame(priv, &frame);
if (!ret) {
/* Host want to be the probe responder. */
ret = wsm_set_probe_responder(priv, true);
}
if (ret) {
+ dev_kfree_skb(frame.skb);
mutex_unlock(&priv->conf_mutex);
up(&priv->scan.lock);
- dev_kfree_skb(frame.skb);
return ret;
}
@@ -120,10 +120,9 @@ int cw1200_hw_scan(struct ieee80211_hw *hw,
++priv->scan.n_ssids;
}
- mutex_unlock(&priv->conf_mutex);
-
if (frame.skb)
dev_kfree_skb(frame.skb);
+ mutex_unlock(&priv->conf_mutex);
queue_work(priv->workqueue, &priv->scan.work);
return 0;
}
--
2.19.1
^ permalink raw reply related
* [PATCH AUTOSEL 4.19 194/258] net: hns3: add max vector number check for pf
From: Sasha Levin @ 2019-01-28 15:58 UTC (permalink / raw)
To: linux-kernel, stable
Cc: Jian Shen, Peng Li, David S . Miller, Sasha Levin, netdev
In-Reply-To: <20190128155924.51521-1-sashal@kernel.org>
From: Jian Shen <shenjian15@huawei.com>
[ Upstream commit 75edb610860fda65ceedb017fc69afabd2806b8b ]
Each pf supports max 64 vectors and 128 tqps. For 2p/4p core scenario,
there may be more than 64 cpus online. So the result of min_t(u16,
num_Online_cpus(), tqp_num) may be more than 64. This patch adds check
for the vector number.
Fixes: dd38c72604dc ("net: hns3: fix for coalesce configuration lost during reset")
Signed-off-by: Jian Shen <shenjian15@huawei.com>
Signed-off-by: Peng Li <lipeng321@huawei.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
drivers/net/ethernet/hisilicon/hns3/hns3_enet.c | 4 ++++
1 file changed, 4 insertions(+)
diff --git a/drivers/net/ethernet/hisilicon/hns3/hns3_enet.c b/drivers/net/ethernet/hisilicon/hns3/hns3_enet.c
index d5f15d8d18a9..0ccfa6a84535 100644
--- a/drivers/net/ethernet/hisilicon/hns3/hns3_enet.c
+++ b/drivers/net/ethernet/hisilicon/hns3/hns3_enet.c
@@ -2691,6 +2691,8 @@ static int hns3_nic_init_vector_data(struct hns3_nic_priv *priv)
static int hns3_nic_alloc_vector_data(struct hns3_nic_priv *priv)
{
+#define HNS3_VECTOR_PF_MAX_NUM 64
+
struct hnae3_handle *h = priv->ae_handle;
struct hns3_enet_tqp_vector *tqp_vector;
struct hnae3_vector_info *vector;
@@ -2703,6 +2705,8 @@ static int hns3_nic_alloc_vector_data(struct hns3_nic_priv *priv)
/* RSS size, cpu online and vector_num should be the same */
/* Should consider 2p/4p later */
vector_num = min_t(u16, num_online_cpus(), tqp_num);
+ vector_num = min_t(u16, vector_num, HNS3_VECTOR_PF_MAX_NUM);
+
vector = devm_kcalloc(&pdev->dev, vector_num, sizeof(*vector),
GFP_KERNEL);
if (!vector)
--
2.19.1
^ permalink raw reply related
* [PATCH AUTOSEL 4.19 198/258] mlx5: update timecounter at least twice per counter overflow
From: Sasha Levin @ 2019-01-28 15:58 UTC (permalink / raw)
To: linux-kernel, stable
Cc: Miroslav Lichvar, Richard Cochran, Ariel Levkovich,
Saeed Mahameed, Sasha Levin, netdev, linux-rdma
In-Reply-To: <20190128155924.51521-1-sashal@kernel.org>
From: Miroslav Lichvar <mlichvar@redhat.com>
[ Upstream commit 5d8678365c90b9ce1fd2243ff5ea562609f6cec1 ]
The timecounter needs to be updated at least once in half of the
cyclecounter interval to prevent timecounter_cyc2time() interpreting a
new timestamp as an old value and causing a backward jump.
This would be an issue if the timecounter multiplier was so small that
the update interval would not be limited by the 64-bit overflow in
multiplication.
Shorten the calculated interval to make sure the timecounter is updated
in time even when the system clock is slowed down by up to 10%, the
multiplier is increased by up to 10%, and the scheduled overflow check
is late by 15%.
Cc: Richard Cochran <richardcochran@gmail.com>
Cc: Ariel Levkovich <lariel@mellanox.com>
Cc: Saeed Mahameed <saeedm@mellanox.com>
Signed-off-by: Miroslav Lichvar <mlichvar@redhat.com>
Signed-off-by: Saeed Mahameed <saeedm@mellanox.com>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
drivers/net/ethernet/mellanox/mlx5/core/lib/clock.c | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/drivers/net/ethernet/mellanox/mlx5/core/lib/clock.c b/drivers/net/ethernet/mellanox/mlx5/core/lib/clock.c
index 3f767cde4c1d..54f1a40a68ed 100644
--- a/drivers/net/ethernet/mellanox/mlx5/core/lib/clock.c
+++ b/drivers/net/ethernet/mellanox/mlx5/core/lib/clock.c
@@ -511,14 +511,14 @@ void mlx5_init_clock(struct mlx5_core_dev *mdev)
ktime_to_ns(ktime_get_real()));
/* Calculate period in seconds to call the overflow watchdog - to make
- * sure counter is checked at least once every wrap around.
+ * sure counter is checked at least twice every wrap around.
* The period is calculated as the minimum between max HW cycles count
* (The clock source mask) and max amount of cycles that can be
* multiplied by clock multiplier where the result doesn't exceed
* 64bits.
*/
overflow_cycles = div64_u64(~0ULL >> 1, clock->cycles.mult);
- overflow_cycles = min(overflow_cycles, clock->cycles.mask >> 1);
+ overflow_cycles = min(overflow_cycles, div_u64(clock->cycles.mask, 3));
ns = cyclecounter_cyc2ns(&clock->cycles, overflow_cycles,
frac, &frac);
--
2.19.1
^ permalink raw reply related
* [PATCH AUTOSEL 4.19 208/258] ice: Do not enable NAPI on q_vectors that have no rings
From: Sasha Levin @ 2019-01-28 15:58 UTC (permalink / raw)
To: linux-kernel, stable; +Cc: Young Xiao, Jeff Kirsher, Sasha Levin, netdev
In-Reply-To: <20190128155924.51521-1-sashal@kernel.org>
From: Young Xiao <YangX92@hotmail.com>
[ Upstream commit eec903769b4ea476591ffff73bb7359f14f38c51 ]
If ice driver has q_vectors w/ active NAPI that has no rings,
then this will result in a divide by zero error. To correct it
I am updating the driver code so that we only support NAPI on
q_vectors that have 1 or more rings allocated to them.
See commit 13a8cd191a2b ("i40e: Do not enable NAPI on q_vectors
that have no rings") for detail.
Signed-off-by: Young Xiao <YangX92@hotmail.com>
Acked-by: Anirudh Venkataramanan <anirudh.venkataramanan@intel.com>
Tested-by: Andrew Bowers <andrewx.bowers@intel.com>
Signed-off-by: Jeff Kirsher <jeffrey.t.kirsher@intel.com>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
drivers/net/ethernet/intel/ice/ice_main.c | 16 ++++++++++++----
1 file changed, 12 insertions(+), 4 deletions(-)
diff --git a/drivers/net/ethernet/intel/ice/ice_main.c b/drivers/net/ethernet/intel/ice/ice_main.c
index 3f047bb43348..db1543bca701 100644
--- a/drivers/net/ethernet/intel/ice/ice_main.c
+++ b/drivers/net/ethernet/intel/ice/ice_main.c
@@ -4333,8 +4333,12 @@ static void ice_napi_enable_all(struct ice_vsi *vsi)
if (!vsi->netdev)
return;
- for (q_idx = 0; q_idx < vsi->num_q_vectors; q_idx++)
- napi_enable(&vsi->q_vectors[q_idx]->napi);
+ for (q_idx = 0; q_idx < vsi->num_q_vectors; q_idx++) {
+ struct ice_q_vector *q_vector = vsi->q_vectors[q_idx];
+
+ if (q_vector->rx.ring || q_vector->tx.ring)
+ napi_enable(&q_vector->napi);
+ }
}
/**
@@ -4817,8 +4821,12 @@ static void ice_napi_disable_all(struct ice_vsi *vsi)
if (!vsi->netdev)
return;
- for (q_idx = 0; q_idx < vsi->num_q_vectors; q_idx++)
- napi_disable(&vsi->q_vectors[q_idx]->napi);
+ for (q_idx = 0; q_idx < vsi->num_q_vectors; q_idx++) {
+ struct ice_q_vector *q_vector = vsi->q_vectors[q_idx];
+
+ if (q_vector->rx.ring || q_vector->tx.ring)
+ napi_disable(&q_vector->napi);
+ }
}
/**
--
2.19.1
^ permalink raw reply related
* [PATCH AUTOSEL 4.19 207/258] i40e: define proper net_device::neigh_priv_len
From: Sasha Levin @ 2019-01-28 15:58 UTC (permalink / raw)
To: linux-kernel, stable
Cc: Konstantin Khorenko, Jeff Kirsher, Sasha Levin, netdev
In-Reply-To: <20190128155924.51521-1-sashal@kernel.org>
From: Konstantin Khorenko <khorenko@virtuozzo.com>
[ Upstream commit 31389b53b3e0b535867af9090a5d19ec64768d55 ]
Out of bound read reported by KASan.
i40iw_net_event() reads unconditionally 16 bytes from
neigh->primary_key while the memory allocated for
"neighbour" struct is evaluated in neigh_alloc() as
tbl->entry_size + dev->neigh_priv_len
where "dev" is a net_device.
But the driver does not setup dev->neigh_priv_len and
we read beyond the neigh entry allocated memory,
so the patch in the next mail fixes this.
Signed-off-by: Konstantin Khorenko <khorenko@virtuozzo.com>
Tested-by: Andrew Bowers <andrewx.bowers@intel.com>
Signed-off-by: Jeff Kirsher <jeffrey.t.kirsher@intel.com>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
drivers/net/ethernet/intel/i40e/i40e_main.c | 3 +++
1 file changed, 3 insertions(+)
diff --git a/drivers/net/ethernet/intel/i40e/i40e_main.c b/drivers/net/ethernet/intel/i40e/i40e_main.c
index bfa5c525cf31..41fa22c562c1 100644
--- a/drivers/net/ethernet/intel/i40e/i40e_main.c
+++ b/drivers/net/ethernet/intel/i40e/i40e_main.c
@@ -12016,6 +12016,9 @@ static int i40e_config_netdev(struct i40e_vsi *vsi)
ether_addr_copy(netdev->dev_addr, mac_addr);
ether_addr_copy(netdev->perm_addr, mac_addr);
+ /* i40iw_net_event() reads 16 bytes from neigh->primary_key */
+ netdev->neigh_priv_len = sizeof(u32) * 4;
+
netdev->priv_flags |= IFF_UNICAST_FLT;
netdev->priv_flags |= IFF_SUPP_NOFCS;
/* Setup netdev TC information */
--
2.19.1
^ permalink raw reply related
* [PATCH AUTOSEL 4.19 229/258] niu: fix missing checks of niu_pci_eeprom_read
From: Sasha Levin @ 2019-01-28 15:58 UTC (permalink / raw)
To: linux-kernel, stable; +Cc: Kangjie Lu, David S . Miller, Sasha Levin, netdev
In-Reply-To: <20190128155924.51521-1-sashal@kernel.org>
From: Kangjie Lu <kjlu@umn.edu>
[ Upstream commit 26fd962bde0b15e54234fe762d86bc0349df1de4 ]
niu_pci_eeprom_read() may fail, so we should check its return value
before using the read data.
Signed-off-by: Kangjie Lu <kjlu@umn.edu>
Acked-by: Shannon Nelson <shannon.lee.nelson@gmail.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
drivers/net/ethernet/sun/niu.c | 10 ++++++++--
1 file changed, 8 insertions(+), 2 deletions(-)
diff --git a/drivers/net/ethernet/sun/niu.c b/drivers/net/ethernet/sun/niu.c
index 9319d84bf49f..d84501441edd 100644
--- a/drivers/net/ethernet/sun/niu.c
+++ b/drivers/net/ethernet/sun/niu.c
@@ -8100,6 +8100,8 @@ static int niu_pci_vpd_scan_props(struct niu *np, u32 start, u32 end)
start += 3;
prop_len = niu_pci_eeprom_read(np, start + 4);
+ if (prop_len < 0)
+ return prop_len;
err = niu_pci_vpd_get_propname(np, start + 5, namebuf, 64);
if (err < 0)
return err;
@@ -8144,8 +8146,12 @@ static int niu_pci_vpd_scan_props(struct niu *np, u32 start, u32 end)
netif_printk(np, probe, KERN_DEBUG, np->dev,
"VPD_SCAN: Reading in property [%s] len[%d]\n",
namebuf, prop_len);
- for (i = 0; i < prop_len; i++)
- *prop_buf++ = niu_pci_eeprom_read(np, off + i);
+ for (i = 0; i < prop_len; i++) {
+ err = niu_pci_eeprom_read(np, off + i);
+ if (err >= 0)
+ *prop_buf = err;
+ ++prop_buf;
+ }
}
start += len;
--
2.19.1
^ permalink raw reply related
* [PATCH AUTOSEL 4.19 240/258] isdn: hisax: hfc_pci: Fix a possible concurrency use-after-free bug in HFCPCI_l1hw()
From: Sasha Levin @ 2019-01-28 15:59 UTC (permalink / raw)
To: linux-kernel, stable; +Cc: Jia-Ju Bai, David S . Miller, Sasha Levin, netdev
In-Reply-To: <20190128155924.51521-1-sashal@kernel.org>
From: Jia-Ju Bai <baijiaju1990@gmail.com>
[ Upstream commit 7418e6520f22a2e35815122fa5a53d5bbfa2c10f ]
In drivers/isdn/hisax/hfc_pci.c, the functions hfcpci_interrupt() and
HFCPCI_l1hw() may be concurrently executed.
HFCPCI_l1hw()
line 1173: if (!cs->tx_skb)
hfcpci_interrupt()
line 942: spin_lock_irqsave();
line 1066: dev_kfree_skb_irq(cs->tx_skb);
Thus, a possible concurrency use-after-free bug may occur
in HFCPCI_l1hw().
To fix these bugs, the calls to spin_lock_irqsave() and
spin_unlock_irqrestore() are added in HFCPCI_l1hw(), to protect the
access to cs->tx_skb.
Signed-off-by: Jia-Ju Bai <baijiaju1990@gmail.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
drivers/isdn/hisax/hfc_pci.c | 2 ++
1 file changed, 2 insertions(+)
diff --git a/drivers/isdn/hisax/hfc_pci.c b/drivers/isdn/hisax/hfc_pci.c
index 8e5b03161b2f..64a63711fd95 100644
--- a/drivers/isdn/hisax/hfc_pci.c
+++ b/drivers/isdn/hisax/hfc_pci.c
@@ -1170,11 +1170,13 @@ HFCPCI_l1hw(struct PStack *st, int pr, void *arg)
if (cs->debug & L1_DEB_LAPD)
debugl1(cs, "-> PH_REQUEST_PULL");
#endif
+ spin_lock_irqsave(&cs->lock, flags);
if (!cs->tx_skb) {
test_and_clear_bit(FLG_L1_PULL_REQ, &st->l1.Flags);
st->l1.l1l2(st, PH_PULL | CONFIRM, NULL);
} else
test_and_set_bit(FLG_L1_PULL_REQ, &st->l1.Flags);
+ spin_unlock_irqrestore(&cs->lock, flags);
break;
case (HW_RESET | REQUEST):
spin_lock_irqsave(&cs->lock, flags);
--
2.19.1
^ permalink raw reply related
* [PATCH AUTOSEL 4.19 242/258] fsl/fman: Use GFP_ATOMIC in {memac,tgec}_add_hash_mac_address()
From: Sasha Levin @ 2019-01-28 15:59 UTC (permalink / raw)
To: linux-kernel, stable; +Cc: Scott Wood, David S . Miller, Sasha Levin, netdev
In-Reply-To: <20190128155924.51521-1-sashal@kernel.org>
From: Scott Wood <oss@buserror.net>
[ Upstream commit 0d9c9a238faf925823bde866182c663b6d734f2e ]
These functions are called from atomic context:
[ 9.150239] BUG: sleeping function called from invalid context at /home/scott/git/linux/mm/slab.h:421
[ 9.158159] in_atomic(): 1, irqs_disabled(): 0, pid: 4432, name: ip
[ 9.163128] CPU: 8 PID: 4432 Comm: ip Not tainted 4.20.0-rc2-00169-g63d86876f324 #29
[ 9.163130] Call Trace:
[ 9.170701] [c0000002e899a980] [c0000000009c1068] .dump_stack+0xa8/0xec (unreliable)
[ 9.177140] [c0000002e899aa10] [c00000000007a7b4] .___might_sleep+0x138/0x164
[ 9.184440] [c0000002e899aa80] [c0000000001d5bac] .kmem_cache_alloc_trace+0x238/0x30c
[ 9.191216] [c0000002e899ab40] [c00000000065ea1c] .memac_add_hash_mac_address+0x104/0x198
[ 9.199464] [c0000002e899abd0] [c00000000065a788] .set_multi+0x1c8/0x218
[ 9.206242] [c0000002e899ac80] [c0000000006615ec] .dpaa_set_rx_mode+0xdc/0x17c
[ 9.213544] [c0000002e899ad00] [c00000000083d2b0] .__dev_set_rx_mode+0x80/0xd4
[ 9.219535] [c0000002e899ad90] [c00000000083d334] .dev_set_rx_mode+0x30/0x54
[ 9.225271] [c0000002e899ae10] [c00000000083d4a0] .__dev_open+0x148/0x1c8
[ 9.230751] [c0000002e899aeb0] [c00000000083d934] .__dev_change_flags+0x19c/0x1e0
[ 9.230755] [c0000002e899af60] [c00000000083d9a4] .dev_change_flags+0x2c/0x80
[ 9.242752] [c0000002e899aff0] [c0000000008554ec] .do_setlink+0x350/0xf08
[ 9.248228] [c0000002e899b170] [c000000000857ad0] .rtnl_newlink+0x588/0x7e0
[ 9.253965] [c0000002e899b740] [c000000000852424] .rtnetlink_rcv_msg+0x3e0/0x498
[ 9.261440] [c0000002e899b820] [c000000000884790] .netlink_rcv_skb+0x134/0x14c
[ 9.267607] [c0000002e899b8e0] [c000000000851840] .rtnetlink_rcv+0x18/0x2c
[ 9.274558] [c0000002e899b950] [c000000000883c8c] .netlink_unicast+0x214/0x318
[ 9.281163] [c0000002e899ba00] [c000000000884220] .netlink_sendmsg+0x348/0x444
[ 9.287076] [c0000002e899bae0] [c00000000080d13c] .sock_sendmsg+0x2c/0x54
[ 9.287080] [c0000002e899bb50] [c0000000008106c0] .___sys_sendmsg+0x2d0/0x2d8
[ 9.298375] [c0000002e899bd30] [c000000000811a80] .__sys_sendmsg+0x5c/0xb0
[ 9.303939] [c0000002e899be20] [c0000000000006b0] system_call+0x60/0x6c
Signed-off-by: Scott Wood <oss@buserror.net>
Signed-off-by: David S. Miller <davem@davemloft.net>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
drivers/net/ethernet/freescale/fman/fman_memac.c | 2 +-
drivers/net/ethernet/freescale/fman/fman_tgec.c | 2 +-
2 files changed, 2 insertions(+), 2 deletions(-)
diff --git a/drivers/net/ethernet/freescale/fman/fman_memac.c b/drivers/net/ethernet/freescale/fman/fman_memac.c
index bc6eb30aa20f..41c6fa200e74 100644
--- a/drivers/net/ethernet/freescale/fman/fman_memac.c
+++ b/drivers/net/ethernet/freescale/fman/fman_memac.c
@@ -928,7 +928,7 @@ int memac_add_hash_mac_address(struct fman_mac *memac, enet_addr_t *eth_addr)
hash = get_mac_addr_hash_code(addr) & HASH_CTRL_ADDR_MASK;
/* Create element to be added to the driver hash table */
- hash_entry = kmalloc(sizeof(*hash_entry), GFP_KERNEL);
+ hash_entry = kmalloc(sizeof(*hash_entry), GFP_ATOMIC);
if (!hash_entry)
return -ENOMEM;
hash_entry->addr = addr;
diff --git a/drivers/net/ethernet/freescale/fman/fman_tgec.c b/drivers/net/ethernet/freescale/fman/fman_tgec.c
index 40705938eecc..f75b9c11b2d2 100644
--- a/drivers/net/ethernet/freescale/fman/fman_tgec.c
+++ b/drivers/net/ethernet/freescale/fman/fman_tgec.c
@@ -553,7 +553,7 @@ int tgec_add_hash_mac_address(struct fman_mac *tgec, enet_addr_t *eth_addr)
hash = (crc >> TGEC_HASH_MCAST_SHIFT) & TGEC_HASH_ADR_MSK;
/* Create element to be added to the driver hash table */
- hash_entry = kmalloc(sizeof(*hash_entry), GFP_KERNEL);
+ hash_entry = kmalloc(sizeof(*hash_entry), GFP_ATOMIC);
if (!hash_entry)
return -ENOMEM;
hash_entry->addr = addr;
--
2.19.1
^ permalink raw reply related
* [PATCH AUTOSEL 4.19 248/258] bpf: fix check_map_access smin_value test when pointer contains offset
From: Sasha Levin @ 2019-01-28 15:59 UTC (permalink / raw)
To: linux-kernel, stable
Cc: Daniel Borkmann, Alexei Starovoitov, Sasha Levin, netdev
In-Reply-To: <20190128155924.51521-1-sashal@kernel.org>
From: Daniel Borkmann <daniel@iogearbox.net>
[ Upstream commit b7137c4eab85c1cf3d46acdde90ce1163b28c873 ]
In check_map_access() we probe actual bounds through __check_map_access()
with offset of reg->smin_value + off for lower bound and offset of
reg->umax_value + off for the upper bound. However, even though the
reg->smin_value could have a negative value, the final result of the
sum with off could be positive when pointer arithmetic with known and
unknown scalars is combined. In this case we reject the program with
an error such as "R<x> min value is negative, either use unsigned index
or do a if (index >=0) check." even though the access itself would be
fine. Therefore extend the check to probe whether the actual resulting
reg->smin_value + off is less than zero.
Signed-off-by: Daniel Borkmann <daniel@iogearbox.net>
Acked-by: Alexei Starovoitov <ast@kernel.org>
Signed-off-by: Alexei Starovoitov <ast@kernel.org>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
kernel/bpf/verifier.c | 6 +++++-
1 file changed, 5 insertions(+), 1 deletion(-)
diff --git a/kernel/bpf/verifier.c b/kernel/bpf/verifier.c
index 341806668f03..9997723038d3 100644
--- a/kernel/bpf/verifier.c
+++ b/kernel/bpf/verifier.c
@@ -1268,13 +1268,17 @@ static int check_map_access(struct bpf_verifier_env *env, u32 regno,
*/
if (env->log.level)
print_verifier_state(env, state);
+
/* The minimum value is only important with signed
* comparisons where we can't assume the floor of a
* value is 0. If we are using signed variables for our
* index'es we need to make sure that whatever we use
* will have a set floor within our range.
*/
- if (reg->smin_value < 0) {
+ if (reg->smin_value < 0 &&
+ (reg->smin_value == S64_MIN ||
+ (off + reg->smin_value != (s64)(s32)(off + reg->smin_value)) ||
+ reg->smin_value + off < 0)) {
verbose(env, "R%d min value is negative, either use unsigned index or do a if (index >=0) check.\n",
regno);
return -EACCES;
--
2.19.1
^ permalink raw reply related
* [PATCH AUTOSEL 4.14 032/170] net/mlx5: EQ, Use the right place to store/read IRQ affinity hint
From: Sasha Levin @ 2019-01-28 16:09 UTC (permalink / raw)
To: linux-kernel, stable
Cc: Saeed Mahameed, Leon Romanovsky, Sasha Levin, netdev, linux-rdma
In-Reply-To: <20190128161200.55107-1-sashal@kernel.org>
From: Saeed Mahameed <saeedm@mellanox.com>
[ Upstream commit 1e86ace4c140fd5a693e266c9b23409358f25381 ]
Currently the cpu affinity hint mask for completion EQs is stored and
read from the wrong place, since reading and storing is done from the
same index, there is no actual issue with that, but internal irq_info
for completion EQs stars at MLX5_EQ_VEC_COMP_BASE offset in irq_info
array, this patch changes the code to use the correct offset to store
and read the IRQ affinity hint.
Signed-off-by: Saeed Mahameed <saeedm@mellanox.com>
Reviewed-by: Leon Romanovsky <leonro@mellanox.com>
Reviewed-by: Tariq Toukan <tariqt@mellanox.com>
Signed-off-by: Leon Romanovsky <leonro@mellanox.com>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
drivers/net/ethernet/mellanox/mlx5/core/en_main.c | 2 +-
drivers/net/ethernet/mellanox/mlx5/core/main.c | 14 ++++++++------
include/linux/mlx5/driver.h | 2 +-
3 files changed, 10 insertions(+), 8 deletions(-)
diff --git a/drivers/net/ethernet/mellanox/mlx5/core/en_main.c b/drivers/net/ethernet/mellanox/mlx5/core/en_main.c
index bf34264c734b..14bab8a5550d 100644
--- a/drivers/net/ethernet/mellanox/mlx5/core/en_main.c
+++ b/drivers/net/ethernet/mellanox/mlx5/core/en_main.c
@@ -1605,7 +1605,7 @@ static void mlx5e_close_cq(struct mlx5e_cq *cq)
static int mlx5e_get_cpu(struct mlx5e_priv *priv, int ix)
{
- return cpumask_first(priv->mdev->priv.irq_info[ix].mask);
+ return cpumask_first(priv->mdev->priv.irq_info[ix + MLX5_EQ_VEC_COMP_BASE].mask);
}
static int mlx5e_open_tx_cqs(struct mlx5e_channel *c,
diff --git a/drivers/net/ethernet/mellanox/mlx5/core/main.c b/drivers/net/ethernet/mellanox/mlx5/core/main.c
index e99f1382a4f0..558fc6a05e2a 100644
--- a/drivers/net/ethernet/mellanox/mlx5/core/main.c
+++ b/drivers/net/ethernet/mellanox/mlx5/core/main.c
@@ -619,18 +619,19 @@ u64 mlx5_read_internal_timer(struct mlx5_core_dev *dev)
static int mlx5_irq_set_affinity_hint(struct mlx5_core_dev *mdev, int i)
{
struct mlx5_priv *priv = &mdev->priv;
- int irq = pci_irq_vector(mdev->pdev, MLX5_EQ_VEC_COMP_BASE + i);
+ int vecidx = MLX5_EQ_VEC_COMP_BASE + i;
+ int irq = pci_irq_vector(mdev->pdev, vecidx);
- if (!zalloc_cpumask_var(&priv->irq_info[i].mask, GFP_KERNEL)) {
+ if (!zalloc_cpumask_var(&priv->irq_info[vecidx].mask, GFP_KERNEL)) {
mlx5_core_warn(mdev, "zalloc_cpumask_var failed");
return -ENOMEM;
}
cpumask_set_cpu(cpumask_local_spread(i, priv->numa_node),
- priv->irq_info[i].mask);
+ priv->irq_info[vecidx].mask);
if (IS_ENABLED(CONFIG_SMP) &&
- irq_set_affinity_hint(irq, priv->irq_info[i].mask))
+ irq_set_affinity_hint(irq, priv->irq_info[vecidx].mask))
mlx5_core_warn(mdev, "irq_set_affinity_hint failed, irq 0x%.4x", irq);
return 0;
@@ -638,11 +639,12 @@ static int mlx5_irq_set_affinity_hint(struct mlx5_core_dev *mdev, int i)
static void mlx5_irq_clear_affinity_hint(struct mlx5_core_dev *mdev, int i)
{
+ int vecidx = MLX5_EQ_VEC_COMP_BASE + i;
struct mlx5_priv *priv = &mdev->priv;
- int irq = pci_irq_vector(mdev->pdev, MLX5_EQ_VEC_COMP_BASE + i);
+ int irq = pci_irq_vector(mdev->pdev, vecidx);
irq_set_affinity_hint(irq, NULL);
- free_cpumask_var(priv->irq_info[i].mask);
+ free_cpumask_var(priv->irq_info[vecidx].mask);
}
static int mlx5_irq_set_affinity_hints(struct mlx5_core_dev *mdev)
diff --git a/include/linux/mlx5/driver.h b/include/linux/mlx5/driver.h
index fb677e4f902d..88f0c530fe9c 100644
--- a/include/linux/mlx5/driver.h
+++ b/include/linux/mlx5/driver.h
@@ -1195,7 +1195,7 @@ enum {
static inline const struct cpumask *
mlx5_get_vector_affinity_hint(struct mlx5_core_dev *dev, int vector)
{
- return dev->priv.irq_info[vector].mask;
+ return dev->priv.irq_info[vector + MLX5_EQ_VEC_COMP_BASE].mask;
}
#endif /* MLX5_DRIVER_H */
--
2.19.1
^ permalink raw reply related
* [PATCH AUTOSEL 4.14 037/170] ptp: Fix pass zero to ERR_PTR() in ptp_clock_register
From: Sasha Levin @ 2019-01-28 16:09 UTC (permalink / raw)
To: linux-kernel, stable; +Cc: YueHaibing, David S . Miller, Sasha Levin, netdev
In-Reply-To: <20190128161200.55107-1-sashal@kernel.org>
From: YueHaibing <yuehaibing@huawei.com>
[ Upstream commit aea0a897af9e44c258e8ab9296fad417f1bc063a ]
Fix smatch warning:
drivers/ptp/ptp_clock.c:298 ptp_clock_register() warn:
passing zero to 'ERR_PTR'
'err' should be set while device_create_with_groups and
pps_register_source fails
Fixes: 85a66e550195 ("ptp: create "pins" together with the rest of attributes")
Signed-off-by: YueHaibing <yuehaibing@huawei.com>
Acked-by: Richard Cochran <richardcochran@gmail.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
drivers/ptp/ptp_clock.c | 5 ++++-
1 file changed, 4 insertions(+), 1 deletion(-)
diff --git a/drivers/ptp/ptp_clock.c b/drivers/ptp/ptp_clock.c
index 7eacc1c4b3b1..c64903a5978f 100644
--- a/drivers/ptp/ptp_clock.c
+++ b/drivers/ptp/ptp_clock.c
@@ -253,8 +253,10 @@ struct ptp_clock *ptp_clock_register(struct ptp_clock_info *info,
ptp->dev = device_create_with_groups(ptp_class, parent, ptp->devid,
ptp, ptp->pin_attr_groups,
"ptp%d", ptp->index);
- if (IS_ERR(ptp->dev))
+ if (IS_ERR(ptp->dev)) {
+ err = PTR_ERR(ptp->dev);
goto no_device;
+ }
/* Register a new PPS source. */
if (info->pps) {
@@ -265,6 +267,7 @@ struct ptp_clock *ptp_clock_register(struct ptp_clock_info *info,
pps.owner = info->owner;
ptp->pps_source = pps_register_source(&pps, PTP_PPS_DEFAULTS);
if (!ptp->pps_source) {
+ err = -EINVAL;
pr_err("failed to register pps source\n");
goto no_pps;
}
--
2.19.1
^ permalink raw reply related
* [PATCH lora-next 00/11] net: lora: Get SX130x to transmit lora packets
From: Ben Whitten @ 2019-01-28 16:12 UTC (permalink / raw)
To: afaerber; +Cc: linux-lpwan, Ben Whitten, netdev, linux-kernel
Hello,
This series adds setup nessesary to transmit lora packets from the
SX1301x, it builds on the comments on the RFC [1] to a point where
the card is capable of sending out a LoRa modulated signal using
transmission paramaters from the LORA socket address.
As patches have been refactored and split up extensivly to bite
sized chunks they do not include individual RFC -> v1, this is
covered in this letter.
The setup involves starting the firmware up inside the card by
providing a LUT of its internal gain values calibrated against
the card output. As this information is hardware specific it
is added as a binding in the DT, with documentation to match.
Binding patch is based off a commit of the basic documentation
under review [2]
Not captured here are commands to set this gain table for use
in devices which do not use DT.
As _stat_xmit cannot sleep we spin the tx function to a work queue
so we can write to the SPI backed regmaps.
As proposed [3] as one way of getting lora packet metadata to
the driver is by using the socket address to encode spreading
factor, coding rate, bandwidth etc. The corresponding translation
is added on the driver side, populating the test transmission with
real values and has been tested to show changing bandwidths.
To perform testing a tx_test [4] was used to show changing
parameters on a spectrum analyser.
We also add patches to the defaults in the SX130x to fill in a TODO
in our initialisation.
Thanks,
Ben Whitten
[1] http://lists.infradead.org/pipermail/linux-lpwan/2018-December/000019.html
[2] http://lists.infradead.org/pipermail/linux-lpwan/2019-January/000150.html
[3] https://events.linuxfoundation.org/wp-content/uploads/2017/12/ELCE2018_LoRa_final_Andreas-Farber.pdf slide 16
[4] https://github.com/BWhitten/lora-modules/blob/master/tx_test.c
RFC -> v1
* Split up commits to sensible order and logical block sizes.
* Added DT binding for TX gain LUT.
* Fixed spelling mistakes.
* Converted metadata enums to suggested integers with suitable sizes.
* Fixed out by 1 in test transmission population.
CC: linux-lpwan@lists.infradead.org
CC: netdev@vger.kernel.org
CC: linux-kernel@vger.kernel.org
Ben Whitten (11):
dt-bindings: net: lora: sx130x: add power lut binding
net: lora: sx130x: add loading of tx lut from DT
net: lora: sx130x: add CHRS to volatile register list
net: lora: sx130x: add helper function for writing to the SX130x MCU
net: lora: sx130x: initialise AGC
net: lora: sx130x: add detail to TODO in setup
net: lora: sx130x: add work queue to tx path
net: lora: sx130x: add test transmission
net: lora: introduce lora socket addressing for metadata
net: lora: sx130x: make use of lora address metadata in transmission
net: lora: sx130x: add patch to register fields
.../bindings/net/lora/semtech,sx130x.yaml | 13 +
drivers/net/lora/sx130x.c | 521 +++++++++++++++++-
drivers/net/lora/sx130x.h | 97 ++++
include/linux/lora/skb.h | 9 +
include/uapi/linux/lora.h | 14 +
net/lora/dgram.c | 45 ++
6 files changed, 697 insertions(+), 2 deletions(-)
--
2.17.1
^ permalink raw reply
* [PATCH lora-next 01/11] dt-bindings: net: lora: sx130x: add power lut binding
From: Ben Whitten @ 2019-01-28 16:12 UTC (permalink / raw)
To: afaerber
Cc: linux-lpwan, Ben Whitten, David S. Miller, Rob Herring,
Mark Rutland, netdev, devicetree, linux-kernel
In-Reply-To: <20190128161306.27805-1-ben.whitten@lairdtech.com>
From: Ben Whitten <ben.whitten@gmail.com>
Adding power lookup table for the concentrator specified in DT.
These values are calibrated for the hardware and are unique to hardware
designs and certifications.
First byte is signed power in dBm measured at the rf connector.
Second byte is unsigned value for DIGITAL gain.
Third byte is unsigned value for PA gain, 2 bits only.
Fourth byte is unsigned value for DAC gain, 2 bits only.
Fifth byte is unsigned value for MIXER gain, 4 bits only.
Signed-off-by: Ben Whitten <ben.whitten@gmail.com>
---
.../bindings/net/lora/semtech,sx130x.yaml | 13 +++++++++++++
1 file changed, 13 insertions(+)
diff --git a/Documentation/devicetree/bindings/net/lora/semtech,sx130x.yaml b/Documentation/devicetree/bindings/net/lora/semtech,sx130x.yaml
index 24fad1218735..187fa2090a0b 100644
--- a/Documentation/devicetree/bindings/net/lora/semtech,sx130x.yaml
+++ b/Documentation/devicetree/bindings/net/lora/semtech,sx130x.yaml
@@ -37,6 +37,15 @@ properties:
maxItems: 1
description: A connection of the reset gpio line.
+ power-lut:
+ description: Power lookup table for the concentrator.
+ Consisting of maximum 16 entries, each entry having the following format;
+ First byte is signed power in dBm measured at the rf connector.
+ Second byte is unsigned value for DIGITAL gain.
+ Third byte is unsigned value for PA gain, 2 bits only.
+ Fourth byte is unsigned value for DAC gain, 2 bits only.
+ Fifth byte is unsigned value for MIXER gain, 4 bits only.
+
radio-spi:
type: object
description: The concentrator can have two radios connected which are
@@ -83,6 +92,10 @@ examples:
reset-gpios = <&pioB 27 GPIO_ACTIVE_HIGH>;
spi-max-frequency = <8000000>;
+ power-lut = [ 00 00 00 03 09
+ 03 00 00 03 0C
+ 04 00 00 03 0D ];
+
radio-spi {
#address-cells = <1>;
#size-cells = <0>;
--
2.17.1
^ permalink raw reply related
* [PATCH lora-next 02/11] net: lora: sx130x: add loading of tx lut from DT
From: Ben Whitten @ 2019-01-28 16:12 UTC (permalink / raw)
To: afaerber; +Cc: linux-lpwan, Ben Whitten, David S. Miller, netdev, linux-kernel
In-Reply-To: <20190128161306.27805-1-ben.whitten@lairdtech.com>
From: Ben Whitten <ben.whitten@gmail.com>
The AGC software requires loading of a power lookup table on initialisation
prior to transmission.
The fields required are digital, pa, dac, and mixer gain. These values are
typically hardware specific and calibrated for a particular power output at
the card rf port.
The format of the DT binding is <power(s8) dig(u8) pa(u8) dac(u8) mix(u8)>
a valid entry is 5 bytes, a valid table is up to 16 entries.
Signed-off-by: Ben Whitten <ben.whitten@gmail.com>
---
drivers/net/lora/sx130x.c | 29 +++++++++++++++++++++++++++++
drivers/net/lora/sx130x.h | 2 ++
2 files changed, 31 insertions(+)
diff --git a/drivers/net/lora/sx130x.c b/drivers/net/lora/sx130x.c
index 3174fc695d54..70cfb4532b51 100644
--- a/drivers/net/lora/sx130x.c
+++ b/drivers/net/lora/sx130x.c
@@ -51,6 +51,14 @@ static const struct reg_field sx130x_regmap_fields[] = {
REG_FIELD(SX1301_EMERGENCY_FORCE_HOST_CTRL, 0, 0),
};
+struct sx130x_tx_gain_lut {
+ s8 power; /* dBm measured at board connector */
+ u8 dig_gain;
+ u8 pa_gain;
+ u8 dac_gain;
+ u8 mix_gain;
+};
+
struct sx130x_priv {
struct lora_dev_priv lora;
struct device *dev;
@@ -59,6 +67,8 @@ struct sx130x_priv {
struct regmap_field *regmap_fields[ARRAY_SIZE(sx130x_regmap_fields)];
struct mutex io_lock;
void *drvdata;
+ struct sx130x_tx_gain_lut tx_gain_lut[SX1301_TX_GAIN_LUT_MAX];
+ u8 tx_gain_lut_size;
};
struct regmap *sx130x_get_regmap(struct device *dev)
@@ -589,6 +599,7 @@ int sx130x_early_probe(struct regmap *regmap, struct gpio_desc *rst)
struct device *dev = regmap_get_device(regmap);
struct net_device *netdev;
struct sx130x_priv *priv;
+ const u8 *power_lut;
int ret;
int i;
@@ -620,6 +631,24 @@ int sx130x_early_probe(struct regmap *regmap, struct gpio_desc *rst)
return ret;
}
}
+
+ if (IS_ENABLED(CONFIG_OF)) {
+ power_lut = of_get_property(dev->of_node, "power-lut", &ret);
+ if (power_lut && (ret % 5)) {
+ dev_err(dev, "Invalid power table\n");
+ return -EINVAL;
+ } else if (power_lut) {
+ priv->tx_gain_lut_size = ret / 5;
+ for (i = 0; i < priv->tx_gain_lut_size; i++) {
+ priv->tx_gain_lut[i].power = *(power_lut++);
+ priv->tx_gain_lut[i].dig_gain = *(power_lut++);
+ priv->tx_gain_lut[i].pa_gain = *(power_lut++) & 0x03;
+ priv->tx_gain_lut[i].dac_gain = *(power_lut++) & 0x03;
+ priv->tx_gain_lut[i].mix_gain = *(power_lut++) & 0x0F;
+ }
+ }
+ }
+
return 0;
}
EXPORT_SYMBOL_GPL(sx130x_early_probe);
diff --git a/drivers/net/lora/sx130x.h b/drivers/net/lora/sx130x.h
index abab2ee42512..6330777f4eac 100644
--- a/drivers/net/lora/sx130x.h
+++ b/drivers/net/lora/sx130x.h
@@ -18,6 +18,8 @@
#define SX1301_MCU_AGC_FW_VERSION 4
#define SX1301_MCU_AGC_CAL_FW_VERSION 2
+#define SX1301_TX_GAIN_LUT_MAX 16
+
/* Page independent */
#define SX1301_PAGE 0x00
#define SX1301_VER 0x01
--
2.17.1
^ permalink raw reply related
* Re: [PATCH AUTOSEL 4.19 034/258] sctp: Fix SKB list traversal in sctp_intl_store_reasm().
From: Marcelo Ricardo Leitner @ 2019-01-28 17:04 UTC (permalink / raw)
To: Sasha Levin; +Cc: linux-kernel, stable, David S. Miller, linux-sctp, netdev
In-Reply-To: <20190128155924.51521-34-sashal@kernel.org>
On Mon, Jan 28, 2019 at 10:55:40AM -0500, Sasha Levin wrote:
> From: "David S. Miller" <davem@davemloft.net>
>
> [ Upstream commit 348bbc25c40844c5efa083a3842c7f53d70a815e ]
>
> To be fully correct, an iterator has an undefined value when something
> like skb_queue_walk() naturally terminates.
>
> This will actually matter when SKB queues are converted over to
> list_head.
>
> Formalize what this code ends up doing with the current
> implementation.
I don't think this patch is really needed for -stable without the SKB
queue convertion, but okay.
Marcelo
^ permalink raw reply
* [PATCH lora-next 03/11] net: lora: sx130x: add CHRS to volatile register list
From: Ben Whitten @ 2019-01-28 16:12 UTC (permalink / raw)
To: afaerber; +Cc: linux-lpwan, Ben Whitten, David S. Miller, netdev, linux-kernel
In-Reply-To: <20190128161306.27805-1-ben.whitten@lairdtech.com>
From: Ben Whitten <ben.whitten@gmail.com>
The CHRS register is used in transactions to the MCU within the SX130x,
we need to always write to it.
Signed-off-by: Ben Whitten <ben.whitten@gmail.com>
---
drivers/net/lora/sx130x.c | 1 +
1 file changed, 1 insertion(+)
diff --git a/drivers/net/lora/sx130x.c b/drivers/net/lora/sx130x.c
index 70cfb4532b51..529ca6622878 100644
--- a/drivers/net/lora/sx130x.c
+++ b/drivers/net/lora/sx130x.c
@@ -134,6 +134,7 @@ static bool sx130x_volatile_reg(struct device *dev, unsigned int reg)
case SX1301_MPD:
case SX1301_AGCSTS:
+ case SX1301_CHRS:
case SX1301_MCU_CTRL:
case SX1301_RADIO_A_SPI_DATA_RB:
--
2.17.1
^ permalink raw reply related
* [PATCH lora-next 04/11] net: lora: sx130x: add helper function for writing to the SX130x MCU
From: Ben Whitten @ 2019-01-28 16:12 UTC (permalink / raw)
To: afaerber; +Cc: linux-lpwan, Ben Whitten, David S. Miller, netdev, linux-kernel
In-Reply-To: <20190128161306.27805-1-ben.whitten@lairdtech.com>
From: Ben Whitten <ben.whitten@gmail.com>
The transaction to the internal MCU starts with CMD_WAIT to start a
transaction, written to CHRS followed by writing the value, the status of
the command is read back from AGCSTS.
Signed-off-by: Ben Whitten <ben.whitten@gmail.com>
---
drivers/net/lora/sx130x.c | 28 ++++++++++++++++++++++++++++
drivers/net/lora/sx130x.h | 2 ++
2 files changed, 30 insertions(+)
diff --git a/drivers/net/lora/sx130x.c b/drivers/net/lora/sx130x.c
index 529ca6622878..818a1c9192b3 100644
--- a/drivers/net/lora/sx130x.c
+++ b/drivers/net/lora/sx130x.c
@@ -337,6 +337,34 @@ static int sx130x_load_firmware(struct sx130x_priv *priv, int mcu, const struct
return 0;
}
+static int sx130x_agc_transaction(struct sx130x_priv *priv, unsigned int val,
+ unsigned int *status)
+{
+ int ret;
+
+ ret = regmap_write(priv->regmap, SX1301_CHRS, SX1301_AGC_CMD_WAIT);
+ if (ret) {
+ dev_err(priv->dev, "AGC transaction start failed\n");
+ return ret;
+ }
+ usleep_range(1000, 2000);
+
+ ret = regmap_write(priv->regmap, SX1301_CHRS, val);
+ if (ret) {
+ dev_err(priv->dev, "AGC transaction value failed\n");
+ return ret;
+ }
+ usleep_range(1000, 2000);
+
+ ret = regmap_read(priv->regmap, SX1301_AGCSTS, status);
+ if (ret) {
+ dev_err(priv->dev, "AGC status read failed\n");
+ return ret;
+ }
+
+ return 0;
+}
+
static int sx130x_agc_calibrate(struct sx130x_priv *priv)
{
const struct firmware *fw;
diff --git a/drivers/net/lora/sx130x.h b/drivers/net/lora/sx130x.h
index 6330777f4eac..69bb9cbd1aba 100644
--- a/drivers/net/lora/sx130x.h
+++ b/drivers/net/lora/sx130x.h
@@ -18,6 +18,8 @@
#define SX1301_MCU_AGC_FW_VERSION 4
#define SX1301_MCU_AGC_CAL_FW_VERSION 2
+#define SX1301_AGC_CMD_WAIT 16
+
#define SX1301_TX_GAIN_LUT_MAX 16
/* Page independent */
--
2.17.1
^ permalink raw reply related
* [PATCH lora-next 07/11] net: lora: sx130x: add work queue to tx path
From: Ben Whitten @ 2019-01-28 16:13 UTC (permalink / raw)
To: afaerber; +Cc: linux-lpwan, Ben Whitten, David S. Miller, netdev, linux-kernel
In-Reply-To: <20190128161306.27805-1-ben.whitten@lairdtech.com>
As we are not allowed to sleep in _start_xmit, we need to add a work queue
to handle transmission of the packets.
Signed-off-by: Ben Whitten <ben.whitten@lairdtech.com>
---
drivers/net/lora/sx130x.c | 50 ++++++++++++++++++++++++++++++++++++++-
1 file changed, 49 insertions(+), 1 deletion(-)
diff --git a/drivers/net/lora/sx130x.c b/drivers/net/lora/sx130x.c
index 88932fbbb598..820ec0220e28 100644
--- a/drivers/net/lora/sx130x.c
+++ b/drivers/net/lora/sx130x.c
@@ -69,6 +69,10 @@ struct sx130x_priv {
void *drvdata;
struct sx130x_tx_gain_lut tx_gain_lut[SX1301_TX_GAIN_LUT_MAX];
u8 tx_gain_lut_size;
+
+ struct sk_buff *tx_skb;
+ struct workqueue_struct *wq;
+ struct work_struct tx_work;
};
struct regmap *sx130x_get_regmap(struct device *dev)
@@ -644,6 +648,8 @@ static int sx130x_agc_init(struct sx130x_priv *priv)
static netdev_tx_t sx130x_loradev_start_xmit(struct sk_buff *skb, struct net_device *netdev)
{
+ struct sx130x_priv *priv = netdev_priv(netdev);
+
if (skb->protocol != htons(ETH_P_LORA)) {
kfree_skb(skb);
netdev->stats.tx_dropped++;
@@ -651,11 +657,36 @@ static netdev_tx_t sx130x_loradev_start_xmit(struct sk_buff *skb, struct net_dev
}
netif_stop_queue(netdev);
+ priv->tx_skb = skb;
+ queue_work(priv->wq, &priv->tx_work);
- /* TODO */
return NETDEV_TX_OK;
}
+static void sx130x_tx_work_handler(struct work_struct *ws)
+{
+ struct sx130x_priv *priv = container_of(ws, struct sx130x_priv, tx_work);
+ struct net_device *netdev = dev_get_drvdata(priv->dev);
+ int ret;
+
+ netdev_dbg(netdev, "%s\n", __func__);
+
+ if (priv->tx_skb) {
+
+ /* TODO actual tx* */
+
+ if (!(netdev->flags & IFF_ECHO) ||
+ priv->tx_skb->pkt_type != PACKET_LOOPBACK ||
+ priv->tx_skb->protocol != htons(ETH_P_LORA))
+ kfree_skb(priv->tx_skb);
+
+ priv->tx_skb = NULL;
+ }
+
+ if (netif_queue_stopped(netdev))
+ netif_wake_queue(netdev);
+}
+
static int sx130x_loradev_open(struct net_device *netdev)
{
struct sx130x_priv *priv = netdev_priv(netdev);
@@ -715,6 +746,12 @@ static int sx130x_loradev_open(struct net_device *netdev)
mutex_unlock(&priv->io_lock);
+ priv->tx_skb = NULL;
+
+ priv->wq = alloc_workqueue("sx130x_wq",
+ WQ_FREEZABLE | WQ_MEM_RECLAIM, 0);
+ INIT_WORK(&priv->tx_work, sx130x_tx_work_handler);
+
netif_start_queue(netdev);
return 0;
@@ -729,11 +766,22 @@ static int sx130x_loradev_open(struct net_device *netdev)
static int sx130x_loradev_stop(struct net_device *netdev)
{
+ struct sx130x_priv *priv = netdev_priv(netdev);
+
netdev_dbg(netdev, "%s", __func__);
netif_stop_queue(netdev);
close_loradev(netdev);
+ destroy_workqueue(priv->wq);
+ priv->wq = NULL;
+
+ if (priv->tx_skb) {
+ netdev->stats.tx_errors++;
+ dev_kfree_skb(priv->tx_skb);
+ }
+ priv->tx_skb = NULL;
+
return 0;
}
--
2.17.1
^ permalink raw reply related
* [PATCH lora-next 06/11] net: lora: sx130x: add detail to TODO in setup
From: Ben Whitten @ 2019-01-28 16:13 UTC (permalink / raw)
To: afaerber; +Cc: linux-lpwan, Ben Whitten, David S. Miller, netdev, linux-kernel
In-Reply-To: <20190128161306.27805-1-ben.whitten@lairdtech.com>
From: Ben Whitten <ben.whitten@gmail.com>
Setup requires a more steps to be complete, call these out specifically
so they are not missed.
Signed-off-by: Ben Whitten <ben.whitten@gmail.com>
---
drivers/net/lora/sx130x.c | 12 +++++++++++-
1 file changed, 11 insertions(+), 1 deletion(-)
diff --git a/drivers/net/lora/sx130x.c b/drivers/net/lora/sx130x.c
index 18acfc8e934d..88932fbbb598 100644
--- a/drivers/net/lora/sx130x.c
+++ b/drivers/net/lora/sx130x.c
@@ -688,7 +688,17 @@ static int sx130x_loradev_open(struct net_device *netdev)
if (ret)
goto err_calibrate;
- /* TODO */
+ /* TODO Load constant adjustments, patches */
+
+ /* TODO Frequency time drift */
+
+ /* TODO Configure lora multi demods, bitfield of active */
+
+ /* TODO Load concentrator multi channel frequencies */
+
+ /* TODO enable the correlator on enabled frequencies */
+
+ /* TODO PPM, and modem enable */
ret = sx130x_load_all_firmware(priv);
if (ret)
--
2.17.1
^ permalink raw reply related
* [PATCH lora-next 09/11] net: lora: introduce lora socket addressing for metadata
From: Ben Whitten @ 2019-01-28 16:13 UTC (permalink / raw)
To: afaerber; +Cc: linux-lpwan, Ben Whitten, David S. Miller, linux-kernel, netdev
In-Reply-To: <20190128161306.27805-1-ben.whitten@lairdtech.com>
Information such as spreading factor, coding rate and power are on a per
transmission basis so we can encode this information in the lora socket
address.
In future we may have a different format for receive with additional
fields which get populated.
Signed-off-by: Ben Whitten <ben.whitten@lairdtech.com>
---
include/linux/lora/skb.h | 9 ++++++++
include/uapi/linux/lora.h | 14 ++++++++++++
net/lora/dgram.c | 45 +++++++++++++++++++++++++++++++++++++++
3 files changed, 68 insertions(+)
diff --git a/include/linux/lora/skb.h b/include/linux/lora/skb.h
index 8806741464d0..6abeb39b8b7f 100644
--- a/include/linux/lora/skb.h
+++ b/include/linux/lora/skb.h
@@ -12,6 +12,15 @@
struct lora_skb_priv {
int ifindex;
+
+ u64 freq;
+ u8 sf;
+ u8 cr;
+ u16 bw;
+
+ u8 sync;
+
+ s8 power;
};
static inline struct lora_skb_priv *lora_skb_prv(struct sk_buff *skb)
diff --git a/include/uapi/linux/lora.h b/include/uapi/linux/lora.h
index 4ff00b9c3c20..4c458ee3ed9a 100644
--- a/include/uapi/linux/lora.h
+++ b/include/uapi/linux/lora.h
@@ -10,6 +10,18 @@
#include <linux/types.h>
#include <linux/socket.h>
+/* TX addressing definition */
+struct tx_addr {
+ __u64 freq;
+ __u8 sf;
+ __u8 cr;
+ __u16 bw;
+
+ __u8 sync;
+
+ __s8 power;
+};
+
/* particular protocols of the protocol family PF_LORA */
#define LORA_PROTO_DATAGRAM 0
#define LORA_NPROTO 1
@@ -17,7 +29,9 @@
struct sockaddr_lora {
__kernel_sa_family_t lora_family;
int lora_ifindex;
+ __u8 lora_protocol;
union {
+ struct tx_addr tx;
} lora_addr;
};
diff --git a/net/lora/dgram.c b/net/lora/dgram.c
index 4d931fd3778a..1556ad0f8835 100644
--- a/net/lora/dgram.c
+++ b/net/lora/dgram.c
@@ -20,6 +20,15 @@ struct dgram_sock {
int ifindex;
bool bound;
struct notifier_block notifier;
+
+ u64 freq;
+ u8 sf;
+ u8 cr;
+ u16 bw;
+
+ u8 sync;
+
+ s8 power;
};
static inline struct dgram_sock *dgram_sk(const struct sock *sk)
@@ -69,6 +78,12 @@ static int dgram_bind(struct socket *sock, struct sockaddr *uaddr, int len)
ifindex = 0;
dgram->ifindex = ifindex;
+ dgram->freq = addr->lora_addr.tx.freq;
+ dgram->sf = addr->lora_addr.tx.sf;
+ dgram->cr = addr->lora_addr.tx.cr;
+ dgram->bw = addr->lora_addr.tx.bw;
+ dgram->sync = addr->lora_addr.tx.sync;
+ dgram->power = addr->lora_addr.tx.power;
dgram->bound = true;
out:
@@ -118,6 +133,12 @@ static int dgram_sendmsg(struct socket *sock, struct msghdr *msg, size_t size)
lora_skb_reserve(skb);
lora_skb_prv(skb)->ifindex = netdev->ifindex;
+ lora_skb_prv(skb)->freq = dgram->freq;
+ lora_skb_prv(skb)->sf = dgram->sf;
+ lora_skb_prv(skb)->cr = dgram->cr;
+ lora_skb_prv(skb)->bw = dgram->bw;
+ lora_skb_prv(skb)->sync = dgram->sync;
+ lora_skb_prv(skb)->power = dgram->power;
ret = memcpy_from_msg(skb_put(skb, size), msg, size);
if (ret < 0)
@@ -172,6 +193,12 @@ static int dgram_getname(struct socket *sock, struct sockaddr *uaddr,
memset(addr, 0, sizeof(*addr));
addr->lora_family = AF_LORA;
addr->lora_ifindex = dgram->ifindex;
+ addr->lora_addr.tx.freq = dgram->freq;
+ addr->lora_addr.tx.sf = dgram->sf;
+ addr->lora_addr.tx.cr = dgram->cr;
+ addr->lora_addr.tx.bw = dgram->bw;
+ addr->lora_addr.tx.sync = dgram->sync;
+ addr->lora_addr.tx.power = dgram->power;
#if LINUX_VERSION_CODE >= KERNEL_VERSION(4, 13, 0)
return sizeof(*addr);
@@ -198,6 +225,12 @@ static int dgram_release(struct socket *sock)
lock_sock(sk);
dgram->ifindex = 0;
+ dgram->freq = 0;
+ dgram->sf = 0;
+ dgram->cr = 0;
+ dgram->bw = 0;
+ dgram->sync = 0;
+ dgram->power = 0;
dgram->bound = false;
sock_orphan(sk);
@@ -251,6 +284,12 @@ static int dgram_notifier(struct notifier_block *nb, unsigned long msg, void *pt
lock_sock(sk);
dgram->ifindex = 0;
+ dgram->freq = 0;
+ dgram->sf = 0;
+ dgram->cr = 0;
+ dgram->bw = 0;
+ dgram->sync = 0;
+ dgram->power = 0;
dgram->bound = false;
release_sock(sk);
@@ -277,6 +316,12 @@ static int dgram_init(struct sock *sk)
pr_debug("lora: %s\n", __func__);
dgram->bound = false;
+ dgram->freq = 0;
+ dgram->sf = 0;
+ dgram->cr = 0;
+ dgram->bw = 0;
+ dgram->sync = 0;
+ dgram->power = 0;
dgram->ifindex = 0;
dgram->notifier.notifier_call = dgram_notifier;
--
2.17.1
^ permalink raw reply related
* [PATCH lora-next 10/11] net: lora: sx130x: make use of lora address metadata in transmission
From: Ben Whitten @ 2019-01-28 16:13 UTC (permalink / raw)
To: afaerber; +Cc: linux-lpwan, Ben Whitten, David S. Miller, netdev, linux-kernel
In-Reply-To: <20190128161306.27805-1-ben.whitten@lairdtech.com>
We take the metadata encoded in the lora address and apply it to the
outgoing transmission.
Signed-off-by: Ben Whitten <ben.whitten@lairdtech.com>
---
drivers/net/lora/sx130x.c | 58 ++++++++++++++++++++++++++++++++-------
1 file changed, 48 insertions(+), 10 deletions(-)
diff --git a/drivers/net/lora/sx130x.c b/drivers/net/lora/sx130x.c
index f96f32d2e1ff..428e82b4ccb8 100644
--- a/drivers/net/lora/sx130x.c
+++ b/drivers/net/lora/sx130x.c
@@ -22,6 +22,7 @@
#include <linux/slab.h>
#include <linux/gpio/consumer.h>
#include <linux/lora/dev.h>
+#include <linux/lora/skb.h>
#include <linux/spi/spi.h>
#include "sx130x.h"
@@ -688,12 +689,13 @@ static int sx130x_agc_init(struct sx130x_priv *priv)
return ret;
}
-static int sx130x_tx(struct sx130x_priv *priv, void *data, int len)
+static int sx130x_tx(struct sx130x_priv *priv, struct sk_buff *skb)
{
int ret, i;
u8 buff[256 + 16];
struct sx130x_tx_header *hdr = (struct sx130x_tx_header *)buff;
struct net_device *netdev = dev_get_drvdata(priv->dev);
+ u8 sf;
/* TODO general checks to make sure we CAN send */
@@ -722,11 +724,47 @@ static int sx130x_tx(struct sx130x_priv *priv, void *data, int len)
hdr->tx_power = 15; /* HACK power entry 15 */
hdr->u.lora.crc16_en = 1; /* Enable CRC16 */
- hdr->u.lora.cr = 1; /* CR 4/5 */
- hdr->u.lora.sf = 7; /* SF7 */
- hdr->u.lora.payload_len = len; /* Set the data len to the skb len */
+
+ switch (lora_skb_prv(skb)->cr) {
+ case 5:
+ hdr->u.lora.cr = 1; /* CR 4/5 */
+ break;
+ case 6:
+ hdr->u.lora.cr = 2; /* CR 4/6 */
+ break;
+ case 7:
+ hdr->u.lora.cr = 3; /* CR 4/7 */
+ break;
+ case 8:
+ hdr->u.lora.cr = 4; /* CR 4/8 */
+ break;
+ default:
+ return -ENXIO;
+ }
+
+ sf = lora_skb_prv(skb)->sf;
+ if ((sf < 6) || (sf > 12))
+ return -ENXIO;
+
+ hdr->u.lora.sf = sf;
+
+ hdr->u.lora.payload_len = skb->len; /* Set the data length */
hdr->u.lora.implicit_header = 0; /* No implicit header */
- hdr->u.lora.mod_bw = 0; /* Set 125KHz BW */
+
+ switch(lora_skb_prv(skb)->bw) {
+ case 125:
+ hdr->u.lora.mod_bw = 0; /* 125KHz BW */
+ break;
+ case 250:
+ hdr->u.lora.mod_bw = 1; /* 250KHz BW */
+ break;
+ case 500:
+ hdr->u.lora.mod_bw = 2; /* 500KHz BW */
+ break;
+ default:
+ return -ENXIO;
+ }
+
hdr->u.lora.ppm_offset = 0; /* TODO no ppm offset? */
hdr->u.lora.invert_pol = 0; /* TODO set no inverted polarity */
@@ -737,7 +775,7 @@ static int sx130x_tx(struct sx130x_priv *priv, void *data, int len)
/* Copy the TX data into the buffer ready to go */
- memcpy((void *)&buff[16], data, len);
+ memcpy((void *)&buff[16], skb->data, skb->len);
/* Reset any transmissions */
ret = regmap_write(priv->regmap, SX1301_TX_TRIG, 0);
@@ -749,7 +787,7 @@ static int sx130x_tx(struct sx130x_priv *priv, void *data, int len)
if (ret)
return ret;
ret = regmap_noinc_write(priv->regmap, SX1301_TX_DATA_BUF_DATA, buff,
- len + 16);
+ skb->len + 16);
if (ret)
return ret;
@@ -758,8 +796,8 @@ static int sx130x_tx(struct sx130x_priv *priv, void *data, int len)
if (ret)
return ret;
- netdev_dbg(netdev, "Transmitting packet of size %d: ", len);
- for (i = 0; i < len + 16; i++)
+ netdev_dbg(netdev, "Transmitting packet of size %d: ", skb->len);
+ for (i = 0; i < skb->len + 16; i++)
netdev_dbg(netdev, "%X", buff[i]);
return ret;
@@ -791,7 +829,7 @@ static void sx130x_tx_work_handler(struct work_struct *ws)
netdev_dbg(netdev, "%s\n", __func__);
if (priv->tx_skb) {
- ret = sx130x_tx(priv, priv->tx_skb->data, priv->tx_skb->len);
+ ret = sx130x_tx(priv, priv->tx_skb);
if (ret) {
netdev->stats.tx_errors++;
} else {
--
2.17.1
^ permalink raw reply related
* [PATCH lora-next 11/11] net: lora: sx130x: add patch to register fields
From: Ben Whitten @ 2019-01-28 16:13 UTC (permalink / raw)
To: afaerber; +Cc: linux-lpwan, Ben Whitten, David S. Miller, netdev, linux-kernel
In-Reply-To: <20190128161306.27805-1-ben.whitten@lairdtech.com>
The SX130x chips require a number of constant adjustments and patches.
We add the fields for the registers which require patches, add patch
values then add a helper to patch fields. Removing one TODO.
Signed-off-by: Ben Whitten <ben.whitten@lairdtech.com>
---
drivers/net/lora/sx130x.c | 131 +++++++++++++++++++++++++++++++++++++-
drivers/net/lora/sx130x.h | 75 ++++++++++++++++++++++
2 files changed, 205 insertions(+), 1 deletion(-)
diff --git a/drivers/net/lora/sx130x.c b/drivers/net/lora/sx130x.c
index 428e82b4ccb8..6e3b42de98a0 100644
--- a/drivers/net/lora/sx130x.c
+++ b/drivers/net/lora/sx130x.c
@@ -27,6 +27,63 @@
#include "sx130x.h"
+struct sx130x_fields_sequence {
+ enum sx130x_fields field;
+ u8 val;
+};
+
+static const struct sx130x_fields_sequence sx130x_regmap_fields_patch[] = {
+ /* I/Q path setup */
+ {F_RSSI_BB_FILTER_ALPHA, 6},
+ {F_RSSI_DEC_FILTER_ALPHA, 7},
+ {F_RSSI_CHANN_FILTER_ALPHA, 7},
+ {F_RSSI_BB_DEFAULT_VALUE, 23},
+ {F_RSSI_DEC_DEFAULT_VALUE, 85},
+ {F_RSSI_CHANN_DEFAULT_VALUE, 66},
+ {F_DEC_GAIN_OFFSET, 7},
+ {F_CHAN_GAIN_OFFSET, 6},
+
+ /* LoRa 'multi' demodulator setup */
+ {F_SNR_AVG_CST, 3},
+ {F_FRAME_SYNCH_PEAK1_POS, 3}, // Public LoRa network
+ {F_FRAME_SYNCH_PEAK2_POS, 4}, // Public LoRa network
+
+ /* LoRa standalone 'MBWSSF' demodulator setup */
+ {F_MBWSSF_FRAME_SYNCH_PEAK1_POS, 3}, // Public LoRa network
+ {F_MBWSSF_FRAME_SYNCH_PEAK2_POS, 4}, // Public LoRa network
+
+ /* Improvement of ref clock freq error tolerance */
+ {F_ADJUST_MODEM_START_OFFSET_RDX4L, 1},
+ {F_ADJUST_MODEM_START_OFFSET_SF12_RDX4L, (4094 & 0xFF)},
+ {F_ADJUST_MODEM_START_OFFSET_SF12_RDX4H, (4094 >> 8)},
+ {F_CORR_MAC_GAIN, 7},
+
+ /* FSK datapath setup */
+ {F_FSK_RX_INVERT, 1},
+ {F_FSK_MODEM_INVERT_IQ, 1},
+
+ /* FSK demodulator setup */
+ {F_FSK_RSSI_LENGTH, 4},
+ {F_FSK_PKT_MODE, 1},
+ {F_FSK_CRC_EN, 1},
+ {F_FSK_DCFREE_ENC, 2},
+ {F_FSK_ERROR_OSR_TOL, 10},
+ {F_FSK_PKT_LENGTH, 255},
+ {F_FSK_PATTERN_TIMEOUT_CFGL, 128},
+
+ /* TX general parameters */
+ {F_TX_START_DELAYL, (TX_START_DELAY_DEFAULT & 0xFF)},
+ {F_TX_START_DELAYH, (TX_START_DELAY_DEFAULT >> 8)},
+
+ /* TX LoRa */
+ {F_TX_SWAP_IQ, 1},
+ {F_TX_FRAME_SYNCH_PEAK1_POS, 3}, // Public LoRa network
+ {F_TX_FRAME_SYNCH_PEAK2_POS, 4}, // Public LoRa network
+
+ /* TX FSK */
+ {F_FSK_TX_GAUSSIAN_SELECT_BT, 2},
+};
+
static const struct reg_field sx130x_regmap_fields[] = {
/* PAGE */
[F_SOFT_RESET] = REG_FIELD(SX1301_PAGE, 7, 7),
@@ -54,6 +111,59 @@ static const struct reg_field sx130x_regmap_fields[] = {
[F_TX_TRIG_IMMEDIATE] = REG_FIELD(SX1301_TX_TRIG, 0, 0),
[F_TX_TRIG_DELAYED] = REG_FIELD(SX1301_TX_TRIG, 1, 1),
[F_TX_TRIG_GPS] = REG_FIELD(SX1301_TX_TRIG, 2, 2),
+
+ /* RSSI_X_FILTER_ALPHA */
+ [F_RSSI_BB_FILTER_ALPHA] = REG_FIELD(SX1301_RSSI_BB_FILTER_ALPHA, 0, 4),
+ [F_RSSI_DEC_FILTER_ALPHA] = REG_FIELD(SX1301_RSSI_DEC_FILTER_ALPHA, 0, 4),
+ [F_RSSI_CHANN_FILTER_ALPHA] = REG_FIELD(SX1301_RSSI_CHANN_FILTER_ALPHA, 0, 4),
+ /* RSSI_X_DEFAULT_VALUE */
+ [F_RSSI_BB_DEFAULT_VALUE] = REG_FIELD(SX1301_RSSI_BB_DEFAULT_VALUE, 0, 7),
+ [F_RSSI_DEC_DEFAULT_VALUE] = REG_FIELD(SX1301_RSSI_DEC_DEFAULT_VALUE, 0, 7),
+ [F_RSSI_CHANN_DEFAULT_VALUE] = REG_FIELD(SX1301_RSSI_CHANN_DEFAULT_VALUE, 0, 7),
+ /* GAIN_OFFSET */
+ [F_DEC_GAIN_OFFSET] = REG_FIELD(SX1301_GAIN_OFFSET, 0, 3),
+ [F_CHAN_GAIN_OFFSET] = REG_FIELD(SX1301_GAIN_OFFSET, 4, 7),
+
+ [F_SNR_AVG_CST] = REG_FIELD(SX1301_MISC_CFG1, 4, 5),
+ [F_FRAME_SYNCH_PEAK1_POS] = REG_FIELD(SX1301_FRAME_SYNCH, 0, 3),
+ [F_FRAME_SYNCH_PEAK2_POS] = REG_FIELD(SX1301_FRAME_SYNCH, 4, 7),
+
+ [F_MBWSSF_FRAME_SYNCH_PEAK1_POS] = REG_FIELD(SX1301_BHSYNCPOS, 0, 3),
+ [F_MBWSSF_FRAME_SYNCH_PEAK2_POS] = REG_FIELD(SX1301_BHSYNCPOS, 4, 7),
+
+ [F_ADJUST_MODEM_START_OFFSET_RDX4L] =
+ REG_FIELD(SX1301_MODEM_START_RDX4L, 0, 7), // 12 bits
+ [F_ADJUST_MODEM_START_OFFSET_RDX4H] =
+ REG_FIELD(SX1301_MODEM_START_RDX4H, 0, 3),
+ [F_ADJUST_MODEM_START_OFFSET_SF12_RDX4L] =
+ REG_FIELD(SX1301_MODEM_START_SF12_RDX4L, 0, 7), // 12 bits
+ [F_ADJUST_MODEM_START_OFFSET_SF12_RDX4H] =
+ REG_FIELD(SX1301_MODEM_START_SF12_RDX4H, 0, 3),
+ [F_CORR_MAC_GAIN] = REG_FIELD(SX1301_CORR_CFG, 4, 6),
+
+ [F_FSK_RSSI_LENGTH] = REG_FIELD(SX1301_FSK_CFG1, 3, 5),
+ [F_FSK_RX_INVERT] = REG_FIELD(SX1301_FSK_CFG1, 6, 6),
+ [F_FSK_PKT_MODE] = REG_FIELD(SX1301_FSK_CFG1, 7, 7),
+
+ [F_FSK_MODEM_INVERT_IQ] = REG_FIELD(SX1301_IQCFG, 5, 5),
+
+ [F_FSK_CRC_EN] = REG_FIELD(SX1301_FSK_CFG2, 3, 3),
+ [F_FSK_DCFREE_ENC] = REG_FIELD(SX1301_FSK_CFG2, 4, 5),
+ [F_FSK_ERROR_OSR_TOL] = REG_FIELD(SX1301_FSK_ERROR_OSR_TOL, 0, 4),
+ [F_FSK_PKT_LENGTH] = REG_FIELD(SX1301_FSK_PKT_LENGTH, 0, 7),
+ [F_FSK_PATTERN_TIMEOUT_CFGL] =
+ REG_FIELD(SX1301_FSK_PATTERN_TIMEOUT_CFGL, 0, 7), // 10 bits
+ [F_FSK_PATTERN_TIMEOUT_CFGH] =
+ REG_FIELD(SX1301_FSK_PATTERN_TIMEOUT_CFGH, 0, 1),
+
+ [F_TX_START_DELAYL] = REG_FIELD(SX1301_TX_START_DELAYL, 0, 7), // 16 bit
+ [F_TX_START_DELAYH] = REG_FIELD(SX1301_TX_START_DELAYH, 0, 7),
+
+ [F_TX_SWAP_IQ] = REG_FIELD(SX1301_TX_CFG2, 7, 7),
+ [F_TX_FRAME_SYNCH_PEAK1_POS] = REG_FIELD(SX1301_TX_FRAME_SYNCH, 0, 3),
+ [F_TX_FRAME_SYNCH_PEAK2_POS] = REG_FIELD(SX1301_TX_FRAME_SYNCH, 4, 7),
+
+ [F_FSK_TX_GAUSSIAN_SELECT_BT] = REG_FIELD(SX1301_FSK_TX, 1, 2),
};
struct sx130x_tx_header {
@@ -263,6 +373,23 @@ static int sx130x_soft_reset(struct sx130x_priv *priv)
return 0;
}
+static int sx130x_fields_patch(struct sx130x_priv *priv)
+{
+ int i, ret;
+
+ for (i = 0; i < ARRAY_SIZE(sx130x_regmap_fields_patch); i++) {
+ ret = sx130x_field_force_write(priv, sx130x_regmap_fields_patch[i].field,
+ sx130x_regmap_fields_patch[i].val);
+ if (ret) {
+ dev_err(priv->dev,
+ "Failed to patch regmap field: %d\n", i);
+ break;
+ }
+ }
+
+ return ret;
+}
+
static int sx130x_agc_ram_read(struct sx130x_priv *priv, u8 addr, unsigned int *val)
{
int ret;
@@ -881,7 +1008,9 @@ static int sx130x_loradev_open(struct net_device *netdev)
if (ret)
goto err_calibrate;
- /* TODO Load constant adjustments, patches */
+ ret = sx130x_fields_patch(priv);
+ if (ret)
+ return ret;
/* TODO Frequency time drift */
diff --git a/drivers/net/lora/sx130x.h b/drivers/net/lora/sx130x.h
index 38f1b58b2165..121c8a35b5c3 100644
--- a/drivers/net/lora/sx130x.h
+++ b/drivers/net/lora/sx130x.h
@@ -29,6 +29,9 @@
#define SX1301_PA_GAIN_OFFSET 6
#define SX1301_DAC_GAIN_OFFSET 4
+/* Calibrated value for 500KHz BW and notch filter disabled */
+#define TX_START_DELAY_DEFAULT 1497
+
/* Page independent */
#define SX1301_PAGE 0x00
#define SX1301_VER 0x01
@@ -49,12 +52,39 @@
#define SX1301_PAGE_BASE(n) (SX1301_VIRT_BASE + (SX1301_PAGE_LEN * n))
/* Page 0 */
+#define SX1301_IQCFG (SX1301_PAGE_BASE(0) + 0x21)
#define SX1301_CHRS (SX1301_PAGE_BASE(0) + 0x23)
+#define SX1301_CORR_CFG (SX1301_PAGE_BASE(0) + 0x4E)
+#define SX1301_MODEM_START_RDX4L (SX1301_PAGE_BASE(0) + 0x51)
+#define SX1301_MODEM_START_RDX4H (SX1301_PAGE_BASE(0) + 0x52)
+#define SX1301_MODEM_START_SF12_RDX4L (SX1301_PAGE_BASE(0) + 0x53)
+#define SX1301_MODEM_START_SF12_RDX4H (SX1301_PAGE_BASE(0) + 0x54)
+#define SX1301_FRAME_SYNCH (SX1301_PAGE_BASE(0) + 0x5F)
+#define SX1301_MISC_CFG1 (SX1301_PAGE_BASE(0) + 0x63)
+#define SX1301_GAIN_OFFSET (SX1301_PAGE_BASE(0) + 0x68)
#define SX1301_FORCE_CTRL (SX1301_PAGE_BASE(0) + 0x69)
#define SX1301_MCU_CTRL (SX1301_PAGE_BASE(0) + 0x6A)
+#define SX1301_RSSI_BB_DEFAULT_VALUE (SX1301_PAGE_BASE(0) + 0x6C)
+#define SX1301_RSSI_DEC_DEFAULT_VALUE (SX1301_PAGE_BASE(0) + 0x6D)
+#define SX1301_RSSI_CHANN_DEFAULT_VALUE (SX1301_PAGE_BASE(0) + 0x6E)
+#define SX1301_RSSI_BB_FILTER_ALPHA (SX1301_PAGE_BASE(0) + 0x6F)
+#define SX1301_RSSI_DEC_FILTER_ALPHA (SX1301_PAGE_BASE(0) + 0x70)
+#define SX1301_RSSI_CHANN_FILTER_ALPHA (SX1301_PAGE_BASE(0) + 0x71)
/* Page 1 */
#define SX1301_TX_TRIG (SX1301_PAGE_BASE(1) + 0x21)
+#define SX1301_TX_START_DELAYL (SX1301_PAGE_BASE(1) + 0x22)
+#define SX1301_TX_START_DELAYH (SX1301_PAGE_BASE(1) + 0x23)
+#define SX1301_TX_FRAME_SYNCH (SX1301_PAGE_BASE(1) + 0x24)
+#define SX1301_TX_CFG2 (SX1301_PAGE_BASE(1) + 0x2A)
+#define SX1301_BHSYNCPOS (SX1301_PAGE_BASE(1) + 0x2E)
+#define SX1301_FSK_CFG1 (SX1301_PAGE_BASE(1) + 0x3F)
+#define SX1301_FSK_CFG2 (SX1301_PAGE_BASE(1) + 0x40)
+#define SX1301_FSK_ERROR_OSR_TOL (SX1301_PAGE_BASE(1) + 0x41)
+#define SX1301_FSK_PKT_LENGTH (SX1301_PAGE_BASE(1) + 0x4C)
+#define SX1301_FSK_TX (SX1301_PAGE_BASE(1) + 0x4D)
+#define SX1301_FSK_PATTERN_TIMEOUT_CFGL (SX1301_PAGE_BASE(1) + 0x53)
+#define SX1301_FSK_PATTERN_TIMEOUT_CFGH (SX1301_PAGE_BASE(1) + 0x54)
/* Page 2 */
#define SX1301_RADIO_A_SPI_DATA (SX1301_PAGE_BASE(2) + 0x21)
@@ -98,6 +128,51 @@ enum sx130x_fields {
F_TX_TRIG_IMMEDIATE,
F_TX_TRIG_DELAYED,
F_TX_TRIG_GPS,
+
+ F_RSSI_BB_FILTER_ALPHA,
+ F_RSSI_DEC_FILTER_ALPHA,
+ F_RSSI_CHANN_FILTER_ALPHA,
+
+ F_RSSI_BB_DEFAULT_VALUE,
+ F_RSSI_DEC_DEFAULT_VALUE,
+ F_RSSI_CHANN_DEFAULT_VALUE,
+
+ F_DEC_GAIN_OFFSET,
+ F_CHAN_GAIN_OFFSET,
+
+ F_SNR_AVG_CST,
+ F_FRAME_SYNCH_PEAK1_POS,
+ F_FRAME_SYNCH_PEAK2_POS,
+
+ F_MBWSSF_FRAME_SYNCH_PEAK1_POS,
+ F_MBWSSF_FRAME_SYNCH_PEAK2_POS,
+
+ F_ADJUST_MODEM_START_OFFSET_RDX4L,
+ F_ADJUST_MODEM_START_OFFSET_RDX4H,
+ F_ADJUST_MODEM_START_OFFSET_SF12_RDX4L,
+ F_ADJUST_MODEM_START_OFFSET_SF12_RDX4H,
+ F_CORR_MAC_GAIN,
+
+ F_FSK_RX_INVERT,
+ F_FSK_MODEM_INVERT_IQ,
+
+ F_FSK_RSSI_LENGTH,
+ F_FSK_PKT_MODE,
+ F_FSK_CRC_EN,
+ F_FSK_DCFREE_ENC,
+ F_FSK_ERROR_OSR_TOL,
+ F_FSK_PKT_LENGTH,
+ F_FSK_PATTERN_TIMEOUT_CFGL,
+ F_FSK_PATTERN_TIMEOUT_CFGH,
+
+ F_TX_START_DELAYL,
+ F_TX_START_DELAYH,
+
+ F_TX_SWAP_IQ,
+ F_TX_FRAME_SYNCH_PEAK1_POS,
+ F_TX_FRAME_SYNCH_PEAK2_POS,
+
+ F_FSK_TX_GAUSSIAN_SELECT_BT,
};
struct regmap *sx130x_get_regmap(struct device *dev);
--
2.17.1
^ permalink raw reply related
* [PATCH AUTOSEL 4.14 094/170] selftests/bpf: use __bpf_constant_htons in test_prog.c
From: Sasha Levin @ 2019-01-28 16:10 UTC (permalink / raw)
To: linux-kernel, stable
Cc: Stanislav Fomichev, Daniel Borkmann, Alexei Starovoitov,
Sasha Levin, netdev, linux-kselftest
In-Reply-To: <20190128161200.55107-1-sashal@kernel.org>
From: Stanislav Fomichev <sdf@google.com>
[ Upstream commit a0517a0f7ef23550b4484c37e2b9c2d32abebf64 ]
For some reason, my older GCC (< 4.8) isn't smart enough to optimize the
!__builtin_constant_p() branch in bpf_htons, I see:
error: implicit declaration of function '__builtin_bswap16'
Let's use __bpf_constant_htons as suggested by Daniel Borkmann.
I tried to use simple htons, but it produces the following:
test_progs.c:54:17: error: braced-group within expression allowed only
inside a function
.eth.h_proto = htons(ETH_P_IP),
Signed-off-by: Stanislav Fomichev <sdf@google.com>
Signed-off-by: Daniel Borkmann <daniel@iogearbox.net>
Signed-off-by: Alexei Starovoitov <ast@kernel.org>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
tools/testing/selftests/bpf/test_progs.c | 8 ++++----
1 file changed, 4 insertions(+), 4 deletions(-)
diff --git a/tools/testing/selftests/bpf/test_progs.c b/tools/testing/selftests/bpf/test_progs.c
index 11ee25cea227..1903fb4f45d8 100644
--- a/tools/testing/selftests/bpf/test_progs.c
+++ b/tools/testing/selftests/bpf/test_progs.c
@@ -43,10 +43,10 @@ static struct {
struct iphdr iph;
struct tcphdr tcp;
} __packed pkt_v4 = {
- .eth.h_proto = bpf_htons(ETH_P_IP),
+ .eth.h_proto = __bpf_constant_htons(ETH_P_IP),
.iph.ihl = 5,
.iph.protocol = 6,
- .iph.tot_len = bpf_htons(MAGIC_BYTES),
+ .iph.tot_len = __bpf_constant_htons(MAGIC_BYTES),
.tcp.urg_ptr = 123,
};
@@ -56,9 +56,9 @@ static struct {
struct ipv6hdr iph;
struct tcphdr tcp;
} __packed pkt_v6 = {
- .eth.h_proto = bpf_htons(ETH_P_IPV6),
+ .eth.h_proto = __bpf_constant_htons(ETH_P_IPV6),
.iph.nexthdr = 6,
- .iph.payload_len = bpf_htons(MAGIC_BYTES),
+ .iph.payload_len = __bpf_constant_htons(MAGIC_BYTES),
.tcp.urg_ptr = 123,
};
--
2.19.1
^ 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