Merge git://git.kernel.org/pub/scm/linux/kernel/git/davem/net
Conflicts: drivers/net/usb/asix_common.c drivers/net/usb/sr9800.c drivers/net/usb/usbnet.c include/linux/usb/usbnet.h net/ipv4/tcp_ipv4.c net/ipv6/tcp_ipv6.c The TCP conflicts were overlapping changes. In 'net' we added a READ_ONCE() to the socket cached RX route read, whilst in 'net-next' Eric Dumazet touched the surrounding code dealing with how mini sockets are handled. With USB, it's a case of the same bug fix first going into net-next and then I cherry picked it back into net. Signed-off-by: David S. Miller <davem@davemloft.net>
This commit is contained in:
@@ -901,6 +901,8 @@ static int gs_usb_probe(struct usb_interface *intf, const struct usb_device_id *
|
||||
}
|
||||
|
||||
dev = kzalloc(sizeof(*dev), GFP_KERNEL);
|
||||
if (!dev)
|
||||
return -ENOMEM;
|
||||
init_usb_anchor(&dev->rx_submitted);
|
||||
|
||||
atomic_set(&dev->active_channels, 0);
|
||||
|
@@ -25,7 +25,6 @@
|
||||
#include <linux/can/dev.h>
|
||||
#include <linux/can/error.h>
|
||||
|
||||
#define MAX_TX_URBS 16
|
||||
#define MAX_RX_URBS 4
|
||||
#define START_TIMEOUT 1000 /* msecs */
|
||||
#define STOP_TIMEOUT 1000 /* msecs */
|
||||
@@ -443,6 +442,7 @@ struct kvaser_usb_error_summary {
|
||||
};
|
||||
};
|
||||
|
||||
/* Context for an outstanding, not yet ACKed, transmission */
|
||||
struct kvaser_usb_tx_urb_context {
|
||||
struct kvaser_usb_net_priv *priv;
|
||||
u32 echo_index;
|
||||
@@ -456,8 +456,13 @@ struct kvaser_usb {
|
||||
struct usb_endpoint_descriptor *bulk_in, *bulk_out;
|
||||
struct usb_anchor rx_submitted;
|
||||
|
||||
/* @max_tx_urbs: Firmware-reported maximum number of oustanding,
|
||||
* not yet ACKed, transmissions on this device. This value is
|
||||
* also used as a sentinel for marking free tx contexts.
|
||||
*/
|
||||
u32 fw_version;
|
||||
unsigned int nchannels;
|
||||
unsigned int max_tx_urbs;
|
||||
enum kvaser_usb_family family;
|
||||
|
||||
bool rxinitdone;
|
||||
@@ -467,19 +472,18 @@ struct kvaser_usb {
|
||||
|
||||
struct kvaser_usb_net_priv {
|
||||
struct can_priv can;
|
||||
|
||||
spinlock_t tx_contexts_lock;
|
||||
int active_tx_contexts;
|
||||
struct kvaser_usb_tx_urb_context tx_contexts[MAX_TX_URBS];
|
||||
|
||||
struct usb_anchor tx_submitted;
|
||||
struct completion start_comp, stop_comp;
|
||||
struct can_berr_counter bec;
|
||||
|
||||
struct kvaser_usb *dev;
|
||||
struct net_device *netdev;
|
||||
int channel;
|
||||
|
||||
struct can_berr_counter bec;
|
||||
struct completion start_comp, stop_comp;
|
||||
struct usb_anchor tx_submitted;
|
||||
|
||||
spinlock_t tx_contexts_lock;
|
||||
int active_tx_contexts;
|
||||
struct kvaser_usb_tx_urb_context tx_contexts[];
|
||||
};
|
||||
|
||||
static const struct usb_device_id kvaser_usb_table[] = {
|
||||
@@ -592,8 +596,8 @@ static int kvaser_usb_wait_msg(const struct kvaser_usb *dev, u8 id,
|
||||
* for further details.
|
||||
*/
|
||||
if (tmp->len == 0) {
|
||||
pos = round_up(pos,
|
||||
dev->bulk_in->wMaxPacketSize);
|
||||
pos = round_up(pos, le16_to_cpu(dev->bulk_in->
|
||||
wMaxPacketSize));
|
||||
continue;
|
||||
}
|
||||
|
||||
@@ -657,9 +661,13 @@ static int kvaser_usb_get_software_info(struct kvaser_usb *dev)
|
||||
switch (dev->family) {
|
||||
case KVASER_LEAF:
|
||||
dev->fw_version = le32_to_cpu(msg.u.leaf.softinfo.fw_version);
|
||||
dev->max_tx_urbs =
|
||||
le16_to_cpu(msg.u.leaf.softinfo.max_outstanding_tx);
|
||||
break;
|
||||
case KVASER_USBCAN:
|
||||
dev->fw_version = le32_to_cpu(msg.u.usbcan.softinfo.fw_version);
|
||||
dev->max_tx_urbs =
|
||||
le16_to_cpu(msg.u.usbcan.softinfo.max_outstanding_tx);
|
||||
break;
|
||||
}
|
||||
|
||||
@@ -715,7 +723,7 @@ static void kvaser_usb_tx_acknowledge(const struct kvaser_usb *dev,
|
||||
|
||||
stats = &priv->netdev->stats;
|
||||
|
||||
context = &priv->tx_contexts[tid % MAX_TX_URBS];
|
||||
context = &priv->tx_contexts[tid % dev->max_tx_urbs];
|
||||
|
||||
/* Sometimes the state change doesn't come after a bus-off event */
|
||||
if (priv->can.restart_ms &&
|
||||
@@ -744,7 +752,7 @@ static void kvaser_usb_tx_acknowledge(const struct kvaser_usb *dev,
|
||||
spin_lock_irqsave(&priv->tx_contexts_lock, flags);
|
||||
|
||||
can_get_echo_skb(priv->netdev, context->echo_index);
|
||||
context->echo_index = MAX_TX_URBS;
|
||||
context->echo_index = dev->max_tx_urbs;
|
||||
--priv->active_tx_contexts;
|
||||
netif_wake_queue(priv->netdev);
|
||||
|
||||
@@ -1329,7 +1337,8 @@ static void kvaser_usb_read_bulk_callback(struct urb *urb)
|
||||
* number of events in case of a heavy rx load on the bus.
|
||||
*/
|
||||
if (msg->len == 0) {
|
||||
pos = round_up(pos, dev->bulk_in->wMaxPacketSize);
|
||||
pos = round_up(pos, le16_to_cpu(dev->bulk_in->
|
||||
wMaxPacketSize));
|
||||
continue;
|
||||
}
|
||||
|
||||
@@ -1512,11 +1521,13 @@ error:
|
||||
|
||||
static void kvaser_usb_reset_tx_urb_contexts(struct kvaser_usb_net_priv *priv)
|
||||
{
|
||||
int i;
|
||||
int i, max_tx_urbs;
|
||||
|
||||
max_tx_urbs = priv->dev->max_tx_urbs;
|
||||
|
||||
priv->active_tx_contexts = 0;
|
||||
for (i = 0; i < MAX_TX_URBS; i++)
|
||||
priv->tx_contexts[i].echo_index = MAX_TX_URBS;
|
||||
for (i = 0; i < max_tx_urbs; i++)
|
||||
priv->tx_contexts[i].echo_index = max_tx_urbs;
|
||||
}
|
||||
|
||||
/* This method might sleep. Do not call it in the atomic context
|
||||
@@ -1702,14 +1713,14 @@ static netdev_tx_t kvaser_usb_start_xmit(struct sk_buff *skb,
|
||||
*msg_tx_can_flags |= MSG_FLAG_REMOTE_FRAME;
|
||||
|
||||
spin_lock_irqsave(&priv->tx_contexts_lock, flags);
|
||||
for (i = 0; i < ARRAY_SIZE(priv->tx_contexts); i++) {
|
||||
if (priv->tx_contexts[i].echo_index == MAX_TX_URBS) {
|
||||
for (i = 0; i < dev->max_tx_urbs; i++) {
|
||||
if (priv->tx_contexts[i].echo_index == dev->max_tx_urbs) {
|
||||
context = &priv->tx_contexts[i];
|
||||
|
||||
context->echo_index = i;
|
||||
can_put_echo_skb(skb, netdev, context->echo_index);
|
||||
++priv->active_tx_contexts;
|
||||
if (priv->active_tx_contexts >= MAX_TX_URBS)
|
||||
if (priv->active_tx_contexts >= dev->max_tx_urbs)
|
||||
netif_stop_queue(netdev);
|
||||
|
||||
break;
|
||||
@@ -1743,7 +1754,7 @@ static netdev_tx_t kvaser_usb_start_xmit(struct sk_buff *skb,
|
||||
spin_lock_irqsave(&priv->tx_contexts_lock, flags);
|
||||
|
||||
can_free_echo_skb(netdev, context->echo_index);
|
||||
context->echo_index = MAX_TX_URBS;
|
||||
context->echo_index = dev->max_tx_urbs;
|
||||
--priv->active_tx_contexts;
|
||||
netif_wake_queue(netdev);
|
||||
|
||||
@@ -1881,7 +1892,9 @@ static int kvaser_usb_init_one(struct usb_interface *intf,
|
||||
if (err)
|
||||
return err;
|
||||
|
||||
netdev = alloc_candev(sizeof(*priv), MAX_TX_URBS);
|
||||
netdev = alloc_candev(sizeof(*priv) +
|
||||
dev->max_tx_urbs * sizeof(*priv->tx_contexts),
|
||||
dev->max_tx_urbs);
|
||||
if (!netdev) {
|
||||
dev_err(&intf->dev, "Cannot alloc candev\n");
|
||||
return -ENOMEM;
|
||||
@@ -2009,6 +2022,13 @@ static int kvaser_usb_probe(struct usb_interface *intf,
|
||||
return err;
|
||||
}
|
||||
|
||||
dev_dbg(&intf->dev, "Firmware version: %d.%d.%d\n",
|
||||
((dev->fw_version >> 24) & 0xff),
|
||||
((dev->fw_version >> 16) & 0xff),
|
||||
(dev->fw_version & 0xffff));
|
||||
|
||||
dev_dbg(&intf->dev, "Max oustanding tx = %d URBs\n", dev->max_tx_urbs);
|
||||
|
||||
err = kvaser_usb_get_card_info(dev);
|
||||
if (err) {
|
||||
dev_err(&intf->dev,
|
||||
@@ -2016,11 +2036,6 @@ static int kvaser_usb_probe(struct usb_interface *intf,
|
||||
return err;
|
||||
}
|
||||
|
||||
dev_dbg(&intf->dev, "Firmware version: %d.%d.%d\n",
|
||||
((dev->fw_version >> 24) & 0xff),
|
||||
((dev->fw_version >> 16) & 0xff),
|
||||
(dev->fw_version & 0xffff));
|
||||
|
||||
for (i = 0; i < dev->nchannels; i++) {
|
||||
err = kvaser_usb_init_one(intf, id, i);
|
||||
if (err) {
|
||||
|
@@ -26,8 +26,8 @@
|
||||
#define PUCAN_CMD_FILTER_STD 0x008
|
||||
#define PUCAN_CMD_TX_ABORT 0x009
|
||||
#define PUCAN_CMD_WR_ERR_CNT 0x00a
|
||||
#define PUCAN_CMD_RX_FRAME_ENABLE 0x00b
|
||||
#define PUCAN_CMD_RX_FRAME_DISABLE 0x00c
|
||||
#define PUCAN_CMD_SET_EN_OPTION 0x00b
|
||||
#define PUCAN_CMD_CLR_DIS_OPTION 0x00c
|
||||
#define PUCAN_CMD_END_OF_COLLECTION 0x3ff
|
||||
|
||||
/* uCAN received messages list */
|
||||
@@ -101,14 +101,15 @@ struct __packed pucan_wr_err_cnt {
|
||||
u16 unused;
|
||||
};
|
||||
|
||||
/* uCAN RX_FRAME_ENABLE command fields */
|
||||
#define PUCAN_FLTEXT_ERROR 0x0001
|
||||
#define PUCAN_FLTEXT_BUSLOAD 0x0002
|
||||
/* uCAN SET_EN/CLR_DIS _OPTION command fields */
|
||||
#define PUCAN_OPTION_ERROR 0x0001
|
||||
#define PUCAN_OPTION_BUSLOAD 0x0002
|
||||
#define PUCAN_OPTION_CANDFDISO 0x0004
|
||||
|
||||
struct __packed pucan_filter_ext {
|
||||
struct __packed pucan_options {
|
||||
__le16 opcode_channel;
|
||||
|
||||
__le16 ext_mask;
|
||||
__le16 options;
|
||||
u32 unused;
|
||||
};
|
||||
|
||||
|
@@ -110,13 +110,13 @@ struct __packed pcan_ufd_led {
|
||||
u8 unused[5];
|
||||
};
|
||||
|
||||
/* Extended usage of uCAN commands CMD_RX_FRAME_xxxABLE for PCAN-USB Pro FD */
|
||||
/* Extended usage of uCAN commands CMD_xxx_xx_OPTION for PCAN-USB Pro FD */
|
||||
#define PCAN_UFD_FLTEXT_CALIBRATION 0x8000
|
||||
|
||||
struct __packed pcan_ufd_filter_ext {
|
||||
struct __packed pcan_ufd_options {
|
||||
__le16 opcode_channel;
|
||||
|
||||
__le16 ext_mask;
|
||||
__le16 ucan_mask;
|
||||
u16 unused;
|
||||
__le16 usb_mask;
|
||||
};
|
||||
@@ -251,6 +251,27 @@ static int pcan_usb_fd_build_restart_cmd(struct peak_usb_device *dev, u8 *buf)
|
||||
/* moves the pointer forward */
|
||||
pc += sizeof(struct pucan_wr_err_cnt);
|
||||
|
||||
/* add command to switch from ISO to non-ISO mode, if fw allows it */
|
||||
if (dev->can.ctrlmode_supported & CAN_CTRLMODE_FD_NON_ISO) {
|
||||
struct pucan_options *puo = (struct pucan_options *)pc;
|
||||
|
||||
puo->opcode_channel =
|
||||
(dev->can.ctrlmode & CAN_CTRLMODE_FD_NON_ISO) ?
|
||||
pucan_cmd_opcode_channel(dev,
|
||||
PUCAN_CMD_CLR_DIS_OPTION) :
|
||||
pucan_cmd_opcode_channel(dev, PUCAN_CMD_SET_EN_OPTION);
|
||||
|
||||
puo->options = cpu_to_le16(PUCAN_OPTION_CANDFDISO);
|
||||
|
||||
/* to be sure that no other extended bits will be taken into
|
||||
* account
|
||||
*/
|
||||
puo->unused = 0;
|
||||
|
||||
/* moves the pointer forward */
|
||||
pc += sizeof(struct pucan_options);
|
||||
}
|
||||
|
||||
/* next, go back to operational mode */
|
||||
cmd = (struct pucan_command *)pc;
|
||||
cmd->opcode_channel = pucan_cmd_opcode_channel(dev,
|
||||
@@ -321,21 +342,21 @@ static int pcan_usb_fd_set_filter_std(struct peak_usb_device *dev, int idx,
|
||||
return pcan_usb_fd_send_cmd(dev, cmd);
|
||||
}
|
||||
|
||||
/* set/unset notifications filter:
|
||||
/* set/unset options
|
||||
*
|
||||
* onoff sets(1)/unset(0) notifications
|
||||
* mask each bit defines a kind of notification to set/unset
|
||||
* onoff set(1)/unset(0) options
|
||||
* mask each bit defines a kind of options to set/unset
|
||||
*/
|
||||
static int pcan_usb_fd_set_filter_ext(struct peak_usb_device *dev,
|
||||
bool onoff, u16 ext_mask, u16 usb_mask)
|
||||
static int pcan_usb_fd_set_options(struct peak_usb_device *dev,
|
||||
bool onoff, u16 ucan_mask, u16 usb_mask)
|
||||
{
|
||||
struct pcan_ufd_filter_ext *cmd = pcan_usb_fd_cmd_buffer(dev);
|
||||
struct pcan_ufd_options *cmd = pcan_usb_fd_cmd_buffer(dev);
|
||||
|
||||
cmd->opcode_channel = pucan_cmd_opcode_channel(dev,
|
||||
(onoff) ? PUCAN_CMD_RX_FRAME_ENABLE :
|
||||
PUCAN_CMD_RX_FRAME_DISABLE);
|
||||
(onoff) ? PUCAN_CMD_SET_EN_OPTION :
|
||||
PUCAN_CMD_CLR_DIS_OPTION);
|
||||
|
||||
cmd->ext_mask = cpu_to_le16(ext_mask);
|
||||
cmd->ucan_mask = cpu_to_le16(ucan_mask);
|
||||
cmd->usb_mask = cpu_to_le16(usb_mask);
|
||||
|
||||
/* send the command */
|
||||
@@ -770,9 +791,9 @@ static int pcan_usb_fd_start(struct peak_usb_device *dev)
|
||||
&pcan_usb_pro_fd);
|
||||
|
||||
/* enable USB calibration messages */
|
||||
err = pcan_usb_fd_set_filter_ext(dev, 1,
|
||||
PUCAN_FLTEXT_ERROR,
|
||||
PCAN_UFD_FLTEXT_CALIBRATION);
|
||||
err = pcan_usb_fd_set_options(dev, 1,
|
||||
PUCAN_OPTION_ERROR,
|
||||
PCAN_UFD_FLTEXT_CALIBRATION);
|
||||
}
|
||||
|
||||
pdev->usb_if->dev_opened_count++;
|
||||
@@ -806,9 +827,9 @@ static int pcan_usb_fd_stop(struct peak_usb_device *dev)
|
||||
|
||||
/* turn off special msgs for that interface if no other dev opened */
|
||||
if (pdev->usb_if->dev_opened_count == 1)
|
||||
pcan_usb_fd_set_filter_ext(dev, 0,
|
||||
PUCAN_FLTEXT_ERROR,
|
||||
PCAN_UFD_FLTEXT_CALIBRATION);
|
||||
pcan_usb_fd_set_options(dev, 0,
|
||||
PUCAN_OPTION_ERROR,
|
||||
PCAN_UFD_FLTEXT_CALIBRATION);
|
||||
pdev->usb_if->dev_opened_count--;
|
||||
|
||||
return 0;
|
||||
@@ -860,8 +881,14 @@ static int pcan_usb_fd_init(struct peak_usb_device *dev)
|
||||
pdev->usb_if->fw_info.fw_version[2],
|
||||
dev->adapter->ctrl_count);
|
||||
|
||||
/* the currently supported hw is non-ISO */
|
||||
dev->can.ctrlmode = CAN_CTRLMODE_FD_NON_ISO;
|
||||
/* check for ability to switch between ISO/non-ISO modes */
|
||||
if (pdev->usb_if->fw_info.fw_version[0] >= 2) {
|
||||
/* firmware >= 2.x supports ISO/non-ISO switching */
|
||||
dev->can.ctrlmode_supported |= CAN_CTRLMODE_FD_NON_ISO;
|
||||
} else {
|
||||
/* firmware < 2.x only supports fixed(!) non-ISO */
|
||||
dev->can.ctrlmode |= CAN_CTRLMODE_FD_NON_ISO;
|
||||
}
|
||||
|
||||
/* tell the hardware the can driver is running */
|
||||
err = pcan_usb_fd_drv_loaded(dev, 1);
|
||||
@@ -937,9 +964,9 @@ static void pcan_usb_fd_exit(struct peak_usb_device *dev)
|
||||
if (dev->ctrl_idx == 0) {
|
||||
/* turn off calibration message if any device were opened */
|
||||
if (pdev->usb_if->dev_opened_count > 0)
|
||||
pcan_usb_fd_set_filter_ext(dev, 0,
|
||||
PUCAN_FLTEXT_ERROR,
|
||||
PCAN_UFD_FLTEXT_CALIBRATION);
|
||||
pcan_usb_fd_set_options(dev, 0,
|
||||
PUCAN_OPTION_ERROR,
|
||||
PCAN_UFD_FLTEXT_CALIBRATION);
|
||||
|
||||
/* tell USB adapter that the driver is being unloaded */
|
||||
pcan_usb_fd_drv_loaded(dev, 0);
|
||||
|
Reference in New Issue
Block a user