Compare commits
No commits in common. "7158af4b7302e5b3f32ae4e72ac3ca1b17f062ef" and "4841b2863c1ad0a70e9d8d9334f82997195f6b2e" have entirely different histories.
7158af4b73
...
4841b2863c
159
intrepid.c
159
intrepid.c
|
|
@ -57,8 +57,8 @@
|
||||||
|
|
||||||
#define KO_DESC "Netdevice driver for Intrepid CAN/Ethernet devices"
|
#define KO_DESC "Netdevice driver for Intrepid CAN/Ethernet devices"
|
||||||
#define KO_MAJOR 3
|
#define KO_MAJOR 3
|
||||||
#define KO_MINOR 1
|
#define KO_MINOR 0
|
||||||
#define KO_PATCH 0
|
#define KO_PATCH 4
|
||||||
#define KO_VERSION str(KO_MAJOR) "." str(KO_MINOR) "." str(KO_PATCH)
|
#define KO_VERSION str(KO_MAJOR) "." str(KO_MINOR) "." str(KO_PATCH)
|
||||||
#define KO_VERSION_INT (KO_MAJOR << 16) | (KO_MINOR << 8) | KO_PATCH
|
#define KO_VERSION_INT (KO_MAJOR << 16) | (KO_MINOR << 8) | KO_PATCH
|
||||||
|
|
||||||
|
|
@ -86,7 +86,6 @@ MODULE_VERSION(KO_VERSION);
|
||||||
#define SIOCGMAXIFACES 0x3007
|
#define SIOCGMAXIFACES 0x3007
|
||||||
#define SIOCGVERSION 0x3008
|
#define SIOCGVERSION 0x3008
|
||||||
#define SIOCGCLIENTVEROK 0x3009
|
#define SIOCGCLIENTVEROK 0x3009
|
||||||
#define SIOCSBAUDRATE 0x300A
|
|
||||||
|
|
||||||
/* This is true until we have Ethernet support
|
/* This is true until we have Ethernet support
|
||||||
* It is used to stop the netif queues before we have to return NETDEV_TX_BUSY
|
* It is used to stop the netif queues before we have to return NETDEV_TX_BUSY
|
||||||
|
|
@ -109,18 +108,15 @@ struct intrepid_pending_tx_info {
|
||||||
};
|
};
|
||||||
|
|
||||||
struct intrepid_netdevice {
|
struct intrepid_netdevice {
|
||||||
struct can_priv can;
|
|
||||||
struct net_device *dev;
|
struct net_device *dev;
|
||||||
spinlock_t lock;
|
spinlock_t lock;
|
||||||
int is_stopped;
|
int is_stopped;
|
||||||
unsigned char *from_user;
|
unsigned char *from_user;
|
||||||
uint8_t tx_idx;
|
uint8_t tx_idx;
|
||||||
int bitrate_changed;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
static int is_open;
|
static int is_open;
|
||||||
static int major_number;
|
static int major_number;
|
||||||
static int client_version;
|
|
||||||
static unsigned char *shared_mem;
|
static unsigned char *shared_mem;
|
||||||
static struct class *intrepid_dev_class;
|
static struct class *intrepid_dev_class;
|
||||||
static struct device *intrepid_dev;
|
static struct device *intrepid_dev;
|
||||||
|
|
@ -421,68 +417,6 @@ static int intrepid_remove_can_if(int index)
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int intrepid_set_bittiming(struct net_device *netdev)
|
|
||||||
{
|
|
||||||
struct intrepid_netdevice *dev = netdev_priv(netdev);
|
|
||||||
struct can_bittiming *bt = &dev->can.bittiming;
|
|
||||||
|
|
||||||
dev_dbg(&netdev->dev, "bitrate %d sample_point %d tq %d sjw %d phase1 %d phase2 %d prop %d brp %d",
|
|
||||||
bt->bitrate, bt->sample_point, bt->tq, bt->sjw, bt->phase_seg1, bt->phase_seg2, bt->prop_seg, bt->brp);
|
|
||||||
|
|
||||||
dev->bitrate_changed = 1;
|
|
||||||
wake_up_interruptible(&tx_wait);
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
static int intrepid_set_data_bittiming(struct net_device *netdev)
|
|
||||||
{
|
|
||||||
struct intrepid_netdevice *dev = netdev_priv(netdev);
|
|
||||||
struct can_bittiming *bt = &dev->can.data_bittiming;
|
|
||||||
|
|
||||||
dev_dbg(&netdev->dev, "bitrate %d sample_point %d tq %d sjw %d phase1 %d phase2 %d prop %d brp %d",
|
|
||||||
bt->bitrate, bt->sample_point, bt->tq, bt->sjw, bt->phase_seg1, bt->phase_seg2, bt->prop_seg, bt->brp);
|
|
||||||
|
|
||||||
dev->bitrate_changed = 1;
|
|
||||||
wake_up_interruptible(&tx_wait);
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
static int intrepid_bitrates[] = {
|
|
||||||
20000,
|
|
||||||
33000,
|
|
||||||
50000,
|
|
||||||
62000,
|
|
||||||
83000,
|
|
||||||
100000,
|
|
||||||
125000,
|
|
||||||
250000,
|
|
||||||
500000,
|
|
||||||
666000,
|
|
||||||
800000,
|
|
||||||
1000000
|
|
||||||
};
|
|
||||||
|
|
||||||
static int intrepid_data_bitrates[] = {
|
|
||||||
20000,
|
|
||||||
33000,
|
|
||||||
50000,
|
|
||||||
62000,
|
|
||||||
83000,
|
|
||||||
100000,
|
|
||||||
125000,
|
|
||||||
250000,
|
|
||||||
500000,
|
|
||||||
666000,
|
|
||||||
800000,
|
|
||||||
1000000,
|
|
||||||
2000000,
|
|
||||||
4000000,
|
|
||||||
5000000,
|
|
||||||
6667000,
|
|
||||||
8000000,
|
|
||||||
10000000
|
|
||||||
};
|
|
||||||
|
|
||||||
static int intrepid_add_can_if(struct intrepid_netdevice **result, const char *requestedName)
|
static int intrepid_add_can_if(struct intrepid_netdevice **result, const char *requestedName)
|
||||||
{
|
{
|
||||||
// The `requestedName` parameter is always NULL if KERNEL_SUPPORTS_ALIASES is false
|
// The `requestedName` parameter is always NULL if KERNEL_SUPPORTS_ALIASES is false
|
||||||
|
|
@ -538,17 +472,6 @@ static int intrepid_add_can_if(struct intrepid_netdevice **result, const char *r
|
||||||
ics->from_user = GET_RX_BOX(i); /* incoming rx messages */
|
ics->from_user = GET_RX_BOX(i); /* incoming rx messages */
|
||||||
ics->tx_idx = 0;
|
ics->tx_idx = 0;
|
||||||
|
|
||||||
if (VER_MIN_FROM_INT(client_version) > 1) {
|
|
||||||
ics->can.bitrate_const = intrepid_bitrates;
|
|
||||||
ics->can.bitrate_const_cnt = ARRAY_SIZE(intrepid_bitrates);
|
|
||||||
ics->can.data_bitrate_const = intrepid_data_bitrates;
|
|
||||||
ics->can.data_bitrate_const_cnt = ARRAY_SIZE(intrepid_data_bitrates);
|
|
||||||
ics->can.do_set_bittiming = intrepid_set_bittiming;
|
|
||||||
ics->can.do_set_data_bittiming = intrepid_set_data_bittiming;
|
|
||||||
}
|
|
||||||
ics->can.state = CAN_STATE_ERROR_ACTIVE;
|
|
||||||
ics->can.ctrlmode_supported = CAN_CTRLMODE_FD;
|
|
||||||
|
|
||||||
spin_lock_init(&ics->lock);
|
spin_lock_init(&ics->lock);
|
||||||
|
|
||||||
ret = register_candev(dev);
|
ret = register_candev(dev);
|
||||||
|
|
@ -1022,22 +945,6 @@ static long intrepid_dev_ioctl(struct file *fp, unsigned int cmd, unsigned long
|
||||||
case SIOCSREMOVECANIF:
|
case SIOCSREMOVECANIF:
|
||||||
ret = intrepid_remove_can_if (arg);
|
ret = intrepid_remove_can_if (arg);
|
||||||
break;
|
break;
|
||||||
case SIOCSBAUDRATE: {
|
|
||||||
struct baudrate_info {
|
|
||||||
int handle;
|
|
||||||
int64_t baudrates[2];
|
|
||||||
} info;
|
|
||||||
ret = copy_from_user(&info, (void __user*)arg, sizeof(info));
|
|
||||||
if (ret)
|
|
||||||
break;
|
|
||||||
struct net_device *device = intrepid_get_dev_by_index(info.handle);
|
|
||||||
if (device == NULL)
|
|
||||||
break;
|
|
||||||
struct intrepid_netdevice *ics = netdev_priv(device);
|
|
||||||
ics->can.bittiming.bitrate = info.baudrates[0];
|
|
||||||
ics->can.data_bittiming.bitrate = info.baudrates[1];
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
case SIOCSADDETHIF: {
|
case SIOCSADDETHIF: {
|
||||||
struct intrepid_netdevice *result = NULL;
|
struct intrepid_netdevice *result = NULL;
|
||||||
#if KERNEL_SUPPORTS_ALIASES
|
#if KERNEL_SUPPORTS_ALIASES
|
||||||
|
|
@ -1069,8 +976,7 @@ static long intrepid_dev_ioctl(struct file *fp, unsigned int cmd, unsigned long
|
||||||
ret = KO_VERSION_INT;
|
ret = KO_VERSION_INT;
|
||||||
break;
|
break;
|
||||||
case SIOCGCLIENTVEROK:
|
case SIOCGCLIENTVEROK:
|
||||||
client_version = arg;
|
if (VER_MAJ_FROM_INT(arg) == 3 && VER_MIN_FROM_INT(arg) == 1 && VER_PATCH_FROM_INT(arg) >= 0)
|
||||||
if (VER_MAJ_FROM_INT(arg) == 3 && VER_MIN_FROM_INT(arg) >= 1 && VER_PATCH_FROM_INT(arg) >= 0)
|
|
||||||
ret = 0; /* ok to start */
|
ret = 0; /* ok to start */
|
||||||
else
|
else
|
||||||
ret = 1;
|
ret = 1;
|
||||||
|
|
@ -1147,33 +1053,6 @@ static int intrepid_dev_release(struct inode *ip, struct file *fp)
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Re-use the pending_tx_info struct to send changed bitrates to userland
|
|
||||||
* Set the box index to -(dev_id) and encode the rest of the data in the count
|
|
||||||
* and bytes fields.
|
|
||||||
* count is the bitrate value
|
|
||||||
* bytes is the data bitrate value. */
|
|
||||||
static int check_bitrate_change(struct intrepid_pending_tx_info *info)
|
|
||||||
{
|
|
||||||
int i;
|
|
||||||
struct intrepid_netdevice *ics;
|
|
||||||
|
|
||||||
for (i = 0; i < MAX_NET_DEVICES; i++) {
|
|
||||||
if (net_devices[i] == NULL || net_devices[i]->type != ARPHRD_CAN)
|
|
||||||
continue;
|
|
||||||
ics = netdev_priv(net_devices[i]);
|
|
||||||
|
|
||||||
if (ics->bitrate_changed) {
|
|
||||||
info->tx_box_index = -(i + 1);
|
|
||||||
info->count = ics->can.bittiming.bitrate;
|
|
||||||
info->bytes = ics->can.data_bittiming.bitrate;
|
|
||||||
ics->bitrate_changed = 0;
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* usermode uses read() to get the current size of the tx buffer. we use a ping pong buffer
|
/* usermode uses read() to get the current size of the tx buffer. we use a ping pong buffer
|
||||||
* so the user doesn't have to worry about the data changing out from under them while
|
* so the user doesn't have to worry about the data changing out from under them while
|
||||||
* still avoiding a full copy to user. the ping pong flips on every call to this func */
|
* still avoiding a full copy to user. the ping pong flips on every call to this func */
|
||||||
|
|
@ -1185,15 +1064,6 @@ static ssize_t intrepid_dev_read(struct file *fp, char *buffer, size_t len, loff
|
||||||
if (len < sizeof(info))
|
if (len < sizeof(info))
|
||||||
return -EFAULT;
|
return -EFAULT;
|
||||||
|
|
||||||
/* check if we have to send a bitrate change */
|
|
||||||
if (VER_MIN_FROM_INT(client_version) > 1) {
|
|
||||||
if (check_bitrate_change(&info)) {
|
|
||||||
if (copy_to_user(buffer, &info, sizeof(info)))
|
|
||||||
return -EFAULT;
|
|
||||||
return sizeof(info);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
spin_lock_bh(&tx_box_lock);
|
spin_lock_bh(&tx_box_lock);
|
||||||
|
|
||||||
/* fill out the info for the user */
|
/* fill out the info for the user */
|
||||||
|
|
@ -1228,18 +1098,6 @@ static unsigned int intrepid_dev_poll(struct file *fp, poll_table *wait)
|
||||||
if (tx_box_count[current_tx_box] > 0)
|
if (tx_box_count[current_tx_box] > 0)
|
||||||
return POLLIN | POLLRDNORM;
|
return POLLIN | POLLRDNORM;
|
||||||
|
|
||||||
if (VER_MIN_FROM_INT(client_version) > 1) {
|
|
||||||
int i;
|
|
||||||
for (i = 0; i < MAX_NET_DEVICES; i++) {
|
|
||||||
if (net_devices[i] == NULL || net_devices[i]->type != ARPHRD_CAN)
|
|
||||||
continue;
|
|
||||||
struct intrepid_netdevice *ics = netdev_priv(net_devices[i]);
|
|
||||||
|
|
||||||
if (ics->bitrate_changed)
|
|
||||||
return POLLIN | POLLRDNORM;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -1257,17 +1115,6 @@ static __init int intrepid_init(void)
|
||||||
int ret;
|
int ret;
|
||||||
pr_info("intrepid: %s %s\n", KO_DESC, KO_VERSION);
|
pr_info("intrepid: %s %s\n", KO_DESC, KO_VERSION);
|
||||||
|
|
||||||
BUILD_BUG_ON_MSG(sizeof(neomessage_t) != (56 + sizeof(void*) + sizeof(size_t)),
|
|
||||||
"neomessage_t size is incorrect!");
|
|
||||||
BUILD_BUG_ON_MSG(sizeof(neomessage_frame_t) != sizeof(neomessage_t),
|
|
||||||
"All types of neomessage_t must be the same size! (Base frame is not)");
|
|
||||||
BUILD_BUG_ON_MSG(sizeof(neomessage_can_t) != sizeof(neomessage_t),
|
|
||||||
"All types of neomessage_t must be the same size! (CAN is not)");
|
|
||||||
BUILD_BUG_ON_MSG(sizeof(neomessage_can_error_t) != sizeof(neomessage_t),
|
|
||||||
"All types of neomessage_t must be the same size! (CAN error is not)");
|
|
||||||
BUILD_BUG_ON_MSG(sizeof(neomessage_eth_t) != sizeof(neomessage_t),
|
|
||||||
"All types of neomessage_t must be the same size! (Ethernet is not)");
|
|
||||||
|
|
||||||
is_open = 0;
|
is_open = 0;
|
||||||
|
|
||||||
/* this is the shared memory used to transfer between us and the user daemon */
|
/* this is the shared memory used to transfer between us and the user daemon */
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue