linux-can-next-for-5.11-20201130
-----BEGIN PGP SIGNATURE----- iQFHBAABCgAxFiEEK3kIWJt9yTYMP3ehqclaivrt76kFAl/E/NkTHG1rbEBwZW5n dXRyb25peC5kZQAKCRCpyVqK+u3vqREXB/93EL5RGMeI48Yni3WEk0HZadw8oelq LWooZQjkNbpzboxwy9w7PspiMfrswkADH3bpPnGnWk9StUeHKgk7T+HxhWsQn/C+ 6xkeOjTr4/qxrKMC+xmgLpML+29gOXdyXFw2FOsHYi6F+bHZWWx483JiLUBc/+SP 78TiyGSC8Y6cKkU113iPTEg/8FRqmajj/W0hbGgYdksXUPkCxQ3LK0jjt8jybCj0 ojn7wsqiB0l7nZrgL09L1v9+jgsWwbC1I1kJSOxFVXK3gEcAbV08dbIufpWd649G sx8BOa+mkLHiOLdf9KZoLbvHXa/uVS1rZcmTBThdAkUw1cTwq2GmO/zI =3YGc -----END PGP SIGNATURE----- Merge tag 'linux-can-next-for-5.11-20201130' of git://git.kernel.org/pub/scm/linux/kernel/git/mkl/linux-can-next Marc Kleine-Budde says: ==================== pull-request: can-next 2020-11-30 Gustavo A. R. Silva's patch for the pcan_usb driver fixes fall-through warnings for Clang. The next 5 patches target the mcp251xfd driver and are by Ursula Maplehurst and me. They optimizie the TEF and RX path by reducing number of SPI core requests to set the UINC bit. The remaining 8 patches target the m_can driver. The first 4 are various cleanups for the SPI binding driver (tcan4x5x) by Sean Nyekjaer, Dan Murphy and me. Followed by 4 cleanup patches by me for the m_can and m_can_platform driver. * tag 'linux-can-next-for-5.11-20201130' of git://git.kernel.org/pub/scm/linux/kernel/git/mkl/linux-can-next: can: m_can: m_can_class_unregister(): move right after m_can_class_register() can: m_can: m_can_plat_remove(): remove unneeded platform_set_drvdata() can: m_can: remove not used variable struct m_can_classdev::freq can: m_can: Kconfig: convert the into menu can: tcan4x5x: tcan4x5x_can_probe(): remove probe failed error message can: tcan4x5x: remove mram_start and reg_offset from struct tcan4x5x_priv can: tcan4x5x: rename parse_config() function can: tcan4x5x: tcan4x5x_clear_interrupts(): remove redundant return statement can: mcp251xfd: tef-path: reduce number of SPI core requests to set UINC bit can: mcp251xfd: move struct mcp251xfd_tef_ring definition can: mcp251xfd: struct mcp251xfd_priv::tef to array of length 1 can: mcp25xxfd: rx-path: reduce number of SPI core requests to set UINC bit can: mcp251xfd: mcp25xxfd_ring_alloc(): add define instead open coding the maximum number of RX objects can: pcan_usb_core: fix fall-through warnings for Clang ==================== Link: https://lore.kernel.org/r/20201130141432.278219-1-mkl@pengutronix.de Signed-off-by: Jakub Kicinski <kuba@kernel.org>
This commit is contained in:
Коммит
cb7fb043e6
|
@ -1,21 +1,21 @@
|
|||
# SPDX-License-Identifier: GPL-2.0-only
|
||||
config CAN_M_CAN
|
||||
menuconfig CAN_M_CAN
|
||||
tristate "Bosch M_CAN support"
|
||||
help
|
||||
Say Y here if you want support for Bosch M_CAN controller framework.
|
||||
This is common support for devices that embed the Bosch M_CAN IP.
|
||||
|
||||
if CAN_M_CAN
|
||||
|
||||
config CAN_M_CAN_PLATFORM
|
||||
tristate "Bosch M_CAN support for io-mapped devices"
|
||||
depends on HAS_IOMEM
|
||||
depends on CAN_M_CAN
|
||||
help
|
||||
Say Y here if you want support for IO Mapped Bosch M_CAN controller.
|
||||
This support is for devices that have the Bosch M_CAN controller
|
||||
IP embedded into the device and the IP is IO Mapped to the processor.
|
||||
|
||||
config CAN_M_CAN_TCAN4X5X
|
||||
depends on CAN_M_CAN
|
||||
depends on SPI
|
||||
select REGMAP_SPI
|
||||
tristate "TCAN4X5X M_CAN device"
|
||||
|
@ -23,3 +23,5 @@ config CAN_M_CAN_TCAN4X5X
|
|||
Say Y here if you want support for Texas Instruments TCAN4x5x
|
||||
M_CAN controller. This device is a peripheral device that uses the
|
||||
SPI bus for communication.
|
||||
|
||||
endif
|
||||
|
|
|
@ -1869,6 +1869,14 @@ pm_runtime_fail:
|
|||
}
|
||||
EXPORT_SYMBOL_GPL(m_can_class_register);
|
||||
|
||||
void m_can_class_unregister(struct m_can_classdev *m_can_dev)
|
||||
{
|
||||
unregister_candev(m_can_dev->net);
|
||||
|
||||
m_can_clk_stop(m_can_dev);
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(m_can_class_unregister);
|
||||
|
||||
int m_can_class_suspend(struct device *dev)
|
||||
{
|
||||
struct net_device *ndev = dev_get_drvdata(dev);
|
||||
|
@ -1915,14 +1923,6 @@ int m_can_class_resume(struct device *dev)
|
|||
}
|
||||
EXPORT_SYMBOL_GPL(m_can_class_resume);
|
||||
|
||||
void m_can_class_unregister(struct m_can_classdev *m_can_dev)
|
||||
{
|
||||
unregister_candev(m_can_dev->net);
|
||||
|
||||
m_can_clk_stop(m_can_dev);
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(m_can_class_unregister);
|
||||
|
||||
MODULE_AUTHOR("Dong Aisheng <b29396@freescale.com>");
|
||||
MODULE_AUTHOR("Dan Murphy <dmurphy@ti.com>");
|
||||
MODULE_LICENSE("GPL v2");
|
||||
|
|
|
@ -89,7 +89,6 @@ struct m_can_classdev {
|
|||
void *device_data;
|
||||
|
||||
int version;
|
||||
int freq;
|
||||
u32 irqstatus;
|
||||
|
||||
int pm_clock_support;
|
||||
|
|
|
@ -141,8 +141,6 @@ static int m_can_plat_remove(struct platform_device *pdev)
|
|||
|
||||
m_can_class_free_dev(mcan_class->net);
|
||||
|
||||
platform_set_drvdata(pdev, NULL);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
|
|
@ -123,10 +123,6 @@ struct tcan4x5x_priv {
|
|||
struct gpio_desc *device_wake_gpio;
|
||||
struct gpio_desc *device_state_gpio;
|
||||
struct regulator *power;
|
||||
|
||||
/* Register based ip */
|
||||
int mram_start;
|
||||
int reg_offset;
|
||||
};
|
||||
|
||||
static struct can_bittiming_const tcan4x5x_bittiming_const = {
|
||||
|
@ -260,7 +256,7 @@ static u32 tcan4x5x_read_reg(struct m_can_classdev *cdev, int reg)
|
|||
struct tcan4x5x_priv *priv = cdev->device_data;
|
||||
u32 val;
|
||||
|
||||
regmap_read(priv->regmap, priv->reg_offset + reg, &val);
|
||||
regmap_read(priv->regmap, TCAN4X5X_MCAN_OFFSET + reg, &val);
|
||||
|
||||
return val;
|
||||
}
|
||||
|
@ -270,7 +266,7 @@ static u32 tcan4x5x_read_fifo(struct m_can_classdev *cdev, int addr_offset)
|
|||
struct tcan4x5x_priv *priv = cdev->device_data;
|
||||
u32 val;
|
||||
|
||||
regmap_read(priv->regmap, priv->mram_start + addr_offset, &val);
|
||||
regmap_read(priv->regmap, TCAN4X5X_MRAM_START + addr_offset, &val);
|
||||
|
||||
return val;
|
||||
}
|
||||
|
@ -279,7 +275,7 @@ static int tcan4x5x_write_reg(struct m_can_classdev *cdev, int reg, int val)
|
|||
{
|
||||
struct tcan4x5x_priv *priv = cdev->device_data;
|
||||
|
||||
return regmap_write(priv->regmap, priv->reg_offset + reg, val);
|
||||
return regmap_write(priv->regmap, TCAN4X5X_MCAN_OFFSET + reg, val);
|
||||
}
|
||||
|
||||
static int tcan4x5x_write_fifo(struct m_can_classdev *cdev,
|
||||
|
@ -287,7 +283,7 @@ static int tcan4x5x_write_fifo(struct m_can_classdev *cdev,
|
|||
{
|
||||
struct tcan4x5x_priv *priv = cdev->device_data;
|
||||
|
||||
return regmap_write(priv->regmap, priv->mram_start + addr_offset, val);
|
||||
return regmap_write(priv->regmap, TCAN4X5X_MRAM_START + addr_offset, val);
|
||||
}
|
||||
|
||||
static int tcan4x5x_power_enable(struct regulator *reg, int enable)
|
||||
|
@ -328,12 +324,8 @@ static int tcan4x5x_clear_interrupts(struct m_can_classdev *cdev)
|
|||
if (ret)
|
||||
return ret;
|
||||
|
||||
ret = tcan4x5x_write_tcan_reg(cdev, TCAN4X5X_ERROR_STATUS,
|
||||
TCAN4X5X_CLEAR_ALL_INT);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
return ret;
|
||||
return tcan4x5x_write_tcan_reg(cdev, TCAN4X5X_ERROR_STATUS,
|
||||
TCAN4X5X_CLEAR_ALL_INT);
|
||||
}
|
||||
|
||||
static int tcan4x5x_init(struct m_can_classdev *cdev)
|
||||
|
@ -379,7 +371,7 @@ static int tcan4x5x_disable_state(struct m_can_classdev *cdev)
|
|||
TCAN4X5X_DISABLE_INH_MSK, 0x01);
|
||||
}
|
||||
|
||||
static int tcan4x5x_parse_config(struct m_can_classdev *cdev)
|
||||
static int tcan4x5x_get_gpios(struct m_can_classdev *cdev)
|
||||
{
|
||||
struct tcan4x5x_priv *tcan4x5x = cdev->device_data;
|
||||
int ret;
|
||||
|
@ -469,8 +461,6 @@ static int tcan4x5x_can_probe(struct spi_device *spi)
|
|||
goto out_m_can_class_free_dev;
|
||||
}
|
||||
|
||||
priv->reg_offset = TCAN4X5X_MCAN_OFFSET;
|
||||
priv->mram_start = TCAN4X5X_MRAM_START;
|
||||
priv->spi = spi;
|
||||
priv->mcan_dev = mcan_class;
|
||||
|
||||
|
@ -502,7 +492,7 @@ static int tcan4x5x_can_probe(struct spi_device *spi)
|
|||
if (ret)
|
||||
goto out_clk;
|
||||
|
||||
ret = tcan4x5x_parse_config(mcan_class);
|
||||
ret = tcan4x5x_get_gpios(mcan_class);
|
||||
if (ret)
|
||||
goto out_power;
|
||||
|
||||
|
@ -526,8 +516,6 @@ out_clk:
|
|||
}
|
||||
out_m_can_class_free_dev:
|
||||
m_can_class_free_dev(mcan_class->net);
|
||||
dev_err(&spi->dev, "Probe failed, err=%d\n", ret);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
|
|
@ -326,17 +326,36 @@ mcp251xfd_tx_ring_init_tx_obj(const struct mcp251xfd_priv *priv,
|
|||
|
||||
static void mcp251xfd_ring_init(struct mcp251xfd_priv *priv)
|
||||
{
|
||||
struct mcp251xfd_tef_ring *tef_ring;
|
||||
struct mcp251xfd_tx_ring *tx_ring;
|
||||
struct mcp251xfd_rx_ring *rx_ring, *prev_rx_ring = NULL;
|
||||
struct mcp251xfd_tx_obj *tx_obj;
|
||||
u32 val;
|
||||
u16 addr;
|
||||
u8 len;
|
||||
int i;
|
||||
int i, j;
|
||||
|
||||
/* TEF */
|
||||
priv->tef.head = 0;
|
||||
priv->tef.tail = 0;
|
||||
tef_ring = priv->tef;
|
||||
tef_ring->head = 0;
|
||||
tef_ring->tail = 0;
|
||||
|
||||
/* FIFO increment TEF tail pointer */
|
||||
addr = MCP251XFD_REG_TEFCON;
|
||||
val = MCP251XFD_REG_TEFCON_UINC;
|
||||
len = mcp251xfd_cmd_prepare_write_reg(priv, &tef_ring->uinc_buf,
|
||||
addr, val, val);
|
||||
|
||||
for (j = 0; j < ARRAY_SIZE(tef_ring->uinc_xfer); j++) {
|
||||
struct spi_transfer *xfer;
|
||||
|
||||
xfer = &tef_ring->uinc_xfer[j];
|
||||
xfer->tx_buf = &tef_ring->uinc_buf;
|
||||
xfer->len = len;
|
||||
xfer->cs_change = 1;
|
||||
xfer->cs_change_delay.value = 0;
|
||||
xfer->cs_change_delay.unit = SPI_DELAY_UNIT_NSECS;
|
||||
}
|
||||
|
||||
/* TX */
|
||||
tx_ring = priv->tx;
|
||||
|
@ -370,6 +389,23 @@ static void mcp251xfd_ring_init(struct mcp251xfd_priv *priv)
|
|||
prev_rx_ring->obj_num;
|
||||
|
||||
prev_rx_ring = rx_ring;
|
||||
|
||||
/* FIFO increment RX tail pointer */
|
||||
addr = MCP251XFD_REG_FIFOCON(rx_ring->fifo_nr);
|
||||
val = MCP251XFD_REG_FIFOCON_UINC;
|
||||
len = mcp251xfd_cmd_prepare_write_reg(priv, &rx_ring->uinc_buf,
|
||||
addr, val, val);
|
||||
|
||||
for (j = 0; j < ARRAY_SIZE(rx_ring->uinc_xfer); j++) {
|
||||
struct spi_transfer *xfer;
|
||||
|
||||
xfer = &rx_ring->uinc_xfer[j];
|
||||
xfer->tx_buf = &rx_ring->uinc_buf;
|
||||
xfer->len = len;
|
||||
xfer->cs_change = 1;
|
||||
xfer->cs_change_delay.value = 0;
|
||||
xfer->cs_change_delay.unit = SPI_DELAY_UNIT_NSECS;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -416,7 +452,8 @@ static int mcp251xfd_ring_alloc(struct mcp251xfd_priv *priv)
|
|||
int rx_obj_num;
|
||||
|
||||
rx_obj_num = ram_free / rx_obj_size;
|
||||
rx_obj_num = min(1 << (fls(rx_obj_num) - 1), 32);
|
||||
rx_obj_num = min(1 << (fls(rx_obj_num) - 1),
|
||||
MCP251XFD_RX_OBJ_NUM_MAX);
|
||||
|
||||
rx_ring = kzalloc(sizeof(*rx_ring) + rx_obj_size * rx_obj_num,
|
||||
GFP_KERNEL);
|
||||
|
@ -1201,7 +1238,7 @@ mcp251xfd_handle_tefif_recover(const struct mcp251xfd_priv *priv, const u32 seq)
|
|||
tef_sta & MCP251XFD_REG_TEFSTA_TEFFIF ?
|
||||
"full" : tef_sta & MCP251XFD_REG_TEFSTA_TEFNEIF ?
|
||||
"not empty" : "empty",
|
||||
seq, priv->tef.tail, priv->tef.head, tx_ring->head);
|
||||
seq, priv->tef->tail, priv->tef->head, tx_ring->head);
|
||||
|
||||
/* The Sequence Number in the TEF doesn't match our tef_tail. */
|
||||
return -EAGAIN;
|
||||
|
@ -1211,10 +1248,8 @@ static int
|
|||
mcp251xfd_handle_tefif_one(struct mcp251xfd_priv *priv,
|
||||
const struct mcp251xfd_hw_tef_obj *hw_tef_obj)
|
||||
{
|
||||
struct mcp251xfd_tx_ring *tx_ring = priv->tx;
|
||||
struct net_device_stats *stats = &priv->ndev->stats;
|
||||
u32 seq, seq_masked, tef_tail_masked;
|
||||
int err;
|
||||
|
||||
seq = FIELD_GET(MCP251XFD_OBJ_FLAGS_SEQ_MCP2518FD_MASK,
|
||||
hw_tef_obj->flags);
|
||||
|
@ -1225,7 +1260,7 @@ mcp251xfd_handle_tefif_one(struct mcp251xfd_priv *priv,
|
|||
*/
|
||||
seq_masked = seq &
|
||||
field_mask(MCP251XFD_OBJ_FLAGS_SEQ_MCP2517FD_MASK);
|
||||
tef_tail_masked = priv->tef.tail &
|
||||
tef_tail_masked = priv->tef->tail &
|
||||
field_mask(MCP251XFD_OBJ_FLAGS_SEQ_MCP2517FD_MASK);
|
||||
if (seq_masked != tef_tail_masked)
|
||||
return mcp251xfd_handle_tefif_recover(priv, seq);
|
||||
|
@ -1235,18 +1270,9 @@ mcp251xfd_handle_tefif_one(struct mcp251xfd_priv *priv,
|
|||
mcp251xfd_get_tef_tail(priv),
|
||||
hw_tef_obj->ts);
|
||||
stats->tx_packets++;
|
||||
priv->tef->tail++;
|
||||
|
||||
/* finally increment the TEF pointer */
|
||||
err = regmap_update_bits(priv->map_reg, MCP251XFD_REG_TEFCON,
|
||||
GENMASK(15, 8),
|
||||
MCP251XFD_REG_TEFCON_UINC);
|
||||
if (err)
|
||||
return err;
|
||||
|
||||
priv->tef.tail++;
|
||||
tx_ring->tail++;
|
||||
|
||||
return mcp251xfd_check_tef_tail(priv);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int mcp251xfd_tef_ring_update(struct mcp251xfd_priv *priv)
|
||||
|
@ -1263,12 +1289,12 @@ static int mcp251xfd_tef_ring_update(struct mcp251xfd_priv *priv)
|
|||
/* chip_tx_tail, is the next TX-Object send by the HW.
|
||||
* The new TEF head must be >= the old head, ...
|
||||
*/
|
||||
new_head = round_down(priv->tef.head, tx_ring->obj_num) + chip_tx_tail;
|
||||
if (new_head <= priv->tef.head)
|
||||
new_head = round_down(priv->tef->head, tx_ring->obj_num) + chip_tx_tail;
|
||||
if (new_head <= priv->tef->head)
|
||||
new_head += tx_ring->obj_num;
|
||||
|
||||
/* ... but it cannot exceed the TX head. */
|
||||
priv->tef.head = min(new_head, tx_ring->head);
|
||||
priv->tef->head = min(new_head, tx_ring->head);
|
||||
|
||||
return mcp251xfd_check_tef_tail(priv);
|
||||
}
|
||||
|
@ -1333,6 +1359,40 @@ static int mcp251xfd_handle_tefif(struct mcp251xfd_priv *priv)
|
|||
}
|
||||
|
||||
out_netif_wake_queue:
|
||||
len = i; /* number of handled goods TEFs */
|
||||
if (len) {
|
||||
struct mcp251xfd_tef_ring *ring = priv->tef;
|
||||
struct mcp251xfd_tx_ring *tx_ring = priv->tx;
|
||||
struct spi_transfer *last_xfer;
|
||||
|
||||
tx_ring->tail += len;
|
||||
|
||||
/* Increment the TEF FIFO tail pointer 'len' times in
|
||||
* a single SPI message.
|
||||
*/
|
||||
|
||||
/* Note:
|
||||
*
|
||||
* "cs_change == 1" on the last transfer results in an
|
||||
* active chip select after the complete SPI
|
||||
* message. This causes the controller to interpret
|
||||
* the next register access as data. Temporary set
|
||||
* "cs_change" of the last transfer to "0" to properly
|
||||
* deactivate the chip select at the end of the
|
||||
* message.
|
||||
*/
|
||||
last_xfer = &ring->uinc_xfer[len - 1];
|
||||
last_xfer->cs_change = 0;
|
||||
err = spi_sync_transfer(priv->spi, ring->uinc_xfer, len);
|
||||
last_xfer->cs_change = 1;
|
||||
if (err)
|
||||
return err;
|
||||
|
||||
err = mcp251xfd_check_tef_tail(priv);
|
||||
if (err)
|
||||
return err;
|
||||
}
|
||||
|
||||
mcp251xfd_ecc_tefif_successful(priv);
|
||||
|
||||
if (mcp251xfd_get_tx_free(priv->tx)) {
|
||||
|
@ -1439,13 +1499,7 @@ mcp251xfd_handle_rxif_one(struct mcp251xfd_priv *priv,
|
|||
if (err)
|
||||
stats->rx_fifo_errors++;
|
||||
|
||||
ring->tail++;
|
||||
|
||||
/* finally increment the RX pointer */
|
||||
return regmap_update_bits(priv->map_reg,
|
||||
MCP251XFD_REG_FIFOCON(ring->fifo_nr),
|
||||
GENMASK(15, 8),
|
||||
MCP251XFD_REG_FIFOCON_UINC);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static inline int
|
||||
|
@ -1477,6 +1531,8 @@ mcp251xfd_handle_rxif_ring(struct mcp251xfd_priv *priv,
|
|||
return err;
|
||||
|
||||
while ((len = mcp251xfd_get_rx_linear_len(ring))) {
|
||||
struct spi_transfer *last_xfer;
|
||||
|
||||
rx_tail = mcp251xfd_get_rx_tail(ring);
|
||||
|
||||
err = mcp251xfd_rx_obj_read(priv, ring, hw_rx_obj,
|
||||
|
@ -1491,6 +1547,28 @@ mcp251xfd_handle_rxif_ring(struct mcp251xfd_priv *priv,
|
|||
if (err)
|
||||
return err;
|
||||
}
|
||||
|
||||
/* Increment the RX FIFO tail pointer 'len' times in a
|
||||
* single SPI message.
|
||||
*/
|
||||
ring->tail += len;
|
||||
|
||||
/* Note:
|
||||
*
|
||||
* "cs_change == 1" on the last transfer results in an
|
||||
* active chip select after the complete SPI
|
||||
* message. This causes the controller to interpret
|
||||
* the next register access as data. Temporary set
|
||||
* "cs_change" of the last transfer to "0" to properly
|
||||
* deactivate the chip select at the end of the
|
||||
* message.
|
||||
*/
|
||||
last_xfer = &ring->uinc_xfer[len - 1];
|
||||
last_xfer->cs_change = 0;
|
||||
err = spi_sync_transfer(priv->spi, ring->uinc_xfer, len);
|
||||
last_xfer->cs_change = 1;
|
||||
if (err)
|
||||
return err;
|
||||
}
|
||||
|
||||
return 0;
|
||||
|
|
|
@ -368,6 +368,7 @@
|
|||
* FIFO setup: tef: 8*12 bytes = 96 bytes, tx: 8*16 bytes = 128 bytes
|
||||
* FIFO setup: tef: 4*12 bytes = 48 bytes, tx: 4*72 bytes = 288 bytes
|
||||
*/
|
||||
#define MCP251XFD_RX_OBJ_NUM_MAX 32
|
||||
#define MCP251XFD_TX_OBJ_NUM_CAN 8
|
||||
#define MCP251XFD_TX_OBJ_NUM_CANFD 4
|
||||
|
||||
|
@ -458,14 +459,6 @@ struct mcp251xfd_hw_rx_obj_canfd {
|
|||
u8 data[sizeof_field(struct canfd_frame, data)];
|
||||
};
|
||||
|
||||
struct mcp251xfd_tef_ring {
|
||||
unsigned int head;
|
||||
unsigned int tail;
|
||||
|
||||
/* u8 obj_num equals tx_ring->obj_num */
|
||||
/* u8 obj_size equals sizeof(struct mcp251xfd_hw_tef_obj) */
|
||||
};
|
||||
|
||||
struct __packed mcp251xfd_buf_cmd {
|
||||
__be16 cmd;
|
||||
};
|
||||
|
@ -505,6 +498,17 @@ struct mcp251xfd_tx_obj {
|
|||
union mcp251xfd_tx_obj_load_buf buf;
|
||||
};
|
||||
|
||||
struct mcp251xfd_tef_ring {
|
||||
unsigned int head;
|
||||
unsigned int tail;
|
||||
|
||||
/* u8 obj_num equals tx_ring->obj_num */
|
||||
/* u8 obj_size equals sizeof(struct mcp251xfd_hw_tef_obj) */
|
||||
|
||||
union mcp251xfd_write_reg_buf uinc_buf;
|
||||
struct spi_transfer uinc_xfer[MCP251XFD_TX_OBJ_NUM_MAX];
|
||||
};
|
||||
|
||||
struct mcp251xfd_tx_ring {
|
||||
unsigned int head;
|
||||
unsigned int tail;
|
||||
|
@ -527,6 +531,8 @@ struct mcp251xfd_rx_ring {
|
|||
u8 obj_num;
|
||||
u8 obj_size;
|
||||
|
||||
union mcp251xfd_write_reg_buf uinc_buf;
|
||||
struct spi_transfer uinc_xfer[MCP251XFD_RX_OBJ_NUM_MAX];
|
||||
struct mcp251xfd_hw_rx_obj_canfd obj[];
|
||||
};
|
||||
|
||||
|
@ -580,7 +586,7 @@ struct mcp251xfd_priv {
|
|||
struct spi_device *spi;
|
||||
u32 spi_max_speed_hz_orig;
|
||||
|
||||
struct mcp251xfd_tef_ring tef;
|
||||
struct mcp251xfd_tef_ring tef[1];
|
||||
struct mcp251xfd_tx_ring tx[1];
|
||||
struct mcp251xfd_rx_ring *rx[1];
|
||||
|
||||
|
@ -741,17 +747,17 @@ mcp251xfd_get_rx_obj_addr(const struct mcp251xfd_rx_ring *ring, u8 n)
|
|||
|
||||
static inline u8 mcp251xfd_get_tef_head(const struct mcp251xfd_priv *priv)
|
||||
{
|
||||
return priv->tef.head & (priv->tx->obj_num - 1);
|
||||
return priv->tef->head & (priv->tx->obj_num - 1);
|
||||
}
|
||||
|
||||
static inline u8 mcp251xfd_get_tef_tail(const struct mcp251xfd_priv *priv)
|
||||
{
|
||||
return priv->tef.tail & (priv->tx->obj_num - 1);
|
||||
return priv->tef->tail & (priv->tx->obj_num - 1);
|
||||
}
|
||||
|
||||
static inline u8 mcp251xfd_get_tef_len(const struct mcp251xfd_priv *priv)
|
||||
{
|
||||
return priv->tef.head - priv->tef.tail;
|
||||
return priv->tef->head - priv->tef->tail;
|
||||
}
|
||||
|
||||
static inline u8 mcp251xfd_get_tef_linear_len(const struct mcp251xfd_priv *priv)
|
||||
|
|
|
@ -295,15 +295,16 @@ static void peak_usb_write_bulk_callback(struct urb *urb)
|
|||
netif_trans_update(netdev);
|
||||
break;
|
||||
|
||||
default:
|
||||
if (net_ratelimit())
|
||||
netdev_err(netdev, "Tx urb aborted (%d)\n",
|
||||
urb->status);
|
||||
case -EPROTO:
|
||||
case -ENOENT:
|
||||
case -ECONNRESET:
|
||||
case -ESHUTDOWN:
|
||||
break;
|
||||
|
||||
default:
|
||||
if (net_ratelimit())
|
||||
netdev_err(netdev, "Tx urb aborted (%d)\n",
|
||||
urb->status);
|
||||
break;
|
||||
}
|
||||
|
||||
|
|
Загрузка…
Ссылка в новой задаче