From: Stefan Wahren <hidden> Date: 2017-03-27 13:41:50
The Qualcomm QCA7000 HomePlug GreenPHY supports two interfaces:
UART and SPI. This patch series adds the missing support for UART.
This driver based on the Qualcomm code [1], but contains some changes:
* use random MAC address per default
* use net_device_stats from device
* share frame decoding between SPI and UART driver
* improve error handling
* reimplement tty_wakeup with work queue (based on slcan)
* use new serial device bus instead of ldisc
The patches 1 - 3 are just for clean up and are not related to
the UART support. Patches 4 - 7 prepare the existing QCA7000
code for UART support. Patch 8 contains the new driver. The last
two patches are suggested improvements for serial device bus.
The code itself has been tested on a Freescale i.MX28 board and
a Raspberry Pi Zero.
Changes in v4:
* rebase to current linux-next
* use parameter -M for git format-patch
* change order of local variables where possible
* implement basic serdev support (without hardware flow control)
Changes in v3:
* rebase to current net-next
Changes in v2:
* fix build issue by using netif_trans_update() and dev_trans_start()
[1] - https://github.com/IoE/qca7000
Stefan Wahren (10):
net: qualcomm: remove unnecessary includes
net: qca_debug: use net_device_ops instead of direct call
net: qualcomm: move qcaspi_tx_cmd to qca_spi.c
net: qualcomm: rename qca_framing.c to qca_common.c
net: qualcomm: prepare frame decoding for UART driver
net: qualcomm: make qca_common a separate kernel module
dt-bindings: net: add binding for QCA7000 UART
net: qualcomm: add QCA7000 UART driver
tty: serdev-ttyport: return actual baudrate from ttyport_set_baudrate
tty: serdev: add functions to retrieve common UART settings
.../devicetree/bindings/net/qca-qca7000-uart.txt | 31 ++
drivers/net/ethernet/qualcomm/Kconfig | 18 +-
drivers/net/ethernet/qualcomm/Makefile | 7 +-
drivers/net/ethernet/qualcomm/qca_7k.c | 28 --
drivers/net/ethernet/qualcomm/qca_7k.h | 1 -
.../qualcomm/{qca_framing.c => qca_common.c} | 24 +-
.../qualcomm/{qca_framing.h => qca_common.h} | 14 +-
drivers/net/ethernet/qualcomm/qca_debug.c | 5 +-
drivers/net/ethernet/qualcomm/qca_spi.c | 28 +-
drivers/net/ethernet/qualcomm/qca_spi.h | 5 +-
drivers/net/ethernet/qualcomm/qca_uart.c | 419 +++++++++++++++++++++
drivers/tty/serdev/core.c | 33 ++
drivers/tty/serdev/serdev-ttyport.c | 49 ++-
include/linux/serdev.h | 22 ++
14 files changed, 634 insertions(+), 50 deletions(-)
create mode 100644 Documentation/devicetree/bindings/net/qca-qca7000-uart.txt
rename drivers/net/ethernet/qualcomm/{qca_framing.c => qca_common.c} (86%)
rename drivers/net/ethernet/qualcomm/{qca_framing.h => qca_common.h} (90%)
create mode 100644 drivers/net/ethernet/qualcomm/qca_uart.c
--
2.1.4
From: Stefan Wahren <hidden> Date: 2017-03-27 13:38:09
Most of the includes in qca_7k.c are unnecessary so we better remove them.
Signed-off-by: Stefan Wahren <redacted>
---
drivers/net/ethernet/qualcomm/qca_7k.c | 4 ----
1 file changed, 4 deletions(-)
--
2.1.4
--
To unsubscribe from this list: send the line "unsubscribe devicetree" in
the body of a message to majordomo-u79uwXL29TY76Z2rM5mHXA@public.gmane.org
More majordomo info at http://vger.kernel.org/majordomo-info.html
From: Stefan Wahren <hidden> Date: 2017-03-27 13:38:48
In order to share common functions between QCA7000 SPI and UART protocol
driver the qca_common needs to be a separate kernel module.
Signed-off-by: Stefan Wahren <redacted>
---
drivers/net/ethernet/qualcomm/Kconfig | 8 +++++++-
drivers/net/ethernet/qualcomm/Makefile | 5 +++--
drivers/net/ethernet/qualcomm/qca_common.c | 10 ++++++++++
3 files changed, 20 insertions(+), 3 deletions(-)
@@ -57,6 +60,7 @@ qcafrm_create_footer(u8 *buf)buf[1]=0x55;returnQCAFRM_FOOTER_LEN;}+EXPORT_SYMBOL_GPL(qcafrm_create_footer);/* Gather received bytes and try to extract a full ethernet frame by*followingasimplestatemachine.
--
2.1.4
--
To unsubscribe from this list: send the line "unsubscribe devicetree" in
the body of a message to majordomo-u79uwXL29TY76Z2rM5mHXA@public.gmane.org
More majordomo info at http://vger.kernel.org/majordomo-info.html
* by an atheros frame while transmitted over a serial channel;
*/
+#include <linux/init.h>
#include <linux/kernel.h>
+#include <linux/module.h>
#include "qca_common.h"
buf[1] = 0x55;
return QCAFRM_FOOTER_LEN;
}
+EXPORT_SYMBOL_GPL(qcafrm_create_footer);
/* Gather received bytes and try to extract a full ethernet frame
by
* following a simple state machine.
From: Stefan Wahren <hidden> Date: 2017-03-28 16:26:06
Am 27.03.2017 um 17:44 schrieb Dan Williams:
On Mon, 2017-03-27 at 15:37 +0200, Stefan Wahren wrote:
quoted
In order to share common functions between QCA7000 SPI and UART
protocol
driver the qca_common needs to be a separate kernel module.
Maybe "qca_eth_common"? There are many things Qualcomm, slightly fewer
things Qualcomm Atheros, and "qca_common" isn't very descriptive.
Since it is a Homeplug powerline chip which doesn't have any physical
connection to Ethernet only on protocol level, i wouldn't use eth in the
module name.
The code is very specific to the QCA7000, so how about "qca_7k_common"?
@@ -57,6 +60,7 @@ qcafrm_create_footer(u8 *buf)buf[1]=0x55;returnQCAFRM_FOOTER_LEN;}+EXPORT_SYMBOL_GPL(qcafrm_create_footer);/* Gather received bytes and try to extract a full ethernet frame
*** Diese E-Mail ist allein für den bezeichneten Adressaten bestimmt. Sie kann rechtlich vertrauliche Informationen enthalten. Wenn Sie diese E-Mail irrtümlich erhalten haben, informieren Sie bitte unverzüglich den Absender per E-Mail und löschen Sie diese E-Mail von Ihrem Computer, ohne Kopien anzufertigen.
Vielen Dank. ***
*** This email is for the exclusive use of the addressee. It may contain legally privileged information. If you have received this message in error, please notify the sender by email immediately and delete the message from your computer without making any copies.
Thank you. ***
From: Dan Williams <hidden> Date: 2017-03-28 17:19:10
On Tue, 2017-03-28 at 18:24 +0200, Stefan Wahren wrote:
Am 27.03.2017 um 17:44 schrieb Dan Williams:
quoted
On Mon, 2017-03-27 at 15:37 +0200, Stefan Wahren wrote:
quoted
In order to share common functions between QCA7000 SPI and UART
protocol
driver the qca_common needs to be a separate kernel module.
Maybe "qca_eth_common"? There are many things Qualcomm, slightly
fewer
things Qualcomm Atheros, and "qca_common" isn't very descriptive.
Since it is a Homeplug powerline chip which doesn't have any physical
connection to Ethernet only on protocol level, i wouldn't use eth in
the
module name.
The code is very specific to the QCA7000, so how about
"qca_7k_common"?
Sure; I just saw it was under drivers/net/ethernet, which kinda means
it's ethernet-related... But 7k common is fine.
Dan
* by an atheros frame while transmitted over a serial
channel;
*/
+#include <linux/init.h>
#include <linux/kernel.h>
+#include <linux/module.h>
#include "qca_common.h"
buf[1] = 0x55;
return QCAFRM_FOOTER_LEN;
}
+EXPORT_SYMBOL_GPL(qcafrm_create_footer);
/* Gather received bytes and try to extract a full ethernet
frame
by
* following a simple state machine.
*** Diese E-Mail ist allein für den bezeichneten Adressaten bestimmt.
Sie kann rechtlich vertrauliche Informationen enthalten. Wenn Sie
diese E-Mail irrtümlich erhalten haben, informieren Sie bitte
unverzüglich den Absender per E-Mail und löschen Sie diese E-Mail von
Ihrem Computer, ohne Kopien anzufertigen.
Vielen Dank. ***
*** This email is for the exclusive use of the addressee. It may
contain legally privileged information. If you have received this
message in error, please notify the sender by email immediately and
delete the message from your computer without making any copies.
Thank you. ***
From: Stefan Wahren <hidden> Date: 2017-03-27 13:40:41
Currently serdev core doesn't provide functions to retrieve common
UART settings like data bits, stop bits or parity. This patch adds
the interface to the core and the necessary implementation for
serdev-ttyport.
Signed-off-by: Stefan Wahren <redacted>
---
drivers/tty/serdev/core.c | 33 ++++++++++++++++++++++++++
drivers/tty/serdev/serdev-ttyport.c | 47 +++++++++++++++++++++++++++++++++++++
include/linux/serdev.h | 22 +++++++++++++++++
3 files changed, 102 insertions(+)
From: Rob Herring <robh+dt@kernel.org> Date: 2017-03-27 20:00:40
On Mon, Mar 27, 2017 at 8:37 AM, Stefan Wahren [off-list ref] wrote:
Currently serdev core doesn't provide functions to retrieve common
UART settings like data bits, stop bits or parity. This patch adds
the interface to the core and the necessary implementation for
serdev-ttyport.
It doesn't provide them because why do you need to know? The attached
device should request the settings it needs and be done with it. Maybe
some devices can support a number of settings and you could want
negotiate the settings with the UART, though surely 8N1 is in that
list. It's rare to see something that's not 8N1 from what I've seen.
Rob
From: Stefan Wahren <hidden> Date: 2017-03-28 16:34:35
Am 27.03.2017 um 22:00 schrieb Rob Herring:
On Mon, Mar 27, 2017 at 8:37 AM, Stefan Wahren [off-list ref] wrote:
quoted
Currently serdev core doesn't provide functions to retrieve common
UART settings like data bits, stop bits or parity. This patch adds
the interface to the core and the necessary implementation for
serdev-ttyport.
It doesn't provide them because why do you need to know? The attached
device should request the settings it needs and be done with it. Maybe
some devices can support a number of settings and you could want
negotiate the settings with the UART, though surely 8N1 is in that
list. It's rare to see something that's not 8N1 from what I've seen.
During development it's very helpful to check the current UART settings
and error counter. Currently i can't see a replacement for
/sys/class/tty/ttyXYZ .
Are there any plans about it?
From: Stefan Wahren <hidden> Date: 2017-03-27 13:40:41
The function qcaspi_tx_cmd() is only called from qca_spi.c. So we better
move it there.
Signed-off-by: Stefan Wahren <redacted>
---
drivers/net/ethernet/qualcomm/qca_7k.c | 24 ------------------------
drivers/net/ethernet/qualcomm/qca_7k.h | 1 -
drivers/net/ethernet/qualcomm/qca_spi.c | 24 ++++++++++++++++++++++++
3 files changed, 24 insertions(+), 25 deletions(-)
From: Stefan Wahren <hidden> Date: 2017-03-27 13:41:44
Unfortunately the frame format is not exactly identical between SPI
and UART. In case of SPI there is an additional HW length at the
beginning. So store the initial state to make the decoding state machine
more flexible and easy to extend for UART support.
Signed-off-by: Stefan Wahren <redacted>
---
drivers/net/ethernet/qualcomm/qca_common.c | 12 ++++++------
drivers/net/ethernet/qualcomm/qca_common.h | 8 ++++++--
drivers/net/ethernet/qualcomm/qca_spi.c | 2 +-
3 files changed, 13 insertions(+), 9 deletions(-)
@@ -83,7 +83,7 @@ qcafrm_fsm_decode(struct qcafrm_handle *handle, u8 *buf, u16 buf_len, u8 recv_byif(recv_byte!=0x00){/* first two bytes of length must be 0 */-handle->state=QCAFRM_HW_LEN0;+handle->state=handle->init;}break;caseQCAFRM_HW_LEN2:
@@ -61,6 +61,7 @@#define QCAFRM_ERR_BASE -1000enumqcafrm_state{+/* HW length is only available on SPI */QCAFRM_HW_LEN0=0x8000,QCAFRM_HW_LEN1=QCAFRM_HW_LEN0-1,QCAFRM_HW_LEN2=QCAFRM_HW_LEN1-1,
@@ -101,6 +102,8 @@ enum qcafrm_state {structqcafrm_handle{/* Current decoding state */enumqcafrm_statestate;+/* Initial state depends on connection type */+enumqcafrm_stateinit;/* Offset in buffer (borrowed for length too) */s16offset;
@@ -113,9 +116,10 @@ u16 qcafrm_create_header(u8 *buf, u16 len);u16qcafrm_create_footer(u8*buf);-staticinlinevoidqcafrm_fsm_init(structqcafrm_handle*handle)+staticinlinevoidqcafrm_fsm_init_spi(structqcafrm_handle*handle){-handle->state=QCAFRM_HW_LEN0;+handle->init=QCAFRM_HW_LEN0;+handle->state=handle->init;}/* Gather received bytes and try to extract a full Ethernet frame
--
2.1.4
--
To unsubscribe from this list: send the line "unsubscribe devicetree" in
the body of a message to majordomo-u79uwXL29TY76Z2rM5mHXA@public.gmane.org
More majordomo info at http://vger.kernel.org/majordomo-info.html
From: Stefan Wahren <hidden> Date: 2017-03-27 13:41:48
There is no need to export qcaspi_netdev_open and qcaspi_netdev_close
because they are also accessible via the net_device_ops.
Signed-off-by: Stefan Wahren <redacted>
---
drivers/net/ethernet/qualcomm/qca_debug.c | 5 +++--
drivers/net/ethernet/qualcomm/qca_spi.h | 3 ---
2 files changed, 3 insertions(+), 5 deletions(-)
From: Stefan Wahren <hidden> Date: 2017-03-27 13:41:51
This is the serdev binding for the QCA7000 UART driver (Ethernet over UART).
Signed-off-by: Stefan Wahren <redacted>
---
According to this binding are still some questions:
Where should be the optional hardware flow control defined (at master or slave side)?
Is it okay to have two bindings (qca-qca7000-spi and qca-qca7000-uart) or should they be merged?
.../devicetree/bindings/net/qca-qca7000-uart.txt | 31 ++++++++++++++++++++++
1 file changed, 31 insertions(+)
create mode 100644 Documentation/devicetree/bindings/net/qca-qca7000-uart.txt
@@ -0,0 +1,31 @@+* Qualcomm QCA7000 (Ethernet over UART protocol)++Note: This binding applies in case the QCA7000 is configured as a+UART slave device. It is possible to preconfigure the UART settings+of the QCA7000 firmware, which can't be changed during runtime.++Required properties:+- compatible : Should be "qca,qca7000-uart"++Optional properties:+- local-mac-address : 6 bytes, Specifies MAC address+- current-speed : Specifies the serial device speed in+ bits per second (default = 115200), which is+ predefined by the QCA7000 firmware configuration++Example:++/* Freescale i.MX28 UART */+auart0: serial@8006a000 {+ compatible = "fsl,imx28-auart", "fsl,imx23-auart";+ reg = <0x8006a000 0x2000>;+ pinctrl-names = "default";+ pinctrl-0 = <&auart0_2pins_a>;+ status = "okay";++ qca7000: ethernet {+ compatible = "qca,qca7000-uart";+ local-mac-address = [ A0 B0 C0 D0 E0 F0 ];+ current-speed = <38400>;+ };+};
From: Rob Herring <robh+dt@kernel.org> Date: 2017-03-27 20:30:43
On Mon, Mar 27, 2017 at 8:37 AM, Stefan Wahren [off-list ref] wrote:
This is the serdev binding for the QCA7000 UART driver (Ethernet over UART).
Signed-off-by: Stefan Wahren <redacted>
---
According to this binding are still some questions:
Where should be the optional hardware flow control defined (at master or slave side)?
Probably should be in the slave side. We already have uart-has-rtscts
and rts/cts-gpios for the UART. Those mean we have RTS/CTS, but not
necessarily that we want to enable them.
In many cases, the driver may know what it needs.
Is it okay to have two bindings (qca-qca7000-spi and qca-qca7000-uart) or should they be merged?
Are they mutually-exclusive or both are used at the same time? What
are the dependencies between the interfaces?
@@ -0,0 +1,31 @@+* Qualcomm QCA7000 (Ethernet over UART protocol)++Note: This binding applies in case the QCA7000 is configured as a+UART slave device. It is possible to preconfigure the UART settings+of the QCA7000 firmware, which can't be changed during runtime.++Required properties:+- compatible : Should be "qca,qca7000-uart"++Optional properties:+- local-mac-address : 6 bytes, Specifies MAC address
The description can be "see ./ethernet.txt"
+- current-speed : Specifies the serial device speed in
+ bits per second (default = 115200), which is
+ predefined by the QCA7000 firmware configuration
Add this to the slave binding doc with some caveats as to when this
should or should not be used as we discussed.
Rob
--
To unsubscribe from this list: send the line "unsubscribe devicetree" in
the body of a message to majordomo-u79uwXL29TY76Z2rM5mHXA@public.gmane.org
More majordomo info at http://vger.kernel.org/majordomo-info.html
From: Stefan Wahren <hidden> Date: 2017-03-28 16:20:49
Am 27.03.2017 um 22:30 schrieb Rob Herring:
On Mon, Mar 27, 2017 at 8:37 AM, Stefan Wahren [off-list ref] wrote:
quoted
This is the serdev binding for the QCA7000 UART driver (Ethernet over UART).
Signed-off-by: Stefan Wahren <redacted>
---
According to this binding are still some questions:
Where should be the optional hardware flow control defined (at master or slave side)?
Probably should be in the slave side. We already have uart-has-rtscts
and rts/cts-gpios for the UART. Those mean we have RTS/CTS, but not
necessarily that we want to enable them.
In many cases, the driver may know what it needs.
Like all the other UART settings the hardware flow control can be
configured in the QCA7000 firmware and the driver can't detect it.
Property suggestion for the slave side:
use-rtscts
quoted
Is it okay to have two bindings (qca-qca7000-spi and qca-qca7000-uart) or should they be merged?
Are they mutually-exclusive or both are used at the same time?
They are mutually-exclusive because they use the same pins.
What
are the dependencies between the interfaces?
Except they uses the same pins of the QCA7000, i can't see any dependency.
@@ -0,0 +1,31 @@+* Qualcomm QCA7000 (Ethernet over UART protocol)++Note: This binding applies in case the QCA7000 is configured as a+UART slave device. It is possible to preconfigure the UART settings+of the QCA7000 firmware, which can't be changed during runtime.++Required properties:+- compatible : Should be "qca,qca7000-uart"++Optional properties:+- local-mac-address : 6 bytes, Specifies MAC address
The description can be "see ./ethernet.txt"
quoted
+- current-speed : Specifies the serial device speed in
+ bits per second (default = 115200), which is
+ predefined by the QCA7000 firmware configuration
Add this to the slave binding doc with some caveats as to when this
should or should not be used as we discussed.
Rob
--
To unsubscribe from this list: send the line "unsubscribe devicetree" in
the body of a message to majordomo-u79uwXL29TY76Z2rM5mHXA@public.gmane.org
More majordomo info at http://vger.kernel.org/majordomo-info.html
From: Rob Herring <robh@kernel.org> Date: 2017-04-03 13:23:27
On Tue, Mar 28, 2017 at 06:18:03PM +0200, Stefan Wahren wrote:
Am 27.03.2017 um 22:30 schrieb Rob Herring:
quoted
On Mon, Mar 27, 2017 at 8:37 AM, Stefan Wahren [off-list ref] wrote:
quoted
This is the serdev binding for the QCA7000 UART driver (Ethernet over UART).
Signed-off-by: Stefan Wahren <redacted>
---
According to this binding are still some questions:
Where should be the optional hardware flow control defined (at master or slave side)?
Probably should be in the slave side. We already have uart-has-rtscts
and rts/cts-gpios for the UART. Those mean we have RTS/CTS, but not
necessarily that we want to enable them.
In many cases, the driver may know what it needs.
Like all the other UART settings the hardware flow control can be
configured in the QCA7000 firmware and the driver can't detect it.
Property suggestion for the slave side:
use-rtscts
Okay.
quoted
quoted
Is it okay to have two bindings (qca-qca7000-spi and qca-qca7000-uart) or should they be merged?
Are they mutually-exclusive or both are used at the same time?
They are mutually-exclusive because they use the same pins.
quoted
What
are the dependencies between the interfaces?
Except they uses the same pins of the QCA7000, i can't see any dependency.
I think they should be a single doc.
Rob
--
To unsubscribe from this list: send the line "unsubscribe devicetree" in
the body of a message to majordomo-u79uwXL29TY76Z2rM5mHXA@public.gmane.org
More majordomo info at http://vger.kernel.org/majordomo-info.html
@@ -122,6 +122,12 @@ static inline void qcafrm_fsm_init_spi(struct qcafrm_handle *handle)handle->state=handle->init;}+staticinlinevoidqcafrm_fsm_init_uart(structqcafrm_handle*handle)+{+handle->init=QCAFRM_WAIT_AA1;+handle->state=handle->init;+}+/* Gather received bytes and try to extract a full Ethernet frame*byfollowingasimplestatemachine.*
@@ -0,0 +1,419 @@+/*+*Copyright(c)2011,2012,QualcommAtherosCommunicationsInc.+*Copyright(c)2017,I2SEGmbH+*+*Permissiontouse,copy,modify,and/ordistributethissoftware+*foranypurposewithorwithoutfeeisherebygranted,provided+*thattheabovecopyrightnoticeandthispermissionnoticeappear+*inallcopies.+*+*THESOFTWAREISPROVIDED"AS IS"ANDTHEAUTHORDISCLAIMSALL+*WARRANTIESWITHREGARDTOTHISSOFTWAREINCLUDINGALLIMPLIED+*WARRANTIESOFMERCHANTABILITYANDFITNESS.INNOEVENTSHALL+*THEAUTHORBELIABLEFORANYSPECIAL,DIRECT,INDIRECT,OR+*CONSEQUENTIALDAMAGESORANYDAMAGESWHATSOEVERRESULTINGFROM+*LOSSOFUSE,DATAORPROFITS,WHETHERINANACTIONOFCONTRACT,+*NEGLIGENCEOROTHERTORTIOUSACTION,ARISINGOUTOFORIN+*CONNECTIONWITHTHEUSEORPERFORMANCEOFTHISSOFTWARE.+*/++/* This module implements the Qualcomm Atheros UART protocol for+*kernel-basedUARTdevice;itisessentiallyanEthernet-to-UART+*serialconverter;+*/++#include<linux/errno.h>+#include<linux/etherdevice.h>+#include<linux/if_arp.h>+#include<linux/if_ether.h>+#include<linux/init.h>+#include<linux/jiffies.h>+#include<linux/kernel.h>+#include<linux/module.h>+#include<linux/netdevice.h>+#include<linux/of.h>+#include<linux/of_device.h>+#include<linux/of_net.h>+#include<linux/sched.h>+#include<linux/serdev.h>+#include<linux/skbuff.h>+#include<linux/types.h>++#include"qca_common.h"++#define QCAUART_DRV_VERSION "0.1.0"+#define QCAUART_DRV_NAME "qcauart"+#define QCAUART_TX_TIMEOUT (1 * HZ)++structqcauart{+structnet_device*net_dev;+spinlock_tlock;/* transmit lock */+structwork_structtx_work;/* Flushes transmit buffer */++structserdev_device*serdev;++unsignedcharxbuff[QCAFRM_ETHMAXMTU];/* transmitter buffer */+unsignedchar*xhead;/* pointer to next XMIT byte */+intxleft;/* bytes left in XMIT queue */++structqcafrm_handlefrm_handle;++structsk_buff*rx_skb;+};++staticint+qca_tty_receive(structserdev_device*serdev,constunsignedchar*data,+size_tcount)+{+structqcauart*qca=serdev_device_get_drvdata(serdev);+structnet_device_stats*n_stats=&qca->net_dev->stats;+size_ti;++if(!qca->rx_skb){+qca->rx_skb=netdev_alloc_skb(qca->net_dev,qca->net_dev->mtu++VLAN_ETH_HLEN);+if(!qca->rx_skb){+n_stats->rx_errors++;+n_stats->rx_dropped++;+return0;+}+}++for(i=0;i<count;i++){+s32retcode;++retcode=qcafrm_fsm_decode(&qca->frm_handle,+qca->rx_skb->data,+skb_tailroom(qca->rx_skb),+data[i]);++switch(retcode){+caseQCAFRM_GATHER:+caseQCAFRM_NOHEAD:+break;+caseQCAFRM_NOTAIL:+netdev_dbg(qca->net_dev,"recv: no RX tail\n");+n_stats->rx_errors++;+n_stats->rx_dropped++;+break;+caseQCAFRM_INVLEN:+netdev_dbg(qca->net_dev,"recv: invalid RX length\n");+n_stats->rx_errors++;+n_stats->rx_dropped++;+break;+default:+qca->rx_skb->dev=qca->net_dev;+n_stats->rx_packets++;+n_stats->rx_bytes+=retcode;+skb_put(qca->rx_skb,retcode);+qca->rx_skb->protocol=eth_type_trans(+qca->rx_skb,qca->rx_skb->dev);+qca->rx_skb->ip_summed=CHECKSUM_UNNECESSARY;+netif_rx_ni(qca->rx_skb);+qca->rx_skb=netdev_alloc_skb(qca->net_dev,+qca->net_dev->mtu++VLAN_ETH_HLEN);+if(!qca->rx_skb){+netdev_dbg(qca->net_dev,"recv: out of RX resources\n");+n_stats->rx_errors++;+break;+}+}+}++returni;+}++/* Write out any remaining transmit buffer. Scheduled when tty is writable */+staticvoidqcauart_transmit(structwork_struct*work)+{+structqcauart*qca=container_of(work,structqcauart,tx_work);+structnet_device_stats*n_stats=&qca->net_dev->stats;+intwritten;++spin_lock_bh(&qca->lock);++/* First make sure we're connected. */+if(!netif_running(qca->net_dev)){+spin_unlock_bh(&qca->lock);+return;+}++if(qca->xleft<=0){+/* Now serial buffer is almost free & we can start+*transmissionofanotherpacket+*/+n_stats->tx_packets++;+spin_unlock_bh(&qca->lock);+netif_wake_queue(qca->net_dev);+return;+}++written=serdev_device_write_buf(qca->serdev,qca->xhead,qca->xleft);+if(written>0){+qca->xleft-=written;+qca->xhead+=written;+}+spin_unlock_bh(&qca->lock);+}++/* Called by the driver when there's room for more data.+*Schedulethetransmit.+*/+staticvoidqca_tty_wakeup(structserdev_device*serdev)+{+structqcauart*qca=serdev_device_get_drvdata(serdev);++schedule_work(&qca->tx_work);+}++staticstructserdev_device_opsqca_serdev_ops={+.receive_buf=qca_tty_receive,+.write_wakeup=qca_tty_wakeup,+};++int+qcauart_netdev_open(structnet_device*dev)+{+structqcauart*qca=netdev_priv(dev);++qcafrm_fsm_init_uart(&qca->frm_handle);+netif_start_queue(qca->net_dev);++return0;+}++int+qcauart_netdev_close(structnet_device*dev)+{+structqcauart*qca=netdev_priv(dev);++spin_lock_bh(&qca->lock);+netif_stop_queue(dev);+qca->xleft=0;+spin_unlock_bh(&qca->lock);++return0;+}++netdev_tx_t+qcauart_netdev_xmit(structsk_buff*skb,structnet_device*dev)+{+structnet_device_stats*n_stats=&dev->stats;+structqcauart*qca=netdev_priv(dev);+u8pad_len=0;+intwritten;+u8*pos;++spin_lock(&qca->lock);++if(!netif_running(dev)){+spin_unlock(&qca->lock);+netdev_warn(qca->net_dev,"xmit: iface is down\n");+gotoout;+}++pos=qca->xbuff;++if(skb->len<QCAFRM_ETHMINLEN)+pad_len=QCAFRM_ETHMINLEN-skb->len;++pos+=qcafrm_create_header(pos,skb->len+pad_len);++memcpy(pos,skb->data,skb->len);+pos+=skb->len;++if(pad_len){+memset(pos,0,pad_len);+pos+=pad_len;+}++pos+=qcafrm_create_footer(pos);++netif_stop_queue(qca->net_dev);++written=serdev_device_write_buf(qca->serdev,qca->xbuff,+pos-qca->xbuff);+if(written>0){+qca->xleft=(pos-qca->xbuff)-written;+qca->xhead=qca->xbuff+written;+n_stats->tx_bytes+=written;+}+spin_unlock(&qca->lock);++netif_trans_update(dev);+out:+kfree_skb(skb);+returnNETDEV_TX_OK;+}++void+qcauart_netdev_tx_timeout(structnet_device*dev)+{+structqcauart*qca=netdev_priv(dev);++netdev_info(qca->net_dev,"Transmit timeout at %ld, latency %ld\n",+jiffies,dev_trans_start(dev));+dev->stats.tx_errors++;+dev->stats.tx_dropped++;+}++staticint+qcauart_netdev_init(structnet_device*dev)+{+structqcauart*qca=netdev_priv(dev);++/* Finish setting up the device info. */+dev->mtu=QCAFRM_ETHMAXMTU;+dev->type=ARPHRD_ETHER;++qca->rx_skb=netdev_alloc_skb(qca->net_dev,+qca->net_dev->mtu+VLAN_ETH_HLEN);+if(!qca->rx_skb)+return-ENOMEM;++return0;+}++staticvoid+qcauart_netdev_uninit(structnet_device*dev)+{+structqcauart*qca=netdev_priv(dev);++if(qca->rx_skb)+dev_kfree_skb(qca->rx_skb);+}++staticconststructnet_device_opsqcauart_netdev_ops={+.ndo_init=qcauart_netdev_init,+.ndo_uninit=qcauart_netdev_uninit,+.ndo_open=qcauart_netdev_open,+.ndo_stop=qcauart_netdev_close,+.ndo_start_xmit=qcauart_netdev_xmit,+.ndo_set_mac_address=eth_mac_addr,+.ndo_tx_timeout=qcauart_netdev_tx_timeout,+.ndo_validate_addr=eth_validate_addr,+};++staticvoid+qcauart_netdev_setup(structnet_device*dev)+{+structqcauart*qca;++dev->netdev_ops=&qcauart_netdev_ops;+dev->watchdog_timeo=QCAUART_TX_TIMEOUT;+dev->priv_flags&=~IFF_TX_SKB_SHARING;+dev->tx_queue_len=100;++/* MTU range: 46 - 1500 */+dev->min_mtu=QCAFRM_ETHMINMTU;+dev->max_mtu=QCAFRM_ETHMAXMTU;++qca=netdev_priv(dev);+memset(qca,0,sizeof(structqcauart));+}++staticconststructof_device_idqca_uart_of_match[]={+{+.compatible="qca,qca7000-uart",+},+{}+};+MODULE_DEVICE_TABLE(of,qca_uart_of_match);++staticintqca_uart_probe(structserdev_device*serdev)+{+structnet_device*qcauart_dev=alloc_etherdev(sizeof(structqcauart));+structqcauart*qca;+constchar*mac;+u32speed=115200;+intret;++if(!qcauart_dev)+return-ENOMEM;++qcauart_netdev_setup(qcauart_dev);++qca=netdev_priv(qcauart_dev);+if(!qca){+pr_err("qca_uart: Fail to retrieve private structure\n");+ret=-ENOMEM;+gotofree;+}+qca->net_dev=qcauart_dev;+qca->serdev=serdev;++spin_lock_init(&qca->lock);+INIT_WORK(&qca->tx_work,qcauart_transmit);++of_property_read_u32(serdev->dev.of_node,"current-speed",&speed);++mac=of_get_mac_address(serdev->dev.of_node);++if(mac)+ether_addr_copy(qca->net_dev->dev_addr,mac);++if(!is_valid_ether_addr(qca->net_dev->dev_addr)){+eth_hw_addr_random(qca->net_dev);+dev_info(&serdev->dev,"Using random MAC address: %pM\n",+qca->net_dev->dev_addr);+}++netif_carrier_on(qca->net_dev);+serdev_device_set_drvdata(serdev,qca);+serdev_device_set_client_ops(serdev,&qca_serdev_ops);++ret=serdev_device_open(serdev);+if(ret){+dev_err(&serdev->dev,"Unable to open device %s\n",+qcauart_dev->name);+gotofree;+}++speed=serdev_device_set_baudrate(serdev,speed);+dev_info(&serdev->dev,"Using baudrate: %u\n",speed);++serdev_device_set_flow_control(serdev,false);++ret=register_netdev(qcauart_dev);+if(ret){+dev_err(&serdev->dev,"Unable to register net device %s\n",+qcauart_dev->name);+gotofree;+}++return0;++free:+free_netdev(qcauart_dev);+returnret;+}++staticvoidqca_uart_remove(structserdev_device*serdev)+{+structqcauart*qca=serdev_device_get_drvdata(serdev);++/* Flush any pending characters in the driver. */+serdev_device_close(serdev);++netif_carrier_off(qca->net_dev);+unregister_netdev(qca->net_dev);+free_netdev(qca->net_dev);+}++staticstructserdev_device_driverqca_uart_driver={+.probe=qca_uart_probe,+.remove=qca_uart_remove,+.driver={+.name=QCAUART_DRV_NAME,+.of_match_table=of_match_ptr(qca_uart_of_match),+},+};++module_serdev_device_driver(qca_uart_driver);++MODULE_DESCRIPTION("Qualcomm Atheros UART Driver");+MODULE_AUTHOR("Qualcomm Atheros Communications");+MODULE_AUTHOR("Stefan Wahren <stefan.wahren@i2se.com>");+MODULE_LICENSE("Dual BSD/GPL");+MODULE_VERSION(QCAUART_DRV_VERSION);
From: Stefan Wahren <hidden> Date: 2017-03-27 13:41:54
As preparation for the upcoming UART driver we need a module
which contains common functions for both interfaces. The module
qca_framing is a good candidate but renaming to qca_common would
make it clear.
Signed-off-by: Stefan Wahren <redacted>
---
drivers/net/ethernet/qualcomm/Makefile | 2 +-
drivers/net/ethernet/qualcomm/{qca_framing.c => qca_common.c} | 2 +-
drivers/net/ethernet/qualcomm/{qca_framing.h => qca_common.h} | 0
drivers/net/ethernet/qualcomm/qca_spi.c | 2 +-
drivers/net/ethernet/qualcomm/qca_spi.h | 2 +-
5 files changed, 4 insertions(+), 4 deletions(-)
rename drivers/net/ethernet/qualcomm/{qca_framing.c => qca_common.c} (99%)
rename drivers/net/ethernet/qualcomm/{qca_framing.h => qca_common.h} (100%)
diff --git a/drivers/net/ethernet/qualcomm/qca_framing.c b/drivers/net/ethernet/qualcomm/qca_common.csimilarity index 99%rename from drivers/net/ethernet/qualcomm/qca_framing.crename to drivers/net/ethernet/qualcomm/qca_common.cindex faa924c..26453a9 100644--- a/drivers/net/ethernet/qualcomm/qca_framing.c+++ b/drivers/net/ethernet/qualcomm/qca_common.c
From: Stefan Wahren <hidden> Date: 2017-03-27 13:47:17
Instead of returning the requested baudrate, we better return the
actual one because it isn't always the same.
Signed-off-by: Stefan Wahren <redacted>
---
drivers/tty/serdev/serdev-ttyport.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
@@ -150,7 +150,7 @@ static unsigned int ttyport_set_baudrate(struct serdev_controller *ctrl, unsigne/* tty_set_termios() return not checked as it is always 0 */tty_set_termios(tty,&ktermios);-returnspeed;+returnktermios.c_ospeed;}staticvoidttyport_set_flow_control(structserdev_controller*ctrl,boolenable)
From: Rob Herring <robh+dt@kernel.org> Date: 2017-03-27 20:02:07
On Mon, Mar 27, 2017 at 8:37 AM, Stefan Wahren [off-list ref] wrote:
Instead of returning the requested baudrate, we better return the
actual one because it isn't always the same.
Signed-off-by: Stefan Wahren <redacted>
---
drivers/tty/serdev/serdev-ttyport.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)