Commit 13441ed6 authored by Marc Kleine-Budde's avatar Marc Kleine-Budde

Merge patch series "can: kvaser_usb: Fixes and improvements"

Jimmy Assarsson <extja@kvaser.com> says:

Split v4 series, since it got rejected [1]. This part only contains
non-critical fixes and improvements.

Note: This series depend on changes in [2].

Changes in v5:
 - Split v4 series, since it got rejected [1].
   This part only contains non-critical fixes and improvements.

Changes in v4: https://lore.kernel.org/all/20220903182344.139-1-extja@kvaser.com
 - Add Tested-by: Anssi Hannula to
   [PATCH v4 04/15] can: kvaser_usb: kvaser_usb_leaf: Get capabilities from device
 - Update commit message in
   [PATCH v4 04/15] can: kvaser_usb: kvaser_usb_leaf: Get capabilities from device

Changes in v3: https://lore.kernel.org/all/20220901122729.271-1-extja@kvaser.com
 - Rebase on top of commit
   1d5eeda2 ("can: kvaser_usb: advertise timestamping capabilities and add ioctl support")
 - Add Tested-by: Anssi Hannula
 - Add stable@vger.kernel.org to CC.
 - Add my S-o-b to all patches
 - Fix regression introduced in
   [PATCH v2 04/15] can: kvaser_usb: kvaser_usb_leaf: Get capabilities from device
   found by Anssi Hannula
   https://lore.kernel.org/all/b25bc059-d776-146d-0b3c-41aecf4bd9f8@bitwise.fi

v2: https://lore.kernel.org/all/20220708115709.232815-1-extja@kvaser.com

v1: https://lore.kernel.org/all/20220516134748.3724796-1-anssi.hannula@bitwise.fi

[1] https://lore.kernel.org/all/20220920122246.00dbe946@kernel.org
[2] https://lore.kernel.org/all/20221010150829.199676-1-extja@kvaser.com

