Skip to content

Commit 4b47ad0

Browse files
committed
Merge branch 'ipa-cleanups'
Alex Elder says: ==================== net: ipa: some more cleanup Version 3 of this series uses dev_err_probe() in the second patch, as suggested by Heiner Kallweit. Version 2 was sent to ensure the series was based on current net-next/master, and added copyright updates to files touched. The original introduction is below. This is another fairly innocuous set of cleanup patches. The first was motivated by a bug found that would affect IPA v4.5. It maintain a new GSI address pointer; one is the "raw" (original mapped) address, and the other will have been adjusted if necessary for use on newer platforms. The second just quiets some unnecessary noise during early probe. The third fixes some errors that show up when IPA_VALIDATION is enabled. The last two just create helper functions to improve readability. ==================== Signed-off-by: David S. Miller <[email protected]>
2 parents 21cc70c + 6170b6d commit 4b47ad0

File tree

7 files changed

+87
-54
lines changed

7 files changed

+87
-54
lines changed

drivers/net/ipa/gsi.c

Lines changed: 26 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
// SPDX-License-Identifier: GPL-2.0
22

33
/* Copyright (c) 2015-2018, The Linux Foundation. All rights reserved.
4-
* Copyright (C) 2018-2020 Linaro Ltd.
4+
* Copyright (C) 2018-2021 Linaro Ltd.
55
*/
66

77
#include <linux/types.h>
@@ -175,6 +175,12 @@ static u32 gsi_channel_id(struct gsi_channel *channel)
175175
return channel - &channel->gsi->channel[0];
176176
}
177177

