Commit 4cee0fb9 authored by Jakub Kicinski's avatar Jakub Kicinski

Merge tag 'linux-can-next-for-6.4-20230327' of...

Merge tag 'linux-can-next-for-6.4-20230327' of git://git.kernel.org/pub/scm/linux/kernel/git/mkl/linux-can-next

Marc Kleine-Budde says:

====================
pull-request: can-next 2023-03-27

The first 2 patches by Geert Uytterhoeven add transceiver support and
improve the error messages in the rcar_canfd driver.

Cai Huoqing contributes 3 patches which remove a redundant call to
pci_clear_master() in the c_can, ctucanfd and kvaser_pciefd driver.

Frank Jungclaus's patch replaces the struct esd_usb_msg with a union
in the esd_usb driver to improve readability.

Markus Schneider-Pargmann contributes 5 patches to improve the
performance in the m_can driver, especially for SPI attached
controllers like the tcan4x5x.

* tag 'linux-can-next-for-6.4-20230327' of git://git.kernel.org/pub/scm/linux/kernel/git/mkl/linux-can-next:
  can: m_can: Keep interrupts enabled during peripheral read
  can: m_can: Disable unused interrupts
  can: m_can: Remove double interrupt enable
  can: m_can: Always acknowledge all interrupts
  can: m_can: Remove repeated check for is_peripheral
  can: esd_usb: Improve code readability by means of replacing struct esd_usb_msg with a union
  can: kvaser_pciefd: Remove redundant pci_clear_master
  can: ctucanfd: Remove redundant pci_clear_master
  can: c_can: Remove redundant pci_clear_master
  can: rcar_canfd: Improve error messages
  can: rcar_canfd: Add transceiver support
====================