Link: https://lore.kernel.org/all/20221010185237.319219-1-extja@kvaser.com
[mkl: move "1/1 can: kvaser_usb: Fix possible completions during init_completion" to linux-can tree]
[mkl: improve change log, update links]
Signed-off-by: default avatarMarc Kleine-Budde <mkl@pengutronix.de>
parents a6375fd7 39d3df6b
...@@ -76,6 +76,14 @@ struct kvaser_usb_tx_urb_context { ...@@ -76,6 +76,14 @@ struct kvaser_usb_tx_urb_context {
u32 echo_index; u32 echo_index;
}; };
struct kvaser_usb_busparams {
__le32 bitrate;
u8 tseg1;
u8 tseg2;
u8 sjw;
u8 nsamples;
} __packed;
struct kvaser_usb { struct kvaser_usb {
struct usb_device *udev; struct usb_device *udev;
struct usb_interface *intf; struct usb_interface *intf;
...@@ -104,13 +112,19 @@ struct kvaser_usb_net_priv { ...@@ -104,13 +112,19 @@ struct kvaser_usb_net_priv {
struct can_priv can; struct can_priv can;
struct can_berr_counter bec; struct can_berr_counter bec;
/* subdriver-specific data */
void *sub_priv;
struct kvaser_usb *dev; struct kvaser_usb *dev;
struct net_device *netdev; struct net_device *netdev;
int channel; int channel;
struct completion start_comp, stop_comp, flush_comp; struct completion start_comp, stop_comp, flush_comp,
get_busparams_comp;
struct usb_anchor tx_submitted; struct usb_anchor tx_submitted;
struct kvaser_usb_busparams busparams_nominal, busparams_data;
spinlock_t tx_contexts_lock; /* lock for active_tx_contexts */ spinlock_t tx_contexts_lock; /* lock for active_tx_contexts */
int active_tx_contexts; int active_tx_contexts;
struct kvaser_usb_tx_urb_context tx_contexts[]; struct kvaser_usb_tx_urb_context tx_contexts[];
...@@ -120,11 +134,15 @@ struct kvaser_usb_net_priv { ...@@ -120,11 +134,15 @@ struct kvaser_usb_net_priv {
* struct kvaser_usb_dev_ops - Device specific functions * struct kvaser_usb_dev_ops - Device specific functions
* @dev_set_mode: used for can.do_set_mode * @dev_set_mode: used for can.do_set_mode
* @dev_set_bittiming: used for can.do_set_bittiming * @dev_set_bittiming: used for can.do_set_bittiming
* @dev_get_busparams: readback arbitration busparams
* @dev_set_data_bittiming: used for can.do_set_data_bittiming * @dev_set_data_bittiming: used for can.do_set_data_bittiming
* @dev_get_data_busparams: readback data busparams
* @dev_get_berr_counter: used for can.do_get_berr_counter * @dev_get_berr_counter: used for can.do_get_berr_counter
* *
* @dev_setup_endpoints: setup USB in and out endpoints * @dev_setup_endpoints: setup USB in and out endpoints
* @dev_init_card: initialize card * @dev_init_card: initialize card
* @dev_init_channel: initialize channel
* @dev_remove_channel: uninitialize channel
* @dev_get_software_info: get software info * @dev_get_software_info: get software info
* @dev_get_software_details: get software details * @dev_get_software_details: get software details
* @dev_get_card_info: get card info * @dev_get_card_info: get card info
...@@ -140,12 +158,18 @@ struct kvaser_usb_net_priv { ...@@ -140,12 +158,18 @@ struct kvaser_usb_net_priv {
*/ */
struct kvaser_usb_dev_ops { struct kvaser_usb_dev_ops {
int (*dev_set_mode)(struct net_device *netdev, enum can_mode mode); int (*dev_set_mode)(struct net_device *netdev, enum can_mode mode);
int (*dev_set_bittiming)(struct net_device *netdev); int (*dev_set_bittiming)(const struct net_device *netdev,
int (*dev_set_data_bittiming)(struct net_device *netdev); const struct kvaser_usb_busparams *busparams);
int (*dev_get_busparams)(struct kvaser_usb_net_priv *priv);
int (*dev_set_data_bittiming)(const struct net_device *netdev,
const struct kvaser_usb_busparams *busparams);
int (*dev_get_data_busparams)(struct kvaser_usb_net_priv *priv);
int (*dev_get_berr_counter)(const struct net_device *netdev, int (*dev_get_berr_counter)(const struct net_device *netdev,
struct can_berr_counter *bec); struct can_berr_counter *bec);
int (*dev_setup_endpoints)(struct kvaser_usb *dev); int (*dev_setup_endpoints)(struct kvaser_usb *dev);
int (*dev_init_card)(struct kvaser_usb *dev); int (*dev_init_card)(struct kvaser_usb *dev);
int (*dev_init_channel)(struct kvaser_usb_net_priv *priv);
void (*dev_remove_channel)(struct kvaser_usb_net_priv *priv);
int (*dev_get_software_info)(struct kvaser_usb *dev); int (*dev_get_software_info)(struct kvaser_usb *dev);
int (*dev_get_software_details)(struct kvaser_usb *dev); int (*dev_get_software_details)(struct kvaser_usb *dev);
int (*dev_get_card_info)(struct kvaser_usb *dev); int (*dev_get_card_info)(struct kvaser_usb *dev);
......
...@@ -440,10 +440,6 @@ static int kvaser_usb_open(struct net_device *netdev) ...@@ -440,10 +440,6 @@ static int kvaser_usb_open(struct net_device *netdev)
if (err) if (err)
return err; return err;
err = kvaser_usb_setup_rx_urbs(dev);
if (err)
goto error;
err = ops->dev_set_opt_mode(priv); err = ops->dev_set_opt_mode(priv);
if (err) if (err)
goto error; goto error;
...@@ -534,6 +530,93 @@ static int kvaser_usb_close(struct net_device *netdev) ...@@ -534,6 +530,93 @@ static int kvaser_usb_close(struct net_device *netdev)
return 0; return 0;
} }
static int kvaser_usb_set_bittiming(struct net_device *netdev)
{
struct kvaser_usb_net_priv *priv = netdev_priv(netdev);
struct kvaser_usb *dev = priv->dev;
const struct kvaser_usb_dev_ops *ops = dev->driver_info->ops;
struct can_bittiming *bt = &priv->can.bittiming;
struct kvaser_usb_busparams busparams;
int tseg1 = bt->prop_seg + bt->phase_seg1;
int tseg2 = bt->phase_seg2;
int sjw = bt->sjw;
int err = -EOPNOTSUPP;
busparams.bitrate = cpu_to_le32(bt->bitrate);
busparams.sjw = (u8)sjw;
busparams.tseg1 = (u8)tseg1;
busparams.tseg2 = (u8)tseg2;
if (priv->can.ctrlmode & CAN_CTRLMODE_3_SAMPLES)
busparams.nsamples = 3;
else
busparams.nsamples = 1;
err = ops->dev_set_bittiming(netdev, &busparams);
if (err)
return err;
err = kvaser_usb_setup_rx_urbs(priv->dev);
if (err)
return err;
err = ops->dev_get_busparams(priv);
if (err) {
/* Treat EOPNOTSUPP as success */
if (err == -EOPNOTSUPP)
err = 0;
return err;
}
if (memcmp(&busparams, &priv->busparams_nominal,
sizeof(priv->busparams_nominal)) != 0)
err = -EINVAL;
return err;
}
static int kvaser_usb_set_data_bittiming(struct net_device *netdev)
{
struct kvaser_usb_net_priv *priv = netdev_priv(netdev);
struct kvaser_usb *dev = priv->dev;
const struct kvaser_usb_dev_ops *ops = dev->driver_info->ops;
struct can_bittiming *dbt = &priv->can.data_bittiming;
struct kvaser_usb_busparams busparams;
int tseg1 = dbt->prop_seg + dbt->phase_seg1;
int tseg2 = dbt->phase_seg2;
int sjw = dbt->sjw;
int err;
if (!ops->dev_set_data_bittiming ||
!ops->dev_get_data_busparams)
return -EOPNOTSUPP;
busparams.bitrate = cpu_to_le32(dbt->bitrate);
busparams.sjw = (u8)sjw;
busparams.tseg1 = (u8)tseg1;
busparams.tseg2 = (u8)tseg2;
busparams.nsamples = 1;
err = ops->dev_set_data_bittiming(netdev, &busparams);
if (err)
return err;
err = kvaser_usb_setup_rx_urbs(priv->dev);
if (err)
return err;
err = ops->dev_get_data_busparams(priv);
if (err)
return err;
if (memcmp(&busparams, &priv->busparams_data,
sizeof(priv->busparams_data)) != 0)
err = -EINVAL;
return err;
}
static void kvaser_usb_write_bulk_callback(struct urb *urb) static void kvaser_usb_write_bulk_callback(struct urb *urb)
{ {
struct kvaser_usb_tx_urb_context *context = urb->context; struct kvaser_usb_tx_urb_context *context = urb->context;
...@@ -684,6 +767,7 @@ static const struct ethtool_ops kvaser_usb_ethtool_ops_hwts = { ...@@ -684,6 +767,7 @@ static const struct ethtool_ops kvaser_usb_ethtool_ops_hwts = {
static void kvaser_usb_remove_interfaces(struct kvaser_usb *dev) static void kvaser_usb_remove_interfaces(struct kvaser_usb *dev)
{ {
const struct kvaser_usb_dev_ops *ops = dev->driver_info->ops;
int i; int i;
for (i = 0; i < dev->nchannels; i++) { for (i = 0; i < dev->nchannels; i++) {
...@@ -699,6 +783,9 @@ static void kvaser_usb_remove_interfaces(struct kvaser_usb *dev) ...@@ -699,6 +783,9 @@ static void kvaser_usb_remove_interfaces(struct kvaser_usb *dev)
if (!dev->nets[i]) if (!dev->nets[i])
continue; continue;
if (ops->dev_remove_channel)
ops->dev_remove_channel(dev->nets[i]);
free_candev(dev->nets[i]->netdev); free_candev(dev->nets[i]->netdev);
} }
} }
...@@ -730,6 +817,7 @@ static int kvaser_usb_init_one(struct kvaser_usb *dev, int channel) ...@@ -730,6 +817,7 @@ static int kvaser_usb_init_one(struct kvaser_usb *dev, int channel)
init_completion(&priv->start_comp); init_completion(&priv->start_comp);
init_completion(&priv->stop_comp); init_completion(&priv->stop_comp);
init_completion(&priv->flush_comp); init_completion(&priv->flush_comp);
init_completion(&priv->get_busparams_comp);
priv->can.ctrlmode_supported = 0; priv->can.ctrlmode_supported = 0;
priv->dev = dev; priv->dev = dev;
...@@ -742,7 +830,7 @@ static int kvaser_usb_init_one(struct kvaser_usb *dev, int channel) ...@@ -742,7 +830,7 @@ static int kvaser_usb_init_one(struct kvaser_usb *dev, int channel)
priv->can.state = CAN_STATE_STOPPED; priv->can.state = CAN_STATE_STOPPED;
priv->can.clock.freq = dev->cfg->clock.freq; priv->can.clock.freq = dev->cfg->clock.freq;
priv->can.bittiming_const = dev->cfg->bittiming_const; priv->can.bittiming_const = dev->cfg->bittiming_const;
priv->can.do_set_bittiming = ops->dev_set_bittiming; priv->can.do_set_bittiming = kvaser_usb_set_bittiming;
priv->can.do_set_mode = ops->dev_set_mode; priv->can.do_set_mode = ops->dev_set_mode;
if ((driver_info->quirks & KVASER_USB_QUIRK_HAS_TXRX_ERRORS) || if ((driver_info->quirks & KVASER_USB_QUIRK_HAS_TXRX_ERRORS) ||
(priv->dev->card_data.capabilities & KVASER_USB_CAP_BERR_CAP)) (priv->dev->card_data.capabilities & KVASER_USB_CAP_BERR_CAP))
...@@ -754,7 +842,7 @@ static int kvaser_usb_init_one(struct kvaser_usb *dev, int channel) ...@@ -754,7 +842,7 @@ static int kvaser_usb_init_one(struct kvaser_usb *dev, int channel)
if (priv->can.ctrlmode_supported & CAN_CTRLMODE_FD) { if (priv->can.ctrlmode_supported & CAN_CTRLMODE_FD) {
priv->can.data_bittiming_const = dev->cfg->data_bittiming_const; priv->can.data_bittiming_const = dev->cfg->data_bittiming_const;
priv->can.do_set_data_bittiming = ops->dev_set_data_bittiming; priv->can.do_set_data_bittiming = kvaser_usb_set_data_bittiming;
} }
netdev->flags |= IFF_ECHO; netdev->flags |= IFF_ECHO;
...@@ -772,17 +860,26 @@ static int kvaser_usb_init_one(struct kvaser_usb *dev, int channel) ...@@ -772,17 +860,26 @@ static int kvaser_usb_init_one(struct kvaser_usb *dev, int channel)
dev->nets[channel] = priv; dev->nets[channel] = priv;
if (ops->dev_init_channel) {
err = ops->dev_init_channel(priv);
if (err)
goto err;
}
err = register_candev(netdev); err = register_candev(netdev);
if (err) { if (err) {
dev_err(&dev->intf->dev, "Failed to register CAN device\n"); dev_err(&dev->intf->dev, "Failed to register CAN device\n");
free_candev(netdev); goto err;
dev->nets[channel] = NULL;
return err;
} }
netdev_dbg(netdev, "device registered\n"); netdev_dbg(netdev, "device registered\n");
return 0; return 0;
err:
free_candev(netdev);
dev->nets[channel] = NULL;
return err;
} }
static int kvaser_usb_probe(struct usb_interface *intf, static int kvaser_usb_probe(struct usb_interface *intf,
......
...@@ -45,6 +45,8 @@ static const struct kvaser_usb_dev_cfg kvaser_usb_hydra_dev_cfg_rt; ...@@ -45,6 +45,8 @@ static const struct kvaser_usb_dev_cfg kvaser_usb_hydra_dev_cfg_rt;
/* Minihydra command IDs */ /* Minihydra command IDs */
#define CMD_SET_BUSPARAMS_REQ 16 #define CMD_SET_BUSPARAMS_REQ 16
#define CMD_GET_BUSPARAMS_REQ 17
#define CMD_GET_BUSPARAMS_RESP 18
#define CMD_GET_CHIP_STATE_REQ 19 #define CMD_GET_CHIP_STATE_REQ 19
#define CMD_CHIP_STATE_EVENT 20 #define CMD_CHIP_STATE_EVENT 20
#define CMD_SET_DRIVERMODE_REQ 21 #define CMD_SET_DRIVERMODE_REQ 21
...@@ -196,21 +198,26 @@ struct kvaser_cmd_chip_state_event { ...@@ -196,21 +198,26 @@ struct kvaser_cmd_chip_state_event {
#define KVASER_USB_HYDRA_BUS_MODE_CANFD_ISO 0x01 #define KVASER_USB_HYDRA_BUS_MODE_CANFD_ISO 0x01
#define KVASER_USB_HYDRA_BUS_MODE_NONISO 0x02 #define KVASER_USB_HYDRA_BUS_MODE_NONISO 0x02
struct kvaser_cmd_set_busparams { struct kvaser_cmd_set_busparams {
__le32 bitrate; struct kvaser_usb_busparams busparams_nominal;
u8 tseg1;
u8 tseg2;
u8 sjw;
u8 nsamples;
u8 reserved0[4]; u8 reserved0[4];
__le32 bitrate_d; struct kvaser_usb_busparams busparams_data;
u8 tseg1_d;
u8 tseg2_d;
u8 sjw_d;
u8 nsamples_d;
u8 canfd_mode; u8 canfd_mode;
u8 reserved1[7]; u8 reserved1[7];
} __packed; } __packed;
/* Busparam type */
#define KVASER_USB_HYDRA_BUSPARAM_TYPE_CAN 0x00
#define KVASER_USB_HYDRA_BUSPARAM_TYPE_CANFD 0x01
struct kvaser_cmd_get_busparams_req {
u8 type;
u8 reserved[27];
} __packed;
struct kvaser_cmd_get_busparams_res {
struct kvaser_usb_busparams busparams;
u8 reserved[20];
} __packed;
/* Ctrl modes */ /* Ctrl modes */
#define KVASER_USB_HYDRA_CTRLMODE_NORMAL 0x01 #define KVASER_USB_HYDRA_CTRLMODE_NORMAL 0x01
#define KVASER_USB_HYDRA_CTRLMODE_LISTEN 0x02 #define KVASER_USB_HYDRA_CTRLMODE_LISTEN 0x02
...@@ -281,6 +288,8 @@ struct kvaser_cmd { ...@@ -281,6 +288,8 @@ struct kvaser_cmd {
struct kvaser_cmd_error_event error_event; struct kvaser_cmd_error_event error_event;
struct kvaser_cmd_set_busparams set_busparams_req; struct kvaser_cmd_set_busparams set_busparams_req;
struct kvaser_cmd_get_busparams_req get_busparams_req;
struct kvaser_cmd_get_busparams_res get_busparams_res;
struct kvaser_cmd_chip_state_event chip_state_event; struct kvaser_cmd_chip_state_event chip_state_event;
...@@ -363,6 +372,10 @@ struct kvaser_cmd_ext { ...@@ -363,6 +372,10 @@ struct kvaser_cmd_ext {
} __packed; } __packed;
} __packed; } __packed;
struct kvaser_usb_net_hydra_priv {
int pending_get_busparams_type;
};
static const struct can_bittiming_const kvaser_usb_hydra_kcan_bittiming_c = { static const struct can_bittiming_const kvaser_usb_hydra_kcan_bittiming_c = {
.name = "kvaser_usb_kcan", .name = "kvaser_usb_kcan",
.tseg1_min = 1, .tseg1_min = 1,
...@@ -840,6 +853,39 @@ static void kvaser_usb_hydra_flush_queue_reply(const struct kvaser_usb *dev, ...@@ -840,6 +853,39 @@ static void kvaser_usb_hydra_flush_queue_reply(const struct kvaser_usb *dev,
complete(&priv->flush_comp); complete(&priv->flush_comp);
} }
static void kvaser_usb_hydra_get_busparams_reply(const struct kvaser_usb *dev,
const struct kvaser_cmd *cmd)
{
struct kvaser_usb_net_priv *priv;
struct kvaser_usb_net_hydra_priv *hydra;
priv = kvaser_usb_hydra_net_priv_from_cmd(dev, cmd);
if (!priv)
return;
hydra = priv->sub_priv;
if (!hydra)
return;
switch (hydra->pending_get_busparams_type) {
case KVASER_USB_HYDRA_BUSPARAM_TYPE_CAN:
memcpy(&priv->busparams_nominal, &cmd->get_busparams_res.busparams,
sizeof(priv->busparams_nominal));
break;
case KVASER_USB_HYDRA_BUSPARAM_TYPE_CANFD:
memcpy(&priv->busparams_data, &cmd->get_busparams_res.busparams,
sizeof(priv->busparams_nominal));
break;
default:
dev_warn(&dev->intf->dev, "Unknown get_busparams_type %d\n",
hydra->pending_get_busparams_type);
break;
}
hydra->pending_get_busparams_type = -1;
complete(&priv->get_busparams_comp);
}
static void static void
kvaser_usb_hydra_bus_status_to_can_state(const struct kvaser_usb_net_priv *priv, kvaser_usb_hydra_bus_status_to_can_state(const struct kvaser_usb_net_priv *priv,
u8 bus_status, u8 bus_status,
...@@ -1326,6 +1372,10 @@ static void kvaser_usb_hydra_handle_cmd_std(const struct kvaser_usb *dev, ...@@ -1326,6 +1372,10 @@ static void kvaser_usb_hydra_handle_cmd_std(const struct kvaser_usb *dev,
kvaser_usb_hydra_state_event(dev, cmd); kvaser_usb_hydra_state_event(dev, cmd);
break; break;
case CMD_GET_BUSPARAMS_RESP:
kvaser_usb_hydra_get_busparams_reply(dev, cmd);
break;
case CMD_ERROR_EVENT: case CMD_ERROR_EVENT:
kvaser_usb_hydra_error_event(dev, cmd); kvaser_usb_hydra_error_event(dev, cmd);
break; break;
...@@ -1522,15 +1572,58 @@ static int kvaser_usb_hydra_set_mode(struct net_device *netdev, ...@@ -1522,15 +1572,58 @@ static int kvaser_usb_hydra_set_mode(struct net_device *netdev,
return err; return err;
} }
static int kvaser_usb_hydra_set_bittiming(struct net_device *netdev) static int kvaser_usb_hydra_get_busparams(struct kvaser_usb_net_priv *priv,
int busparams_type)
{
struct kvaser_usb *dev = priv->dev;
struct kvaser_usb_net_hydra_priv *hydra = priv->sub_priv;
struct kvaser_cmd *cmd;
int err;
if (!hydra)
return -EINVAL;
cmd = kcalloc(1, sizeof(struct kvaser_cmd), GFP_KERNEL);
if (!cmd)
return -ENOMEM;
cmd->header.cmd_no = CMD_GET_BUSPARAMS_REQ;
kvaser_usb_hydra_set_cmd_dest_he
(cmd, dev->card_data.hydra.channel_to_he[priv->channel]);
kvaser_usb_hydra_set_cmd_transid
(cmd, kvaser_usb_hydra_get_next_transid(dev));
cmd->get_busparams_req.type = busparams_type;
hydra->pending_get_busparams_type = busparams_type;
reinit_completion(&priv->get_busparams_comp);
err = kvaser_usb_send_cmd(dev, cmd, kvaser_usb_hydra_cmd_size(cmd));
if (err)
return err;
if (!wait_for_completion_timeout(&priv->get_busparams_comp,
msecs_to_jiffies(KVASER_USB_TIMEOUT)))
return -ETIMEDOUT;
return err;
}
static int kvaser_usb_hydra_get_nominal_busparams(struct kvaser_usb_net_priv *priv)
{
return kvaser_usb_hydra_get_busparams(priv, KVASER_USB_HYDRA_BUSPARAM_TYPE_CAN);
}
static int kvaser_usb_hydra_get_data_busparams(struct kvaser_usb_net_priv *priv)
{
return kvaser_usb_hydra_get_busparams(priv, KVASER_USB_HYDRA_BUSPARAM_TYPE_CANFD);
}
static int kvaser_usb_hydra_set_bittiming(const struct net_device *netdev,
const struct kvaser_usb_busparams *busparams)
{ {
struct kvaser_cmd *cmd; struct kvaser_cmd *cmd;
struct kvaser_usb_net_priv *priv = netdev_priv(netdev); struct kvaser_usb_net_priv *priv = netdev_priv(netdev);
struct can_bittiming *bt = &priv->can.bittiming;
struct kvaser_usb *dev = priv->dev; struct kvaser_usb *dev = priv->dev;
int tseg1 = bt->prop_seg + bt->phase_seg1;
int tseg2 = bt->phase_seg2;
int sjw = bt->sjw;
int err; int err;
cmd = kzalloc(sizeof(*cmd), GFP_KERNEL); cmd = kzalloc(sizeof(*cmd), GFP_KERNEL);
...@@ -1538,11 +1631,8 @@ static int kvaser_usb_hydra_set_bittiming(struct net_device *netdev) ...@@ -1538,11 +1631,8 @@ static int kvaser_usb_hydra_set_bittiming(struct net_device *netdev)
return -ENOMEM; return -ENOMEM;
cmd->header.cmd_no = CMD_SET_BUSPARAMS_REQ; cmd->header.cmd_no = CMD_SET_BUSPARAMS_REQ;
cmd->set_busparams_req.bitrate = cpu_to_le32(bt->bitrate); memcpy(&cmd->set_busparams_req.busparams_nominal, busparams,
cmd->set_busparams_req.sjw = (u8)sjw; sizeof(cmd->set_busparams_req.busparams_nominal));
cmd->set_busparams_req.tseg1 = (u8)tseg1;
cmd->set_busparams_req.tseg2 = (u8)tseg2;
cmd->set_busparams_req.nsamples = 1;
kvaser_usb_hydra_set_cmd_dest_he kvaser_usb_hydra_set_cmd_dest_he
(cmd, dev->card_data.hydra.channel_to_he[priv->channel]); (cmd, dev->card_data.hydra.channel_to_he[priv->channel]);
...@@ -1556,15 +1646,12 @@ static int kvaser_usb_hydra_set_bittiming(struct net_device *netdev) ...@@ -1556,15 +1646,12 @@ static int kvaser_usb_hydra_set_bittiming(struct net_device *netdev)
return err; return err;
} }
static int kvaser_usb_hydra_set_data_bittiming(struct net_device *netdev) static int kvaser_usb_hydra_set_data_bittiming(const struct net_device *netdev,
const struct kvaser_usb_busparams *busparams)
{ {
struct kvaser_cmd *cmd; struct kvaser_cmd *cmd;
struct kvaser_usb_net_priv *priv = netdev_priv(netdev); struct kvaser_usb_net_priv *priv = netdev_priv(netdev);
struct can_bittiming *dbt = &priv->can.data_bittiming;
struct kvaser_usb *dev = priv->dev; struct kvaser_usb *dev = priv->dev;
int tseg1 = dbt->prop_seg + dbt->phase_seg1;
int tseg2 = dbt->phase_seg2;
int sjw = dbt->sjw;
int err; int err;
cmd = kzalloc(sizeof(*cmd), GFP_KERNEL); cmd = kzalloc(sizeof(*cmd), GFP_KERNEL);
...@@ -1572,11 +1659,8 @@ static int kvaser_usb_hydra_set_data_bittiming(struct net_device *netdev) ...@@ -1572,11 +1659,8 @@ static int kvaser_usb_hydra_set_data_bittiming(struct net_device *netdev)
return -ENOMEM; return -ENOMEM;
cmd->header.cmd_no = CMD_SET_BUSPARAMS_FD_REQ; cmd->header.cmd_no = CMD_SET_BUSPARAMS_FD_REQ;
cmd->set_busparams_req.bitrate_d = cpu_to_le32(dbt->bitrate); memcpy(&cmd->set_busparams_req.busparams_data, busparams,
cmd->set_busparams_req.sjw_d = (u8)sjw; sizeof(cmd->set_busparams_req.busparams_data));
cmd->set_busparams_req.tseg1_d = (u8)tseg1;
cmd->set_busparams_req.tseg2_d = (u8)tseg2;
cmd->set_busparams_req.nsamples_d = 1;
if (priv->can.ctrlmode & CAN_CTRLMODE_FD) { if (priv->can.ctrlmode & CAN_CTRLMODE_FD) {
if (priv->can.ctrlmode & CAN_CTRLMODE_FD_NON_ISO) if (priv->can.ctrlmode & CAN_CTRLMODE_FD_NON_ISO)
...@@ -1683,6 +1767,19 @@ static int kvaser_usb_hydra_init_card(struct kvaser_usb *dev) ...@@ -1683,6 +1767,19 @@ static int kvaser_usb_hydra_init_card(struct kvaser_usb *dev)
return 0; return 0;
} }
static int kvaser_usb_hydra_init_channel(struct kvaser_usb_net_priv *priv)
{
struct kvaser_usb_net_hydra_priv *hydra;
hydra = devm_kzalloc(&priv->dev->intf->dev, sizeof(*hydra), GFP_KERNEL);
if (!hydra)
return -ENOMEM;
priv->sub_priv = hydra;
return 0;
}
static int kvaser_usb_hydra_get_software_info(struct kvaser_usb *dev) static int kvaser_usb_hydra_get_software_info(struct kvaser_usb *dev)
{ {
struct kvaser_cmd cmd; struct kvaser_cmd cmd;
...@@ -2027,10 +2124,13 @@ kvaser_usb_hydra_frame_to_cmd(const struct kvaser_usb_net_priv *priv, ...@@ -2027,10 +2124,13 @@ kvaser_usb_hydra_frame_to_cmd(const struct kvaser_usb_net_priv *priv,
const struct kvaser_usb_dev_ops kvaser_usb_hydra_dev_ops = { const struct kvaser_usb_dev_ops kvaser_usb_hydra_dev_ops = {
.dev_set_mode = kvaser_usb_hydra_set_mode, .dev_set_mode = kvaser_usb_hydra_set_mode,
.dev_set_bittiming = kvaser_usb_hydra_set_bittiming, .dev_set_bittiming = kvaser_usb_hydra_set_bittiming,
.dev_get_busparams = kvaser_usb_hydra_get_nominal_busparams,
.dev_set_data_bittiming = kvaser_usb_hydra_set_data_bittiming, .dev_set_data_bittiming = kvaser_usb_hydra_set_data_bittiming,
.dev_get_data_busparams = kvaser_usb_hydra_get_data_busparams,
.dev_get_berr_counter = kvaser_usb_hydra_get_berr_counter, .dev_get_berr_counter = kvaser_usb_hydra_get_berr_counter,
.dev_setup_endpoints = kvaser_usb_hydra_setup_endpoints, .dev_setup_endpoints = kvaser_usb_hydra_setup_endpoints,
.dev_init_card = kvaser_usb_hydra_init_card, .dev_init_card = kvaser_usb_hydra_init_card,
.dev_init_channel = kvaser_usb_hydra_init_channel,
.dev_get_software_info = kvaser_usb_hydra_get_software_info, .dev_get_software_info = kvaser_usb_hydra_get_software_info,
.dev_get_software_details = kvaser_usb_hydra_get_software_details, .dev_get_software_details = kvaser_usb_hydra_get_software_details,
.dev_get_card_info = kvaser_usb_hydra_get_card_info, .dev_get_card_info = kvaser_usb_hydra_get_card_info,
......
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