28 #define DRIVER_VERSION "v.2.0"
29 #define DRIVER_AUTHOR "Paxton Smith, Matthew Safar, Rory Filer"
30 #define DRIVER_DESC "USB-to-WWAN Driver for Sierra Wireless modems"
36 #include <linux/module.h>
38 #include <linux/ethtool.h>
39 #include <linux/mii.h>
40 #include <linux/sched.h>
46 #include <asm/unaligned.h>
49 #define SWI_USB_REQUEST_GET_FW_ATTR 0x06
50 #define SWI_GET_FW_ATTR_MASK 0x08
60 #define SIERRA_NET_SYNCDELAY (2*HZ)
63 #define SIERRA_NET_MAX_SUPPORTED_MTU 1500
69 #define SIERRA_NET_USBCTL_BUF_LEN 1024
72 #define SIERRA_NET_RX_URB_SIZE (8 * 1024)
91 #define SIERRA_NET_EVENT_RESP_AVAIL 0x01
92 #define SIERRA_NET_TIMER_EXPIRY 0x02
109 #define SIERRA_NET_HIP_EXTENDEDID 0x7F
110 #define SIERRA_NET_HIP_HSYNC_ID 0x60
111 #define SIERRA_NET_HIP_RESTART_ID 0x62
112 #define SIERRA_NET_HIP_MSYNC_ID 0x20
113 #define SIERRA_NET_HIP_SHUTD_ID 0x26
115 #define SIERRA_NET_HIP_EXT_IP_IN_ID 0x0202
116 #define SIERRA_NET_HIP_EXT_IP_OUT_ID 0x0002
119 #define SIERRA_NET_HIP_LSI_UMTSID 0x78
122 #define SIERRA_NET_HIP_RCGI 0x64
125 #define SIERRA_NET_PROTOCOL_UMTS 0x01
127 #define SIERRA_NET_COVERAGE_NONE 0x00
128 #define SIERRA_NET_COVERAGE_NOPACKET 0x01
131 #define SIERRA_NET_SESSION_IDLE 0x00
133 #define SIERRA_NET_AS_LINK_TYPE_IPv4 0x00
162 #define SIERRA_NET_LSI_COMMON_LEN 4
163 #define SIERRA_NET_LSI_UMTS_LEN (sizeof(struct lsi_umts))
164 #define SIERRA_NET_LSI_UMTS_STATUS_LEN \
165 (SIERRA_NET_LSI_UMTS_LEN - SIERRA_NET_LSI_COMMON_LEN)
168 static void sierra_sync_timer(
unsigned long syncdata);
169 static int sierra_net_change_mtu(
struct net_device *
net,
int new_mtu);
177 .ndo_change_mtu = sierra_net_change_mtu,
189 static inline void sierra_net_set_private(
struct usbnet *dev,
208 skb_reset_mac_header(skb);
210 if (skb_is_nonlinear(skb)) {
211 netdev_err(dev->
net,
"Non linear buffer-dropping\n");
217 skb->
protocol = eth_hdr(skb)->h_proto;
222 static const u8 *save16bit(
struct param *
p,
const u8 *datap)
225 p->
word = get_unaligned_be16(datap);
226 return datap +
sizeof(p->
word);
229 static const u8 *save8bit(
struct param *
p,
const u8 *datap)
233 return datap +
sizeof(p->
byte);
240 #define SIERRA_NET_HIP_HDR_LEN 4
242 #define SIERRA_NET_HIP_EXT_HDR_LEN 6
254 const u8 *curp =
buf;
261 curp = save8bit(&hh->
msgid, curp);
264 padded = hh->
msgid.byte & 0x80;
265 hh->
msgid.byte &= 0x7F;
274 curp = save16bit(&hh->
extmsgid, curp);
295 static void build_hip(
u8 *buf,
const u16 payloadlen,
301 put_unaligned_be16(payloadlen, buf);
308 static int sierra_net_send_cmd(
struct usbnet *dev,
309 u8 *
cmd,
int cmdlen,
const char * cmd_name)
317 priv->
ifnum, cmd, cmdlen, USB_CTRL_SET_TIMEOUT);
319 if (status != cmdlen && status != -
ENODEV)
320 netdev_err(dev->
net,
"Submit %s failed %d\n", cmd_name, status);
325 static int sierra_net_send_sync(
struct usbnet *dev)
332 status = sierra_net_send_cmd(dev, priv->
sync_msg,
340 dev_dbg(&(priv->
usbnet->udev->dev),
"%s %d", __func__, ctx_ix);
347 static inline int sierra_net_is_valid_addrlen(
u8 len)
349 return len ==
sizeof(
struct in_addr);
356 if (datalen <
sizeof(
struct lsi_umts)) {
357 netdev_err(dev->
net,
"%s: Data length %d, exp %Zu\n",
364 netdev_err(dev->
net,
"%s: LSI_UMTS_STATUS_LEN %d, exp %u\n",
372 netdev_err(dev->
net,
"Protocol unsupported, 0x%02x\n",
379 netdev_err(dev->
net,
"Link type unsupported: 0x%02x\n",
387 netdev_err(dev->
net,
"No coverage, 0x%02x\n", lsi->
coverage);
393 netdev_err(dev->
net,
"Session idle, 0x%02x\n",
402 static void sierra_net_handle_lsi(
struct usbnet *dev,
char *data,
408 link_up = sierra_net_parse_lsi(dev, data + hh->
hdrlen,
411 netdev_err(dev->
net,
"Invalid LSI\n");
415 sierra_net_set_ctx_index(priv, hh->
msgspecific.byte);
424 static void sierra_net_dosync(
struct usbnet *dev)
432 status = sierra_net_send_sync(dev);
435 "Send SYNC failed, status %d\n", status);
436 status = sierra_net_send_sync(dev);
439 "Send SYNC failed, status %d\n", status);
442 priv->
sync_timer.function = sierra_sync_timer;
465 "failed to allocate buf for LS msg\n");
473 USB_CTRL_SET_TIMEOUT);
477 "usb_control_msg failed, status %d\n", len);
481 dev_dbg(&dev->
udev->dev,
"%s: Received status message,"
482 " %04x bytes", __func__, len);
484 err = parse_hip(buf, len, &hh);
486 netdev_err(dev->
net,
"%s: Bad packet,"
487 " parse result %d\n", __func__, err);
494 netdev_err(dev->
net,
"%s: Bad packet, received"
495 " %d, expected %d\n", __func__, len,
502 switch (hh.
msgid.byte) {
506 sierra_net_handle_lsi(dev, buf, &hh);
510 " stopping sync timer",
519 err = sierra_net_send_sync(dev);
522 "Send SYNC failed %d\n", err);
525 netdev_err(dev->
net,
"Unrecognized HIP msg, "
526 "extmsgid 0x%04x\n", hh.
extmsgid.word);
532 netdev_err(dev->
net,
"Unrecognized HIP msg, "
533 "msgid 0x%02x\n", hh.
msgid.byte);
542 dev_dbg(&dev->
udev->dev,
"Deferred sync timer expiry");
543 sierra_net_dosync(priv->
usbnet);
547 dev_dbg(&dev->
udev->dev,
"sierra_net_kevent done, "
551 static void sierra_net_defer_kevent(
struct usbnet *dev,
int work)
562 static void sierra_sync_timer(
unsigned long syncdata)
571 static void sierra_net_status(
struct usbnet *dev,
struct urb *
urb)
577 if (urb->actual_length <
sizeof *event)
581 event = urb->transfer_buffer;
591 netdev_err(dev->
net,
": unexpected notification %02x!\n",
608 struct usbnet *dev = netdev_priv(net);
610 return sierra_net_get_private(dev)->link_up && netif_running(net);
613 static const struct ethtool_ops sierra_net_ethtool_ops = {
614 .get_drvinfo = sierra_net_get_drvinfo,
615 .get_link = sierra_net_get_link,
624 static int sierra_net_change_mtu(
struct net_device *
net,
int new_mtu)
632 static int sierra_net_get_fw_attr(
struct usbnet *dev,
u16 *datap)
643 usb_rcvctrlpipe(dev->
udev, 0),
651 USB_CTRL_SET_TIMEOUT);
675 static const u8 sync_tmplate[
sizeof(priv->
sync_msg)] = {
677 static const u8 shdwn_tmplate[
sizeof(priv->
shdwn_msg)] = {
682 ifacenum = intf->cur_altsetting->desc.bInterfaceNumber;
683 numendpoints = intf->cur_altsetting->desc.bNumEndpoints;
685 if (numendpoints != 3) {
686 dev_err(&dev->
udev->dev,
"Expected 3 endpoints, found: %d",
694 dev_err(&dev->
udev->dev,
"Error in usbnet_get_endpoints (%d)",
706 priv->
ifnum = ifacenum;
707 dev->
net->netdev_ops = &sierra_net_device_ops;
721 sierra_net_set_ctx_index(priv, 0);
733 dev->
net->ethtool_ops = &sierra_net_ethtool_ops;
736 sierra_net_set_private(dev, priv);
747 status = sierra_net_get_fw_attr(dev, &fwattr);
753 dev_err(&dev->
udev->dev,
"Incompatible driver and firmware"
762 sierra_net_dosync(dev);
779 status = sierra_net_send_cmd(dev, priv->
shdwn_msg,
783 "usb_control_msg failed, status %d\n", status);
785 sierra_net_set_private(dev,
NULL);
790 static struct sk_buff *sierra_net_skb_clone(
struct usbnet *dev,
806 netdev_err(dev->
net,
"failed to get skb\n");
807 dev->
net->stats.rx_dropped++;
814 static int sierra_net_rx_fixup(
struct usbnet *dev,
struct sk_buff *skb)
824 err = parse_hip(skb->
data, skb->
len, &hh);
827 netdev_err(dev->
net,
"Invalid HIP header %d\n",
830 dev->
net->stats.rx_length_errors++;
838 netdev_err(dev->
net,
"HIP/ETH: Invalid pkt\n");
840 dev->
net->stats.rx_frame_errors++;
848 memcpy(skb->
data, sierra_net_get_private(dev)->ethr_hdr_tmpl,
855 new_skb = sierra_net_skb_clone(dev, skb, hh.
payload_len.word);
865 static struct sk_buff *sierra_net_tx_fixup(
struct usbnet *dev,
876 if (priv->
link_up && check_ethip_packet(skb, dev) && is_ip(skb)) {
886 if (
unlikely(skb_tailroom(skb) == 0)) {
887 netdev_err(dev->
net,
"tx_fixup:"
888 "no room for packet\n");
897 build_hip(skb->
data, len, priv);
903 netdev_err(dev->
net,
"tx_fixup: no room for HIP\n");
908 dev->
net->stats.tx_carrier_errors++;
917 static const struct driver_info sierra_net_info_direct_ip = {
918 .description =
"Sierra Wireless USB-to-WWAN Modem",
920 .bind = sierra_net_bind,
921 .unbind = sierra_net_unbind,
922 .status = sierra_net_status,
923 .rx_fixup = sierra_net_rx_fixup,
924 .tx_fixup = sierra_net_tx_fixup,
927 #define DIRECT_IP_DEVICE(vend, prod) \
928 {USB_DEVICE_INTERFACE_NUMBER(vend, prod, 7), \
929 .driver_info = (unsigned long)&sierra_net_info_direct_ip}, \
930 {USB_DEVICE_INTERFACE_NUMBER(vend, prod, 10), \
931 .driver_info = (unsigned long)&sierra_net_info_direct_ip}, \
932 {USB_DEVICE_INTERFACE_NUMBER(vend, prod, 11), \
933 .driver_info = (unsigned long)&sierra_net_info_direct_ip}
946 static struct usb_driver sierra_net_driver = {
947 .name =
"sierra_net",
948 .id_table = products,
954 .disable_hub_initiated_lpm = 1,