178+
/* An initialized channel has a non-null GSI pointer */
179+
static bool gsi_channel_initialized(struct gsi_channel *channel)
180+
{
181+
return !!channel->gsi;
182+
}
183+
178184
/* Update the GSI IRQ type register with the cached value */
179185
static void gsi_irq_type_update(struct gsi *gsi, u32 val)
180186
{
@@ -195,8 +201,6 @@ static void gsi_irq_type_disable(struct gsi *gsi, enum gsi_irq_type_id type_id)
195201
/* Turn off all GSI interrupts initially */
196202
static void gsi_irq_setup(struct gsi *gsi)
197203
{
198-
u32 adjust;
199-
200204
/* Disable all interrupt types */
201205
gsi_irq_type_update(gsi, 0);
202206

@@ -206,10 +210,9 @@ static void gsi_irq_setup(struct gsi *gsi)
206210
iowrite32(0, gsi->virt + GSI_CNTXT_GLOB_IRQ_EN_OFFSET);
207211
iowrite32(0, gsi->virt + GSI_CNTXT_SRC_IEOB_IRQ_MSK_OFFSET);
208212

209-
/* Reverse the offset adjustment for inter-EE register offsets */
210-
adjust = gsi->version < IPA_VERSION_4_5 ? 0 : GSI_EE_REG_ADJUST;
211-
iowrite32(0, gsi->virt + adjust + GSI_INTER_EE_SRC_CH_IRQ_OFFSET);
212-
iowrite32(0, gsi->virt + adjust + GSI_INTER_EE_SRC_EV_CH_IRQ_OFFSET);
213+
/* The inter-EE registers are in the non-adjusted address range */
214+
iowrite32(0, gsi->virt_raw + GSI_INTER_EE_SRC_CH_IRQ_OFFSET);
215+
iowrite32(0, gsi->virt_raw + GSI_INTER_EE_SRC_EV_CH_IRQ_OFFSET);
213216

214217
iowrite32(0, gsi->virt + GSI_CNTXT_GSI_IRQ_EN_OFFSET);
215218
}
@@ -1641,8 +1644,8 @@ static int gsi_channel_setup_one(struct gsi *gsi, u32 channel_id)
16411644
u32 evt_ring_id = channel->evt_ring_id;
16421645
int ret;
16431646

1644-
if (!channel->gsi)
1645-
return 0; /* Ignore uninitialized channels */
1647+
if (!gsi_channel_initialized(channel))
1648+
return 0;
16461649

16471650
ret = gsi_evt_ring_alloc_command(gsi, evt_ring_id);
16481651
if (ret)
@@ -1678,8 +1681,8 @@ static void gsi_channel_teardown_one(struct gsi *gsi, u32 channel_id)
16781681
struct gsi_channel *channel = &gsi->channel[channel_id];
16791682
u32 evt_ring_id = channel->evt_ring_id;
16801683

1681-
if (!channel->gsi)
1682-
return; /* Ignore uninitialized channels */
1684+
if (!gsi_channel_initialized(channel))
1685+
return;
16831686

16841687
netif_napi_del(&channel->napi);
16851688

@@ -1773,8 +1776,8 @@ static int gsi_channel_setup(struct gsi *gsi)
17731776
while (channel_id < GSI_CHANNEL_COUNT_MAX) {
17741777
struct gsi_channel *channel = &gsi->channel[channel_id++];
17751778

1776-
if (!channel->gsi)
1777-
continue; /* Ignore uninitialized channels */
1779+
if (!gsi_channel_initialized(channel))
1780+
continue;
17781781

17791782
ret = -EINVAL;
17801783
dev_err(gsi->dev, "channel %u not supported by hardware\n",
@@ -2092,8 +2095,8 @@ static int gsi_channel_init_one(struct gsi *gsi,
20922095
/* Inverse of gsi_channel_init_one() */
20932096
static void gsi_channel_exit_one(struct gsi_channel *channel)
20942097
{
2095-
if (!channel->gsi)
2096-
return; /* Ignore uninitialized channels */
2098+
if (!gsi_channel_initialized(channel))
2099+
return;
20972100

20982101
if (channel->command)
20992102
ipa_cmd_pool_exit(channel);
@@ -2181,9 +2184,8 @@ int gsi_init(struct gsi *gsi, struct platform_device *pdev,
21812184
gsi->dev = dev;
21822185
gsi->version = version;
21832186

2184-
/* The GSI layer performs NAPI on all endpoints. NAPI requires a
2185-
* network device structure, but the GSI layer does not have one,
2186-
* so we must create a dummy network device for this purpose.
2187+
/* GSI uses NAPI on all channels. Create a dummy network device
2188+
* for the channel NAPI contexts to be associated with.
21872189
*/
21882190
init_dummy_netdev(&gsi->dummy_dev);
21892191

@@ -2208,13 +2210,13 @@ int gsi_init(struct gsi *gsi, struct platform_device *pdev,
22082210
return -EINVAL;
22092211
}
22102212

2211-
gsi->virt = ioremap(res->start, size);
2212-
if (!gsi->virt) {
2213+
gsi->virt_raw = ioremap(res->start, size);
2214+
if (!gsi->virt_raw) {
22132215
dev_err(dev, "unable to remap \"gsi\" memory\n");
22142216
return -ENOMEM;
22152217
}
2216-
/* Adjust register range pointer downward for newer IPA versions */
2217-
gsi->virt -= adjust;
2218+
/* Most registers are accessed using an adjusted register range */
2219+
gsi->virt = gsi->virt_raw - adjust;
22182220

22192221
init_completion(&gsi->completion);
22202222

@@ -2233,7 +2235,7 @@ int gsi_init(struct gsi *gsi, struct platform_device *pdev,
22332235
err_irq_exit:
22342236
gsi_irq_exit(gsi);
22352237
err_iounmap:
2236-
iounmap(gsi->virt);
2238+
iounmap(gsi->virt_raw);
22372239

22382240
return ret;
22392241
}
@@ -2244,7 +2246,7 @@ void gsi_exit(struct gsi *gsi)
22442246
mutex_destroy(&gsi->mutex);
22452247
gsi_channel_exit(gsi);
22462248
gsi_irq_exit(gsi);
2247-
iounmap(gsi->virt);
2249+
iounmap(gsi->virt_raw);
22482250
}
22492251

22502252
/* The maximum number of outstanding TREs on a channel. This limits

drivers/net/ipa/gsi.h

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
/* SPDX-License-Identifier: GPL-2.0 */
22

33
/* Copyright (c) 2015-2018, The Linux Foundation. All rights reserved.
4-
* Copyright (C) 2018-2020 Linaro Ltd.
4+
* Copyright (C) 2018-2021 Linaro Ltd.
55
*/
66
#ifndef _GSI_H_
77
#define _GSI_H_
@@ -149,7 +149,8 @@ struct gsi {
149149
struct device *dev; /* Same as IPA device */
150150
enum ipa_version version;
151151
struct net_device dummy_dev; /* needed for NAPI */
152-
void __iomem *virt;
152+
void __iomem *virt_raw; /* I/O mapped address range */
153+
void __iomem *virt; /* Adjusted for most registers */
153154
u32 irq;
154155
u32 channel_count;
155156
u32 evt_ring_count;

drivers/net/ipa/gsi_reg.h

Lines changed: 13 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
/* SPDX-License-Identifier: GPL-2.0 */
22

33
/* Copyright (c) 2015-2018, The Linux Foundation. All rights reserved.
4-
* Copyright (C) 2018-2020 Linaro Ltd.
4+
* Copyright (C) 2018-2021 Linaro Ltd.
55
*/
66
#ifndef _GSI_REG_H_
77
#define _GSI_REG_H_
@@ -38,17 +38,21 @@
3838
* (though the actual limit is hardware-dependent).
3939
*/
4040

41-
/* GSI EE registers as a group are shifted downward by a fixed
42-
* constant amount for IPA versions 4.5 and beyond. This applies
43-
* to all GSI registers we use *except* the ones that disable
44-
* inter-EE interrupts for channels and event channels.
41+
/* GSI EE registers as a group are shifted downward by a fixed constant amount
42+
* for IPA versions 4.5 and beyond. This applies to all GSI registers we use
43+
* *except* the ones that disable inter-EE interrupts for channels and event
44+
* channels.
4545
*
46-
* We handle this by adjusting the pointer to the mapped GSI memory
47-
* region downward. Then in the one place we use them (gsi_irq_setup())
48-
* we undo that adjustment for the inter-EE interrupt registers.
46+
* The "raw" (not adjusted) GSI register range is mapped, and a pointer to
47+
* the mapped range is held in gsi->virt_raw. The inter-EE interrupt
48+
* registers are accessed using that pointer.
49+
*
50+
* Most registers are accessed using gsi->virt, which is a copy of the "raw"
51+
* pointer, adjusted downward by the fixed amount.
4952
*/
5053
#define GSI_EE_REG_ADJUST 0x0000d000 /* IPA v4.5+ */
5154

55+
/* The two inter-EE IRQ register offsets are relative to gsi->virt_raw */
5256
#define GSI_INTER_EE_SRC_CH_IRQ_OFFSET \
5357
GSI_INTER_EE_N_SRC_CH_IRQ_OFFSET(GSI_EE_AP)
5458
#define GSI_INTER_EE_N_SRC_CH_IRQ_OFFSET(ee) \
@@ -59,6 +63,7 @@
5963
#define GSI_INTER_EE_N_SRC_EV_CH_IRQ_OFFSET(ee) \
6064
(0x0000c01c + 0x1000 * (ee))
6165

66+
/* All other register offsets are relative to gsi->virt */
6267
#define GSI_CH_C_CNTXT_0_OFFSET(ch) \
6368
GSI_EE_N_CH_C_CNTXT_0_OFFSET((ch), GSI_EE_AP)
6469
#define GSI_EE_N_CH_C_CNTXT_0_OFFSET(ch, ee) \

drivers/net/ipa/ipa_clock.c

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
// SPDX-License-Identifier: GPL-2.0
22

33
/* Copyright (c) 2012-2018, The Linux Foundation. All rights reserved.
4-
* Copyright (C) 2018-2020 Linaro Ltd.
4+
* Copyright (C) 2018-2021 Linaro Ltd.
55
*/
66

77
#include <linux/refcount.h>
@@ -68,8 +68,8 @@ static int ipa_interconnect_init_one(struct device *dev,
6868
if (IS_ERR(path)) {
6969
int ret = PTR_ERR(path);
7070

71-
dev_err(dev, "error %d getting %s interconnect\n", ret,
72-
data->name);
71+
dev_err_probe(dev, ret, "error getting %s interconnect\n",
72+
data->name);
7373

7474
return ret;
7575
}
@@ -281,7 +281,8 @@ ipa_clock_init(struct device *dev, const struct ipa_clock_data *data)
281281

282282
clk = clk_get(dev, "core");
283283
if (IS_ERR(clk)) {
284-
dev_err(dev, "error %ld getting core clock\n", PTR_ERR(clk));
284+
dev_err_probe(dev, PTR_ERR(clk), "error getting core clock\n");
285+
285286
return ERR_CAST(clk);
286287
}
287288

drivers/net/ipa/ipa_cmd.c

Lines changed: 24 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
// SPDX-License-Identifier: GPL-2.0
22

33
/* Copyright (c) 2012-2018, The Linux Foundation. All rights reserved.
4-
* Copyright (C) 2019-2020 Linaro Ltd.
4+
* Copyright (C) 2019-2021 Linaro Ltd.
55
*/
66

77
#include <linux/types.h>
@@ -244,11 +244,15 @@ static bool ipa_cmd_register_write_offset_valid(struct ipa *ipa,
244244
if (ipa->version != IPA_VERSION_3_5_1)
245245
bit_count += hweight32(REGISTER_WRITE_FLAGS_OFFSET_HIGH_FMASK);
246246
BUILD_BUG_ON(bit_count > 32);
247-
offset_max = ~0 >> (32 - bit_count);
247+
offset_max = ~0U >> (32 - bit_count);
248248

249+
/* Make sure the offset can be represented by the field(s)
250+
* that holds it. Also make sure the offset is not outside
251+
* the overall IPA memory range.
252+
*/
249253
if (offset > offset_max || ipa->mem_offset > offset_max - offset) {
250254
dev_err(dev, "%s offset too large 0x%04x + 0x%04x > 0x%04x)\n",
251-
ipa->mem_offset + offset, offset_max);
255+
name, ipa->mem_offset, offset, offset_max);
252256
return false;
253257
}
254258

@@ -261,12 +265,24 @@ static bool ipa_cmd_register_write_valid(struct ipa *ipa)
261265
const char *name;
262266
u32 offset;
263267

264-
offset = ipa_reg_filt_rout_hash_flush_offset(ipa->version);
265-
name = "filter/route hash flush";
266-
if (!ipa_cmd_register_write_offset_valid(ipa, name, offset))
267-
return false;
268+
/* If hashed tables are supported, ensure the hash flush register
269+
* offset will fit in a register write IPA immediate command.
270+
*/
271+
if (ipa_table_hash_support(ipa)) {
272+
offset = ipa_reg_filt_rout_hash_flush_offset(ipa->version);
273+
name = "filter/route hash flush";
274+
if (!ipa_cmd_register_write_offset_valid(ipa, name, offset))
275+
return false;
276+
}
268277

269-
offset = IPA_REG_ENDP_STATUS_N_OFFSET(IPA_ENDPOINT_COUNT);
278+
/* Each endpoint can have a status endpoint associated with it,
279+
* and this is recorded in an endpoint register. If the modem
280+
* crashes, we reset the status endpoint for all modem endpoints
281+
* using a register write IPA immediate command. Make sure the
282+
* worst case (highest endpoint number) offset of that endpoint
283+
* fits in the register write command field(s) that must hold it.
284+
*/
285+
offset = IPA_REG_ENDP_STATUS_N_OFFSET(IPA_ENDPOINT_COUNT - 1);
270286
name = "maximal endpoint status";
271287
if (!ipa_cmd_register_write_offset_valid(ipa, name, offset))
272288
return false;

drivers/net/ipa/ipa_table.c

Lines changed: 9 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
// SPDX-License-Identifier: GPL-2.0
22

33
/* Copyright (c) 2012-2018, The Linux Foundation. All rights reserved.
4-
* Copyright (C) 2018-2020 Linaro Ltd.
4+
* Copyright (C) 2018-2021 Linaro Ltd.
55
*/
66

77
#include <linux/types.h>
@@ -239,6 +239,11 @@ static void ipa_table_validate_build(void)
239239

240240
#endif /* !IPA_VALIDATE */
241241

242+
bool ipa_table_hash_support(struct ipa *ipa)
243+
{
244+
return ipa->version != IPA_VERSION_4_2;
245+
}
246+
242247
/* Zero entry count means no table, so just return a 0 address */
243248
static dma_addr_t ipa_table_addr(struct ipa *ipa, bool filter_mask, u16 count)
244249
{
@@ -412,8 +417,7 @@ int ipa_table_hash_flush(struct ipa *ipa)
412417
struct gsi_trans *trans;
413418
u32 val;
414419

415-
/* IPA version 4.2 does not support hashed tables */
416-
if (ipa->version == IPA_VERSION_4_2)
420+
if (!ipa_table_hash_support(ipa))
417421
return 0;
418422

419423
trans = ipa_cmd_trans_alloc(ipa, 1);
@@ -531,8 +535,7 @@ static void ipa_filter_config(struct ipa *ipa, bool modem)
531535
enum gsi_ee_id ee_id = modem ? GSI_EE_MODEM : GSI_EE_AP;
532536
u32 ep_mask = ipa->filter_map;
533537

534-
/* IPA version 4.2 has no hashed route tables */
535-
if (ipa->version == IPA_VERSION_4_2)
538+
if (!ipa_table_hash_support(ipa))
536539
return;
537540

538541
while (ep_mask) {
@@ -582,8 +585,7 @@ static void ipa_route_config(struct ipa *ipa, bool modem)
582585
{
583586
u32 route_id;
584587

585-
/* IPA version 4.2 has no hashed route tables */
586-
if (ipa->version == IPA_VERSION_4_2)
588+
if (!ipa_table_hash_support(ipa))
587589
return;
588590

589591
for (route_id = 0; route_id < IPA_ROUTE_COUNT_MAX; route_id++)

drivers/net/ipa/ipa_table.h

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
/* SPDX-License-Identifier: GPL-2.0 */
22

33
/* Copyright (c) 2012-2018, The Linux Foundation. All rights reserved.
4-
* Copyright (C) 2019-2020 Linaro Ltd.
4+
* Copyright (C) 2019-2021 Linaro Ltd.
55
*/
66
#ifndef _IPA_TABLE_H_
77
#define _IPA_TABLE_H_
@@ -51,6 +51,12 @@ static inline bool ipa_filter_map_valid(struct ipa *ipa, u32 filter_mask)
5151

5252
#endif /* !IPA_VALIDATE */
5353

54+
/**
55+
* ipa_table_hash_support() - Return true if hashed tables are supported
56+
* @ipa: IPA pointer
57+
*/
58+
bool ipa_table_hash_support(struct ipa *ipa);
59+
5460
/**
5561
* ipa_table_reset() - Reset filter and route tables entries to "none"
5662
* @ipa: IPA pointer

0 commit comments

Comments
 (0)