mirror of
https://github.com/torvalds/linux.git
synced 2024-12-21 10:31:54 +00:00
linux-can-next-for-4.11-20170124
-----BEGIN PGP SIGNATURE----- iQFHBAABCgAxFiEES2FAuYbJvAGobdVQPTuqJaypJWoFAliHTm8THG1rbEBwZW5n dXRyb25peC5kZQAKCRA9O6olrKklajYkB/wOJxby2DFi4ukCPyrTpXtkQWmXa6+M Wr/nY5PBg88JipQ+u3rl6bW9NMF3U3xtPO6I/ezfn1jfWOTg0jVIecEfqlW8JNAU 275IOaiQ7jYgGEo+ALUAv2kSe7Fl8HQyaq+9ugMkWUTdv5Vjay1GZgCzyKZzjM8q 8UOoB1YsXlB9f230HPMLeHcbGHqHCOpfNk9yWNcbd0Up6U7EweXtK4Pf/L8g+bL1 0LR1QHRoUtmivuIi96KhB7O/+w8WuigWRy7qkfGpFescZQWOHzbwCVHlZ9ZYCOnJ eGEP8koksJuMg4OoEUCv0k2v3Txnfr8YNC5MvNdQ06YmoBWwQeamCozL =fBeU -----END PGP SIGNATURE----- Merge tag 'linux-can-next-for-4.11-20170124' of git://git.kernel.org/pub/scm/linux/kernel/git/mkl/linux-can-next Marc Kleine-Budde says: ==================== pull-request: can-next 2017-01-24 this is a pull request of 4 patches for net-next/master. The first patch by Oliver Hartkopp adds a netlink API to configure the interface termination of a CAN card. The next two patches are by me and add a netlink API to query and configure CAN interfaces that only support fixed bitrates. The last patch by Colin Ian King simplifies the return path in the softing_cs driver's softingcs_probe() function. ==================== Signed-off-by: David S. Miller <davem@davemloft.net>
This commit is contained in:
commit
a00ebc464d
@ -279,25 +279,45 @@ static int can_fixup_bittiming(struct net_device *dev, struct can_bittiming *bt,
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* Checks the validity of predefined bitrate settings */
|
||||
static int can_validate_bitrate(struct net_device *dev, struct can_bittiming *bt,
|
||||
const u32 *bitrate_const,
|
||||
const unsigned int bitrate_const_cnt)
|
||||
{
|
||||
struct can_priv *priv = netdev_priv(dev);
|
||||
unsigned int i;
|
||||
|
||||
for (i = 0; i < bitrate_const_cnt; i++) {
|
||||
if (bt->bitrate == bitrate_const[i])
|
||||
break;
|
||||
}
|
||||
|
||||
if (i >= priv->bitrate_const_cnt)
|
||||
return -EINVAL;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int can_get_bittiming(struct net_device *dev, struct can_bittiming *bt,
|
||||
const struct can_bittiming_const *btc)
|
||||
const struct can_bittiming_const *btc,
|
||||
const u32 *bitrate_const,
|
||||
const unsigned int bitrate_const_cnt)
|
||||
{
|
||||
int err;
|
||||
|
||||
/* Check if the CAN device has bit-timing parameters */
|
||||
if (!btc)
|
||||
return -EOPNOTSUPP;
|
||||
|
||||
/*
|
||||
* Depending on the given can_bittiming parameter structure the CAN
|
||||
* timing parameters are calculated based on the provided bitrate OR
|
||||
* alternatively the CAN timing parameters (tq, prop_seg, etc.) are
|
||||
* provided directly which are then checked and fixed up.
|
||||
*/
|
||||
if (!bt->tq && bt->bitrate)
|
||||
if (!bt->tq && bt->bitrate && btc)
|
||||
err = can_calc_bittiming(dev, bt, btc);
|
||||
else if (bt->tq && !bt->bitrate)
|
||||
else if (bt->tq && !bt->bitrate && btc)
|
||||
err = can_fixup_bittiming(dev, bt, btc);
|
||||
else if (!bt->tq && bt->bitrate && bitrate_const)
|
||||
err = can_validate_bitrate(dev, bt, bitrate_const,
|
||||
bitrate_const_cnt);
|
||||
else
|
||||
err = -EINVAL;
|
||||
|
||||
@ -872,8 +892,20 @@ static int can_changelink(struct net_device *dev,
|
||||
/* Do not allow changing bittiming while running */
|
||||
if (dev->flags & IFF_UP)
|
||||
return -EBUSY;
|
||||
|
||||
/* Calculate bittiming parameters based on
|
||||
* bittiming_const if set, otherwise pass bitrate
|
||||
* directly via do_set_bitrate(). Bail out if neither
|
||||
* is given.
|
||||
*/
|
||||
if (!priv->bittiming_const && !priv->do_set_bittiming)
|
||||
return -EOPNOTSUPP;
|
||||
|
||||
memcpy(&bt, nla_data(data[IFLA_CAN_BITTIMING]), sizeof(bt));
|
||||
err = can_get_bittiming(dev, &bt, priv->bittiming_const);
|
||||
err = can_get_bittiming(dev, &bt,
|
||||
priv->bittiming_const,
|
||||
priv->bitrate_const,
|
||||
priv->bitrate_const_cnt);
|
||||
if (err)
|
||||
return err;
|
||||
memcpy(&priv->bittiming, &bt, sizeof(bt));
|
||||
@ -943,9 +975,21 @@ static int can_changelink(struct net_device *dev,
|
||||
/* Do not allow changing bittiming while running */
|
||||
if (dev->flags & IFF_UP)
|
||||
return -EBUSY;
|
||||
|
||||
/* Calculate bittiming parameters based on
|
||||
* data_bittiming_const if set, otherwise pass bitrate
|
||||
* directly via do_set_bitrate(). Bail out if neither
|
||||
* is given.
|
||||
*/
|
||||
if (!priv->data_bittiming_const && !priv->do_set_data_bittiming)
|
||||
return -EOPNOTSUPP;
|
||||
|
||||
memcpy(&dbt, nla_data(data[IFLA_CAN_DATA_BITTIMING]),
|
||||
sizeof(dbt));
|
||||
err = can_get_bittiming(dev, &dbt, priv->data_bittiming_const);
|
||||
err = can_get_bittiming(dev, &dbt,
|
||||
priv->data_bittiming_const,
|
||||
priv->data_bitrate_const,
|
||||
priv->data_bitrate_const_cnt);
|
||||
if (err)
|
||||
return err;
|
||||
memcpy(&priv->data_bittiming, &dbt, sizeof(dbt));
|
||||
@ -958,6 +1002,30 @@ static int can_changelink(struct net_device *dev,
|
||||
}
|
||||
}
|
||||
|
||||
if (data[IFLA_CAN_TERMINATION]) {
|
||||
const u16 termval = nla_get_u16(data[IFLA_CAN_TERMINATION]);
|
||||
const unsigned int num_term = priv->termination_const_cnt;
|
||||
unsigned int i;
|
||||
|
||||
if (!priv->do_set_termination)
|
||||
return -EOPNOTSUPP;
|
||||
|
||||
/* check whether given value is supported by the interface */
|
||||
for (i = 0; i < num_term; i++) {
|
||||
if (termval == priv->termination_const[i])
|
||||
break;
|
||||
}
|
||||
if (i >= num_term)
|
||||
return -EINVAL;
|
||||
|
||||
/* Finally, set the termination value */
|
||||
err = priv->do_set_termination(dev, termval);
|
||||
if (err)
|
||||
return err;
|
||||
|
||||
priv->termination = termval;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
@ -980,6 +1048,17 @@ static size_t can_get_size(const struct net_device *dev)
|
||||
size += nla_total_size(sizeof(struct can_bittiming));
|
||||
if (priv->data_bittiming_const) /* IFLA_CAN_DATA_BITTIMING_CONST */
|
||||
size += nla_total_size(sizeof(struct can_bittiming_const));
|
||||
if (priv->termination_const) {
|
||||
size += nla_total_size(sizeof(priv->termination)); /* IFLA_CAN_TERMINATION */
|
||||
size += nla_total_size(sizeof(*priv->termination_const) * /* IFLA_CAN_TERMINATION_CONST */
|
||||
priv->termination_const_cnt);
|
||||
}
|
||||
if (priv->bitrate_const) /* IFLA_CAN_BITRATE_CONST */
|
||||
size += nla_total_size(sizeof(*priv->bitrate_const) *
|
||||
priv->bitrate_const_cnt);
|
||||
if (priv->data_bitrate_const) /* IFLA_CAN_DATA_BITRATE_CONST */
|
||||
size += nla_total_size(sizeof(*priv->data_bitrate_const) *
|
||||
priv->data_bitrate_const_cnt);
|
||||
|
||||
return size;
|
||||
}
|
||||
@ -1018,7 +1097,28 @@ static int can_fill_info(struct sk_buff *skb, const struct net_device *dev)
|
||||
(priv->data_bittiming_const &&
|
||||
nla_put(skb, IFLA_CAN_DATA_BITTIMING_CONST,
|
||||
sizeof(*priv->data_bittiming_const),
|
||||
priv->data_bittiming_const)))
|
||||
priv->data_bittiming_const)) ||
|
||||
|
||||
(priv->termination_const &&
|
||||
(nla_put_u16(skb, IFLA_CAN_TERMINATION, priv->termination) ||
|
||||
nla_put(skb, IFLA_CAN_TERMINATION_CONST,
|
||||
sizeof(*priv->termination_const) *
|
||||
priv->termination_const_cnt,
|
||||
priv->termination_const))) ||
|
||||
|
||||
(priv->bitrate_const &&
|
||||
nla_put(skb, IFLA_CAN_BITRATE_CONST,
|
||||
sizeof(*priv->bitrate_const) *
|
||||
priv->bitrate_const_cnt,
|
||||
priv->bitrate_const)) ||
|
||||
|
||||
(priv->data_bitrate_const &&
|
||||
nla_put(skb, IFLA_CAN_DATA_BITRATE_CONST,
|
||||
sizeof(*priv->data_bitrate_const) *
|
||||
priv->data_bitrate_const_cnt,
|
||||
priv->data_bitrate_const))
|
||||
)
|
||||
|
||||
return -EMSGSIZE;
|
||||
|
||||
return 0;
|
||||
@ -1073,6 +1173,22 @@ static struct rtnl_link_ops can_link_ops __read_mostly = {
|
||||
*/
|
||||
int register_candev(struct net_device *dev)
|
||||
{
|
||||
struct can_priv *priv = netdev_priv(dev);
|
||||
|
||||
/* Ensure termination_const, termination_const_cnt and
|
||||
* do_set_termination consistency. All must be either set or
|
||||
* unset.
|
||||
*/
|
||||
if ((!priv->termination_const != !priv->termination_const_cnt) ||
|
||||
(!priv->termination_const != !priv->do_set_termination))
|
||||
return -EINVAL;
|
||||
|
||||
if (!priv->bitrate_const != !priv->bitrate_const_cnt)
|
||||
return -EINVAL;
|
||||
|
||||
if (!priv->data_bitrate_const != !priv->data_bitrate_const_cnt)
|
||||
return -EINVAL;
|
||||
|
||||
dev->rtnl_link_ops = &can_link_ops;
|
||||
return register_netdev(dev);
|
||||
}
|
||||
|
@ -310,7 +310,7 @@ pcmcia_bad:
|
||||
pcmcia_failed:
|
||||
pcmcia_disable_device(pcmcia);
|
||||
pcmcia->priv = NULL;
|
||||
return ret ?: -ENODEV;
|
||||
return ret;
|
||||
}
|
||||
|
||||
static const struct pcmcia_device_id softingcs_ids[] = {
|
||||
|
@ -38,6 +38,13 @@ struct can_priv {
|
||||
struct can_bittiming bittiming, data_bittiming;
|
||||
const struct can_bittiming_const *bittiming_const,
|
||||
*data_bittiming_const;
|
||||
const u16 *termination_const;
|
||||
unsigned int termination_const_cnt;
|
||||
u16 termination;
|
||||
const u32 *bitrate_const;
|
||||
unsigned int bitrate_const_cnt;
|
||||
const u32 *data_bitrate_const;
|
||||
unsigned int data_bitrate_const_cnt;
|
||||
struct can_clock clock;
|
||||
|
||||
enum can_state state;
|
||||
@ -53,6 +60,7 @@ struct can_priv {
|
||||
int (*do_set_bittiming)(struct net_device *dev);
|
||||
int (*do_set_data_bittiming)(struct net_device *dev);
|
||||
int (*do_set_mode)(struct net_device *dev, enum can_mode mode);
|
||||
int (*do_set_termination)(struct net_device *dev, u16 term);
|
||||
int (*do_get_state)(const struct net_device *dev,
|
||||
enum can_state *state);
|
||||
int (*do_get_berr_counter)(const struct net_device *dev,
|
||||
|
@ -127,9 +127,16 @@ enum {
|
||||
IFLA_CAN_BERR_COUNTER,
|
||||
IFLA_CAN_DATA_BITTIMING,
|
||||
IFLA_CAN_DATA_BITTIMING_CONST,
|
||||
IFLA_CAN_TERMINATION,
|
||||
IFLA_CAN_TERMINATION_CONST,
|
||||
IFLA_CAN_BITRATE_CONST,
|
||||
IFLA_CAN_DATA_BITRATE_CONST,
|
||||
__IFLA_CAN_MAX
|
||||
};
|
||||
|
||||
#define IFLA_CAN_MAX (__IFLA_CAN_MAX - 1)
|
||||
|
||||
/* u16 termination range: 1..65535 Ohms */
|
||||
#define CAN_TERMINATION_DISABLED 0
|
||||
|
||||
#endif /* !_UAPI_CAN_NETLINK_H */
|
||||
|
Loading…
Reference in New Issue
Block a user