17 #include <linux/module.h>
19 #include <linux/netdevice.h>
21 #include <linux/ctype.h>
22 #include <linux/ethtool.h>
24 #include <linux/mii.h>
54 #define KALMIA_HEADER_LENGTH 6
55 #define KALMIA_ALIGN_SIZE 4
56 #define KALMIA_USB_TIMEOUT 10000
61 kalmia_send_init_packet(
struct usbnet *
dev,
u8 *init_msg,
u8 init_msg_len,
73 "Error sending init packet. Status %i, length %i\n",
77 else if (act_len != init_msg_len) {
79 "Did not send all of init packet. Bytes sent: %i",
91 "Error receiving init result. Status %i, length %i\n",
93 else if (act_len != expected_len)
94 netdev_err(dev->
net,
"Unexpected init result length: %i\n",
101 kalmia_init_and_get_ethernet_addr(
struct usbnet *
dev,
u8 *ethernet_addr)
103 static const char init_msg_1[] =
104 { 0x57, 0x50, 0x04, 0x00, 0x00, 0x00, 0x00, 0x20, 0x00, 0x00,
106 static const char init_msg_2[] =
107 { 0x57, 0x50, 0x04, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0xf4,
109 static const int buflen = 28;
117 memcpy(usb_buf, init_msg_1, 12);
118 status = kalmia_send_init_packet(dev, usb_buf,
sizeof(init_msg_1)
119 /
sizeof(init_msg_1[0]), usb_buf, 24);
123 memcpy(usb_buf, init_msg_2, 12);
124 status = kalmia_send_init_packet(dev, usb_buf,
sizeof(init_msg_2)
125 /
sizeof(init_msg_2[0]), usb_buf, 28);
153 status = kalmia_init_and_get_ethernet_addr(dev, ethernet_addr);
156 usb_set_intfdata(intf,
NULL);
172 unsigned char *header_start;
173 unsigned char ether_type_1, ether_type_2;
174 u8 remainder, padlen = 0;
176 if (!skb_cloned(skb)) {
177 int headroom = skb_headroom(skb);
178 int tailroom = skb_tailroom(skb);
188 skb_set_tail_pointer(skb, skb->
len);
206 netdev_dbg(dev->
net,
"Sending etherType: %02x%02x", ether_type_1,
210 header_start[0] = 0x57;
211 header_start[1] = 0x44;
214 put_unaligned_le16(content_len, &header_start[2]);
215 header_start[4] = ether_type_1;
216 header_start[5] = ether_type_2;
227 "Sending package with length %i and padding %i. Header: %02x:%02x:%02x:%02x:%02x:%02x.",
228 content_len, padlen, header_start[0], header_start[1],
229 header_start[2], header_start[3], header_start[4],
242 static const u8 HEADER_END_OF_USB_PACKET[] =
243 { 0x57, 0x5a, 0x00, 0x00, 0x08, 0x00 };
244 static const u8 EXPECTED_UNKNOWN_HEADER_1[] =
245 { 0x57, 0x43, 0x1e, 0x00, 0x15, 0x02 };
246 static const u8 EXPECTED_UNKNOWN_HEADER_2[] =
247 { 0x57, 0x50, 0x0e, 0x00, 0x00, 0x00 };
257 u16 usb_packet_length, ether_packet_length;
260 header_start = skb->
data;
262 if (
unlikely(header_start[0] != 0x57 || header_start[1] != 0x44)) {
263 if (!
memcmp(header_start, EXPECTED_UNKNOWN_HEADER_1,
264 sizeof(EXPECTED_UNKNOWN_HEADER_1)) || !
memcmp(
265 header_start, EXPECTED_UNKNOWN_HEADER_2,
266 sizeof(EXPECTED_UNKNOWN_HEADER_2))) {
269 "Received expected unknown frame header: %02x:%02x:%02x:%02x:%02x:%02x. Package length: %i\n",
270 header_start[0], header_start[1],
271 header_start[2], header_start[3],
272 header_start[4], header_start[5],
278 "Received unknown frame header: %02x:%02x:%02x:%02x:%02x:%02x. Package length: %i\n",
279 header_start[0], header_start[1],
280 header_start[2], header_start[3],
281 header_start[4], header_start[5],
289 "Received header: %02x:%02x:%02x:%02x:%02x:%02x. Package length: %i\n",
290 header_start[0], header_start[1], header_start[2],
291 header_start[3], header_start[4], header_start[5],
296 ether_packet_length = get_unaligned_le16(&header_start[2]);
300 if (usb_packet_length < ether_packet_length) {
301 ether_packet_length = usb_packet_length
309 is_last = (
memcmp(skb->
data + ether_packet_length,
310 HEADER_END_OF_USB_PACKET,
311 sizeof(HEADER_END_OF_USB_PACKET)) == 0);
313 header_start = skb->
data + ether_packet_length;
316 "End header: %02x:%02x:%02x:%02x:%02x:%02x. Package length: %i\n",
317 header_start[0], header_start[1],
318 header_start[2], header_start[3],
319 header_start[4], header_start[5],
333 skb_trim(skb2, ether_packet_length);
351 .description =
"Samsung Kalmia LTE USB dongle",
354 .rx_fixup = kalmia_rx_fixup,
355 .tx_fixup = kalmia_tx_fixup
362 { USB_DEVICE(0x04e8, 0x689a) },
364 { USB_DEVICE(0x04e8, 0x6889),
365 .driver_info = (
unsigned long) &kalmia_info, },
369 static struct usb_driver kalmia_driver = {
371 .id_table = products,
376 .disable_hub_initiated_lpm = 1,