Received: by 2002:a05:7412:b130:b0:e2:908c:2ebd with SMTP id az48csp1313212rdb; Sat, 18 Nov 2023 10:57:21 -0800 (PST) X-Google-Smtp-Source: AGHT+IEgEJ3JTLyoTx481qvsHUX20I+c2hKbnHT3Y801Xw7IPUSxpEFUXBpk1Md98sFMLx4nkgSQ X-Received: by 2002:a17:902:d352:b0:1c9:c6f4:e0c3 with SMTP id l18-20020a170902d35200b001c9c6f4e0c3mr4134379plk.62.1700333841558; Sat, 18 Nov 2023 10:57:21 -0800 (PST) ARC-Seal: i=1; a=rsa-sha256; t=1700333841; cv=none; d=google.com; s=arc-20160816; b=vLPhu2ZYVDy+w+D588anYiDn9T5Qv6ig3iNROQwZ2U4Nb1v9P28CMi9+9Ffuas1b/g h6kHn5skKIN0hguSZ4CyDR+Lh0GNRUgJVez0vNkgPwbZEkLdyVYt26XbZqi0SPlbOA3R t2VJ+VwM2rAoqF/2uSdrZXYd0CIvJFIRoQg9M5S7BEEK/aQEr9y2WHI9D+zuwVBf3Qpk 0ynsF7h5Q2pm0Y8X8SXnNMpPs8cgl8TLYR3piB1/umENqd7KlZs46wkhASvqL0+bktMH 0mboIxMmsTBwrj/hdCuJdKdqQ2TLJsewsHLVP6jCfKsXrFoZ//uPxS2HHneLxWhGGS7S dsig== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=list-id:precedence:in-reply-to:content-disposition:mime-version :references:message-id:subject:cc:to:from:date:dkim-signature; bh=b5JCReSehGd9vgarmSFVhXVxVGPZtnscv9/0QR9Wvgw=; fh=dBSj1Anongxm3AqEVsAoqej2eyguUa3eeydsriREnjo=; b=RmlYKgtl2v5lprc4YUovG2cDzZnuZEi0jZ/1vv/IuRQ95ecem/7ONrGJeeeFuWsGfy pZvV/C/hqrBSdvKji3kzyBrSqhWSp14ZA1MG595lm/vXTOc2MWIuR3AlQzZGzkstRDjr kPnGZXCygEd4cu4tIX6cWc4b0Dfu8p5KIeVxzN+tqWMCWpQagwnDFDm3kHOCih43x3nZ ImCmPIsTtS96zShn2RC8ziS8aQm3/ptSGypG3mlFGrJ9/GKK8Z2CeXJNK45PdKlVe16W aWdRFu/aOkgPl5GcWasFGLUG7wVRY51qlwdq8fN0Gb/MZdZZvvGNVUWGWou37luiDZu7 KJuA== ARC-Authentication-Results: i=1; mx.google.com; dkim=pass header.i=@lunn.ch header.s=20171124 header.b=e5wJMpE9; spf=pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 23.128.96.37 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=lunn.ch Return-Path: Received: from snail.vger.email (snail.vger.email. [23.128.96.37]) by mx.google.com with ESMTPS id n10-20020a170902d2ca00b001cc407388a8si461282plc.337.2023.11.18.10.57.20 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Sat, 18 Nov 2023 10:57:21 -0800 (PST) Received-SPF: pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 23.128.96.37 as permitted sender) client-ip=23.128.96.37; Authentication-Results: mx.google.com; dkim=pass header.i=@lunn.ch header.s=20171124 header.b=e5wJMpE9; spf=pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 23.128.96.37 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=lunn.ch Received: from out1.vger.email (depot.vger.email [IPv6:2620:137:e000::3:0]) by snail.vger.email (Postfix) with ESMTP id 2AA628070797; Sat, 18 Nov 2023 10:56:48 -0800 (PST) X-Virus-Status: Clean X-Virus-Scanned: clamav-milter 0.103.11 at snail.vger.email Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S229662AbjKRSyu (ORCPT + 99 others); Sat, 18 Nov 2023 13:54:50 -0500 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:41410 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S229478AbjKRSyt (ORCPT ); Sat, 18 Nov 2023 13:54:49 -0500 Received: from vps0.lunn.ch (vps0.lunn.ch [156.67.10.101]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id ACA65F2; Sat, 18 Nov 2023 10:54:43 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=lunn.ch; s=20171124; h=In-Reply-To:Content-Disposition:Content-Type:MIME-Version: References:Message-ID:Subject:Cc:To:From:Date:From:Sender:Reply-To:Subject: Date:Message-ID:To:Cc:MIME-Version:Content-Type:Content-Transfer-Encoding: Content-ID:Content-Description:Content-Disposition:In-Reply-To:References; bh=b5JCReSehGd9vgarmSFVhXVxVGPZtnscv9/0QR9Wvgw=; b=e5wJMpE9Tmh6r68FpqiceA9rhG o8drF/CTrDqcdPP+9WDA8GtTxWn2jrpb8JnvRazj8r2N82ceUDUKs/OAzLaQUKuPN/tJlLWL2rGWE V1FQTBvNdf4pxOm4+l0xWTTIVcLohoIHw8pYw/ObMlE7hadsh2IR/HcoAggBcZryJ9mI=; Received: from andrew by vps0.lunn.ch with local (Exim 4.94.2) (envelope-from ) id 1r4QSc-000WY3-Ks; Sat, 18 Nov 2023 19:54:30 +0100 Date: Sat, 18 Nov 2023 19:54:30 +0100 From: Andrew Lunn To: Kory Maincent Cc: "David S. Miller" , Eric Dumazet , Jakub Kicinski , Paolo Abeni , Jonathan Corbet , Luis Chamberlain , Russ Weight , Greg Kroah-Hartman , "Rafael J. Wysocki" , Rob Herring , Krzysztof Kozlowski , Conor Dooley , Thomas Petazzoni , netdev@vger.kernel.org, linux-kernel@vger.kernel.org, linux-doc@vger.kernel.org, devicetree@vger.kernel.org Subject: Re: [PATCH net-next 9/9] net: pse-pd: Add PD692x0 PSE controller driver Message-ID: <45694d77-bcf8-4377-9aa0-046796de8d74@lunn.ch> References: <20231116-feature_poe-v1-0-be48044bf249@bootlin.com> <20231116-feature_poe-v1-9-be48044bf249@bootlin.com> MIME-Version: 1.0 Content-Type: text/plain; charset=us-ascii Content-Disposition: inline In-Reply-To: <20231116-feature_poe-v1-9-be48044bf249@bootlin.com> X-Spam-Status: No, score=-2.1 required=5.0 tests=BAYES_00,DKIM_SIGNED, DKIM_VALID,DKIM_VALID_AU,DKIM_VALID_EF,RCVD_IN_DNSWL_BLOCKED, SPF_HELO_PASS,SPF_PASS,T_SCC_BODY_TEXT_LINE autolearn=ham autolearn_force=no version=3.4.6 X-Spam-Checker-Version: SpamAssassin 3.4.6 (2021-04-09) on lindbergh.monkeyblade.net Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org X-Greylist: Sender passed SPF test, not delayed by milter-greylist-4.6.4 (snail.vger.email [0.0.0.0]); Sat, 18 Nov 2023 10:56:48 -0800 (PST) > +struct pd692x0_priv { > + struct i2c_client *client; > + struct pse_controller_dev pcdev; > + > + enum pd692x0_fw_state fw_state; > + struct fw_upload *fwl; > + bool cancel_request:1; > + > + u8 msg_id; > + bool last_cmd_key:1; Does a bool bit field of size 1 make any sense? I would also put the two bitfields next to each other, and the compiler might then pack them into the same word. The base type of a u8 would allow the compile to put it next to the msg_id without any padding. > + unsigned long last_cmd_key_time; > + > + enum ethtool_pse_admin_state admin_state[PD692X0_MAX_LOGICAL_PORTS]; > +}; > + > +/* Template list of the fixed bytes of the communication messages */ > +static const struct pd692x0_msg pd692x0_msg_template_list[PD692X0_MSG_CNT] = { > + [PD692X0_MSG_RESET] = { > + .content = { > + .key = PD692X0_KEY_CMD, > + .sub = {0x07, 0x55, 0x00}, > + .data = {0x55, 0x00, 0x55, 0x4e, > + 0x4e, 0x4e, 0x4e, 0x4e}, > + }, > + }, Is there any documentation about what all these magic number mean? > +/* Implementation of the i2c communication in particular when there is > + * a communication loss. See the "Synchronization During Communication Loss" > + * paragraph of the Communication Protocol document. > + */ Is this document public? > +static int pd692x0_recv_msg(struct pd692x0_priv *priv, > + struct pd692x0_msg *msg, > + struct pd692x0_msg_content *buf) > +{ > + const struct i2c_client *client = priv->client; > + int ret; > + > + memset(buf, 0, sizeof(*buf)); > + if (msg->delay_recv) > + msleep(msg->delay_recv); > + else > + msleep(30); > + > + i2c_master_recv(client, (u8 *)buf, sizeof(*buf)); > + if (buf->key) > + goto out; This is the first attempt to receive the message. I assume buf->key not being 0 indicates something has been received? > + > + msleep(100); > + > + i2c_master_recv(client, (u8 *)buf, sizeof(*buf)); > + if (buf->key) > + goto out; So this is a second attempt. Should there be another memset? Could the first failed transfer fill the buffer with random junk in the higher bytes, and a successful read here could be a partial read and the end of the buffer still contains the junk. > + > + ret = pd692x0_send_msg(priv, msg); > + if (ret) > + return ret; So now we are re-transmitting the request. > + > + if (msg->delay_recv) > + msleep(msg->delay_recv); > + else > + msleep(30); > + > + i2c_master_recv(client, (u8 *)buf, sizeof(*buf)); > + if (buf->key) > + goto out; > + > + msleep(100); > + > + i2c_master_recv(client, (u8 *)buf, sizeof(*buf)); > + if (buf->key) > + goto out; > + > + msleep(10000); And two more attemps to receive it. > + > + ret = pd692x0_send_msg(priv, msg); > + if (ret) > + return ret; > + > + if (msg->delay_recv) > + msleep(msg->delay_recv); > + else > + msleep(30); > + > + i2c_master_recv(client, (u8 *)buf, sizeof(*buf)); > + if (buf->key) > + goto out; > + > + msleep(100); > + > + i2c_master_recv(client, (u8 *)buf, sizeof(*buf)); > + if (buf->key) > + goto out; Another resend and two more attempts to receive. Is there a reason to not uses for loops here? And maybe put send/receive/receive into a helper? And maybe make the first send part of this, rather then separate? I think the code will be more readable when restructured. > +static int pd692x0_ethtool_set_config(struct pse_controller_dev *pcdev, > + unsigned long id, > + struct netlink_ext_ack *extack, > + const struct pse_control_config *config) > +{ > + struct pd692x0_priv *priv = to_pd692x0_priv(pcdev); > + struct pd692x0_msg_content buf = {0}; > + struct pd692x0_msg msg; > + int ret; > + > + ret = pd692x0_fw_unavailable(priv); > + if (ret) > + return ret; It seems a bit late to check if the device has any firmware. I would of expected probe to check that, and maybe attempt to download firmware. If that fails, fail the probe, since the PSE is a brick. > +static struct pd692x0_msg_ver pd692x0_get_sw_version(struct pd692x0_priv *priv) > +{ > + struct pd692x0_msg msg = pd692x0_msg_template_list[PD692X0_MSG_GET_SW_VER]; > + struct device *dev = &priv->client->dev; > + struct pd692x0_msg_content buf = {0}; > + struct pd692x0_msg_ver ver = {0}; > + int ret; > + > + ret = pd692x0_sendrecv_msg(priv, &msg, &buf); > + if (ret < 0) { > + dev_err(dev, "Failed to get PSE version (%pe)\n", ERR_PTR(ret)); > + return ver; I _think_ that return is wrong ??? > +static enum fw_upload_err pd692x0_fw_write(struct fw_upload *fwl, > + const u8 *data, u32 offset, > + u32 size, u32 *written) > +{ > + struct pd692x0_priv *priv = fwl->dd_handle; > + char line[PD692X0_FW_LINE_MAX_SZ]; > + const struct i2c_client *client; > + int ret, i; > + char cmd; > + > + client = priv->client; > + priv->fw_state = PD692X0_FW_WRITE; > + > + /* Erase */ > + cmd = 'E'; > + ret = i2c_master_send(client, &cmd, 1); > + if (ret < 0) { > + dev_err(&client->dev, > + "Failed to boot programming mode (%pe)\n", > + ERR_PTR(ret)); > + return FW_UPLOAD_ERR_RW_ERROR; > + } > + > + ret = pd692x0_fw_recv_resp(client, 100, "TOE\r\n", sizeof("TOE\r\n") - 1); > + if (ret) > + return ret; > + > + ret = pd692x0_fw_recv_resp(client, 5000, "TE\r\n", sizeof("TE\r\n") - 1); > + if (ret) > + dev_warn(&client->dev, > + "Failed to erase internal memory, however still try to write Firmware\n"); > + > + ret = pd692x0_fw_recv_resp(client, 100, "TPE\r\n", sizeof("TPE\r\n") - 1); > + if (ret) > + dev_warn(&client->dev, > + "Failed to erase internal memory, however still try to write Firmware\n"); > + > + if (priv->cancel_request) > + return FW_UPLOAD_ERR_CANCELED; > + > + /* Program */ > + cmd = 'P'; > + ret = i2c_master_send(client, &cmd, sizeof(char)); > + if (ret < 0) { > + dev_err(&client->dev, > + "Failed to boot programming mode (%pe)\n", > + ERR_PTR(ret)); > + return ret; > + } > + > + ret = pd692x0_fw_recv_resp(client, 100, "TOP\r\n", sizeof("TOP\r\n") - 1); > + if (ret) > + return ret; > + > + i = 0; > + while (i < size) { > + ret = pd692x0_fw_get_next_line(data, line, size - i); > + if (!ret) { > + ret = FW_UPLOAD_ERR_FW_INVALID; > + goto err; > + } > + > + i += ret; > + data += ret; > + if (line[0] == 'S' && line[1] == '0') { > + continue; > + } else if (line[0] == 'S' && line[1] == '7') { > + ret = pd692x0_fw_write_line(client, line, true); > + if (ret) > + goto err; Is the firmware in Motorola SREC format? I thought the kernel had a helper for that, but a quick search did not find it. So maybe i'm remembering wrongly. But it seems silly for every driver to implement an SREC parser. Andrew