mirror of
https://github.com/Fishwaldo/Star64_linux.git
synced 2025-06-29 10:01:25 +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
4 changed files with 142 additions and 11 deletions
|
@ -279,25 +279,45 @@ static int can_fixup_bittiming(struct net_device *dev, struct can_bittiming *bt,
|
||||||
return 0;
|
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,
|
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;
|
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
|
* Depending on the given can_bittiming parameter structure the CAN
|
||||||
* timing parameters are calculated based on the provided bitrate OR
|
* timing parameters are calculated based on the provided bitrate OR
|
||||||
* alternatively the CAN timing parameters (tq, prop_seg, etc.) are
|
* alternatively the CAN timing parameters (tq, prop_seg, etc.) are
|
||||||
* provided directly which are then checked and fixed up.
|
* 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);
|
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);
|
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
|
else
|
||||||
err = -EINVAL;
|
err = -EINVAL;
|
||||||
|
|
||||||
|
@ -872,8 +892,20 @@ static int can_changelink(struct net_device *dev,
|
||||||
/* Do not allow changing bittiming while running */
|
/* Do not allow changing bittiming while running */
|
||||||
if (dev->flags & IFF_UP)
|
if (dev->flags & IFF_UP)
|
||||||
return -EBUSY;
|
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));
|
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)
|
if (err)
|
||||||
return err;
|
return err;
|
||||||
memcpy(&priv->bittiming, &bt, sizeof(bt));
|
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 */
|
/* Do not allow changing bittiming while running */
|
||||||
if (dev->flags & IFF_UP)
|
if (dev->flags & IFF_UP)
|
||||||
return -EBUSY;
|
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]),
|
memcpy(&dbt, nla_data(data[IFLA_CAN_DATA_BITTIMING]),
|
||||||
sizeof(dbt));
|
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)
|
if (err)
|
||||||
return err;
|
return err;
|
||||||
memcpy(&priv->data_bittiming, &dbt, sizeof(dbt));
|
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;
|
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));
|
size += nla_total_size(sizeof(struct can_bittiming));
|
||||||
if (priv->data_bittiming_const) /* IFLA_CAN_DATA_BITTIMING_CONST */
|
if (priv->data_bittiming_const) /* IFLA_CAN_DATA_BITTIMING_CONST */
|
||||||
size += nla_total_size(sizeof(struct can_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;
|
return size;
|
||||||
}
|
}
|
||||||
|
@ -1018,7 +1097,28 @@ static int can_fill_info(struct sk_buff *skb, const struct net_device *dev)
|
||||||
(priv->data_bittiming_const &&
|
(priv->data_bittiming_const &&
|
||||||
nla_put(skb, IFLA_CAN_DATA_BITTIMING_CONST,
|
nla_put(skb, IFLA_CAN_DATA_BITTIMING_CONST,
|
||||||
sizeof(*priv->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 -EMSGSIZE;
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
|
@ -1073,6 +1173,22 @@ static struct rtnl_link_ops can_link_ops __read_mostly = {
|
||||||
*/
|
*/
|
||||||
int register_candev(struct net_device *dev)
|
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;
|
dev->rtnl_link_ops = &can_link_ops;
|
||||||
return register_netdev(dev);
|
return register_netdev(dev);
|
||||||
}
|
}
|
||||||
|
|
|
@ -310,7 +310,7 @@ pcmcia_bad:
|
||||||
pcmcia_failed:
|
pcmcia_failed:
|
||||||
pcmcia_disable_device(pcmcia);
|
pcmcia_disable_device(pcmcia);
|
||||||
pcmcia->priv = NULL;
|
pcmcia->priv = NULL;
|
||||||
return ret ?: -ENODEV;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
static const struct pcmcia_device_id softingcs_ids[] = {
|
static const struct pcmcia_device_id softingcs_ids[] = {
|
||||||
|
|
|
@ -38,6 +38,13 @@ struct can_priv {
|
||||||
struct can_bittiming bittiming, data_bittiming;
|
struct can_bittiming bittiming, data_bittiming;
|
||||||
const struct can_bittiming_const *bittiming_const,
|
const struct can_bittiming_const *bittiming_const,
|
||||||
*data_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;
|
struct can_clock clock;
|
||||||
|
|
||||||
enum can_state state;
|
enum can_state state;
|
||||||
|
@ -53,6 +60,7 @@ struct can_priv {
|
||||||
int (*do_set_bittiming)(struct net_device *dev);
|
int (*do_set_bittiming)(struct net_device *dev);
|
||||||
int (*do_set_data_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_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,
|
int (*do_get_state)(const struct net_device *dev,
|
||||||
enum can_state *state);
|
enum can_state *state);
|
||||||
int (*do_get_berr_counter)(const struct net_device *dev,
|
int (*do_get_berr_counter)(const struct net_device *dev,
|
||||||
|
|
|
@ -127,9 +127,16 @@ enum {
|
||||||
IFLA_CAN_BERR_COUNTER,
|
IFLA_CAN_BERR_COUNTER,
|
||||||
IFLA_CAN_DATA_BITTIMING,
|
IFLA_CAN_DATA_BITTIMING,
|
||||||
IFLA_CAN_DATA_BITTIMING_CONST,
|
IFLA_CAN_DATA_BITTIMING_CONST,
|
||||||
|
IFLA_CAN_TERMINATION,
|
||||||
|
IFLA_CAN_TERMINATION_CONST,
|
||||||
|
IFLA_CAN_BITRATE_CONST,
|
||||||
|
IFLA_CAN_DATA_BITRATE_CONST,
|
||||||
__IFLA_CAN_MAX
|
__IFLA_CAN_MAX
|
||||||
};
|
};
|
||||||
|
|
||||||
#define IFLA_CAN_MAX (__IFLA_CAN_MAX - 1)
|
#define IFLA_CAN_MAX (__IFLA_CAN_MAX - 1)
|
||||||
|
|
||||||
|
/* u16 termination range: 1..65535 Ohms */
|
||||||
|
#define CAN_TERMINATION_DISABLED 0
|
||||||
|
|
||||||
#endif /* !_UAPI_CAN_NETLINK_H */
|
#endif /* !_UAPI_CAN_NETLINK_H */
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue