Lines Matching +full:u +full:- +full:blox
4 * Copyright (C) ST-Ericsson 2010-2012
16 * of the GNU General Public License (GPL) Version 2 or the 2-clause
77 .sizeof_stat = sizeof(((struct cdc_ncm_ctx *)0)->m), \
100 return -EOPNOTSUPP; in cdc_ncm_get_sset_count()
109 struct cdc_ncm_ctx *ctx = (struct cdc_ncm_ctx *)dev->data[0]; in cdc_ncm_get_ethtool_stats()
151 struct cdc_ncm_ctx *ctx = (struct cdc_ncm_ctx *)dev->data[0]; in cdc_ncm_check_rx_max()
156 max = min_t(u32, CDC_NCM_NTB_MAX_SIZE_RX, le32_to_cpu(ctx->ncm_parm.dwNtbInMaxSize)); in cdc_ncm_check_rx_max()
160 dev_warn(&dev->intf->dev, "dwNtbInMaxSize=%u is too small. Using %u\n", in cdc_ncm_check_rx_max()
161 le32_to_cpu(ctx->ncm_parm.dwNtbInMaxSize), min); in cdc_ncm_check_rx_max()
167 dev_dbg(&dev->intf->dev, "rx_max must be in the [%u, %u] range\n", min, max); in cdc_ncm_check_rx_max()
174 struct cdc_ncm_ctx *ctx = (struct cdc_ncm_ctx *)dev->data[0]; in cdc_ncm_check_tx_max()
178 if (ctx->is_ndp16) in cdc_ncm_check_tx_max()
179 min = ctx->max_datagram_size + ctx->max_ndp_size + sizeof(struct usb_cdc_ncm_nth16); in cdc_ncm_check_tx_max()
181 min = ctx->max_datagram_size + ctx->max_ndp_size + sizeof(struct usb_cdc_ncm_nth32); in cdc_ncm_check_tx_max()
183 max = min_t(u32, CDC_NCM_NTB_MAX_SIZE_TX, le32_to_cpu(ctx->ncm_parm.dwNtbOutMaxSize)); in cdc_ncm_check_tx_max()
192 dev_dbg(&dev->intf->dev, "tx_max must be in the [%u, %u] range\n", min, max); in cdc_ncm_check_tx_max()
201 struct cdc_ncm_ctx *ctx = (struct cdc_ncm_ctx *)dev->data[0]; in min_tx_pkt_show()
203 return sprintf(buf, "%u\n", ctx->min_tx_pkt); in min_tx_pkt_show()
210 struct cdc_ncm_ctx *ctx = (struct cdc_ncm_ctx *)dev->data[0]; in rx_max_show()
212 return sprintf(buf, "%u\n", ctx->rx_max); in rx_max_show()
219 struct cdc_ncm_ctx *ctx = (struct cdc_ncm_ctx *)dev->data[0]; in tx_max_show()
221 return sprintf(buf, "%u\n", ctx->tx_max); in tx_max_show()
228 struct cdc_ncm_ctx *ctx = (struct cdc_ncm_ctx *)dev->data[0]; in tx_timer_usecs_show()
230 return sprintf(buf, "%u\n", ctx->timer_interval / (u32)NSEC_PER_USEC); in tx_timer_usecs_show()
238 struct cdc_ncm_ctx *ctx = (struct cdc_ncm_ctx *)dev->data[0]; in min_tx_pkt_store()
241 /* no need to restrict values - anything from 0 to infinity is OK */ in min_tx_pkt_store()
243 return -EINVAL; in min_tx_pkt_store()
245 ctx->min_tx_pkt = val; in min_tx_pkt_store()
254 struct cdc_ncm_ctx *ctx = (struct cdc_ncm_ctx *)dev->data[0]; in rx_max_store()
258 return -EINVAL; in rx_max_store()
260 cdc_ncm_update_rxtx_max(dev, val, ctx->tx_max); in rx_max_store()
269 struct cdc_ncm_ctx *ctx = (struct cdc_ncm_ctx *)dev->data[0]; in tx_max_store()
273 return -EINVAL; in tx_max_store()
275 cdc_ncm_update_rxtx_max(dev, ctx->rx_max, val); in tx_max_store()
284 struct cdc_ncm_ctx *ctx = (struct cdc_ncm_ctx *)dev->data[0]; in tx_timer_usecs_store()
292 return -EINVAL; in tx_timer_usecs_store()
294 spin_lock_bh(&ctx->mtx); in tx_timer_usecs_store()
295 ctx->timer_interval = val * NSEC_PER_USEC; in tx_timer_usecs_store()
296 if (!ctx->timer_interval) in tx_timer_usecs_store()
297 ctx->tx_timer_pending = 0; in tx_timer_usecs_store()
298 spin_unlock_bh(&ctx->mtx); in tx_timer_usecs_store()
310 struct cdc_ncm_ctx *ctx = (struct cdc_ncm_ctx *)dev->data[0]; in ndp_to_end_show()
312 return sprintf(buf, "%c\n", ctx->drvflags & CDC_NCM_FLAG_NDP_TO_END ? 'Y' : 'N'); in ndp_to_end_show()
318 struct cdc_ncm_ctx *ctx = (struct cdc_ncm_ctx *)dev->data[0]; in ndp_to_end_store()
322 return -EINVAL; in ndp_to_end_store()
325 if (enable == (ctx->drvflags & CDC_NCM_FLAG_NDP_TO_END)) in ndp_to_end_store()
329 if (ctx->is_ndp16 && !ctx->delayed_ndp16) { in ndp_to_end_store()
330 ctx->delayed_ndp16 = kzalloc(ctx->max_ndp_size, GFP_KERNEL); in ndp_to_end_store()
331 if (!ctx->delayed_ndp16) in ndp_to_end_store()
332 return -ENOMEM; in ndp_to_end_store()
334 if (!ctx->is_ndp16 && !ctx->delayed_ndp32) { in ndp_to_end_store()
335 ctx->delayed_ndp32 = kzalloc(ctx->max_ndp_size, GFP_KERNEL); in ndp_to_end_store()
336 if (!ctx->delayed_ndp32) in ndp_to_end_store()
337 return -ENOMEM; in ndp_to_end_store()
342 netif_tx_lock_bh(dev->net); in ndp_to_end_store()
343 usbnet_start_xmit(NULL, dev->net); in ndp_to_end_store()
344 spin_lock_bh(&ctx->mtx); in ndp_to_end_store()
346 ctx->drvflags |= CDC_NCM_FLAG_NDP_TO_END; in ndp_to_end_store()
348 ctx->drvflags &= ~CDC_NCM_FLAG_NDP_TO_END; in ndp_to_end_store()
349 spin_unlock_bh(&ctx->mtx); in ndp_to_end_store()
350 netif_tx_unlock_bh(dev->net); in ndp_to_end_store()
360 struct cdc_ncm_ctx *ctx = (struct cdc_ncm_ctx *)dev->data[0]; \
361 return sprintf(buf, format "\n", tocpu(ctx->ncm_parm.name)); \
366 NCM_PARM_ATTR(dwNtbInMaxSize, "%u", le32_to_cpu);
367 NCM_PARM_ATTR(wNdpInDivisor, "%u", le16_to_cpu);
368 NCM_PARM_ATTR(wNdpInPayloadRemainder, "%u", le16_to_cpu);
369 NCM_PARM_ATTR(wNdpInAlignment, "%u", le16_to_cpu);
370 NCM_PARM_ATTR(dwNtbOutMaxSize, "%u", le32_to_cpu);
371 NCM_PARM_ATTR(wNdpOutDivisor, "%u", le16_to_cpu);
372 NCM_PARM_ATTR(wNdpOutPayloadRemainder, "%u", le16_to_cpu);
373 NCM_PARM_ATTR(wNdpOutAlignment, "%u", le16_to_cpu);
374 NCM_PARM_ATTR(wNtbOutMaxDatagrams, "%u", le16_to_cpu);
403 struct cdc_ncm_ctx *ctx = (struct cdc_ncm_ctx *)dev->data[0]; in cdc_ncm_update_rxtx_max()
404 u8 iface_no = ctx->control->cur_altsetting->desc.bInterfaceNumber; in cdc_ncm_update_rxtx_max()
410 if (val != ctx->rx_max) { in cdc_ncm_update_rxtx_max()
413 dev_info(&dev->intf->dev, "setting rx_max = %u\n", val); in cdc_ncm_update_rxtx_max()
420 dev_dbg(&dev->intf->dev, "Setting NTB Input Size failed\n"); in cdc_ncm_update_rxtx_max()
422 ctx->rx_max = val; in cdc_ncm_update_rxtx_max()
426 if (dev->rx_urb_size != ctx->rx_max) { in cdc_ncm_update_rxtx_max()
427 dev->rx_urb_size = ctx->rx_max; in cdc_ncm_update_rxtx_max()
428 if (netif_running(dev->net)) in cdc_ncm_update_rxtx_max()
433 if (val != ctx->tx_max) in cdc_ncm_update_rxtx_max()
434 dev_info(&dev->intf->dev, "setting tx_max = %u\n", val); in cdc_ncm_update_rxtx_max()
440 * We cannot use dev->maxpacket here because this is called from in cdc_ncm_update_rxtx_max()
441 * .bind which is called before usbnet sets up dev->maxpacket in cdc_ncm_update_rxtx_max()
443 if (val != le32_to_cpu(ctx->ncm_parm.dwNtbOutMaxSize) && in cdc_ncm_update_rxtx_max()
444 val % usb_maxpacket(dev->udev, dev->out) == 0) in cdc_ncm_update_rxtx_max()
448 if (netif_running(dev->net) && val > ctx->tx_max) { in cdc_ncm_update_rxtx_max()
449 netif_tx_lock_bh(dev->net); in cdc_ncm_update_rxtx_max()
450 usbnet_start_xmit(NULL, dev->net); in cdc_ncm_update_rxtx_max()
452 if (ctx->tx_curr_skb) { in cdc_ncm_update_rxtx_max()
453 dev_kfree_skb_any(ctx->tx_curr_skb); in cdc_ncm_update_rxtx_max()
454 ctx->tx_curr_skb = NULL; in cdc_ncm_update_rxtx_max()
456 ctx->tx_max = val; in cdc_ncm_update_rxtx_max()
457 netif_tx_unlock_bh(dev->net); in cdc_ncm_update_rxtx_max()
459 ctx->tx_max = val; in cdc_ncm_update_rxtx_max()
462 dev->hard_mtu = ctx->tx_max; in cdc_ncm_update_rxtx_max()
468 ctx->min_tx_pkt = clamp_t(u16, ctx->tx_max - 3 * usb_maxpacket(dev->udev, dev->out), in cdc_ncm_update_rxtx_max()
469 CDC_NCM_MIN_TX_PKT, ctx->tx_max); in cdc_ncm_update_rxtx_max()
475 struct cdc_ncm_ctx *ctx = (struct cdc_ncm_ctx *)dev->data[0]; in cdc_ncm_flags()
477 if (cdc_ncm_comm_intf_is_mbim(dev->intf->cur_altsetting) && ctx->mbim_desc) in cdc_ncm_flags()
478 return ctx->mbim_desc->bmNetworkCapabilities; in cdc_ncm_flags()
479 if (ctx->func_desc) in cdc_ncm_flags()
480 return ctx->func_desc->bmNetworkCapabilities; in cdc_ncm_flags()
486 if (cdc_ncm_comm_intf_is_mbim(dev->intf->cur_altsetting)) in cdc_ncm_eth_hlen()
493 if (cdc_ncm_comm_intf_is_mbim(dev->intf->cur_altsetting)) in cdc_ncm_min_dgram_size()
500 struct cdc_ncm_ctx *ctx = (struct cdc_ncm_ctx *)dev->data[0]; in cdc_ncm_max_dgram_size()
502 if (cdc_ncm_comm_intf_is_mbim(dev->intf->cur_altsetting) && ctx->mbim_desc) in cdc_ncm_max_dgram_size()
503 return le16_to_cpu(ctx->mbim_desc->wMaxSegmentSize); in cdc_ncm_max_dgram_size()
504 if (ctx->ether_desc) in cdc_ncm_max_dgram_size()
505 return le16_to_cpu(ctx->ether_desc->wMaxSegmentSize); in cdc_ncm_max_dgram_size()
509 /* initial one-time device setup. MUST be called with the data interface
514 struct cdc_ncm_ctx *ctx = (struct cdc_ncm_ctx *)dev->data[0]; in cdc_ncm_init()
515 u8 iface_no = ctx->control->cur_altsetting->desc.bInterfaceNumber; in cdc_ncm_init()
521 0, iface_no, &ctx->ncm_parm, in cdc_ncm_init()
522 sizeof(ctx->ncm_parm)); in cdc_ncm_init()
524 dev_err(&dev->intf->dev, "failed GET_NTB_PARAMETERS\n"); in cdc_ncm_init()
530 dev_dbg(&dev->intf->dev, "Setting CRC mode off\n"); in cdc_ncm_init()
537 dev_err(&dev->intf->dev, "SET_CRC_MODE failed\n"); in cdc_ncm_init()
541 ctx->is_ndp16 = 1; in cdc_ncm_init()
548 if (le16_to_cpu(ctx->ncm_parm.bmNtbFormatsSupported) & in cdc_ncm_init()
550 if (ctx->drvflags & CDC_NCM_FLAG_PREFER_NTB32) { in cdc_ncm_init()
551 ctx->is_ndp16 = 0; in cdc_ncm_init()
552 dev_dbg(&dev->intf->dev, "Setting NTB format to 32-bit\n"); in cdc_ncm_init()
559 ctx->is_ndp16 = 1; in cdc_ncm_init()
560 dev_dbg(&dev->intf->dev, "Setting NTB format to 16-bit\n"); in cdc_ncm_init()
568 ctx->is_ndp16 = 1; in cdc_ncm_init()
569 dev_err(&dev->intf->dev, "SET_NTB_FORMAT failed\n"); in cdc_ncm_init()
574 ctx->rx_max = le32_to_cpu(ctx->ncm_parm.dwNtbInMaxSize); in cdc_ncm_init()
575 ctx->tx_max = le32_to_cpu(ctx->ncm_parm.dwNtbOutMaxSize); in cdc_ncm_init()
576 ctx->tx_remainder = le16_to_cpu(ctx->ncm_parm.wNdpOutPayloadRemainder); in cdc_ncm_init()
577 ctx->tx_modulus = le16_to_cpu(ctx->ncm_parm.wNdpOutDivisor); in cdc_ncm_init()
578 ctx->tx_ndp_modulus = le16_to_cpu(ctx->ncm_parm.wNdpOutAlignment); in cdc_ncm_init()
580 ctx->tx_max_datagrams = le16_to_cpu(ctx->ncm_parm.wNtbOutMaxDatagrams); in cdc_ncm_init()
582 dev_dbg(&dev->intf->dev, in cdc_ncm_init()
583 …"dwNtbInMaxSize=%u dwNtbOutMaxSize=%u wNdpOutPayloadRemainder=%u wNdpOutDivisor=%u wNdpOutAlignmen… in cdc_ncm_init()
584 ctx->rx_max, ctx->tx_max, ctx->tx_remainder, ctx->tx_modulus, in cdc_ncm_init()
585 ctx->tx_ndp_modulus, ctx->tx_max_datagrams, cdc_ncm_flags(dev)); in cdc_ncm_init()
588 if ((ctx->tx_max_datagrams == 0) || in cdc_ncm_init()
589 (ctx->tx_max_datagrams > CDC_NCM_DPT_DATAGRAMS_MAX)) in cdc_ncm_init()
590 ctx->tx_max_datagrams = CDC_NCM_DPT_DATAGRAMS_MAX; in cdc_ncm_init()
593 if (ctx->is_ndp16) in cdc_ncm_init()
594 …ctx->max_ndp_size = sizeof(struct usb_cdc_ncm_ndp16) + (ctx->tx_max_datagrams + 1) * sizeof(struct… in cdc_ncm_init()
596 …ctx->max_ndp_size = sizeof(struct usb_cdc_ncm_ndp32) + (ctx->tx_max_datagrams + 1) * sizeof(struct… in cdc_ncm_init()
599 ctx->timer_interval = CDC_NCM_TIMER_INTERVAL_USEC * NSEC_PER_USEC; in cdc_ncm_init()
607 struct cdc_ncm_ctx *ctx = (struct cdc_ncm_ctx *)dev->data[0]; in cdc_ncm_set_dgram_size()
608 u8 iface_no = ctx->control->cur_altsetting->desc.bInterfaceNumber; in cdc_ncm_set_dgram_size()
614 ctx->max_datagram_size = clamp_t(u32, new_size, in cdc_ncm_set_dgram_size()
627 dev_dbg(&dev->intf->dev, "GET_MAX_DATAGRAM_SIZE failed\n"); in cdc_ncm_set_dgram_size()
631 if (le16_to_cpu(max_datagram_size) == ctx->max_datagram_size) in cdc_ncm_set_dgram_size()
634 max_datagram_size = cpu_to_le16(ctx->max_datagram_size); in cdc_ncm_set_dgram_size()
639 dev_dbg(&dev->intf->dev, "SET_MAX_DATAGRAM_SIZE failed\n"); in cdc_ncm_set_dgram_size()
643 dev->net->mtu = min_t(int, dev->net->mtu, ctx->max_datagram_size - cdc_ncm_eth_hlen(dev)); in cdc_ncm_set_dgram_size()
646 if (ctx->mbim_extended_desc) { in cdc_ncm_set_dgram_size()
647 mbim_mtu = le16_to_cpu(ctx->mbim_extended_desc->wMTU); in cdc_ncm_set_dgram_size()
648 if (mbim_mtu != 0 && mbim_mtu < dev->net->mtu) in cdc_ncm_set_dgram_size()
649 dev->net->mtu = mbim_mtu; in cdc_ncm_set_dgram_size()
655 struct cdc_ncm_ctx *ctx = (struct cdc_ncm_ctx *)dev->data[0]; in cdc_ncm_fix_modulus()
660 * - power of two in cdc_ncm_fix_modulus()
661 * - not greater than the maximum transmit length in cdc_ncm_fix_modulus()
662 * - not less than four bytes in cdc_ncm_fix_modulus()
664 val = ctx->tx_ndp_modulus; in cdc_ncm_fix_modulus()
667 (val != ((-val) & val)) || (val >= ctx->tx_max)) { in cdc_ncm_fix_modulus()
668 dev_dbg(&dev->intf->dev, "Using default alignment: 4 bytes\n"); in cdc_ncm_fix_modulus()
669 ctx->tx_ndp_modulus = USB_CDC_NCM_NDP_ALIGN_MIN_SIZE; in cdc_ncm_fix_modulus()
674 * - power of two in cdc_ncm_fix_modulus()
675 * - not greater than the maximum transmit length in cdc_ncm_fix_modulus()
676 * - not less than four bytes in cdc_ncm_fix_modulus()
678 val = ctx->tx_modulus; in cdc_ncm_fix_modulus()
681 (val != ((-val) & val)) || (val >= ctx->tx_max)) { in cdc_ncm_fix_modulus()
682 dev_dbg(&dev->intf->dev, "Using default transmit modulus: 4 bytes\n"); in cdc_ncm_fix_modulus()
683 ctx->tx_modulus = USB_CDC_NCM_NDP_ALIGN_MIN_SIZE; in cdc_ncm_fix_modulus()
687 if (ctx->tx_remainder >= ctx->tx_modulus) { in cdc_ncm_fix_modulus()
688 dev_dbg(&dev->intf->dev, "Using default transmit remainder: 0 bytes\n"); in cdc_ncm_fix_modulus()
689 ctx->tx_remainder = 0; in cdc_ncm_fix_modulus()
692 /* adjust TX-remainder according to NCM specification. */ in cdc_ncm_fix_modulus()
693 ctx->tx_remainder = ((ctx->tx_remainder - cdc_ncm_eth_hlen(dev)) & in cdc_ncm_fix_modulus()
694 (ctx->tx_modulus - 1)); in cdc_ncm_fix_modulus()
699 struct cdc_ncm_ctx *ctx = (struct cdc_ncm_ctx *)dev->data[0]; in cdc_ncm_setup()
706 le32_to_cpu(ctx->ncm_parm.dwNtbInMaxSize)); in cdc_ncm_setup()
708 le32_to_cpu(ctx->ncm_parm.dwNtbOutMaxSize)); in cdc_ncm_setup()
727 for (ep = 0; ep < intf->cur_altsetting->desc.bNumEndpoints; ep++) { in cdc_ncm_find_endpoints()
728 e = intf->cur_altsetting->endpoint + ep; in cdc_ncm_find_endpoints()
731 if (!usb_endpoint_maxp(&e->desc)) in cdc_ncm_find_endpoints()
734 switch (e->desc.bmAttributes & USB_ENDPOINT_XFERTYPE_MASK) { in cdc_ncm_find_endpoints()
736 if (usb_endpoint_dir_in(&e->desc)) { in cdc_ncm_find_endpoints()
737 if (!dev->status) in cdc_ncm_find_endpoints()
738 dev->status = e; in cdc_ncm_find_endpoints()
743 if (usb_endpoint_dir_in(&e->desc)) { in cdc_ncm_find_endpoints()
756 if (in && !dev->in) in cdc_ncm_find_endpoints()
757 dev->in = usb_rcvbulkpipe(dev->udev, in cdc_ncm_find_endpoints()
758 in->desc.bEndpointAddress & in cdc_ncm_find_endpoints()
760 if (out && !dev->out) in cdc_ncm_find_endpoints()
761 dev->out = usb_sndbulkpipe(dev->udev, in cdc_ncm_find_endpoints()
762 out->desc.bEndpointAddress & in cdc_ncm_find_endpoints()
771 if (ctx->tx_rem_skb != NULL) { in cdc_ncm_free()
772 dev_kfree_skb_any(ctx->tx_rem_skb); in cdc_ncm_free()
773 ctx->tx_rem_skb = NULL; in cdc_ncm_free()
776 if (ctx->tx_curr_skb != NULL) { in cdc_ncm_free()
777 dev_kfree_skb_any(ctx->tx_curr_skb); in cdc_ncm_free()
778 ctx->tx_curr_skb = NULL; in cdc_ncm_free()
781 if (ctx->is_ndp16) in cdc_ncm_free()
782 kfree(ctx->delayed_ndp16); in cdc_ncm_free()
784 kfree(ctx->delayed_ndp32); in cdc_ncm_free()
790 * - respect the negotiated maximum datagram size
791 * - avoid unwanted changes to rx and tx buffers
797 net->mtu = new_mtu; in cdc_ncm_change_mtu()
828 return -ENOMEM; in cdc_ncm_bind_common()
830 ctx->dev = dev; in cdc_ncm_bind_common()
832 hrtimer_init(&ctx->tx_timer, CLOCK_MONOTONIC, HRTIMER_MODE_REL); in cdc_ncm_bind_common()
833 ctx->tx_timer.function = &cdc_ncm_tx_timer_cb; in cdc_ncm_bind_common()
834 tasklet_setup(&ctx->bh, cdc_ncm_txpath_bh); in cdc_ncm_bind_common()
835 atomic_set(&ctx->stop, 0); in cdc_ncm_bind_common()
836 spin_lock_init(&ctx->mtx); in cdc_ncm_bind_common()
839 dev->data[0] = (unsigned long)ctx; in cdc_ncm_bind_common()
842 ctx->control = intf; in cdc_ncm_bind_common()
846 buf = intf->cur_altsetting->extra; in cdc_ncm_bind_common()
847 len = intf->cur_altsetting->extralen; in cdc_ncm_bind_common()
853 ctx->data = usb_ifnum_to_if(dev->udev, in cdc_ncm_bind_common()
854 hdr.usb_cdc_union_desc->bSlaveInterface0); in cdc_ncm_bind_common()
855 ctx->ether_desc = hdr.usb_cdc_ether_desc; in cdc_ncm_bind_common()
856 ctx->func_desc = hdr.usb_cdc_ncm_desc; in cdc_ncm_bind_common()
857 ctx->mbim_desc = hdr.usb_cdc_mbim_desc; in cdc_ncm_bind_common()
858 ctx->mbim_extended_desc = hdr.usb_cdc_mbim_extended_desc; in cdc_ncm_bind_common()
861 if (!hdr.usb_cdc_union_desc && intf->intf_assoc && intf->intf_assoc->bInterfaceCount == 2) { in cdc_ncm_bind_common()
862 ctx->data = usb_ifnum_to_if(dev->udev, intf->cur_altsetting->desc.bInterfaceNumber + 1); in cdc_ncm_bind_common()
863 dev_dbg(&intf->dev, "CDC Union missing - got slave from IAD\n"); in cdc_ncm_bind_common()
867 if (!ctx->data) { in cdc_ncm_bind_common()
868 dev_err(&intf->dev, "CDC Union missing and no IAD found\n"); in cdc_ncm_bind_common()
871 if (cdc_ncm_comm_intf_is_mbim(intf->cur_altsetting)) { in cdc_ncm_bind_common()
872 if (!ctx->mbim_desc) { in cdc_ncm_bind_common()
873 dev_err(&intf->dev, "MBIM functional descriptor missing\n"); in cdc_ncm_bind_common()
877 if (!ctx->ether_desc || !ctx->func_desc) { in cdc_ncm_bind_common()
878 dev_err(&intf->dev, "NCM or ECM functional descriptors missing\n"); in cdc_ncm_bind_common()
884 if (ctx->data != ctx->control) { in cdc_ncm_bind_common()
885 temp = usb_driver_claim_interface(driver, ctx->data, dev); in cdc_ncm_bind_common()
887 dev_err(&intf->dev, "failed to claim data intf\n"); in cdc_ncm_bind_common()
892 iface_no = ctx->data->cur_altsetting->desc.bInterfaceNumber; in cdc_ncm_bind_common()
894 /* Device-specific flags */ in cdc_ncm_bind_common()
895 ctx->drvflags = drvflags; in cdc_ncm_bind_common()
903 if (!(ctx->drvflags & CDC_MBIM_FLAG_AVOID_ALTSETTING_TOGGLE)) in cdc_ncm_bind_common()
904 usb_set_interface(dev->udev, iface_no, data_altsetting); in cdc_ncm_bind_common()
906 temp = usb_set_interface(dev->udev, iface_no, 0); in cdc_ncm_bind_common()
908 dev_dbg(&intf->dev, "set interface failed\n"); in cdc_ncm_bind_common()
924 temp = usb_set_interface(dev->udev, iface_no, data_altsetting); in cdc_ncm_bind_common()
926 dev_dbg(&intf->dev, "set interface failed\n"); in cdc_ncm_bind_common()
930 cdc_ncm_find_endpoints(dev, ctx->data); in cdc_ncm_bind_common()
931 cdc_ncm_find_endpoints(dev, ctx->control); in cdc_ncm_bind_common()
932 if (!dev->in || !dev->out || !dev->status) { in cdc_ncm_bind_common()
933 dev_dbg(&intf->dev, "failed to collect endpoints\n"); in cdc_ncm_bind_common()
937 usb_set_intfdata(ctx->control, dev); in cdc_ncm_bind_common()
939 if (ctx->ether_desc) { in cdc_ncm_bind_common()
940 temp = usbnet_get_ethernet_addr(dev, ctx->ether_desc->iMACAddress); in cdc_ncm_bind_common()
942 dev_err(&intf->dev, "failed to get mac address\n"); in cdc_ncm_bind_common()
945 dev_info(&intf->dev, "MAC-Address: %pM\n", dev->net->dev_addr); in cdc_ncm_bind_common()
952 if (ctx->drvflags & CDC_NCM_FLAG_NDP_TO_END) { in cdc_ncm_bind_common()
953 if (ctx->is_ndp16) { in cdc_ncm_bind_common()
954 ctx->delayed_ndp16 = kzalloc(ctx->max_ndp_size, GFP_KERNEL); in cdc_ncm_bind_common()
955 if (!ctx->delayed_ndp16) in cdc_ncm_bind_common()
958 ctx->delayed_ndp32 = kzalloc(ctx->max_ndp_size, GFP_KERNEL); in cdc_ncm_bind_common()
959 if (!ctx->delayed_ndp32) in cdc_ncm_bind_common()
962 dev_info(&intf->dev, "NDP will be placed at end of frame for this device."); in cdc_ncm_bind_common()
966 dev->net->ethtool_ops = &cdc_ncm_ethtool_ops; in cdc_ncm_bind_common()
969 dev->net->sysfs_groups[0] = &cdc_ncm_sysfs_attr_group; in cdc_ncm_bind_common()
972 dev->net->netdev_ops = &cdc_ncm_netdev_ops; in cdc_ncm_bind_common()
973 dev->net->max_mtu = cdc_ncm_max_dgram_size(dev) - cdc_ncm_eth_hlen(dev); in cdc_ncm_bind_common()
978 usb_set_intfdata(ctx->control, NULL); in cdc_ncm_bind_common()
979 usb_set_intfdata(ctx->data, NULL); in cdc_ncm_bind_common()
980 if (ctx->data != ctx->control) in cdc_ncm_bind_common()
981 usb_driver_release_interface(driver, ctx->data); in cdc_ncm_bind_common()
983 cdc_ncm_free((struct cdc_ncm_ctx *)dev->data[0]); in cdc_ncm_bind_common()
984 dev->data[0] = 0; in cdc_ncm_bind_common()
985 dev_info(&intf->dev, "bind() failure\n"); in cdc_ncm_bind_common()
986 return -ENODEV; in cdc_ncm_bind_common()
992 struct cdc_ncm_ctx *ctx = (struct cdc_ncm_ctx *)dev->data[0]; in cdc_ncm_unbind()
998 atomic_set(&ctx->stop, 1); in cdc_ncm_unbind()
1000 hrtimer_cancel(&ctx->tx_timer); in cdc_ncm_unbind()
1002 tasklet_kill(&ctx->bh); in cdc_ncm_unbind()
1005 if (ctx->control == ctx->data) in cdc_ncm_unbind()
1006 ctx->data = NULL; in cdc_ncm_unbind()
1008 /* disconnect master --> disconnect slave */ in cdc_ncm_unbind()
1009 if (intf == ctx->control && ctx->data) { in cdc_ncm_unbind()
1010 usb_set_intfdata(ctx->data, NULL); in cdc_ncm_unbind()
1011 usb_driver_release_interface(driver, ctx->data); in cdc_ncm_unbind()
1012 ctx->data = NULL; in cdc_ncm_unbind()
1014 } else if (intf == ctx->data && ctx->control) { in cdc_ncm_unbind()
1015 usb_set_intfdata(ctx->control, NULL); in cdc_ncm_unbind()
1016 usb_driver_release_interface(driver, ctx->control); in cdc_ncm_unbind()
1017 ctx->control = NULL; in cdc_ncm_unbind()
1047 if (intf->num_altsetting < 2) in cdc_ncm_select_altsetting()
1048 return intf->cur_altsetting->desc.bAlternateSetting; in cdc_ncm_select_altsetting()
1063 return -ENODEV; in cdc_ncm_bind()
1065 /* The NCM data altsetting is fixed, so we hard-coded it. in cdc_ncm_bind()
1074 size_t align = ALIGN(skb->len, modulus) - skb->len + remainder; in cdc_ncm_align_tail()
1076 if (skb->len + align > max) in cdc_ncm_align_tail()
1077 align = max - skb->len; in cdc_ncm_align_tail()
1088 struct usb_cdc_ncm_nth16 *nth16 = (void *)skb->data; in cdc_ncm_ndp16()
1089 size_t ndpoffset = le16_to_cpu(nth16->wNdpIndex); in cdc_ncm_ndp16()
1095 if (ctx->drvflags & CDC_NCM_FLAG_NDP_TO_END) { in cdc_ncm_ndp16()
1096 if (ctx->delayed_ndp16->dwSignature == sign) in cdc_ncm_ndp16()
1097 return ctx->delayed_ndp16; in cdc_ncm_ndp16()
1103 else if (ctx->delayed_ndp16->dwSignature) in cdc_ncm_ndp16()
1109 ndp16 = (struct usb_cdc_ncm_ndp16 *)(skb->data + ndpoffset); in cdc_ncm_ndp16()
1110 if (ndp16->dwSignature == sign) in cdc_ncm_ndp16()
1112 ndpoffset = le16_to_cpu(ndp16->wNextNdpIndex); in cdc_ncm_ndp16()
1116 if (!(ctx->drvflags & CDC_NCM_FLAG_NDP_TO_END)) in cdc_ncm_ndp16()
1117 cdc_ncm_align_tail(skb, ctx->tx_ndp_modulus, 0, ctx->tx_curr_size); in cdc_ncm_ndp16()
1120 if ((ctx->tx_curr_size - skb->len - reserve) < ctx->max_ndp_size) in cdc_ncm_ndp16()
1125 ndp16->wNextNdpIndex = cpu_to_le16(skb->len); in cdc_ncm_ndp16()
1127 nth16->wNdpIndex = cpu_to_le16(skb->len); in cdc_ncm_ndp16()
1130 if (!(ctx->drvflags & CDC_NCM_FLAG_NDP_TO_END)) in cdc_ncm_ndp16()
1131 ndp16 = skb_put_zero(skb, ctx->max_ndp_size); in cdc_ncm_ndp16()
1133 ndp16 = ctx->delayed_ndp16; in cdc_ncm_ndp16()
1135 ndp16->dwSignature = sign; in cdc_ncm_ndp16()
1136 ndp16->wLength = cpu_to_le16(sizeof(struct usb_cdc_ncm_ndp16) + sizeof(struct usb_cdc_ncm_dpe16)); in cdc_ncm_ndp16()
1143 struct usb_cdc_ncm_nth32 *nth32 = (void *)skb->data; in cdc_ncm_ndp32()
1144 size_t ndpoffset = le32_to_cpu(nth32->dwNdpIndex); in cdc_ncm_ndp32()
1150 if (ctx->drvflags & CDC_NCM_FLAG_NDP_TO_END) { in cdc_ncm_ndp32()
1151 if (ctx->delayed_ndp32->dwSignature == sign) in cdc_ncm_ndp32()
1152 return ctx->delayed_ndp32; in cdc_ncm_ndp32()
1158 else if (ctx->delayed_ndp32->dwSignature) in cdc_ncm_ndp32()
1164 ndp32 = (struct usb_cdc_ncm_ndp32 *)(skb->data + ndpoffset); in cdc_ncm_ndp32()
1165 if (ndp32->dwSignature == sign) in cdc_ncm_ndp32()
1167 ndpoffset = le32_to_cpu(ndp32->dwNextNdpIndex); in cdc_ncm_ndp32()
1171 if (!(ctx->drvflags & CDC_NCM_FLAG_NDP_TO_END)) in cdc_ncm_ndp32()
1172 cdc_ncm_align_tail(skb, ctx->tx_ndp_modulus, 0, ctx->tx_curr_size); in cdc_ncm_ndp32()
1175 if ((ctx->tx_curr_size - skb->len - reserve) < ctx->max_ndp_size) in cdc_ncm_ndp32()
1180 ndp32->dwNextNdpIndex = cpu_to_le32(skb->len); in cdc_ncm_ndp32()
1182 nth32->dwNdpIndex = cpu_to_le32(skb->len); in cdc_ncm_ndp32()
1185 if (!(ctx->drvflags & CDC_NCM_FLAG_NDP_TO_END)) in cdc_ncm_ndp32()
1186 ndp32 = skb_put_zero(skb, ctx->max_ndp_size); in cdc_ncm_ndp32()
1188 ndp32 = ctx->delayed_ndp32; in cdc_ncm_ndp32()
1190 ndp32->dwSignature = sign; in cdc_ncm_ndp32()
1191 ndp32->wLength = cpu_to_le16(sizeof(struct usb_cdc_ncm_ndp32) + sizeof(struct usb_cdc_ncm_dpe32)); in cdc_ncm_ndp32()
1198 struct cdc_ncm_ctx *ctx = (struct cdc_ncm_ctx *)dev->data[0]; in cdc_ncm_fill_tx_frame()
1213 /* When our NDP gets written in cdc_ncm_ndp(), then skb_out->len gets updated in cdc_ncm_fill_tx_frame()
1216 if (ctx->drvflags & CDC_NCM_FLAG_NDP_TO_END) in cdc_ncm_fill_tx_frame()
1217 delayed_ndp_size = ctx->max_ndp_size + in cdc_ncm_fill_tx_frame()
1219 ctx->tx_ndp_modulus, in cdc_ncm_fill_tx_frame()
1220 ctx->tx_modulus + ctx->tx_remainder) - 1; in cdc_ncm_fill_tx_frame()
1226 swap(skb, ctx->tx_rem_skb); in cdc_ncm_fill_tx_frame()
1227 swap(sign, ctx->tx_rem_sign); in cdc_ncm_fill_tx_frame()
1233 skb_out = ctx->tx_curr_skb; in cdc_ncm_fill_tx_frame()
1237 if (ctx->tx_low_mem_val == 0) { in cdc_ncm_fill_tx_frame()
1238 ctx->tx_curr_size = ctx->tx_max; in cdc_ncm_fill_tx_frame()
1239 skb_out = alloc_skb(ctx->tx_curr_size, GFP_ATOMIC); in cdc_ncm_fill_tx_frame()
1246 ctx->tx_low_mem_max_cnt = min(ctx->tx_low_mem_max_cnt + 1, in cdc_ncm_fill_tx_frame()
1248 ctx->tx_low_mem_val = ctx->tx_low_mem_max_cnt; in cdc_ncm_fill_tx_frame()
1257 ctx->tx_curr_size = max(skb->len, in cdc_ncm_fill_tx_frame()
1260 ctx->tx_curr_size = USB_CDC_NCM_NTB_MIN_OUT_SIZE; in cdc_ncm_fill_tx_frame()
1261 skb_out = alloc_skb(ctx->tx_curr_size, GFP_ATOMIC); in cdc_ncm_fill_tx_frame()
1267 dev->net->stats.tx_dropped++; in cdc_ncm_fill_tx_frame()
1271 ctx->tx_low_mem_val--; in cdc_ncm_fill_tx_frame()
1273 if (ctx->is_ndp16) { in cdc_ncm_fill_tx_frame()
1274 /* fill out the initial 16-bit NTB header */ in cdc_ncm_fill_tx_frame()
1276 nth.nth16->dwSignature = cpu_to_le32(USB_CDC_NCM_NTH16_SIGN); in cdc_ncm_fill_tx_frame()
1277 nth.nth16->wHeaderLength = cpu_to_le16(sizeof(struct usb_cdc_ncm_nth16)); in cdc_ncm_fill_tx_frame()
1278 nth.nth16->wSequence = cpu_to_le16(ctx->tx_seq++); in cdc_ncm_fill_tx_frame()
1280 /* fill out the initial 32-bit NTB header */ in cdc_ncm_fill_tx_frame()
1282 nth.nth32->dwSignature = cpu_to_le32(USB_CDC_NCM_NTH32_SIGN); in cdc_ncm_fill_tx_frame()
1283 nth.nth32->wHeaderLength = cpu_to_le16(sizeof(struct usb_cdc_ncm_nth32)); in cdc_ncm_fill_tx_frame()
1284 nth.nth32->wSequence = cpu_to_le16(ctx->tx_seq++); in cdc_ncm_fill_tx_frame()
1288 ctx->tx_curr_frame_num = 0; in cdc_ncm_fill_tx_frame()
1291 ctx->tx_curr_frame_payload = 0; in cdc_ncm_fill_tx_frame()
1294 for (n = ctx->tx_curr_frame_num; n < ctx->tx_max_datagrams; n++) { in cdc_ncm_fill_tx_frame()
1297 skb = ctx->tx_rem_skb; in cdc_ncm_fill_tx_frame()
1298 sign = ctx->tx_rem_sign; in cdc_ncm_fill_tx_frame()
1299 ctx->tx_rem_skb = NULL; in cdc_ncm_fill_tx_frame()
1307 if (ctx->is_ndp16) in cdc_ncm_fill_tx_frame()
1308 ndp.ndp16 = cdc_ncm_ndp16(ctx, skb_out, sign, skb->len + ctx->tx_modulus + ctx->tx_remainder); in cdc_ncm_fill_tx_frame()
1310 ndp.ndp32 = cdc_ncm_ndp32(ctx, skb_out, sign, skb->len + ctx->tx_modulus + ctx->tx_remainder); in cdc_ncm_fill_tx_frame()
1313 cdc_ncm_align_tail(skb_out, ctx->tx_modulus, ctx->tx_remainder, ctx->tx_curr_size); in cdc_ncm_fill_tx_frame()
1316 if ((ctx->is_ndp16 && !ndp.ndp16) || (!ctx->is_ndp16 && !ndp.ndp32) || in cdc_ncm_fill_tx_frame()
1317 skb_out->len + skb->len + delayed_ndp_size > ctx->tx_curr_size) { in cdc_ncm_fill_tx_frame()
1322 dev->net->stats.tx_dropped++; in cdc_ncm_fill_tx_frame()
1324 /* no room for skb - store for later */ in cdc_ncm_fill_tx_frame()
1325 if (ctx->tx_rem_skb != NULL) { in cdc_ncm_fill_tx_frame()
1326 dev_kfree_skb_any(ctx->tx_rem_skb); in cdc_ncm_fill_tx_frame()
1327 dev->net->stats.tx_dropped++; in cdc_ncm_fill_tx_frame()
1329 ctx->tx_rem_skb = skb; in cdc_ncm_fill_tx_frame()
1330 ctx->tx_rem_sign = sign; in cdc_ncm_fill_tx_frame()
1333 ctx->tx_reason_ntb_full++; /* count reason for transmitting */ in cdc_ncm_fill_tx_frame()
1339 if (ctx->is_ndp16) { in cdc_ncm_fill_tx_frame()
1340 ndplen = le16_to_cpu(ndp.ndp16->wLength); in cdc_ncm_fill_tx_frame()
1341 index = (ndplen - sizeof(struct usb_cdc_ncm_ndp16)) / sizeof(struct usb_cdc_ncm_dpe16) - 1; in cdc_ncm_fill_tx_frame()
1344 ndp.ndp16->dpe16[index].wDatagramLength = cpu_to_le16(skb->len); in cdc_ncm_fill_tx_frame()
1345 ndp.ndp16->dpe16[index].wDatagramIndex = cpu_to_le16(skb_out->len); in cdc_ncm_fill_tx_frame()
1346 ndp.ndp16->wLength = cpu_to_le16(ndplen + sizeof(struct usb_cdc_ncm_dpe16)); in cdc_ncm_fill_tx_frame()
1348 ndplen = le16_to_cpu(ndp.ndp32->wLength); in cdc_ncm_fill_tx_frame()
1349 index = (ndplen - sizeof(struct usb_cdc_ncm_ndp32)) / sizeof(struct usb_cdc_ncm_dpe32) - 1; in cdc_ncm_fill_tx_frame()
1351 ndp.ndp32->dpe32[index].dwDatagramLength = cpu_to_le32(skb->len); in cdc_ncm_fill_tx_frame()
1352 ndp.ndp32->dpe32[index].dwDatagramIndex = cpu_to_le32(skb_out->len); in cdc_ncm_fill_tx_frame()
1353 ndp.ndp32->wLength = cpu_to_le16(ndplen + sizeof(struct usb_cdc_ncm_dpe32)); in cdc_ncm_fill_tx_frame()
1355 skb_put_data(skb_out, skb->data, skb->len); in cdc_ncm_fill_tx_frame()
1356 ctx->tx_curr_frame_payload += skb->len; /* count real tx payload data */ in cdc_ncm_fill_tx_frame()
1363 ctx->tx_reason_ndp_full++; /* count reason for transmitting */ in cdc_ncm_fill_tx_frame()
1372 dev->net->stats.tx_dropped++; in cdc_ncm_fill_tx_frame()
1375 ctx->tx_curr_frame_num = n; in cdc_ncm_fill_tx_frame()
1380 ctx->tx_curr_skb = skb_out; in cdc_ncm_fill_tx_frame()
1383 } else if ((n < ctx->tx_max_datagrams) && (ready2send == 0) && (ctx->timer_interval > 0)) { in cdc_ncm_fill_tx_frame()
1386 ctx->tx_curr_skb = skb_out; in cdc_ncm_fill_tx_frame()
1389 ctx->tx_timer_pending = CDC_NCM_TIMER_PENDING_CNT; in cdc_ncm_fill_tx_frame()
1393 if (n == ctx->tx_max_datagrams) in cdc_ncm_fill_tx_frame()
1394 ctx->tx_reason_max_datagram++; /* count reason for transmitting */ in cdc_ncm_fill_tx_frame()
1400 if (ctx->drvflags & CDC_NCM_FLAG_NDP_TO_END) { in cdc_ncm_fill_tx_frame()
1401 if (ctx->is_ndp16) { in cdc_ncm_fill_tx_frame()
1402 nth.nth16 = (struct usb_cdc_ncm_nth16 *)skb_out->data; in cdc_ncm_fill_tx_frame()
1403 cdc_ncm_align_tail(skb_out, ctx->tx_ndp_modulus, 0, ctx->tx_curr_size - ctx->max_ndp_size); in cdc_ncm_fill_tx_frame()
1404 nth.nth16->wNdpIndex = cpu_to_le16(skb_out->len); in cdc_ncm_fill_tx_frame()
1405 skb_put_data(skb_out, ctx->delayed_ndp16, ctx->max_ndp_size); in cdc_ncm_fill_tx_frame()
1407 /* Zero out delayed NDP - signature checking will naturally fail. */ in cdc_ncm_fill_tx_frame()
1408 ndp.ndp16 = memset(ctx->delayed_ndp16, 0, ctx->max_ndp_size); in cdc_ncm_fill_tx_frame()
1410 nth.nth32 = (struct usb_cdc_ncm_nth32 *)skb_out->data; in cdc_ncm_fill_tx_frame()
1411 cdc_ncm_align_tail(skb_out, ctx->tx_ndp_modulus, 0, ctx->tx_curr_size - ctx->max_ndp_size); in cdc_ncm_fill_tx_frame()
1412 nth.nth32->dwNdpIndex = cpu_to_le32(skb_out->len); in cdc_ncm_fill_tx_frame()
1413 skb_put_data(skb_out, ctx->delayed_ndp32, ctx->max_ndp_size); in cdc_ncm_fill_tx_frame()
1415 ndp.ndp32 = memset(ctx->delayed_ndp32, 0, ctx->max_ndp_size); in cdc_ncm_fill_tx_frame()
1419 /* If collected data size is less or equal ctx->min_tx_pkt in cdc_ncm_fill_tx_frame()
1428 if (!(dev->driver_info->flags & FLAG_SEND_ZLP) && in cdc_ncm_fill_tx_frame()
1429 skb_out->len > ctx->min_tx_pkt) { in cdc_ncm_fill_tx_frame()
1430 padding_count = ctx->tx_curr_size - skb_out->len; in cdc_ncm_fill_tx_frame()
1431 if (!WARN_ON(padding_count > ctx->tx_curr_size)) in cdc_ncm_fill_tx_frame()
1433 } else if (skb_out->len < ctx->tx_curr_size && in cdc_ncm_fill_tx_frame()
1434 (skb_out->len % dev->maxpacket) == 0) { in cdc_ncm_fill_tx_frame()
1439 if (ctx->is_ndp16) { in cdc_ncm_fill_tx_frame()
1440 nth.nth16 = (struct usb_cdc_ncm_nth16 *)skb_out->data; in cdc_ncm_fill_tx_frame()
1441 nth.nth16->wBlockLength = cpu_to_le16(skb_out->len); in cdc_ncm_fill_tx_frame()
1443 nth.nth32 = (struct usb_cdc_ncm_nth32 *)skb_out->data; in cdc_ncm_fill_tx_frame()
1444 nth.nth32->dwBlockLength = cpu_to_le32(skb_out->len); in cdc_ncm_fill_tx_frame()
1448 ctx->tx_curr_skb = NULL; in cdc_ncm_fill_tx_frame()
1451 ctx->tx_overhead += skb_out->len - ctx->tx_curr_frame_payload; in cdc_ncm_fill_tx_frame()
1452 ctx->tx_ntbs++; in cdc_ncm_fill_tx_frame()
1459 (long)ctx->tx_curr_frame_payload - skb_out->len); in cdc_ncm_fill_tx_frame()
1464 /* Start timer, if there is a remaining non-empty skb */ in cdc_ncm_fill_tx_frame()
1465 if (ctx->tx_curr_skb != NULL && n > 0) in cdc_ncm_fill_tx_frame()
1474 if (!(hrtimer_active(&ctx->tx_timer) || atomic_read(&ctx->stop))) in cdc_ncm_tx_timeout_start()
1475 hrtimer_start(&ctx->tx_timer, in cdc_ncm_tx_timeout_start()
1476 ctx->timer_interval, in cdc_ncm_tx_timeout_start()
1485 if (!atomic_read(&ctx->stop)) in cdc_ncm_tx_timer_cb()
1486 tasklet_schedule(&ctx->bh); in cdc_ncm_tx_timer_cb()
1493 struct usbnet *dev = ctx->dev; in cdc_ncm_txpath_bh()
1495 spin_lock(&ctx->mtx); in cdc_ncm_txpath_bh()
1496 if (ctx->tx_timer_pending != 0) { in cdc_ncm_txpath_bh()
1497 ctx->tx_timer_pending--; in cdc_ncm_txpath_bh()
1499 spin_unlock(&ctx->mtx); in cdc_ncm_txpath_bh()
1500 } else if (dev->net != NULL) { in cdc_ncm_txpath_bh()
1501 ctx->tx_reason_timeout++; /* count reason for transmitting */ in cdc_ncm_txpath_bh()
1502 spin_unlock(&ctx->mtx); in cdc_ncm_txpath_bh()
1503 netif_tx_lock_bh(dev->net); in cdc_ncm_txpath_bh()
1504 usbnet_start_xmit(NULL, dev->net); in cdc_ncm_txpath_bh()
1505 netif_tx_unlock_bh(dev->net); in cdc_ncm_txpath_bh()
1507 spin_unlock(&ctx->mtx); in cdc_ncm_txpath_bh()
1515 struct cdc_ncm_ctx *ctx = (struct cdc_ncm_ctx *)dev->data[0]; in cdc_ncm_tx_fixup()
1527 spin_lock_bh(&ctx->mtx); in cdc_ncm_tx_fixup()
1529 if (ctx->is_ndp16) in cdc_ncm_tx_fixup()
1534 spin_unlock_bh(&ctx->mtx); in cdc_ncm_tx_fixup()
1548 struct usbnet *dev = netdev_priv(skb_in->dev); in cdc_ncm_rx_verify_nth16()
1551 int ret = -EINVAL; in cdc_ncm_rx_verify_nth16()
1556 if (skb_in->len < (sizeof(struct usb_cdc_ncm_nth16) + in cdc_ncm_rx_verify_nth16()
1558 netif_dbg(dev, rx_err, dev->net, "frame too short\n"); in cdc_ncm_rx_verify_nth16()
1562 nth16 = (struct usb_cdc_ncm_nth16 *)skb_in->data; in cdc_ncm_rx_verify_nth16()
1564 if (nth16->dwSignature != cpu_to_le32(USB_CDC_NCM_NTH16_SIGN)) { in cdc_ncm_rx_verify_nth16()
1565 netif_dbg(dev, rx_err, dev->net, in cdc_ncm_rx_verify_nth16()
1567 le32_to_cpu(nth16->dwSignature)); in cdc_ncm_rx_verify_nth16()
1571 len = le16_to_cpu(nth16->wBlockLength); in cdc_ncm_rx_verify_nth16()
1572 if (len > ctx->rx_max) { in cdc_ncm_rx_verify_nth16()
1573 netif_dbg(dev, rx_err, dev->net, in cdc_ncm_rx_verify_nth16()
1574 "unsupported NTB block length %u/%u\n", len, in cdc_ncm_rx_verify_nth16()
1575 ctx->rx_max); in cdc_ncm_rx_verify_nth16()
1579 if ((ctx->rx_seq + 1) != le16_to_cpu(nth16->wSequence) && in cdc_ncm_rx_verify_nth16()
1580 (ctx->rx_seq || le16_to_cpu(nth16->wSequence)) && in cdc_ncm_rx_verify_nth16()
1581 !((ctx->rx_seq == 0xffff) && !le16_to_cpu(nth16->wSequence))) { in cdc_ncm_rx_verify_nth16()
1582 netif_dbg(dev, rx_err, dev->net, in cdc_ncm_rx_verify_nth16()
1584 ctx->rx_seq, le16_to_cpu(nth16->wSequence)); in cdc_ncm_rx_verify_nth16()
1586 ctx->rx_seq = le16_to_cpu(nth16->wSequence); in cdc_ncm_rx_verify_nth16()
1588 ret = le16_to_cpu(nth16->wNdpIndex); in cdc_ncm_rx_verify_nth16()
1596 struct usbnet *dev = netdev_priv(skb_in->dev); in cdc_ncm_rx_verify_nth32()
1599 int ret = -EINVAL; in cdc_ncm_rx_verify_nth32()
1604 if (skb_in->len < (sizeof(struct usb_cdc_ncm_nth32) + in cdc_ncm_rx_verify_nth32()
1606 netif_dbg(dev, rx_err, dev->net, "frame too short\n"); in cdc_ncm_rx_verify_nth32()
1610 nth32 = (struct usb_cdc_ncm_nth32 *)skb_in->data; in cdc_ncm_rx_verify_nth32()
1612 if (nth32->dwSignature != cpu_to_le32(USB_CDC_NCM_NTH32_SIGN)) { in cdc_ncm_rx_verify_nth32()
1613 netif_dbg(dev, rx_err, dev->net, in cdc_ncm_rx_verify_nth32()
1615 le32_to_cpu(nth32->dwSignature)); in cdc_ncm_rx_verify_nth32()
1619 len = le32_to_cpu(nth32->dwBlockLength); in cdc_ncm_rx_verify_nth32()
1620 if (len > ctx->rx_max) { in cdc_ncm_rx_verify_nth32()
1621 netif_dbg(dev, rx_err, dev->net, in cdc_ncm_rx_verify_nth32()
1622 "unsupported NTB block length %u/%u\n", len, in cdc_ncm_rx_verify_nth32()
1623 ctx->rx_max); in cdc_ncm_rx_verify_nth32()
1627 if ((ctx->rx_seq + 1) != le16_to_cpu(nth32->wSequence) && in cdc_ncm_rx_verify_nth32()
1628 (ctx->rx_seq || le16_to_cpu(nth32->wSequence)) && in cdc_ncm_rx_verify_nth32()
1629 !((ctx->rx_seq == 0xffff) && !le16_to_cpu(nth32->wSequence))) { in cdc_ncm_rx_verify_nth32()
1630 netif_dbg(dev, rx_err, dev->net, in cdc_ncm_rx_verify_nth32()
1632 ctx->rx_seq, le16_to_cpu(nth32->wSequence)); in cdc_ncm_rx_verify_nth32()
1634 ctx->rx_seq = le16_to_cpu(nth32->wSequence); in cdc_ncm_rx_verify_nth32()
1636 ret = le32_to_cpu(nth32->dwNdpIndex); in cdc_ncm_rx_verify_nth32()
1645 struct usbnet *dev = netdev_priv(skb_in->dev); in cdc_ncm_rx_verify_ndp16()
1647 int ret = -EINVAL; in cdc_ncm_rx_verify_ndp16()
1649 if ((ndpoffset + sizeof(struct usb_cdc_ncm_ndp16)) > skb_in->len) { in cdc_ncm_rx_verify_ndp16()
1650 netif_dbg(dev, rx_err, dev->net, "invalid NDP offset <%u>\n", in cdc_ncm_rx_verify_ndp16()
1654 ndp16 = (struct usb_cdc_ncm_ndp16 *)(skb_in->data + ndpoffset); in cdc_ncm_rx_verify_ndp16()
1656 if (le16_to_cpu(ndp16->wLength) < USB_CDC_NCM_NDP16_LENGTH_MIN) { in cdc_ncm_rx_verify_ndp16()
1657 netif_dbg(dev, rx_err, dev->net, "invalid DPT16 length <%u>\n", in cdc_ncm_rx_verify_ndp16()
1658 le16_to_cpu(ndp16->wLength)); in cdc_ncm_rx_verify_ndp16()
1662 ret = ((le16_to_cpu(ndp16->wLength) - in cdc_ncm_rx_verify_ndp16()
1665 ret--; /* we process NDP entries except for the last one */ in cdc_ncm_rx_verify_ndp16()
1668 ret * (sizeof(struct usb_cdc_ncm_dpe16))) > skb_in->len) { in cdc_ncm_rx_verify_ndp16()
1669 netif_dbg(dev, rx_err, dev->net, "Invalid nframes = %d\n", ret); in cdc_ncm_rx_verify_ndp16()
1670 ret = -EINVAL; in cdc_ncm_rx_verify_ndp16()
1681 struct usbnet *dev = netdev_priv(skb_in->dev); in cdc_ncm_rx_verify_ndp32()
1683 int ret = -EINVAL; in cdc_ncm_rx_verify_ndp32()
1685 if ((ndpoffset + sizeof(struct usb_cdc_ncm_ndp32)) > skb_in->len) { in cdc_ncm_rx_verify_ndp32()
1686 netif_dbg(dev, rx_err, dev->net, "invalid NDP offset <%u>\n", in cdc_ncm_rx_verify_ndp32()
1690 ndp32 = (struct usb_cdc_ncm_ndp32 *)(skb_in->data + ndpoffset); in cdc_ncm_rx_verify_ndp32()
1692 if (le16_to_cpu(ndp32->wLength) < USB_CDC_NCM_NDP32_LENGTH_MIN) { in cdc_ncm_rx_verify_ndp32()
1693 netif_dbg(dev, rx_err, dev->net, "invalid DPT32 length <%u>\n", in cdc_ncm_rx_verify_ndp32()
1694 le16_to_cpu(ndp32->wLength)); in cdc_ncm_rx_verify_ndp32()
1698 ret = ((le16_to_cpu(ndp32->wLength) - in cdc_ncm_rx_verify_ndp32()
1701 ret--; /* we process NDP entries except for the last one */ in cdc_ncm_rx_verify_ndp32()
1704 ret * (sizeof(struct usb_cdc_ncm_dpe32))) > skb_in->len) { in cdc_ncm_rx_verify_ndp32()
1705 netif_dbg(dev, rx_err, dev->net, "Invalid nframes = %d\n", ret); in cdc_ncm_rx_verify_ndp32()
1706 ret = -EINVAL; in cdc_ncm_rx_verify_ndp32()
1717 struct cdc_ncm_ctx *ctx = (struct cdc_ncm_ctx *)dev->data[0]; in cdc_ncm_rx_fixup()
1735 if (ctx->is_ndp16) in cdc_ncm_rx_fixup()
1744 if (ctx->is_ndp16) { in cdc_ncm_rx_fixup()
1749 ndp.ndp16 = (struct usb_cdc_ncm_ndp16 *)(skb_in->data + ndpoffset); in cdc_ncm_rx_fixup()
1751 if (ndp.ndp16->dwSignature != cpu_to_le32(USB_CDC_NCM_NDP16_NOCRC_SIGN)) { in cdc_ncm_rx_fixup()
1752 netif_dbg(dev, rx_err, dev->net, in cdc_ncm_rx_fixup()
1754 le32_to_cpu(ndp.ndp16->dwSignature)); in cdc_ncm_rx_fixup()
1757 dpe.dpe16 = ndp.ndp16->dpe16; in cdc_ncm_rx_fixup()
1763 ndp.ndp32 = (struct usb_cdc_ncm_ndp32 *)(skb_in->data + ndpoffset); in cdc_ncm_rx_fixup()
1765 if (ndp.ndp32->dwSignature != cpu_to_le32(USB_CDC_NCM_NDP32_NOCRC_SIGN)) { in cdc_ncm_rx_fixup()
1766 netif_dbg(dev, rx_err, dev->net, in cdc_ncm_rx_fixup()
1768 le32_to_cpu(ndp.ndp32->dwSignature)); in cdc_ncm_rx_fixup()
1771 dpe.dpe32 = ndp.ndp32->dpe32; in cdc_ncm_rx_fixup()
1775 if (ctx->is_ndp16) { in cdc_ncm_rx_fixup()
1776 offset = le16_to_cpu(dpe.dpe16->wDatagramIndex); in cdc_ncm_rx_fixup()
1777 len = le16_to_cpu(dpe.dpe16->wDatagramLength); in cdc_ncm_rx_fixup()
1779 offset = le32_to_cpu(dpe.dpe32->dwDatagramIndex); in cdc_ncm_rx_fixup()
1780 len = le32_to_cpu(dpe.dpe32->dwDatagramLength); in cdc_ncm_rx_fixup()
1793 /* sanity checking - watch out for integer wrap*/ in cdc_ncm_rx_fixup()
1794 if ((offset > skb_in->len) || (len > skb_in->len - offset) || in cdc_ncm_rx_fixup()
1795 (len > ctx->rx_max) || (len < ETH_HLEN)) { in cdc_ncm_rx_fixup()
1796 netif_dbg(dev, rx_err, dev->net, in cdc_ncm_rx_fixup()
1797 "invalid frame detected (ignored) offset[%u]=%u, length=%u, skb=%p\n", in cdc_ncm_rx_fixup()
1805 skb = netdev_alloc_skb_ip_align(dev->net, len); in cdc_ncm_rx_fixup()
1808 skb_put_data(skb, skb_in->data + offset, len); in cdc_ncm_rx_fixup()
1813 if (ctx->is_ndp16) in cdc_ncm_rx_fixup()
1820 if (ctx->is_ndp16) in cdc_ncm_rx_fixup()
1821 ndpoffset = le16_to_cpu(ndp.ndp16->wNextNdpIndex); in cdc_ncm_rx_fixup()
1823 ndpoffset = le32_to_cpu(ndp.ndp32->dwNextNdpIndex); in cdc_ncm_rx_fixup()
1825 if (ndpoffset && loopcount--) in cdc_ncm_rx_fixup()
1829 ctx->rx_overhead += skb_in->len - payload; in cdc_ncm_rx_fixup()
1830 ctx->rx_ntbs++; in cdc_ncm_rx_fixup()
1843 dev->rx_speed = le32_to_cpu(data->DLBitRRate); in cdc_ncm_speed_change()
1844 dev->tx_speed = le32_to_cpu(data->ULBitRate); in cdc_ncm_speed_change()
1851 if (urb->actual_length < sizeof(*event)) in cdc_ncm_status()
1854 /* test for split data in 8-byte chunks */ in cdc_ncm_status()
1855 if (test_and_clear_bit(EVENT_STS_SPLIT, &dev->flags)) { in cdc_ncm_status()
1857 (struct usb_cdc_speed_change *)urb->transfer_buffer); in cdc_ncm_status()
1861 event = urb->transfer_buffer; in cdc_ncm_status()
1863 switch (event->bNotificationType) { in cdc_ncm_status()
1873 if (netif_carrier_ok(dev->net) != !!event->wValue) in cdc_ncm_status()
1874 usbnet_link_change(dev, !!event->wValue, 0); in cdc_ncm_status()
1878 if (urb->actual_length < (sizeof(*event) + in cdc_ncm_status()
1880 set_bit(EVENT_STS_SPLIT, &dev->flags); in cdc_ncm_status()
1887 dev_dbg(&dev->udev->dev, in cdc_ncm_status()
1889 event->bNotificationType); in cdc_ncm_status()
2020 /* u-blox TOBY-L4 */
2037 /* Generic CDC-NCM devices */