Link: https://lore.kernel.org/r/20230327073354.1003134-1-mkl@pengutronix.deSigned-off-by: default avatarJakub Kicinski <kuba@kernel.org>
parents da954ae1 db88681c
...@@ -227,7 +227,6 @@ static int c_can_pci_probe(struct pci_dev *pdev, ...@@ -227,7 +227,6 @@ static int c_can_pci_probe(struct pci_dev *pdev,
pci_iounmap(pdev, addr); pci_iounmap(pdev, addr);
out_release_regions: out_release_regions:
pci_disable_msi(pdev); pci_disable_msi(pdev);
pci_clear_master(pdev);
pci_release_regions(pdev); pci_release_regions(pdev);
out_disable_device: out_disable_device:
pci_disable_device(pdev); pci_disable_device(pdev);
...@@ -247,7 +246,6 @@ static void c_can_pci_remove(struct pci_dev *pdev) ...@@ -247,7 +246,6 @@ static void c_can_pci_remove(struct pci_dev *pdev)
pci_iounmap(pdev, addr); pci_iounmap(pdev, addr);
pci_disable_msi(pdev); pci_disable_msi(pdev);
pci_clear_master(pdev);
pci_release_regions(pdev); pci_release_regions(pdev);
pci_disable_device(pdev); pci_disable_device(pdev);
} }
......
...@@ -206,10 +206,8 @@ static int ctucan_pci_probe(struct pci_dev *pdev, ...@@ -206,10 +206,8 @@ static int ctucan_pci_probe(struct pci_dev *pdev,
err_pci_iounmap_bar1: err_pci_iounmap_bar1:
pci_iounmap(pdev, addr); pci_iounmap(pdev, addr);
err_release_regions: err_release_regions:
if (msi_ok) { if (msi_ok)
pci_disable_msi(pdev); pci_disable_msi(pdev);
pci_clear_master(pdev);
}
pci_release_regions(pdev); pci_release_regions(pdev);
err_disable_device: err_disable_device:
pci_disable_device(pdev); pci_disable_device(pdev);
...@@ -257,10 +255,8 @@ static void ctucan_pci_remove(struct pci_dev *pdev) ...@@ -257,10 +255,8 @@ static void ctucan_pci_remove(struct pci_dev *pdev)
pci_iounmap(pdev, bdata->bar1_base); pci_iounmap(pdev, bdata->bar1_base);
if (bdata->use_msi) { if (bdata->use_msi)
pci_disable_msi(pdev); pci_disable_msi(pdev);
pci_clear_master(pdev);
}
pci_release_regions(pdev); pci_release_regions(pdev);
pci_disable_device(pdev); pci_disable_device(pdev);
......
...@@ -1907,7 +1907,6 @@ static void kvaser_pciefd_remove(struct pci_dev *pdev) ...@@ -1907,7 +1907,6 @@ static void kvaser_pciefd_remove(struct pci_dev *pdev)
free_irq(pcie->pci->irq, pcie); free_irq(pcie->pci->irq, pcie);
pci_clear_master(pdev);
pci_iounmap(pdev, pcie->reg_base); pci_iounmap(pdev, pcie->reg_base);
pci_release_regions(pdev); pci_release_regions(pdev);
pci_disable_device(pdev); pci_disable_device(pdev);
......
...@@ -972,8 +972,8 @@ static int m_can_rx_peripheral(struct net_device *dev, u32 irqstatus) ...@@ -972,8 +972,8 @@ static int m_can_rx_peripheral(struct net_device *dev, u32 irqstatus)
/* Don't re-enable interrupts if the driver had a fatal error /* Don't re-enable interrupts if the driver had a fatal error
* (e.g., FIFO read failure). * (e.g., FIFO read failure).
*/ */
if (work_done >= 0) if (work_done < 0)
m_can_enable_all_interrupts(cdev); m_can_disable_all_interrupts(cdev);
return work_done; return work_done;
} }
...@@ -1083,7 +1083,6 @@ static irqreturn_t m_can_isr(int irq, void *dev_id) ...@@ -1083,7 +1083,6 @@ static irqreturn_t m_can_isr(int irq, void *dev_id)
return IRQ_NONE; return IRQ_NONE;
/* ACK all irqs */ /* ACK all irqs */
if (ir & IR_ALL_INT)
m_can_write(cdev, M_CAN_IR, ir); m_can_write(cdev, M_CAN_IR, ir);
if (cdev->ops->clear_interrupts) if (cdev->ops->clear_interrupts)
...@@ -1096,12 +1095,13 @@ static irqreturn_t m_can_isr(int irq, void *dev_id) ...@@ -1096,12 +1095,13 @@ static irqreturn_t m_can_isr(int irq, void *dev_id)
*/ */
if ((ir & IR_RF0N) || (ir & IR_ERR_ALL_30X)) { if ((ir & IR_RF0N) || (ir & IR_ERR_ALL_30X)) {
cdev->irqstatus = ir; cdev->irqstatus = ir;
if (!cdev->is_peripheral) {
m_can_disable_all_interrupts(cdev); m_can_disable_all_interrupts(cdev);
if (!cdev->is_peripheral)
napi_schedule(&cdev->napi); napi_schedule(&cdev->napi);
else if (m_can_rx_peripheral(dev, ir) < 0) } else if (m_can_rx_peripheral(dev, ir) < 0) {
goto out_fail; goto out_fail;
} }
}
if (cdev->version == 30) { if (cdev->version == 30) {
if (ir & IR_TC) { if (ir & IR_TC) {
...@@ -1262,6 +1262,7 @@ static int m_can_set_bittiming(struct net_device *dev) ...@@ -1262,6 +1262,7 @@ static int m_can_set_bittiming(struct net_device *dev)
static int m_can_chip_config(struct net_device *dev) static int m_can_chip_config(struct net_device *dev)
{ {
struct m_can_classdev *cdev = netdev_priv(dev); struct m_can_classdev *cdev = netdev_priv(dev);
u32 interrupts = IR_ALL_INT;
u32 cccr, test; u32 cccr, test;
int err; int err;
...@@ -1271,6 +1272,11 @@ static int m_can_chip_config(struct net_device *dev) ...@@ -1271,6 +1272,11 @@ static int m_can_chip_config(struct net_device *dev)
return err; return err;
} }
/* Disable unused interrupts */
interrupts &= ~(IR_ARA | IR_ELO | IR_DRX | IR_TEFF | IR_TEFW | IR_TFE |
IR_TCF | IR_HPM | IR_RF1F | IR_RF1W | IR_RF1N |
IR_RF0F | IR_RF0W);
m_can_config_endisable(cdev, true); m_can_config_endisable(cdev, true);
/* RX Buffer/FIFO Element Size 64 bytes data field */ /* RX Buffer/FIFO Element Size 64 bytes data field */
...@@ -1365,16 +1371,13 @@ static int m_can_chip_config(struct net_device *dev) ...@@ -1365,16 +1371,13 @@ static int m_can_chip_config(struct net_device *dev)
m_can_write(cdev, M_CAN_TEST, test); m_can_write(cdev, M_CAN_TEST, test);
/* Enable interrupts */ /* Enable interrupts */
m_can_write(cdev, M_CAN_IR, IR_ALL_INT); if (!(cdev->can.ctrlmode & CAN_CTRLMODE_BERR_REPORTING)) {
if (!(cdev->can.ctrlmode & CAN_CTRLMODE_BERR_REPORTING))
if (cdev->version == 30) if (cdev->version == 30)
m_can_write(cdev, M_CAN_IE, IR_ALL_INT & interrupts &= ~(IR_ERR_LEC_30X);
~(IR_ERR_LEC_30X));
else
m_can_write(cdev, M_CAN_IE, IR_ALL_INT &
~(IR_ERR_LEC_31X));
else else
m_can_write(cdev, M_CAN_IE, IR_ALL_INT); interrupts &= ~(IR_ERR_LEC_31X);
}
m_can_write(cdev, M_CAN_IE, interrupts);
/* route all interrupts to INT0 */ /* route all interrupts to INT0 */
m_can_write(cdev, M_CAN_ILS, ILS_ALL_INT0); m_can_write(cdev, M_CAN_ILS, ILS_ALL_INT0);
...@@ -1592,10 +1595,8 @@ static int m_can_close(struct net_device *dev) ...@@ -1592,10 +1595,8 @@ static int m_can_close(struct net_device *dev)
cdev->tx_skb = NULL; cdev->tx_skb = NULL;
destroy_workqueue(cdev->tx_wq); destroy_workqueue(cdev->tx_wq);
cdev->tx_wq = NULL; cdev->tx_wq = NULL;
}
if (cdev->is_peripheral)
can_rx_offload_disable(&cdev->offload); can_rx_offload_disable(&cdev->offload);
}
close_candev(dev); close_candev(dev);
......
...@@ -35,6 +35,7 @@ ...@@ -35,6 +35,7 @@
#include <linux/netdevice.h> #include <linux/netdevice.h>
#include <linux/of.h> #include <linux/of.h>
#include <linux/of_device.h> #include <linux/of_device.h>
#include <linux/phy/phy.h>
#include <linux/platform_device.h> #include <linux/platform_device.h>
#include <linux/reset.h> #include <linux/reset.h>
#include <linux/types.h> #include <linux/types.h>
...@@ -530,6 +531,7 @@ struct rcar_canfd_channel { ...@@ -530,6 +531,7 @@ struct rcar_canfd_channel {
struct net_device *ndev; struct net_device *ndev;
struct rcar_canfd_global *gpriv; /* Controller reference */ struct rcar_canfd_global *gpriv; /* Controller reference */
void __iomem *base; /* Register base address */ void __iomem *base; /* Register base address */
struct phy *transceiver; /* Optional transceiver */
struct napi_struct napi; struct napi_struct napi;
u32 tx_head; /* Incremented on xmit */ u32 tx_head; /* Incremented on xmit */
u32 tx_tail; /* Incremented on xmit done */ u32 tx_tail; /* Incremented on xmit done */
...@@ -1413,16 +1415,22 @@ static int rcar_canfd_open(struct net_device *ndev) ...@@ -1413,16 +1415,22 @@ static int rcar_canfd_open(struct net_device *ndev)
struct rcar_canfd_global *gpriv = priv->gpriv; struct rcar_canfd_global *gpriv = priv->gpriv;
int err; int err;
err = phy_power_on(priv->transceiver);
if (err) {
netdev_err(ndev, "failed to power on PHY: %pe\n", ERR_PTR(err));
return err;
}
/* Peripheral clock is already enabled in probe */ /* Peripheral clock is already enabled in probe */
err = clk_prepare_enable(gpriv->can_clk); err = clk_prepare_enable(gpriv->can_clk);
if (err) { if (err) {
netdev_err(ndev, "failed to enable CAN clock, error %d\n", err); netdev_err(ndev, "failed to enable CAN clock: %pe\n", ERR_PTR(err));
goto out_clock; goto out_phy;
} }
err = open_candev(ndev); err = open_candev(ndev);
if (err) { if (err) {
netdev_err(ndev, "open_candev() failed, error %d\n", err); netdev_err(ndev, "open_candev() failed: %pe\n", ERR_PTR(err));
goto out_can_clock; goto out_can_clock;
} }
...@@ -1437,7 +1445,8 @@ static int rcar_canfd_open(struct net_device *ndev) ...@@ -1437,7 +1445,8 @@ static int rcar_canfd_open(struct net_device *ndev)
close_candev(ndev); close_candev(ndev);
out_can_clock: out_can_clock:
clk_disable_unprepare(gpriv->can_clk); clk_disable_unprepare(gpriv->can_clk);
out_clock: out_phy:
phy_power_off(priv->transceiver);
return err; return err;
} }
...@@ -1480,6 +1489,7 @@ static int rcar_canfd_close(struct net_device *ndev) ...@@ -1480,6 +1489,7 @@ static int rcar_canfd_close(struct net_device *ndev)
napi_disable(&priv->napi); napi_disable(&priv->napi);
clk_disable_unprepare(gpriv->can_clk); clk_disable_unprepare(gpriv->can_clk);
close_candev(ndev); close_candev(ndev);
phy_power_off(priv->transceiver);
return 0; return 0;
} }
...@@ -1711,7 +1721,7 @@ static const struct ethtool_ops rcar_canfd_ethtool_ops = { ...@@ -1711,7 +1721,7 @@ static const struct ethtool_ops rcar_canfd_ethtool_ops = {
}; };
static int rcar_canfd_channel_probe(struct rcar_canfd_global *gpriv, u32 ch, static int rcar_canfd_channel_probe(struct rcar_canfd_global *gpriv, u32 ch,
u32 fcan_freq) u32 fcan_freq, struct phy *transceiver)
{ {
const struct rcar_canfd_hw_info *info = gpriv->info; const struct rcar_canfd_hw_info *info = gpriv->info;
struct platform_device *pdev = gpriv->pdev; struct platform_device *pdev = gpriv->pdev;
...@@ -1721,10 +1731,9 @@ static int rcar_canfd_channel_probe(struct rcar_canfd_global *gpriv, u32 ch, ...@@ -1721,10 +1731,9 @@ static int rcar_canfd_channel_probe(struct rcar_canfd_global *gpriv, u32 ch,
int err = -ENODEV; int err = -ENODEV;
ndev = alloc_candev(sizeof(*priv), RCANFD_FIFO_DEPTH); ndev = alloc_candev(sizeof(*priv), RCANFD_FIFO_DEPTH);
if (!ndev) { if (!ndev)
dev_err(dev, "alloc_candev() failed\n");
return -ENOMEM; return -ENOMEM;
}
priv = netdev_priv(ndev); priv = netdev_priv(ndev);
ndev->netdev_ops = &rcar_canfd_netdev_ops; ndev->netdev_ops = &rcar_canfd_netdev_ops;
...@@ -1732,8 +1741,11 @@ static int rcar_canfd_channel_probe(struct rcar_canfd_global *gpriv, u32 ch, ...@@ -1732,8 +1741,11 @@ static int rcar_canfd_channel_probe(struct rcar_canfd_global *gpriv, u32 ch,
ndev->flags |= IFF_ECHO; ndev->flags |= IFF_ECHO;
priv->ndev = ndev; priv->ndev = ndev;
priv->base = gpriv->base; priv->base = gpriv->base;
priv->transceiver = transceiver;
priv->channel = ch; priv->channel = ch;
priv->gpriv = gpriv; priv->gpriv = gpriv;
if (transceiver)
priv->can.bitrate_max = transceiver->attrs.max_link_rate;
priv->can.clock.freq = fcan_freq; priv->can.clock.freq = fcan_freq;
dev_info(dev, "can_clk rate is %u\n", priv->can.clock.freq); dev_info(dev, "can_clk rate is %u\n", priv->can.clock.freq);
...@@ -1764,8 +1776,8 @@ static int rcar_canfd_channel_probe(struct rcar_canfd_global *gpriv, u32 ch, ...@@ -1764,8 +1776,8 @@ static int rcar_canfd_channel_probe(struct rcar_canfd_global *gpriv, u32 ch,
rcar_canfd_channel_err_interrupt, 0, rcar_canfd_channel_err_interrupt, 0,
irq_name, priv); irq_name, priv);
if (err) { if (err) {
dev_err(dev, "devm_request_irq CH Err(%d) failed, error %d\n", dev_err(dev, "devm_request_irq CH Err %d failed: %pe\n",
err_irq, err); err_irq, ERR_PTR(err));
goto fail; goto fail;
} }
irq_name = devm_kasprintf(dev, GFP_KERNEL, "canfd.ch%d_trx", irq_name = devm_kasprintf(dev, GFP_KERNEL, "canfd.ch%d_trx",
...@@ -1778,8 +1790,8 @@ static int rcar_canfd_channel_probe(struct rcar_canfd_global *gpriv, u32 ch, ...@@ -1778,8 +1790,8 @@ static int rcar_canfd_channel_probe(struct rcar_canfd_global *gpriv, u32 ch,
rcar_canfd_channel_tx_interrupt, 0, rcar_canfd_channel_tx_interrupt, 0,
irq_name, priv); irq_name, priv);
if (err) { if (err) {
dev_err(dev, "devm_request_irq Tx (%d) failed, error %d\n", dev_err(dev, "devm_request_irq Tx %d failed: %pe\n",
tx_irq, err); tx_irq, ERR_PTR(err));
goto fail; goto fail;
} }
} }
...@@ -1810,7 +1822,7 @@ static int rcar_canfd_channel_probe(struct rcar_canfd_global *gpriv, u32 ch, ...@@ -1810,7 +1822,7 @@ static int rcar_canfd_channel_probe(struct rcar_canfd_global *gpriv, u32 ch,
gpriv->ch[priv->channel] = priv; gpriv->ch[priv->channel] = priv;
err = register_candev(ndev); err = register_candev(ndev);
if (err) { if (err) {
dev_err(dev, "register_candev() failed, error %d\n", err); dev_err(dev, "register_candev() failed: %pe\n", ERR_PTR(err));
goto fail_candev; goto fail_candev;
} }
dev_info(dev, "device registered (channel %u)\n", priv->channel); dev_info(dev, "device registered (channel %u)\n", priv->channel);
...@@ -1836,6 +1848,7 @@ static void rcar_canfd_channel_remove(struct rcar_canfd_global *gpriv, u32 ch) ...@@ -1836,6 +1848,7 @@ static void rcar_canfd_channel_remove(struct rcar_canfd_global *gpriv, u32 ch)
static int rcar_canfd_probe(struct platform_device *pdev) static int rcar_canfd_probe(struct platform_device *pdev)
{ {
struct phy *transceivers[RCANFD_NUM_CHANNELS] = { 0, };
const struct rcar_canfd_hw_info *info; const struct rcar_canfd_hw_info *info;
struct device *dev = &pdev->dev; struct device *dev = &pdev->dev;
void __iomem *addr; void __iomem *addr;
...@@ -1857,9 +1870,14 @@ static int rcar_canfd_probe(struct platform_device *pdev) ...@@ -1857,9 +1870,14 @@ static int rcar_canfd_probe(struct platform_device *pdev)
for (i = 0; i < info->max_channels; ++i) { for (i = 0; i < info->max_channels; ++i) {
name[7] = '0' + i; name[7] = '0' + i;
of_child = of_get_child_by_name(dev->of_node, name); of_child = of_get_child_by_name(dev->of_node, name);
if (of_child && of_device_is_available(of_child)) if (of_child && of_device_is_available(of_child)) {
channels_mask |= BIT(i); channels_mask |= BIT(i);
transceivers[i] = devm_of_phy_optional_get(dev,
of_child, NULL);
}
of_node_put(of_child); of_node_put(of_child);
if (IS_ERR(transceivers[i]))
return PTR_ERR(transceivers[i]);
} }
if (info->shared_global_irqs) { if (info->shared_global_irqs) {
...@@ -1948,16 +1966,16 @@ static int rcar_canfd_probe(struct platform_device *pdev) ...@@ -1948,16 +1966,16 @@ static int rcar_canfd_probe(struct platform_device *pdev)
rcar_canfd_channel_interrupt, 0, rcar_canfd_channel_interrupt, 0,
"canfd.ch_int", gpriv); "canfd.ch_int", gpriv);
if (err) { if (err) {
dev_err(dev, "devm_request_irq(%d) failed, error %d\n", dev_err(dev, "devm_request_irq %d failed: %pe\n",
ch_irq, err); ch_irq, ERR_PTR(err));
goto fail_dev; goto fail_dev;
} }
err = devm_request_irq(dev, g_irq, rcar_canfd_global_interrupt, err = devm_request_irq(dev, g_irq, rcar_canfd_global_interrupt,
0, "canfd.g_int", gpriv); 0, "canfd.g_int", gpriv);
if (err) { if (err) {
dev_err(dev, "devm_request_irq(%d) failed, error %d\n", dev_err(dev, "devm_request_irq %d failed: %pe\n",
g_irq, err); g_irq, ERR_PTR(err));
goto fail_dev; goto fail_dev;
} }
} else { } else {
...@@ -1966,8 +1984,8 @@ static int rcar_canfd_probe(struct platform_device *pdev) ...@@ -1966,8 +1984,8 @@ static int rcar_canfd_probe(struct platform_device *pdev)
"canfd.g_recc", gpriv); "canfd.g_recc", gpriv);
if (err) { if (err) {
dev_err(dev, "devm_request_irq(%d) failed, error %d\n", dev_err(dev, "devm_request_irq %d failed: %pe\n",
g_recc_irq, err); g_recc_irq, ERR_PTR(err));
goto fail_dev; goto fail_dev;
} }
...@@ -1975,8 +1993,8 @@ static int rcar_canfd_probe(struct platform_device *pdev) ...@@ -1975,8 +1993,8 @@ static int rcar_canfd_probe(struct platform_device *pdev)
rcar_canfd_global_err_interrupt, 0, rcar_canfd_global_err_interrupt, 0,
"canfd.g_err", gpriv); "canfd.g_err", gpriv);
if (err) { if (err) {
dev_err(dev, "devm_request_irq(%d) failed, error %d\n", dev_err(dev, "devm_request_irq %d failed: %pe\n",
g_err_irq, err); g_err_irq, ERR_PTR(err));
goto fail_dev; goto fail_dev;
} }
} }
...@@ -1993,14 +2011,14 @@ static int rcar_canfd_probe(struct platform_device *pdev) ...@@ -1993,14 +2011,14 @@ static int rcar_canfd_probe(struct platform_device *pdev)
/* Enable peripheral clock for register access */ /* Enable peripheral clock for register access */
err = clk_prepare_enable(gpriv->clkp); err = clk_prepare_enable(gpriv->clkp);
if (err) { if (err) {
dev_err(dev, "failed to enable peripheral clock, error %d\n", dev_err(dev, "failed to enable peripheral clock: %pe\n",
err); ERR_PTR(err));
goto fail_reset; goto fail_reset;
} }
err = rcar_canfd_reset_controller(gpriv); err = rcar_canfd_reset_controller(gpriv);
if (err) { if (err) {
dev_err(dev, "reset controller failed\n"); dev_err(dev, "reset controller failed: %pe\n", ERR_PTR(err));
goto fail_clk; goto fail_clk;
} }
...@@ -2035,7 +2053,8 @@ static int rcar_canfd_probe(struct platform_device *pdev) ...@@ -2035,7 +2053,8 @@ static int rcar_canfd_probe(struct platform_device *pdev)
} }
for_each_set_bit(ch, &gpriv->channels_mask, info->max_channels) { for_each_set_bit(ch, &gpriv->channels_mask, info->max_channels) {
err = rcar_canfd_channel_probe(gpriv, ch, fcan_freq); err = rcar_canfd_channel_probe(gpriv, ch, fcan_freq,
transceivers[ch]);
if (err) if (err)
goto fail_channel; goto fail_channel;
} }
......
...@@ -174,8 +174,7 @@ struct set_baudrate_msg { ...@@ -174,8 +174,7 @@ struct set_baudrate_msg {
}; };
/* Main message type used between library and application */ /* Main message type used between library and application */
struct __packed esd_usb_msg { union __packed esd_usb_msg {
union {
struct header_msg hdr; struct header_msg hdr;
struct version_msg version; struct version_msg version;
struct version_reply_msg version_reply; struct version_reply_msg version_reply;
...@@ -184,7 +183,6 @@ struct __packed esd_usb_msg { ...@@ -184,7 +183,6 @@ struct __packed esd_usb_msg {
struct tx_done_msg txdone; struct tx_done_msg txdone;
struct set_baudrate_msg setbaud; struct set_baudrate_msg setbaud;
struct id_filter_msg filter; struct id_filter_msg filter;
} msg;
}; };
static struct usb_device_id esd_usb_table[] = { static struct usb_device_id esd_usb_table[] = {
...@@ -229,22 +227,22 @@ struct esd_usb_net_priv { ...@@ -229,22 +227,22 @@ struct esd_usb_net_priv {
}; };
static void esd_usb_rx_event(struct esd_usb_net_priv *priv, static void esd_usb_rx_event(struct esd_usb_net_priv *priv,
struct esd_usb_msg *msg) union esd_usb_msg *msg)
{ {
struct net_device_stats *stats = &priv->netdev->stats; struct net_device_stats *stats = &priv->netdev->stats;
struct can_frame *cf; struct can_frame *cf;
struct sk_buff *skb; struct sk_buff *skb;
u32 id = le32_to_cpu(msg->msg.rx.id) & ESD_IDMASK; u32 id = le32_to_cpu(msg->rx.id) & ESD_IDMASK;
if (id == ESD_EV_CAN_ERROR_EXT) { if (id == ESD_EV_CAN_ERROR_EXT) {
u8 state = msg->msg.rx.ev_can_err_ext.status; u8 state = msg->rx.ev_can_err_ext.status;
u8 ecc = msg->msg.rx.ev_can_err_ext.ecc; u8 ecc = msg->rx.ev_can_err_ext.ecc;
u8 rxerr = msg->msg.rx.ev_can_err_ext.rec; u8 rxerr = msg->rx.ev_can_err_ext.rec;
u8 txerr = msg->msg.rx.ev_can_err_ext.tec; u8 txerr = msg->rx.ev_can_err_ext.tec;
netdev_dbg(priv->netdev, netdev_dbg(priv->netdev,
"CAN_ERR_EV_EXT: dlc=%#02x state=%02x ecc=%02x rec=%02x tec=%02x\n", "CAN_ERR_EV_EXT: dlc=%#02x state=%02x ecc=%02x rec=%02x tec=%02x\n",
msg->msg.rx.dlc, state, ecc, rxerr, txerr); msg->rx.dlc, state, ecc, rxerr, txerr);
skb = alloc_can_err_skb(priv->netdev, &cf); skb = alloc_can_err_skb(priv->netdev, &cf);
...@@ -322,7 +320,7 @@ static void esd_usb_rx_event(struct esd_usb_net_priv *priv, ...@@ -322,7 +320,7 @@ static void esd_usb_rx_event(struct esd_usb_net_priv *priv,
} }
static void esd_usb_rx_can_msg(struct esd_usb_net_priv *priv, static void esd_usb_rx_can_msg(struct esd_usb_net_priv *priv,
struct esd_usb_msg *msg) union esd_usb_msg *msg)
{ {
struct net_device_stats *stats = &priv->netdev->stats; struct net_device_stats *stats = &priv->netdev->stats;
struct can_frame *cf; struct can_frame *cf;
...@@ -333,7 +331,7 @@ static void esd_usb_rx_can_msg(struct esd_usb_net_priv *priv, ...@@ -333,7 +331,7 @@ static void esd_usb_rx_can_msg(struct esd_usb_net_priv *priv,
if (!netif_device_present(priv->netdev)) if (!netif_device_present(priv->netdev))
return; return;
id = le32_to_cpu(msg->msg.rx.id); id = le32_to_cpu(msg->rx.id);
if (id & ESD_EVENT) { if (id & ESD_EVENT) {
esd_usb_rx_event(priv, msg); esd_usb_rx_event(priv, msg);
...@@ -345,17 +343,17 @@ static void esd_usb_rx_can_msg(struct esd_usb_net_priv *priv, ...@@ -345,17 +343,17 @@ static void esd_usb_rx_can_msg(struct esd_usb_net_priv *priv,
} }
cf->can_id = id & ESD_IDMASK; cf->can_id = id & ESD_IDMASK;
can_frame_set_cc_len(cf, msg->msg.rx.dlc & ~ESD_RTR, can_frame_set_cc_len(cf, msg->rx.dlc & ~ESD_RTR,
priv->can.ctrlmode); priv->can.ctrlmode);
if (id & ESD_EXTID) if (id & ESD_EXTID)
cf->can_id |= CAN_EFF_FLAG; cf->can_id |= CAN_EFF_FLAG;
if (msg->msg.rx.dlc & ESD_RTR) { if (msg->rx.dlc & ESD_RTR) {
cf->can_id |= CAN_RTR_FLAG; cf->can_id |= CAN_RTR_FLAG;
} else { } else {
for (i = 0; i < cf->len; i++) for (i = 0; i < cf->len; i++)
cf->data[i] = msg->msg.rx.data[i]; cf->data[i] = msg->rx.data[i];
stats->rx_bytes += cf->len; stats->rx_bytes += cf->len;
} }
...@@ -366,7 +364,7 @@ static void esd_usb_rx_can_msg(struct esd_usb_net_priv *priv, ...@@ -366,7 +364,7 @@ static void esd_usb_rx_can_msg(struct esd_usb_net_priv *priv,
} }
static void esd_usb_tx_done_msg(struct esd_usb_net_priv *priv, static void esd_usb_tx_done_msg(struct esd_usb_net_priv *priv,
struct esd_usb_msg *msg) union esd_usb_msg *msg)
{ {
struct net_device_stats *stats = &priv->netdev->stats; struct net_device_stats *stats = &priv->netdev->stats;
struct net_device *netdev = priv->netdev; struct net_device *netdev = priv->netdev;
...@@ -375,9 +373,9 @@ static void esd_usb_tx_done_msg(struct esd_usb_net_priv *priv, ...@@ -375,9 +373,9 @@ static void esd_usb_tx_done_msg(struct esd_usb_net_priv *priv,
if (!netif_device_present(netdev)) if (!netif_device_present(netdev))
return; return;
context = &priv->tx_contexts[msg->msg.txdone.hnd & (MAX_TX_URBS - 1)]; context = &priv->tx_contexts[msg->txdone.hnd & (MAX_TX_URBS - 1)];
if (!msg->msg.txdone.status) { if (!msg->txdone.status) {
stats->tx_packets++; stats->tx_packets++;
stats->tx_bytes += can_get_echo_skb(netdev, context->echo_index, stats->tx_bytes += can_get_echo_skb(netdev, context->echo_index,
NULL); NULL);
...@@ -417,32 +415,32 @@ static void esd_usb_read_bulk_callback(struct urb *urb) ...@@ -417,32 +415,32 @@ static void esd_usb_read_bulk_callback(struct urb *urb)
} }
while (pos < urb->actual_length) { while (pos < urb->actual_length) {
struct esd_usb_msg *msg; union esd_usb_msg *msg;
msg = (struct esd_usb_msg *)(urb->transfer_buffer + pos); msg = (union esd_usb_msg *)(urb->transfer_buffer + pos);
switch (msg->msg.hdr.cmd) { switch (msg->hdr.cmd) {
case CMD_CAN_RX: case CMD_CAN_RX:
if (msg->msg.rx.net >= dev->net_count) { if (msg->rx.net >= dev->net_count) {
dev_err(dev->udev->dev.parent, "format error\n"); dev_err(dev->udev->dev.parent, "format error\n");
break; break;
} }
esd_usb_rx_can_msg(dev->nets[msg->msg.rx.net], msg); esd_usb_rx_can_msg(dev->nets[msg->rx.net], msg);
break; break;
case CMD_CAN_TX: case CMD_CAN_TX:
if (msg->msg.txdone.net >= dev->net_count) { if (msg->txdone.net >= dev->net_count) {
dev_err(dev->udev->dev.parent, "format error\n"); dev_err(dev->udev->dev.parent, "format error\n");
break; break;
} }
esd_usb_tx_done_msg(dev->nets[msg->msg.txdone.net], esd_usb_tx_done_msg(dev->nets[msg->txdone.net],
msg); msg);
break; break;
} }
pos += msg->msg.hdr.len << 2; pos += msg->hdr.len << 2;
if (pos > urb->actual_length) { if (pos > urb->actual_length) {
dev_err(dev->udev->dev.parent, "format error\n"); dev_err(dev->udev->dev.parent, "format error\n");
...@@ -473,7 +471,7 @@ static void esd_usb_write_bulk_callback(struct urb *urb) ...@@ -473,7 +471,7 @@ static void esd_usb_write_bulk_callback(struct urb *urb)
struct esd_tx_urb_context *context = urb->context; struct esd_tx_urb_context *context = urb->context;
struct esd_usb_net_priv *priv; struct esd_usb_net_priv *priv;
struct net_device *netdev; struct net_device *netdev;
size_t size = sizeof(struct esd_usb_msg); size_t size = sizeof(union esd_usb_msg);
WARN_ON(!context); WARN_ON(!context);
...@@ -529,20 +527,20 @@ static ssize_t nets_show(struct device *d, ...@@ -529,20 +527,20 @@ static ssize_t nets_show(struct device *d,
} }
static DEVICE_ATTR_RO(nets); static DEVICE_ATTR_RO(nets);
static int esd_usb_send_msg(struct esd_usb *dev, struct esd_usb_msg *msg) static int esd_usb_send_msg(struct esd_usb *dev, union esd_usb_msg *msg)
{ {
int actual_length; int actual_length;
return usb_bulk_msg(dev->udev, return usb_bulk_msg(dev->udev,
usb_sndbulkpipe(dev->udev, 2), usb_sndbulkpipe(dev->udev, 2),
msg, msg,
msg->msg.hdr.len << 2, msg->hdr.len << 2,
&actual_length, &actual_length,
1000); 1000);
} }
static int esd_usb_wait_msg(struct esd_usb *dev, static int esd_usb_wait_msg(struct esd_usb *dev,
struct esd_usb_msg *msg) union esd_usb_msg *msg)
{ {
int actual_length; int actual_length;
...@@ -630,7 +628,7 @@ static int esd_usb_start(struct esd_usb_net_priv *priv) ...@@ -630,7 +628,7 @@ static int esd_usb_start(struct esd_usb_net_priv *priv)
{ {
struct esd_usb *dev = priv->usb; struct esd_usb *dev = priv->usb;
struct net_device *netdev = priv->netdev; struct net_device *netdev = priv->netdev;
struct esd_usb_msg *msg; union esd_usb_msg *msg;
int err, i; int err, i;
msg = kmalloc(sizeof(*msg), GFP_KERNEL); msg = kmalloc(sizeof(*msg), GFP_KERNEL);
...@@ -651,14 +649,14 @@ static int esd_usb_start(struct esd_usb_net_priv *priv) ...@@ -651,14 +649,14 @@ static int esd_usb_start(struct esd_usb_net_priv *priv)
* the number of the starting bitmask (0..64) to the filter.option * the number of the starting bitmask (0..64) to the filter.option
* field followed by only some bitmasks. * field followed by only some bitmasks.
*/ */
msg->msg.hdr.cmd = CMD_IDADD; msg->hdr.cmd = CMD_IDADD;
msg->msg.hdr.len = 2 + ESD_MAX_ID_SEGMENT; msg->hdr.len = 2 + ESD_MAX_ID_SEGMENT;
msg->msg.filter.net = priv->index; msg->filter.net = priv->index;
msg->msg.filter.option = ESD_ID_ENABLE; /* start with segment 0 */ msg->filter.option = ESD_ID_ENABLE; /* start with segment 0 */
for (i = 0; i < ESD_MAX_ID_SEGMENT; i++) for (i = 0; i < ESD_MAX_ID_SEGMENT; i++)
msg->msg.filter.mask[i] = cpu_to_le32(0xffffffff); msg->filter.mask[i] = cpu_to_le32(0xffffffff);
/* enable 29bit extended IDs */ /* enable 29bit extended IDs */
msg->msg.filter.mask[ESD_MAX_ID_SEGMENT] = cpu_to_le32(0x00000001); msg->filter.mask[ESD_MAX_ID_SEGMENT] = cpu_to_le32(0x00000001);
err = esd_usb_send_msg(dev, msg); err = esd_usb_send_msg(dev, msg);
if (err) if (err)
...@@ -734,12 +732,12 @@ static netdev_tx_t esd_usb_start_xmit(struct sk_buff *skb, ...@@ -734,12 +732,12 @@ static netdev_tx_t esd_usb_start_xmit(struct sk_buff *skb,
struct esd_tx_urb_context *context = NULL; struct esd_tx_urb_context *context = NULL;
struct net_device_stats *stats = &netdev->stats; struct net_device_stats *stats = &netdev->stats;
struct can_frame *cf = (struct can_frame *)skb->data; struct can_frame *cf = (struct can_frame *)skb->data;
struct esd_usb_msg *msg; union esd_usb_msg *msg;
struct urb *urb; struct urb *urb;
u8 *buf; u8 *buf;
int i, err; int i, err;
int ret = NETDEV_TX_OK; int ret = NETDEV_TX_OK;
size_t size = sizeof(struct esd_usb_msg); size_t size = sizeof(union esd_usb_msg);
if (can_dev_dropped_skb(netdev, skb)) if (can_dev_dropped_skb(netdev, skb))
return NETDEV_TX_OK; return NETDEV_TX_OK;
...@@ -761,24 +759,24 @@ static netdev_tx_t esd_usb_start_xmit(struct sk_buff *skb, ...@@ -761,24 +759,24 @@ static netdev_tx_t esd_usb_start_xmit(struct sk_buff *skb,
goto nobufmem; goto nobufmem;
} }
msg = (struct esd_usb_msg *)buf; msg = (union esd_usb_msg *)buf;
msg->msg.hdr.len = 3; /* minimal length */ msg->hdr.len = 3; /* minimal length */
msg->msg.hdr.cmd = CMD_CAN_TX; msg->hdr.cmd = CMD_CAN_TX;
msg->msg.tx.net = priv->index; msg->tx.net = priv->index;
msg->msg.tx.dlc = can_get_cc_dlc(cf, priv->can.ctrlmode); msg->tx.dlc = can_get_cc_dlc(cf, priv->can.ctrlmode);
msg->msg.tx.id = cpu_to_le32(cf->can_id & CAN_ERR_MASK); msg->tx.id = cpu_to_le32(cf->can_id & CAN_ERR_MASK);
if (cf->can_id & CAN_RTR_FLAG) if (cf->can_id & CAN_RTR_FLAG)
msg->msg.tx.dlc |= ESD_RTR; msg->tx.dlc |= ESD_RTR;
if (cf->can_id & CAN_EFF_FLAG) if (cf->can_id & CAN_EFF_FLAG)
msg->msg.tx.id |= cpu_to_le32(ESD_EXTID); msg->tx.id |= cpu_to_le32(ESD_EXTID);
for (i = 0; i < cf->len; i++) for (i = 0; i < cf->len; i++)
msg->msg.tx.data[i] = cf->data[i]; msg->tx.data[i] = cf->data[i];
msg->msg.hdr.len += (cf->len + 3) >> 2; msg->hdr.len += (cf->len + 3) >> 2;
for (i = 0; i < MAX_TX_URBS; i++) { for (i = 0; i < MAX_TX_URBS; i++) {
if (priv->tx_contexts[i].echo_index == MAX_TX_URBS) { if (priv->tx_contexts[i].echo_index == MAX_TX_URBS) {
...@@ -798,10 +796,10 @@ static netdev_tx_t esd_usb_start_xmit(struct sk_buff *skb, ...@@ -798,10 +796,10 @@ static netdev_tx_t esd_usb_start_xmit(struct sk_buff *skb,
context->echo_index = i; context->echo_index = i;
/* hnd must not be 0 - MSB is stripped in txdone handling */ /* hnd must not be 0 - MSB is stripped in txdone handling */
msg->msg.tx.hnd = 0x80000000 | i; /* returned in TX done message */ msg->tx.hnd = 0x80000000 | i; /* returned in TX done message */
usb_fill_bulk_urb(urb, dev->udev, usb_sndbulkpipe(dev->udev, 2), buf, usb_fill_bulk_urb(urb, dev->udev, usb_sndbulkpipe(dev->udev, 2), buf,
msg->msg.hdr.len << 2, msg->hdr.len << 2,
esd_usb_write_bulk_callback, context); esd_usb_write_bulk_callback, context);
urb->transfer_flags |= URB_NO_TRANSFER_DMA_MAP; urb->transfer_flags |= URB_NO_TRANSFER_DMA_MAP;
...@@ -855,7 +853,7 @@ static netdev_tx_t esd_usb_start_xmit(struct sk_buff *skb, ...@@ -855,7 +853,7 @@ static netdev_tx_t esd_usb_start_xmit(struct sk_buff *skb,
static int esd_usb_close(struct net_device *netdev) static int esd_usb_close(struct net_device *netdev)
{ {
struct esd_usb_net_priv *priv = netdev_priv(netdev); struct esd_usb_net_priv *priv = netdev_priv(netdev);
struct esd_usb_msg *msg; union esd_usb_msg *msg;
int i; int i;
msg = kmalloc(sizeof(*msg), GFP_KERNEL); msg = kmalloc(sizeof(*msg), GFP_KERNEL);
...@@ -863,21 +861,21 @@ static int esd_usb_close(struct net_device *netdev) ...@@ -863,21 +861,21 @@ static int esd_usb_close(struct net_device *netdev)
return -ENOMEM; return -ENOMEM;
/* Disable all IDs (see esd_usb_start()) */ /* Disable all IDs (see esd_usb_start()) */
msg->msg.hdr.cmd = CMD_IDADD; msg->hdr.cmd = CMD_IDADD;
msg->msg.hdr.len = 2 + ESD_MAX_ID_SEGMENT; msg->hdr.len = 2 + ESD_MAX_ID_SEGMENT;
msg->msg.filter.net = priv->index; msg->filter.net = priv->index;
msg->msg.filter.option = ESD_ID_ENABLE; /* start with segment 0 */ msg->filter.option = ESD_ID_ENABLE; /* start with segment 0 */
for (i = 0; i <= ESD_MAX_ID_SEGMENT; i++) for (i = 0; i <= ESD_MAX_ID_SEGMENT; i++)
msg->msg.filter.mask[i] = 0; msg->filter.mask[i] = 0;
if (esd_usb_send_msg(priv->usb, msg) < 0) if (esd_usb_send_msg(priv->usb, msg) < 0)
netdev_err(netdev, "sending idadd message failed\n"); netdev_err(netdev, "sending idadd message failed\n");
/* set CAN controller to reset mode */ /* set CAN controller to reset mode */
msg->msg.hdr.len = 2; msg->hdr.len = 2;
msg->msg.hdr.cmd = CMD_SETBAUD; msg->hdr.cmd = CMD_SETBAUD;
msg->msg.setbaud.net = priv->index; msg->setbaud.net = priv->index;
msg->msg.setbaud.rsvd = 0; msg->setbaud.rsvd = 0;
msg->msg.setbaud.baud = cpu_to_le32(ESD_USB_NO_BAUDRATE); msg->setbaud.baud = cpu_to_le32(ESD_USB_NO_BAUDRATE);
if (esd_usb_send_msg(priv->usb, msg) < 0) if (esd_usb_send_msg(priv->usb, msg) < 0)
netdev_err(netdev, "sending setbaud message failed\n"); netdev_err(netdev, "sending setbaud message failed\n");
...@@ -919,7 +917,7 @@ static int esd_usb2_set_bittiming(struct net_device *netdev) ...@@ -919,7 +917,7 @@ static int esd_usb2_set_bittiming(struct net_device *netdev)
{ {
struct esd_usb_net_priv *priv = netdev_priv(netdev); struct esd_usb_net_priv *priv = netdev_priv(netdev);
struct can_bittiming *bt = &priv->can.bittiming; struct can_bittiming *bt = &priv->can.bittiming;
struct esd_usb_msg *msg; union esd_usb_msg *msg;
int err; int err;
u32 canbtr; u32 canbtr;
int sjw_shift; int sjw_shift;
...@@ -950,11 +948,11 @@ static int esd_usb2_set_bittiming(struct net_device *netdev) ...@@ -950,11 +948,11 @@ static int esd_usb2_set_bittiming(struct net_device *netdev)
if (!msg) if (!msg)
return -ENOMEM; return -ENOMEM;
msg->msg.hdr.len = 2; msg->hdr.len = 2;
msg->msg.hdr.cmd = CMD_SETBAUD; msg->hdr.cmd = CMD_SETBAUD;
msg->msg.setbaud.net = priv->index; msg->setbaud.net = priv->index;
msg->msg.setbaud.rsvd = 0; msg->setbaud.rsvd = 0;
msg->msg.setbaud.baud = cpu_to_le32(canbtr); msg->setbaud.baud = cpu_to_le32(canbtr);
netdev_info(netdev, "setting BTR=%#x\n", canbtr); netdev_info(netdev, "setting BTR=%#x\n", canbtr);
...@@ -1065,7 +1063,7 @@ static int esd_usb_probe(struct usb_interface *intf, ...@@ -1065,7 +1063,7 @@ static int esd_usb_probe(struct usb_interface *intf,
const struct usb_device_id *id) const struct usb_device_id *id)
{ {
struct esd_usb *dev; struct esd_usb *dev;
struct esd_usb_msg *msg; union esd_usb_msg *msg;
int i, err; int i, err;
dev = kzalloc(sizeof(*dev), GFP_KERNEL); dev = kzalloc(sizeof(*dev), GFP_KERNEL);
...@@ -1087,11 +1085,11 @@ static int esd_usb_probe(struct usb_interface *intf, ...@@ -1087,11 +1085,11 @@ static int esd_usb_probe(struct usb_interface *intf,
} }
/* query number of CAN interfaces (nets) */ /* query number of CAN interfaces (nets) */
msg->msg.hdr.cmd = CMD_VERSION; msg->hdr.cmd = CMD_VERSION;
msg->msg.hdr.len = 2; msg->hdr.len = 2;
msg->msg.version.rsvd = 0; msg->version.rsvd = 0;
msg->msg.version.flags = 0; msg->version.flags = 0;
msg->msg.version.drv_version = 0; msg->version.drv_version = 0;
err = esd_usb_send_msg(dev, msg); err = esd_usb_send_msg(dev, msg);
if (err < 0) { if (err < 0) {
...@@ -1105,8 +1103,8 @@ static int esd_usb_probe(struct usb_interface *intf, ...@@ -1105,8 +1103,8 @@ static int esd_usb_probe(struct usb_interface *intf,
goto free_msg; goto free_msg;
} }
dev->net_count = (int)msg->msg.version_reply.nets; dev->net_count = (int)msg->version_reply.nets;
dev->version = le32_to_cpu(msg->msg.version_reply.version); dev->version = le32_to_cpu(msg->version_reply.version);
if (device_create_file(&intf->dev, &dev_attr_firmware)) if (device_create_file(&intf->dev, &dev_attr_firmware))
dev_err(&intf->dev, dev_err(&intf->dev,
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment