Commit 502c6f8c authored by Jakub Kicinski's avatar Jakub Kicinski

Merge branch '100GbE' of git://git.kernel.org/pub/scm/linux/kernel/git/tnguy/next-queue

Tony Nguyen says:

====================
100GbE Intel Wired LAN Driver Updates 2022-07-21

This series contains updates to ice driver only.

Karol adds implementation for GNSS write; data is written to the GNSS
module through TTY device using u-blox UBX protocol.

* '100GbE' of git://git.kernel.org/pub/scm/linux/kernel/git/tnguy/next-queue:
  ice: add write functionality for GNSS TTY
  ice: add i2c write command
====================

Link: https://lore.kernel.org/r/20220721202842.3276257-1-anthony.l.nguyen@intel.comSigned-off-by: default avatarJakub Kicinski <kuba@kernel.org>
parents 7074732c d6b98c8d
...@@ -901,6 +901,15 @@ To enable/disable UDP Segmentation Offload, issue the following command:: ...@@ -901,6 +901,15 @@ To enable/disable UDP Segmentation Offload, issue the following command::
# ethtool -K <ethX> tx-udp-segmentation [off|on] # ethtool -K <ethX> tx-udp-segmentation [off|on]
GNSS module
-----------
Allows user to read messages from the GNSS module and write supported commands.
If the module is physically present, driver creates 2 TTYs for each supported
device in /dev, ttyGNSS_<device>:<function>_0 and _1. First one (_0) is RW and
the second one is RO.
The protocol of write commands is dependent on the GNSS module as the driver
writes raw bytes from the TTY to the GNSS i2c. Please refer to the module
documentation for details.
Performance Optimization Performance Optimization
======================== ========================
......
...@@ -545,8 +545,8 @@ struct ice_pf { ...@@ -545,8 +545,8 @@ struct ice_pf {
u32 msg_enable; u32 msg_enable;
struct ice_ptp ptp; struct ice_ptp ptp;
struct tty_driver *ice_gnss_tty_driver; struct tty_driver *ice_gnss_tty_driver;
struct tty_port gnss_tty_port; struct tty_port *gnss_tty_port[ICE_GNSS_TTY_MINOR_DEVICES];
struct gnss_serial *gnss_serial; struct gnss_serial *gnss_serial[ICE_GNSS_TTY_MINOR_DEVICES];
u16 num_rdma_msix; /* Total MSIX vectors for RDMA driver */ u16 num_rdma_msix; /* Total MSIX vectors for RDMA driver */
u16 rdma_base_vector; u16 rdma_base_vector;
......
...@@ -1395,7 +1395,7 @@ struct ice_aqc_get_link_topo { ...@@ -1395,7 +1395,7 @@ struct ice_aqc_get_link_topo {
u8 rsvd[9]; u8 rsvd[9];
}; };
/* Read I2C (direct, 0x06E2) */ /* Read/Write I2C (direct, 0x06E2/0x06E3) */
struct ice_aqc_i2c { struct ice_aqc_i2c {
struct ice_aqc_link_topo_addr topo_addr; struct ice_aqc_link_topo_addr topo_addr;
__le16 i2c_addr; __le16 i2c_addr;
...@@ -1405,7 +1405,7 @@ struct ice_aqc_i2c { ...@@ -1405,7 +1405,7 @@ struct ice_aqc_i2c {
u8 rsvd; u8 rsvd;
__le16 i2c_bus_addr; __le16 i2c_bus_addr;
u8 rsvd2[4]; u8 i2c_data[4]; /* Used only by write command, reserved in read. */
}; };
/* Read I2C Response (direct, 0x06E2) */ /* Read I2C Response (direct, 0x06E2) */
...@@ -2124,7 +2124,7 @@ struct ice_aq_desc { ...@@ -2124,7 +2124,7 @@ struct ice_aq_desc {
struct ice_aqc_get_link_status get_link_status; struct ice_aqc_get_link_status get_link_status;
struct ice_aqc_event_lan_overflow lan_overflow; struct ice_aqc_event_lan_overflow lan_overflow;
struct ice_aqc_get_link_topo get_link_topo; struct ice_aqc_get_link_topo get_link_topo;
struct ice_aqc_i2c read_i2c; struct ice_aqc_i2c read_write_i2c;
struct ice_aqc_read_i2c_resp read_i2c_resp; struct ice_aqc_read_i2c_resp read_i2c_resp;
} params; } params;
}; };
...@@ -2241,6 +2241,7 @@ enum ice_adminq_opc { ...@@ -2241,6 +2241,7 @@ enum ice_adminq_opc {
ice_aqc_opc_set_mac_lb = 0x0620, ice_aqc_opc_set_mac_lb = 0x0620,
ice_aqc_opc_get_link_topo = 0x06E0, ice_aqc_opc_get_link_topo = 0x06E0,
ice_aqc_opc_read_i2c = 0x06E2, ice_aqc_opc_read_i2c = 0x06E2,
ice_aqc_opc_write_i2c = 0x06E3,
ice_aqc_opc_set_port_id_led = 0x06E9, ice_aqc_opc_set_port_id_led = 0x06E9,
ice_aqc_opc_set_gpio = 0x06EC, ice_aqc_opc_set_gpio = 0x06EC,
ice_aqc_opc_get_gpio = 0x06ED, ice_aqc_opc_get_gpio = 0x06ED,
......
...@@ -4823,7 +4823,7 @@ ice_aq_read_i2c(struct ice_hw *hw, struct ice_aqc_link_topo_addr topo_addr, ...@@ -4823,7 +4823,7 @@ ice_aq_read_i2c(struct ice_hw *hw, struct ice_aqc_link_topo_addr topo_addr,
int status; int status;
ice_fill_dflt_direct_cmd_desc(&desc, ice_aqc_opc_read_i2c); ice_fill_dflt_direct_cmd_desc(&desc, ice_aqc_opc_read_i2c);
cmd = &desc.params.read_i2c; cmd = &desc.params.read_write_i2c;
if (!data) if (!data)
return -EINVAL; return -EINVAL;
...@@ -4850,6 +4850,51 @@ ice_aq_read_i2c(struct ice_hw *hw, struct ice_aqc_link_topo_addr topo_addr, ...@@ -4850,6 +4850,51 @@ ice_aq_read_i2c(struct ice_hw *hw, struct ice_aqc_link_topo_addr topo_addr,
return status; return status;
} }
/**
* ice_aq_write_i2c
* @hw: pointer to the hw struct
* @topo_addr: topology address for a device to communicate with
* @bus_addr: 7-bit I2C bus address
* @addr: I2C memory address (I2C offset) with up to 16 bits
* @params: I2C parameters: bit [4] - I2C address type, bits [3:0] - data size to write (0-7 bytes)
* @data: pointer to data (0 to 4 bytes) to be written to the I2C device
* @cd: pointer to command details structure or NULL
*
* Write I2C (0x06E3)
*
* * Return:
* * 0 - Successful write to the i2c device
* * -EINVAL - Data size greater than 4 bytes
* * -EIO - FW error
*/
int
ice_aq_write_i2c(struct ice_hw *hw, struct ice_aqc_link_topo_addr topo_addr,
u16 bus_addr, __le16 addr, u8 params, u8 *data,
struct ice_sq_cd *cd)
{
struct ice_aq_desc desc = { 0 };
struct ice_aqc_i2c *cmd;
u8 data_size;
ice_fill_dflt_direct_cmd_desc(&desc, ice_aqc_opc_write_i2c);
cmd = &desc.params.read_write_i2c;
data_size = FIELD_GET(ICE_AQC_I2C_DATA_SIZE_M, params);
/* data_size limited to 4 */
if (data_size > 4)
return -EINVAL;
cmd->i2c_bus_addr = cpu_to_le16(bus_addr);
cmd->topo_addr = topo_addr;
cmd->i2c_params = params;
cmd->i2c_addr = addr;
memcpy(cmd->i2c_data, data, data_size);
return ice_aq_send_cmd(hw, &desc, NULL, 0, cd);
}
/** /**
* ice_aq_set_driver_param - Set driver parameter to share via firmware * ice_aq_set_driver_param - Set driver parameter to share via firmware
* @hw: pointer to the HW struct * @hw: pointer to the HW struct
......
...@@ -214,5 +214,9 @@ int ...@@ -214,5 +214,9 @@ int
ice_aq_read_i2c(struct ice_hw *hw, struct ice_aqc_link_topo_addr topo_addr, ice_aq_read_i2c(struct ice_hw *hw, struct ice_aqc_link_topo_addr topo_addr,
u16 bus_addr, __le16 addr, u8 params, u8 *data, u16 bus_addr, __le16 addr, u8 params, u8 *data,
struct ice_sq_cd *cd); struct ice_sq_cd *cd);
int
ice_aq_write_i2c(struct ice_hw *hw, struct ice_aqc_link_topo_addr topo_addr,
u16 bus_addr, __le16 addr, u8 params, u8 *data,
struct ice_sq_cd *cd);
bool ice_fw_supports_report_dflt_cfg(struct ice_hw *hw); bool ice_fw_supports_report_dflt_cfg(struct ice_hw *hw);
#endif /* _ICE_COMMON_H_ */ #endif /* _ICE_COMMON_H_ */
This diff is collapsed.
/* SPDX-License-Identifier: GPL-2.0 */ /* SPDX-License-Identifier: GPL-2.0 */
/* Copyright (C) 2018-2021, Intel Corporation. */ /* Copyright (C) 2021-2022, Intel Corporation. */
#ifndef _ICE_GNSS_H_ #ifndef _ICE_GNSS_H_
#define _ICE_GNSS_H_ #define _ICE_GNSS_H_
...@@ -8,14 +8,34 @@ ...@@ -8,14 +8,34 @@
#include <linux/tty_flip.h> #include <linux/tty_flip.h>
#define ICE_E810T_GNSS_I2C_BUS 0x2 #define ICE_E810T_GNSS_I2C_BUS 0x2
#define ICE_GNSS_TIMER_DELAY_TIME (HZ / 10) /* 0.1 second per message */
/* Create 2 minor devices, both using the same GNSS module. First one is RW,
* second one RO.
*/
#define ICE_GNSS_TTY_MINOR_DEVICES 2
#define ICE_GNSS_TTY_WRITE_BUF 250
#define ICE_MAX_I2C_DATA_SIZE FIELD_MAX(ICE_AQC_I2C_DATA_SIZE_M)
#define ICE_MAX_I2C_WRITE_BYTES 4
/* u-blox ZED-F9T specific definitions */
#define ICE_GNSS_UBX_I2C_BUS_ADDR 0x42 #define ICE_GNSS_UBX_I2C_BUS_ADDR 0x42
/* Data length register is big endian */ /* Data length register is big endian */
#define ICE_GNSS_UBX_DATA_LEN_H 0xFD #define ICE_GNSS_UBX_DATA_LEN_H 0xFD
#define ICE_GNSS_UBX_DATA_LEN_WIDTH 2 #define ICE_GNSS_UBX_DATA_LEN_WIDTH 2
#define ICE_GNSS_UBX_EMPTY_DATA 0xFF #define ICE_GNSS_UBX_EMPTY_DATA 0xFF
#define ICE_GNSS_TIMER_DELAY_TIME (HZ / 10) /* 0.1 second per message */ /* For u-blox writes are performed without address so the first byte to write is
#define ICE_MAX_I2C_DATA_SIZE FIELD_MAX(ICE_AQC_I2C_DATA_SIZE_M) * passed as I2C addr parameter.
*/
#define ICE_GNSS_UBX_WRITE_BYTES (ICE_MAX_I2C_WRITE_BYTES + 1)
#define ICE_MAX_UBX_READ_TRIES 255 #define ICE_MAX_UBX_READ_TRIES 255
#define ICE_MAX_UBX_ACK_READ_TRIES 4095
struct gnss_write_buf {
struct list_head queue;
unsigned int size;
unsigned char *buf;
};
/** /**
* struct gnss_serial - data used to initialize GNSS TTY port * struct gnss_serial - data used to initialize GNSS TTY port
...@@ -25,6 +45,8 @@ ...@@ -25,6 +45,8 @@
* @gnss_mutex: gnss_mutex used to protect GNSS serial operations * @gnss_mutex: gnss_mutex used to protect GNSS serial operations
* @kworker: kwork thread for handling periodic work * @kworker: kwork thread for handling periodic work
* @read_work: read_work function for handling GNSS reads * @read_work: read_work function for handling GNSS reads
* @write_work: write_work function for handling GNSS writes
* @queue: write buffers queue
*/ */
struct gnss_serial { struct gnss_serial {
struct ice_pf *back; struct ice_pf *back;
...@@ -33,6 +55,8 @@ struct gnss_serial { ...@@ -33,6 +55,8 @@ struct gnss_serial {
struct mutex gnss_mutex; /* protects GNSS serial structure */ struct mutex gnss_mutex; /* protects GNSS serial structure */
struct kthread_worker *kworker; struct kthread_worker *kworker;
struct kthread_delayed_work read_work; struct kthread_delayed_work read_work;
struct kthread_work write_work;
struct list_head queue;
}; };
#if IS_ENABLED(CONFIG_TTY) #if IS_ENABLED(CONFIG_TTY)
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment