Received: by 2002:a05:6a10:206:0:0:0:0 with SMTP id 6csp4706669pxj; Wed, 12 May 2021 11:20:15 -0700 (PDT) X-Google-Smtp-Source: ABdhPJxao4fWirvUXXxE/MOTKQN40PCNemb6/9iFoZ2wldtUo5L1uNdGDn5nDfaITQOFE60FH4Kk X-Received: by 2002:a17:906:f295:: with SMTP id gu21mr38248276ejb.500.1620843615584; Wed, 12 May 2021 11:20:15 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1620843615; cv=none; d=google.com; s=arc-20160816; b=u3/+anJ30vUmxXsAUo144x7T2+LrSz99o2LKFIu9dzjWiqOibarp8GeiR3jEOovlHZ zfZJIpkLMjWlPhw2eNa5I2VMd8LxuFdJoXjMwHsoBvBRe1f1co2l1oRTOBSgn8V5vyg0 wnNcIALAY9i0YePVAkjgHProafFRv5+gQTJKP9x+vp2rgvAw62MSN2oK3U34W7IASsYS yu0xwkRmvfXteHSQcI2l+Jpp6d02PRn9bBcja7af0wgt39BYGEuw0WLJHiXnQRW4qewj AhSSTozEWxqhtnVC0B2nf+3tDq3Q7vWOpMSb8QzoOQ4wE+KRiLxrcN+5yGZpfw5YHXqo QyLw== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=list-id:precedence:content-transfer-encoding:mime-version :user-agent:references:in-reply-to:message-id:date:subject:cc:to :from:dkim-signature; bh=+JtJh5jePxihIEdxTvF7KmO/mpep8xEo0lx1N7sVFzA=; b=GvOBUvRPEDcfg9mzNxFAtHNsO3ABUAJGyJ4g57e3df7xJ4vcpXHG80PSXWvx1JqoNQ rN4VUqHKlf65eQ5njeNhCQN3t8YfqEln/BTI4qramcAbQbN5XbWGhdel2fUxmbEW5j77 OPysrelKZXef/S50BxRiqBH2EIvaT6UyBTHk5IE/OYiiTJLvDkYt5gOdDGYU6BDV7grA a4/t8sejTnl35gVQOK8VtGUXs8Jo62e2KAN3rhuQroPZUfnz96tA3JkU3KEn4Eei6+7G EwK6aT3+WBhzTMzpwULp7VnuCiJityOiDkofbeXZZyLVVV/iFc4urUFdIYxpywsoDsdt 9qqw== ARC-Authentication-Results: i=1; mx.google.com; dkim=pass header.i=@linuxfoundation.org header.s=korg header.b=Mfd71kTg; spf=pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 23.128.96.18 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=linuxfoundation.org Return-Path: Received: from vger.kernel.org (vger.kernel.org. [23.128.96.18]) by mx.google.com with ESMTP id dn27si279872edb.326.2021.05.12.11.19.51; Wed, 12 May 2021 11:20:15 -0700 (PDT) Received-SPF: pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 23.128.96.18 as permitted sender) client-ip=23.128.96.18; Authentication-Results: mx.google.com; dkim=pass header.i=@linuxfoundation.org header.s=korg header.b=Mfd71kTg; spf=pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 23.128.96.18 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=linuxfoundation.org Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1354002AbhELSQN (ORCPT + 99 others); Wed, 12 May 2021 14:16:13 -0400 Received: from mail.kernel.org ([198.145.29.99]:43696 "EHLO mail.kernel.org" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S241214AbhELQ0x (ORCPT ); Wed, 12 May 2021 12:26:53 -0400 Received: by mail.kernel.org (Postfix) with ESMTPSA id 7B86861E04; Wed, 12 May 2021 15:50:41 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=linuxfoundation.org; s=korg; t=1620834642; bh=JOjVieOFzp5Rry6thbHGsf8Ji+h1yWGuq29DvHerkEM=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=Mfd71kTgvajDAomrEPffH13fSf3Rah/ebKkY8E3y2Y0uh3VWuKzGLt0OLPoueRFLz FwKwuKIju1bEREVZOi7Ehl8b6fOtw1oAOL3xBkO10trwr/XYA6pL39rviLGh4A1rKM CN7J3GKRkQWralM1ThcztayU/BZBbgwm77MwLCDM= From: Greg Kroah-Hartman To: linux-kernel@vger.kernel.org Cc: Greg Kroah-Hartman , stable@vger.kernel.org, Yaqii Wu , Chunfeng Yun Subject: [PATCH 5.12 025/677] usb: xhci-mtk: improve bandwidth scheduling with TT Date: Wed, 12 May 2021 16:41:11 +0200 Message-Id: <20210512144838.066443335@linuxfoundation.org> X-Mailer: git-send-email 2.31.1 In-Reply-To: <20210512144837.204217980@linuxfoundation.org> References: <20210512144837.204217980@linuxfoundation.org> User-Agent: quilt/0.66 MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org From: Chunfeng Yun commit e19ee44a3d07c232f9241024dab1ebd0748cdf5f upstream. When the USB headset is plug into an external hub, sometimes can't set config due to not enough bandwidth, so need improve LS/FS INT/ISOC bandwidth scheduling with TT. Fixes: 54f6a8af3722 ("usb: xhci-mtk: skip dropping bandwidth of unchecked endpoints") Cc: stable Signed-off-by: Yaqii Wu Signed-off-by: Chunfeng Yun Link: https://lore.kernel.org/r/2f30e81400a59afef5f8231c98149169c7520519.1615170625.git.chunfeng.yun@mediatek.com Signed-off-by: Greg Kroah-Hartman --- drivers/usb/host/xhci-mtk-sch.c | 74 ++++++++++++++++++++++++++++++++-------- drivers/usb/host/xhci-mtk.h | 6 ++- 2 files changed, 64 insertions(+), 16 deletions(-) --- a/drivers/usb/host/xhci-mtk-sch.c +++ b/drivers/usb/host/xhci-mtk-sch.c @@ -378,6 +378,31 @@ static void update_bus_bw(struct mu3h_sc sch_ep->allocated = used; } +static int check_fs_bus_bw(struct mu3h_sch_ep_info *sch_ep, int offset) +{ + struct mu3h_sch_tt *tt = sch_ep->sch_tt; + u32 num_esit, tmp; + int base; + int i, j; + + num_esit = XHCI_MTK_MAX_ESIT / sch_ep->esit; + for (i = 0; i < num_esit; i++) { + base = offset + i * sch_ep->esit; + + /* + * Compared with hs bus, no matter what ep type, + * the hub will always delay one uframe to send data + */ + for (j = 0; j < sch_ep->cs_count; j++) { + tmp = tt->fs_bus_bw[base + j] + sch_ep->bw_cost_per_microframe; + if (tmp > FS_PAYLOAD_MAX) + return -ERANGE; + } + } + + return 0; +} + static int check_sch_tt(struct usb_device *udev, struct mu3h_sch_ep_info *sch_ep, u32 offset) { @@ -402,7 +427,7 @@ static int check_sch_tt(struct usb_devic return -ERANGE; for (i = 0; i < sch_ep->cs_count; i++) - if (test_bit(offset + i, tt->split_bit_map)) + if (test_bit(offset + i, tt->ss_bit_map)) return -ERANGE; } else { @@ -432,7 +457,7 @@ static int check_sch_tt(struct usb_devic cs_count = 7; /* HW limit */ for (i = 0; i < cs_count + 2; i++) { - if (test_bit(offset + i, tt->split_bit_map)) + if (test_bit(offset + i, tt->ss_bit_map)) return -ERANGE; } @@ -448,24 +473,44 @@ static int check_sch_tt(struct usb_devic sch_ep->num_budget_microframes = sch_ep->esit; } - return 0; + return check_fs_bus_bw(sch_ep, offset); } static void update_sch_tt(struct usb_device *udev, - struct mu3h_sch_ep_info *sch_ep) + struct mu3h_sch_ep_info *sch_ep, bool used) { struct mu3h_sch_tt *tt = sch_ep->sch_tt; u32 base, num_esit; + int bw_updated; + int bits; int i, j; num_esit = XHCI_MTK_MAX_ESIT / sch_ep->esit; + bits = (sch_ep->ep_type == ISOC_OUT_EP) ? sch_ep->cs_count : 1; + + if (used) + bw_updated = sch_ep->bw_cost_per_microframe; + else + bw_updated = -sch_ep->bw_cost_per_microframe; + for (i = 0; i < num_esit; i++) { base = sch_ep->offset + i * sch_ep->esit; - for (j = 0; j < sch_ep->num_budget_microframes; j++) - set_bit(base + j, tt->split_bit_map); + + for (j = 0; j < bits; j++) { + if (used) + set_bit(base + j, tt->ss_bit_map); + else + clear_bit(base + j, tt->ss_bit_map); + } + + for (j = 0; j < sch_ep->cs_count; j++) + tt->fs_bus_bw[base + j] += bw_updated; } - list_add_tail(&sch_ep->tt_endpoint, &tt->ep_list); + if (used) + list_add_tail(&sch_ep->tt_endpoint, &tt->ep_list); + else + list_del(&sch_ep->tt_endpoint); } static int check_sch_bw(struct usb_device *udev, @@ -535,7 +580,7 @@ static int check_sch_bw(struct usb_devic if (!tt_offset_ok) return -ERANGE; - update_sch_tt(udev, sch_ep); + update_sch_tt(udev, sch_ep, 1); } /* update bus bandwidth info */ @@ -548,15 +593,16 @@ static void destroy_sch_ep(struct usb_de struct mu3h_sch_bw_info *sch_bw, struct mu3h_sch_ep_info *sch_ep) { /* only release ep bw check passed by check_sch_bw() */ - if (sch_ep->allocated) + if (sch_ep->allocated) { update_bus_bw(sch_bw, sch_ep, 0); + if (sch_ep->sch_tt) + update_sch_tt(udev, sch_ep, 0); + } - list_del(&sch_ep->endpoint); - - if (sch_ep->sch_tt) { - list_del(&sch_ep->tt_endpoint); + if (sch_ep->sch_tt) drop_tt(udev); - } + + list_del(&sch_ep->endpoint); kfree(sch_ep); } --- a/drivers/usb/host/xhci-mtk.h +++ b/drivers/usb/host/xhci-mtk.h @@ -20,13 +20,15 @@ #define XHCI_MTK_MAX_ESIT 64 /** - * @split_bit_map: used to avoid split microframes overlay + * @ss_bit_map: used to avoid start split microframes overlay + * @fs_bus_bw: array to keep track of bandwidth already used for FS * @ep_list: Endpoints using this TT * @usb_tt: usb TT related * @tt_port: TT port number */ struct mu3h_sch_tt { - DECLARE_BITMAP(split_bit_map, XHCI_MTK_MAX_ESIT); + DECLARE_BITMAP(ss_bit_map, XHCI_MTK_MAX_ESIT); + u32 fs_bus_bw[XHCI_MTK_MAX_ESIT]; struct list_head ep_list; struct usb_tt *usb_tt; int tt_port;