usb: gadget: f_ncm: Fix NTP-32 support
authorRomain Izard <romain.izard.pro@gmail.com>
Tue, 16 Apr 2019 14:07:31 +0000 (16:07 +0200)
committerFelipe Balbi <felipe.balbi@linux.intel.com>
Fri, 3 May 2019 06:13:47 +0000 (09:13 +0300)
When connecting a CDC-NCM gadget to an host that uses the NTP-32 mode,
or that relies on the default CRC setting, the current implementation gets
confused, and does not expect the correct signature for its packets.

Fix this, by ensuring that the ndp_sign member in the f_ncm structure
always contain a valid value.

Signed-off-by: Romain Izard <romain.izard.pro@gmail.com>
Signed-off-by: Felipe Balbi <felipe.balbi@linux.intel.com>
drivers/usb/gadget/function/f_ncm.c

index 5780fba..d5c47e7 100644 (file)
@@ -35,9 +35,7 @@
 
 /* to trigger crc/non-crc ndp signature */
 
-#define NCM_NDP_HDR_CRC_MASK   0x01000000
 #define NCM_NDP_HDR_CRC                0x01000000
-#define NCM_NDP_HDR_NOCRC      0x00000000
 
 enum ncm_notify_state {
        NCM_NOTIFY_NONE,                /* don't notify */
@@ -526,6 +524,7 @@ static inline void ncm_reset_values(struct f_ncm *ncm)
 {
        ncm->parser_opts = &ndp16_opts;
        ncm->is_crc = false;
+       ncm->ndp_sign = ncm->parser_opts->ndp_sign;
        ncm->port.cdc_filter = DEFAULT_FILTER;
 
        /* doesn't make sense for ncm, fixed size used */
@@ -805,25 +804,20 @@ static int ncm_setup(struct usb_function *f, const struct usb_ctrlrequest *ctrl)
        case ((USB_DIR_OUT | USB_TYPE_CLASS | USB_RECIP_INTERFACE) << 8)
                | USB_CDC_SET_CRC_MODE:
        {
-               int ndp_hdr_crc = 0;
-
                if (w_length != 0 || w_index != ncm->ctrl_id)
                        goto invalid;
                switch (w_value) {
                case 0x0000:
                        ncm->is_crc = false;
-                       ndp_hdr_crc = NCM_NDP_HDR_NOCRC;
                        DBG(cdev, "non-CRC mode selected\n");
                        break;
                case 0x0001:
                        ncm->is_crc = true;
-                       ndp_hdr_crc = NCM_NDP_HDR_CRC;
                        DBG(cdev, "CRC mode selected\n");
                        break;
                default:
                        goto invalid;
                }
-               ncm->ndp_sign = ncm->parser_opts->ndp_sign | ndp_hdr_crc;
                value = 0;
                break;
        }
@@ -840,6 +834,8 @@ invalid:
                        ctrl->bRequestType, ctrl->bRequest,
                        w_value, w_index, w_length);
        }
+       ncm->ndp_sign = ncm->parser_opts->ndp_sign |
+               (ncm->is_crc ? NCM_NDP_HDR_CRC : 0);
 
        /* respond with data transfer or status phase? */
        if (value >= 0) {