Merge branch 'lan743x-PCI11010-#PCI11414'
Raju Lakkaraju says: ==================== net: lan743x: PCI11010 / PCI11414 devices This patch series continues with the addition of supported features for the Ethernet function of the PCI11010 / PCI11414 devices to the LAN743x driver. ==================== Signed-off-by: David S. Miller <davem@davemloft.net>
This commit is contained in:
Коммит
e913c09dbe
|
@ -7,6 +7,8 @@
|
|||
#include <linux/phy.h>
|
||||
#include "lan743x_main.h"
|
||||
#include "lan743x_ethtool.h"
|
||||
#include <linux/sched.h>
|
||||
#include <linux/iopoll.h>
|
||||
|
||||
/* eeprom */
|
||||
#define LAN743X_EEPROM_MAGIC (0x74A5)
|
||||
|
@ -19,6 +21,10 @@
|
|||
#define OTP_INDICATOR_1 (0xF3)
|
||||
#define OTP_INDICATOR_2 (0xF7)
|
||||
|
||||
#define LOCK_TIMEOUT_MAX_CNT (100) // 1 sec (10 msce * 100)
|
||||
|
||||
#define LAN743X_CSR_READ_OP(offset) lan743x_csr_read(adapter, offset)
|
||||
|
||||
static int lan743x_otp_power_up(struct lan743x_adapter *adapter)
|
||||
{
|
||||
u32 reg_value;
|
||||
|
@ -149,6 +155,217 @@ static int lan743x_otp_write(struct lan743x_adapter *adapter, u32 offset,
|
|||
return 0;
|
||||
}
|
||||
|
||||
static int lan743x_hs_syslock_acquire(struct lan743x_adapter *adapter,
|
||||
u16 timeout)
|
||||
{
|
||||
u16 timeout_cnt = 0;
|
||||
u32 val;
|
||||
|
||||
do {
|
||||
spin_lock(&adapter->eth_syslock_spinlock);
|
||||
if (adapter->eth_syslock_acquire_cnt == 0) {
|
||||
lan743x_csr_write(adapter, ETH_SYSTEM_SYS_LOCK_REG,
|
||||
SYS_LOCK_REG_ENET_SS_LOCK_);
|
||||
val = lan743x_csr_read(adapter,
|
||||
ETH_SYSTEM_SYS_LOCK_REG);
|
||||
if (val & SYS_LOCK_REG_ENET_SS_LOCK_) {
|
||||
adapter->eth_syslock_acquire_cnt++;
|
||||
WARN_ON(adapter->eth_syslock_acquire_cnt == 0);
|
||||
spin_unlock(&adapter->eth_syslock_spinlock);
|
||||
break;
|
||||
}
|
||||
} else {
|
||||
adapter->eth_syslock_acquire_cnt++;
|
||||
WARN_ON(adapter->eth_syslock_acquire_cnt == 0);
|
||||
spin_unlock(&adapter->eth_syslock_spinlock);
|
||||
break;
|
||||
}
|
||||
|
||||
spin_unlock(&adapter->eth_syslock_spinlock);
|
||||
|
||||
if (timeout_cnt++ < timeout)
|
||||
usleep_range(10000, 11000);
|
||||
else
|
||||
return -ETIMEDOUT;
|
||||
} while (true);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void lan743x_hs_syslock_release(struct lan743x_adapter *adapter)
|
||||
{
|
||||
u32 val;
|
||||
|
||||
spin_lock(&adapter->eth_syslock_spinlock);
|
||||
WARN_ON(adapter->eth_syslock_acquire_cnt == 0);
|
||||
|
||||
if (adapter->eth_syslock_acquire_cnt) {
|
||||
adapter->eth_syslock_acquire_cnt--;
|
||||
if (adapter->eth_syslock_acquire_cnt == 0) {
|
||||
lan743x_csr_write(adapter, ETH_SYSTEM_SYS_LOCK_REG, 0);
|
||||
val = lan743x_csr_read(adapter,
|
||||
ETH_SYSTEM_SYS_LOCK_REG);
|
||||
WARN_ON((val & SYS_LOCK_REG_ENET_SS_LOCK_) != 0);
|
||||
}
|
||||
}
|
||||
|
||||
spin_unlock(&adapter->eth_syslock_spinlock);
|
||||
}
|
||||
|
||||
static void lan743x_hs_otp_power_up(struct lan743x_adapter *adapter)
|
||||
{
|
||||
u32 reg_value;
|
||||
|
||||
reg_value = lan743x_csr_read(adapter, HS_OTP_PWR_DN);
|
||||
if (reg_value & OTP_PWR_DN_PWRDN_N_) {
|
||||
reg_value &= ~OTP_PWR_DN_PWRDN_N_;
|
||||
lan743x_csr_write(adapter, HS_OTP_PWR_DN, reg_value);
|
||||
/* To flush the posted write so the subsequent delay is
|
||||
* guaranteed to happen after the write at the hardware
|
||||
*/
|
||||
lan743x_csr_read(adapter, HS_OTP_PWR_DN);
|
||||
udelay(1);
|
||||
}
|
||||
}
|
||||
|
||||
static void lan743x_hs_otp_power_down(struct lan743x_adapter *adapter)
|
||||
{
|
||||
u32 reg_value;
|
||||
|
||||
reg_value = lan743x_csr_read(adapter, HS_OTP_PWR_DN);
|
||||
if (!(reg_value & OTP_PWR_DN_PWRDN_N_)) {
|
||||
reg_value |= OTP_PWR_DN_PWRDN_N_;
|
||||
lan743x_csr_write(adapter, HS_OTP_PWR_DN, reg_value);
|
||||
/* To flush the posted write so the subsequent delay is
|
||||
* guaranteed to happen after the write at the hardware
|
||||
*/
|
||||
lan743x_csr_read(adapter, HS_OTP_PWR_DN);
|
||||
udelay(1);
|
||||
}
|
||||
}
|
||||
|
||||
static void lan743x_hs_otp_set_address(struct lan743x_adapter *adapter,
|
||||
u32 address)
|
||||
{
|
||||
lan743x_csr_write(adapter, HS_OTP_ADDR_HIGH, (address >> 8) & 0x03);
|
||||
lan743x_csr_write(adapter, HS_OTP_ADDR_LOW, address & 0xFF);
|
||||
}
|
||||
|
||||
static void lan743x_hs_otp_read_go(struct lan743x_adapter *adapter)
|
||||
{
|
||||
lan743x_csr_write(adapter, HS_OTP_FUNC_CMD, OTP_FUNC_CMD_READ_);
|
||||
lan743x_csr_write(adapter, HS_OTP_CMD_GO, OTP_CMD_GO_GO_);
|
||||
}
|
||||
|
||||
static int lan743x_hs_otp_cmd_cmplt_chk(struct lan743x_adapter *adapter)
|
||||
{
|
||||
u32 val;
|
||||
|
||||
return readx_poll_timeout(LAN743X_CSR_READ_OP, HS_OTP_STATUS, val,
|
||||
!(val & OTP_STATUS_BUSY_),
|
||||
80, 10000);
|
||||
}
|
||||
|
||||
static int lan743x_hs_otp_read(struct lan743x_adapter *adapter, u32 offset,
|
||||
u32 length, u8 *data)
|
||||
{
|
||||
int ret;
|
||||
int i;
|
||||
|
||||
ret = lan743x_hs_syslock_acquire(adapter, LOCK_TIMEOUT_MAX_CNT);
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
|
||||
lan743x_hs_otp_power_up(adapter);
|
||||
|
||||
ret = lan743x_hs_otp_cmd_cmplt_chk(adapter);
|
||||
if (ret < 0)
|
||||
goto power_down;
|
||||
|
||||
lan743x_hs_syslock_release(adapter);
|
||||
|
||||
for (i = 0; i < length; i++) {
|
||||
ret = lan743x_hs_syslock_acquire(adapter,
|
||||
LOCK_TIMEOUT_MAX_CNT);
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
|
||||
lan743x_hs_otp_set_address(adapter, offset + i);
|
||||
|
||||
lan743x_hs_otp_read_go(adapter);
|
||||
ret = lan743x_hs_otp_cmd_cmplt_chk(adapter);
|
||||
if (ret < 0)
|
||||
goto power_down;
|
||||
|
||||
data[i] = lan743x_csr_read(adapter, HS_OTP_READ_DATA);
|
||||
|
||||
lan743x_hs_syslock_release(adapter);
|
||||
}
|
||||
|
||||
ret = lan743x_hs_syslock_acquire(adapter,
|
||||
LOCK_TIMEOUT_MAX_CNT);
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
|
||||
power_down:
|
||||
lan743x_hs_otp_power_down(adapter);
|
||||
lan743x_hs_syslock_release(adapter);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int lan743x_hs_otp_write(struct lan743x_adapter *adapter, u32 offset,
|
||||
u32 length, u8 *data)
|
||||
{
|
||||
int ret;
|
||||
int i;
|
||||
|
||||
ret = lan743x_hs_syslock_acquire(adapter, LOCK_TIMEOUT_MAX_CNT);
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
|
||||
lan743x_hs_otp_power_up(adapter);
|
||||
|
||||
ret = lan743x_hs_otp_cmd_cmplt_chk(adapter);
|
||||
if (ret < 0)
|
||||
goto power_down;
|
||||
|
||||
/* set to BYTE program mode */
|
||||
lan743x_csr_write(adapter, HS_OTP_PRGM_MODE, OTP_PRGM_MODE_BYTE_);
|
||||
|
||||
lan743x_hs_syslock_release(adapter);
|
||||
|
||||
for (i = 0; i < length; i++) {
|
||||
ret = lan743x_hs_syslock_acquire(adapter,
|
||||
LOCK_TIMEOUT_MAX_CNT);
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
|
||||
lan743x_hs_otp_set_address(adapter, offset + i);
|
||||
|
||||
lan743x_csr_write(adapter, HS_OTP_PRGM_DATA, data[i]);
|
||||
lan743x_csr_write(adapter, HS_OTP_TST_CMD,
|
||||
OTP_TST_CMD_PRGVRFY_);
|
||||
lan743x_csr_write(adapter, HS_OTP_CMD_GO, OTP_CMD_GO_GO_);
|
||||
|
||||
ret = lan743x_hs_otp_cmd_cmplt_chk(adapter);
|
||||
if (ret < 0)
|
||||
goto power_down;
|
||||
|
||||
lan743x_hs_syslock_release(adapter);
|
||||
}
|
||||
|
||||
ret = lan743x_hs_syslock_acquire(adapter, LOCK_TIMEOUT_MAX_CNT);
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
|
||||
power_down:
|
||||
lan743x_hs_otp_power_down(adapter);
|
||||
lan743x_hs_syslock_release(adapter);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int lan743x_eeprom_wait(struct lan743x_adapter *adapter)
|
||||
{
|
||||
unsigned long start_time = jiffies;
|
||||
|
@ -263,6 +480,100 @@ static int lan743x_eeprom_write(struct lan743x_adapter *adapter,
|
|||
return 0;
|
||||
}
|
||||
|
||||
static int lan743x_hs_eeprom_cmd_cmplt_chk(struct lan743x_adapter *adapter)
|
||||
{
|
||||
u32 val;
|
||||
|
||||
return readx_poll_timeout(LAN743X_CSR_READ_OP, HS_E2P_CMD, val,
|
||||
(!(val & HS_E2P_CMD_EPC_BUSY_) ||
|
||||
(val & HS_E2P_CMD_EPC_TIMEOUT_)),
|
||||
50, 10000);
|
||||
}
|
||||
|
||||
static int lan743x_hs_eeprom_read(struct lan743x_adapter *adapter,
|
||||
u32 offset, u32 length, u8 *data)
|
||||
{
|
||||
int retval;
|
||||
u32 val;
|
||||
int i;
|
||||
|
||||
retval = lan743x_hs_syslock_acquire(adapter, LOCK_TIMEOUT_MAX_CNT);
|
||||
if (retval < 0)
|
||||
return retval;
|
||||
|
||||
retval = lan743x_hs_eeprom_cmd_cmplt_chk(adapter);
|
||||
lan743x_hs_syslock_release(adapter);
|
||||
if (retval < 0)
|
||||
return retval;
|
||||
|
||||
for (i = 0; i < length; i++) {
|
||||
retval = lan743x_hs_syslock_acquire(adapter,
|
||||
LOCK_TIMEOUT_MAX_CNT);
|
||||
if (retval < 0)
|
||||
return retval;
|
||||
|
||||
val = HS_E2P_CMD_EPC_BUSY_ | HS_E2P_CMD_EPC_CMD_READ_;
|
||||
val |= (offset & HS_E2P_CMD_EPC_ADDR_MASK_);
|
||||
lan743x_csr_write(adapter, HS_E2P_CMD, val);
|
||||
retval = lan743x_hs_eeprom_cmd_cmplt_chk(adapter);
|
||||
if (retval < 0) {
|
||||
lan743x_hs_syslock_release(adapter);
|
||||
return retval;
|
||||
}
|
||||
|
||||
val = lan743x_csr_read(adapter, HS_E2P_DATA);
|
||||
|
||||
lan743x_hs_syslock_release(adapter);
|
||||
|
||||
data[i] = val & 0xFF;
|
||||
offset++;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int lan743x_hs_eeprom_write(struct lan743x_adapter *adapter,
|
||||
u32 offset, u32 length, u8 *data)
|
||||
{
|
||||
int retval;
|
||||
u32 val;
|
||||
int i;
|
||||
|
||||
retval = lan743x_hs_syslock_acquire(adapter, LOCK_TIMEOUT_MAX_CNT);
|
||||
if (retval < 0)
|
||||
return retval;
|
||||
|
||||
retval = lan743x_hs_eeprom_cmd_cmplt_chk(adapter);
|
||||
lan743x_hs_syslock_release(adapter);
|
||||
if (retval < 0)
|
||||
return retval;
|
||||
|
||||
for (i = 0; i < length; i++) {
|
||||
retval = lan743x_hs_syslock_acquire(adapter,
|
||||
LOCK_TIMEOUT_MAX_CNT);
|
||||
if (retval < 0)
|
||||
return retval;
|
||||
|
||||
/* Fill data register */
|
||||
val = data[i];
|
||||
lan743x_csr_write(adapter, HS_E2P_DATA, val);
|
||||
|
||||
/* Send "write" command */
|
||||
val = HS_E2P_CMD_EPC_BUSY_ | HS_E2P_CMD_EPC_CMD_WRITE_;
|
||||
val |= (offset & HS_E2P_CMD_EPC_ADDR_MASK_);
|
||||
lan743x_csr_write(adapter, HS_E2P_CMD, val);
|
||||
|
||||
retval = lan743x_hs_eeprom_cmd_cmplt_chk(adapter);
|
||||
lan743x_hs_syslock_release(adapter);
|
||||
if (retval < 0)
|
||||
return retval;
|
||||
|
||||
offset++;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void lan743x_ethtool_get_drvinfo(struct net_device *netdev,
|
||||
struct ethtool_drvinfo *info)
|
||||
{
|
||||
|
@ -304,10 +615,21 @@ static int lan743x_ethtool_get_eeprom(struct net_device *netdev,
|
|||
struct lan743x_adapter *adapter = netdev_priv(netdev);
|
||||
int ret = 0;
|
||||
|
||||
if (adapter->flags & LAN743X_ADAPTER_FLAG_OTP)
|
||||
ret = lan743x_otp_read(adapter, ee->offset, ee->len, data);
|
||||
else
|
||||
ret = lan743x_eeprom_read(adapter, ee->offset, ee->len, data);
|
||||
if (adapter->flags & LAN743X_ADAPTER_FLAG_OTP) {
|
||||
if (adapter->is_pci11x1x)
|
||||
ret = lan743x_hs_otp_read(adapter, ee->offset,
|
||||
ee->len, data);
|
||||
else
|
||||
ret = lan743x_otp_read(adapter, ee->offset,
|
||||
ee->len, data);
|
||||
} else {
|
||||
if (adapter->is_pci11x1x)
|
||||
ret = lan743x_hs_eeprom_read(adapter, ee->offset,
|
||||
ee->len, data);
|
||||
else
|
||||
ret = lan743x_eeprom_read(adapter, ee->offset,
|
||||
ee->len, data);
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
@ -321,13 +643,22 @@ static int lan743x_ethtool_set_eeprom(struct net_device *netdev,
|
|||
if (adapter->flags & LAN743X_ADAPTER_FLAG_OTP) {
|
||||
/* Beware! OTP is One Time Programming ONLY! */
|
||||
if (ee->magic == LAN743X_OTP_MAGIC) {
|
||||
ret = lan743x_otp_write(adapter, ee->offset,
|
||||
ee->len, data);
|
||||
if (adapter->is_pci11x1x)
|
||||
ret = lan743x_hs_otp_write(adapter, ee->offset,
|
||||
ee->len, data);
|
||||
else
|
||||
ret = lan743x_otp_write(adapter, ee->offset,
|
||||
ee->len, data);
|
||||
}
|
||||
} else {
|
||||
if (ee->magic == LAN743X_EEPROM_MAGIC) {
|
||||
ret = lan743x_eeprom_write(adapter, ee->offset,
|
||||
ee->len, data);
|
||||
if (adapter->is_pci11x1x)
|
||||
ret = lan743x_hs_eeprom_write(adapter,
|
||||
ee->offset,
|
||||
ee->len, data);
|
||||
else
|
||||
ret = lan743x_eeprom_write(adapter, ee->offset,
|
||||
ee->len, data);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -365,6 +696,14 @@ static const char lan743x_set1_sw_cnt_strings[][ETH_GSTRING_LEN] = {
|
|||
"RX Queue 3 Frames",
|
||||
};
|
||||
|
||||
static const char lan743x_tx_queue_cnt_strings[][ETH_GSTRING_LEN] = {
|
||||
"TX Queue 0 Frames",
|
||||
"TX Queue 1 Frames",
|
||||
"TX Queue 2 Frames",
|
||||
"TX Queue 3 Frames",
|
||||
"TX Total Queue Frames",
|
||||
};
|
||||
|
||||
static const char lan743x_set2_hw_cnt_strings[][ETH_GSTRING_LEN] = {
|
||||
"RX Total Frames",
|
||||
"EEE RX LPI Transitions",
|
||||
|
@ -462,6 +801,8 @@ static const char lan743x_priv_flags_strings[][ETH_GSTRING_LEN] = {
|
|||
static void lan743x_ethtool_get_strings(struct net_device *netdev,
|
||||
u32 stringset, u8 *data)
|
||||
{
|
||||
struct lan743x_adapter *adapter = netdev_priv(netdev);
|
||||
|
||||
switch (stringset) {
|
||||
case ETH_SS_STATS:
|
||||
memcpy(data, lan743x_set0_hw_cnt_strings,
|
||||
|
@ -473,6 +814,13 @@ static void lan743x_ethtool_get_strings(struct net_device *netdev,
|
|||
sizeof(lan743x_set1_sw_cnt_strings)],
|
||||
lan743x_set2_hw_cnt_strings,
|
||||
sizeof(lan743x_set2_hw_cnt_strings));
|
||||
if (adapter->is_pci11x1x) {
|
||||
memcpy(&data[sizeof(lan743x_set0_hw_cnt_strings) +
|
||||
sizeof(lan743x_set1_sw_cnt_strings) +
|
||||
sizeof(lan743x_set2_hw_cnt_strings)],
|
||||
lan743x_tx_queue_cnt_strings,
|
||||
sizeof(lan743x_tx_queue_cnt_strings));
|
||||
}
|
||||
break;
|
||||
case ETH_SS_PRIV_FLAGS:
|
||||
memcpy(data, lan743x_priv_flags_strings,
|
||||
|
@ -486,7 +834,9 @@ static void lan743x_ethtool_get_ethtool_stats(struct net_device *netdev,
|
|||
u64 *data)
|
||||
{
|
||||
struct lan743x_adapter *adapter = netdev_priv(netdev);
|
||||
u64 total_queue_count = 0;
|
||||
int data_index = 0;
|
||||
u64 pkt_cnt;
|
||||
u32 buf;
|
||||
int i;
|
||||
|
||||
|
@ -500,6 +850,14 @@ static void lan743x_ethtool_get_ethtool_stats(struct net_device *netdev,
|
|||
buf = lan743x_csr_read(adapter, lan743x_set2_hw_cnt_addr[i]);
|
||||
data[data_index++] = (u64)buf;
|
||||
}
|
||||
if (adapter->is_pci11x1x) {
|
||||
for (i = 0; i < ARRAY_SIZE(adapter->tx); i++) {
|
||||
pkt_cnt = (u64)(adapter->tx[i].frame_count);
|
||||
data[data_index++] = pkt_cnt;
|
||||
total_queue_count += pkt_cnt;
|
||||
}
|
||||
data[data_index++] = total_queue_count;
|
||||
}
|
||||
}
|
||||
|
||||
static u32 lan743x_ethtool_get_priv_flags(struct net_device *netdev)
|
||||
|
@ -520,6 +878,8 @@ static int lan743x_ethtool_set_priv_flags(struct net_device *netdev, u32 flags)
|
|||
|
||||
static int lan743x_ethtool_get_sset_count(struct net_device *netdev, int sset)
|
||||
{
|
||||
struct lan743x_adapter *adapter = netdev_priv(netdev);
|
||||
|
||||
switch (sset) {
|
||||
case ETH_SS_STATS:
|
||||
{
|
||||
|
@ -528,6 +888,8 @@ static int lan743x_ethtool_get_sset_count(struct net_device *netdev, int sset)
|
|||
ret = ARRAY_SIZE(lan743x_set0_hw_cnt_strings);
|
||||
ret += ARRAY_SIZE(lan743x_set1_sw_cnt_strings);
|
||||
ret += ARRAY_SIZE(lan743x_set2_hw_cnt_strings);
|
||||
if (adapter->is_pci11x1x)
|
||||
ret += ARRAY_SIZE(lan743x_tx_queue_cnt_strings);
|
||||
return ret;
|
||||
}
|
||||
case ETH_SS_PRIV_FLAGS:
|
||||
|
|
|
@ -1776,6 +1776,7 @@ static netdev_tx_t lan743x_tx_xmit_frame(struct lan743x_tx *tx,
|
|||
dev_kfree_skb_irq(skb);
|
||||
goto unlock;
|
||||
}
|
||||
tx->frame_count++;
|
||||
|
||||
if (gso)
|
||||
lan743x_tx_frame_add_lso(tx, frame_length, nr_frags);
|
||||
|
@ -2868,6 +2869,7 @@ static int lan743x_hardware_init(struct lan743x_adapter *adapter,
|
|||
adapter->used_tx_channels = PCI11X1X_USED_TX_CHANNELS;
|
||||
adapter->max_vector_count = PCI11X1X_MAX_VECTOR_COUNT;
|
||||
pci11x1x_strap_get_status(adapter);
|
||||
spin_lock_init(&adapter->eth_syslock_spinlock);
|
||||
} else {
|
||||
adapter->max_tx_channels = LAN743X_MAX_TX_CHANNELS;
|
||||
adapter->used_tx_channels = LAN743X_USED_TX_CHANNELS;
|
||||
|
|
|
@ -86,6 +86,40 @@
|
|||
|
||||
#define E2P_DATA (0x044)
|
||||
|
||||
/* Hearthstone top level & System Reg Addresses */
|
||||
#define ETH_CTRL_REG_ADDR_BASE (0x0000)
|
||||
#define ETH_SYS_REG_ADDR_BASE (0x4000)
|
||||
#define CONFIG_REG_ADDR_BASE (0x0000)
|
||||
#define ETH_EEPROM_REG_ADDR_BASE (0x0E00)
|
||||
#define ETH_OTP_REG_ADDR_BASE (0x1000)
|
||||
#define SYS_LOCK_REG (0x00A0)
|
||||
#define SYS_LOCK_REG_MAIN_LOCK_ BIT(7)
|
||||
#define SYS_LOCK_REG_GEN_PERI_LOCK_ BIT(5)
|
||||
#define SYS_LOCK_REG_SPI_PERI_LOCK_ BIT(4)
|
||||
#define SYS_LOCK_REG_SMBUS_PERI_LOCK_ BIT(3)
|
||||
#define SYS_LOCK_REG_UART_SS_LOCK_ BIT(2)
|
||||
#define SYS_LOCK_REG_ENET_SS_LOCK_ BIT(1)
|
||||
#define SYS_LOCK_REG_USB_SS_LOCK_ BIT(0)
|
||||
#define ETH_SYSTEM_SYS_LOCK_REG (ETH_SYS_REG_ADDR_BASE + \
|
||||
CONFIG_REG_ADDR_BASE + \
|
||||
SYS_LOCK_REG)
|
||||
#define HS_EEPROM_REG_ADDR_BASE (ETH_SYS_REG_ADDR_BASE + \
|
||||
ETH_EEPROM_REG_ADDR_BASE)
|
||||
#define HS_E2P_CMD (HS_EEPROM_REG_ADDR_BASE + 0x0000)
|
||||
#define HS_E2P_CMD_EPC_BUSY_ BIT(31)
|
||||
#define HS_E2P_CMD_EPC_CMD_WRITE_ GENMASK(29, 28)
|
||||
#define HS_E2P_CMD_EPC_CMD_READ_ (0x0)
|
||||
#define HS_E2P_CMD_EPC_TIMEOUT_ BIT(17)
|
||||
#define HS_E2P_CMD_EPC_ADDR_MASK_ GENMASK(15, 0)
|
||||
#define HS_E2P_DATA (HS_EEPROM_REG_ADDR_BASE + 0x0004)
|
||||
#define HS_E2P_DATA_MASK_ GENMASK(7, 0)
|
||||
#define HS_E2P_CFG (HS_EEPROM_REG_ADDR_BASE + 0x0008)
|
||||
#define HS_E2P_CFG_I2C_PULSE_MASK_ GENMASK(19, 16)
|
||||
#define HS_E2P_CFG_EEPROM_SIZE_SEL_ BIT(12)
|
||||
#define HS_E2P_CFG_I2C_BAUD_RATE_MASK_ GENMASK(9, 8)
|
||||
#define HS_E2P_CFG_TEST_EEPR_TO_BYP_ BIT(0)
|
||||
#define HS_E2P_PAD_CTL (HS_EEPROM_REG_ADDR_BASE + 0x000C)
|
||||
|
||||
#define GPIO_CFG0 (0x050)
|
||||
#define GPIO_CFG0_GPIO_DIR_BIT_(bit) BIT(16 + (bit))
|
||||
#define GPIO_CFG0_GPIO_DATA_BIT_(bit) BIT(0 + (bit))
|
||||
|
@ -302,6 +336,7 @@
|
|||
#define INT_MOD_CFG9 (0x7E4)
|
||||
|
||||
#define PTP_CMD_CTL (0x0A00)
|
||||
#define PTP_CMD_CTL_PTP_LTC_TARGET_READ_ BIT(13)
|
||||
#define PTP_CMD_CTL_PTP_CLK_STP_NSEC_ BIT(6)
|
||||
#define PTP_CMD_CTL_PTP_CLOCK_STEP_SEC_ BIT(5)
|
||||
#define PTP_CMD_CTL_PTP_CLOCK_LOAD_ BIT(4)
|
||||
|
@ -323,9 +358,51 @@
|
|||
(((value) & 0x7) << (1 + ((channel) << 2)))
|
||||
#define PTP_GENERAL_CONFIG_RELOAD_ADD_X_(channel) (BIT((channel) << 2))
|
||||
|
||||
#define HS_PTP_GENERAL_CONFIG (0x0A04)
|
||||
#define HS_PTP_GENERAL_CONFIG_CLOCK_EVENT_X_MASK_(channel) \
|
||||
(0xf << (4 + ((channel) << 2)))
|
||||
#define HS_PTP_GENERAL_CONFIG_CLOCK_EVENT_100NS_ (0)
|
||||
#define HS_PTP_GENERAL_CONFIG_CLOCK_EVENT_500NS_ (1)
|
||||
#define HS_PTP_GENERAL_CONFIG_CLOCK_EVENT_1US_ (2)
|
||||
#define HS_PTP_GENERAL_CONFIG_CLOCK_EVENT_5US_ (3)
|
||||
#define HS_PTP_GENERAL_CONFIG_CLOCK_EVENT_10US_ (4)
|
||||
#define HS_PTP_GENERAL_CONFIG_CLOCK_EVENT_50US_ (5)
|
||||
#define HS_PTP_GENERAL_CONFIG_CLOCK_EVENT_100US_ (6)
|
||||
#define HS_PTP_GENERAL_CONFIG_CLOCK_EVENT_500US_ (7)
|
||||
#define HS_PTP_GENERAL_CONFIG_CLOCK_EVENT_1MS_ (8)
|
||||
#define HS_PTP_GENERAL_CONFIG_CLOCK_EVENT_5MS_ (9)
|
||||
#define HS_PTP_GENERAL_CONFIG_CLOCK_EVENT_10MS_ (10)
|
||||
#define HS_PTP_GENERAL_CONFIG_CLOCK_EVENT_50MS_ (11)
|
||||
#define HS_PTP_GENERAL_CONFIG_CLOCK_EVENT_100MS_ (12)
|
||||
#define HS_PTP_GENERAL_CONFIG_CLOCK_EVENT_200MS_ (13)
|
||||
#define HS_PTP_GENERAL_CONFIG_CLOCK_EVENT_TOGG_ (14)
|
||||
#define HS_PTP_GENERAL_CONFIG_CLOCK_EVENT_INT_ (15)
|
||||
#define HS_PTP_GENERAL_CONFIG_CLOCK_EVENT_X_SET_(channel, value) \
|
||||
(((value) & 0xf) << (4 + ((channel) << 2)))
|
||||
#define HS_PTP_GENERAL_CONFIG_EVENT_POL_X_(channel) (BIT(1 + ((channel) * 2)))
|
||||
#define HS_PTP_GENERAL_CONFIG_RELOAD_ADD_X_(channel) (BIT((channel) * 2))
|
||||
|
||||
#define PTP_INT_STS (0x0A08)
|
||||
#define PTP_INT_IO_FE_MASK_ GENMASK(31, 24)
|
||||
#define PTP_INT_IO_FE_SHIFT_ (24)
|
||||
#define PTP_INT_IO_FE_SET_(channel) BIT(24 + (channel))
|
||||
#define PTP_INT_IO_RE_MASK_ GENMASK(23, 16)
|
||||
#define PTP_INT_IO_RE_SHIFT_ (16)
|
||||
#define PTP_INT_IO_RE_SET_(channel) BIT(16 + (channel))
|
||||
#define PTP_INT_TX_TS_OVRFL_INT_ BIT(14)
|
||||
#define PTP_INT_TX_SWTS_ERR_INT_ BIT(13)
|
||||
#define PTP_INT_TX_TS_INT_ BIT(12)
|
||||
#define PTP_INT_RX_TS_OVRFL_INT_ BIT(9)
|
||||
#define PTP_INT_RX_TS_INT_ BIT(8)
|
||||
#define PTP_INT_TIMER_INT_B_ BIT(1)
|
||||
#define PTP_INT_TIMER_INT_A_ BIT(0)
|
||||
#define PTP_INT_EN_SET (0x0A0C)
|
||||
#define PTP_INT_EN_FE_EN_SET_(channel) BIT(24 + (channel))
|
||||
#define PTP_INT_EN_RE_EN_SET_(channel) BIT(16 + (channel))
|
||||
#define PTP_INT_EN_TIMER_SET_(channel) BIT(channel)
|
||||
#define PTP_INT_EN_CLR (0x0A10)
|
||||
#define PTP_INT_EN_FE_EN_CLR_(channel) BIT(24 + (channel))
|
||||
#define PTP_INT_EN_RE_EN_CLR_(channel) BIT(16 + (channel))
|
||||
#define PTP_INT_BIT_TX_SWTS_ERR_ BIT(13)
|
||||
#define PTP_INT_BIT_TX_TS_ BIT(12)
|
||||
#define PTP_INT_BIT_TIMER_B_ BIT(1)
|
||||
|
@ -343,6 +420,16 @@
|
|||
#define PTP_CLOCK_TARGET_NS_X(channel) (0x0A34 + ((channel) << 4))
|
||||
#define PTP_CLOCK_TARGET_RELOAD_SEC_X(channel) (0x0A38 + ((channel) << 4))
|
||||
#define PTP_CLOCK_TARGET_RELOAD_NS_X(channel) (0x0A3C + ((channel) << 4))
|
||||
#define PTP_LTC_SET_SEC_HI (0x0A50)
|
||||
#define PTP_LTC_SET_SEC_HI_SEC_47_32_MASK_ GENMASK(15, 0)
|
||||
#define PTP_VERSION (0x0A54)
|
||||
#define PTP_VERSION_TX_UP_MASK_ GENMASK(31, 24)
|
||||
#define PTP_VERSION_TX_LO_MASK_ GENMASK(23, 16)
|
||||
#define PTP_VERSION_RX_UP_MASK_ GENMASK(15, 8)
|
||||
#define PTP_VERSION_RX_LO_MASK_ GENMASK(7, 0)
|
||||
#define PTP_IO_SEL (0x0A58)
|
||||
#define PTP_IO_SEL_MASK_ GENMASK(10, 8)
|
||||
#define PTP_IO_SEL_SHIFT_ (8)
|
||||
#define PTP_LATENCY (0x0A5C)
|
||||
#define PTP_LATENCY_TX_SET_(tx_latency) (((u32)(tx_latency)) << 16)
|
||||
#define PTP_LATENCY_RX_SET_(rx_latency) \
|
||||
|
@ -367,6 +454,59 @@
|
|||
#define PTP_TX_MSG_HEADER_MSG_TYPE_ (0x000F0000)
|
||||
#define PTP_TX_MSG_HEADER_MSG_TYPE_SYNC_ (0x00000000)
|
||||
|
||||
#define PTP_TX_CAP_INFO (0x0AB8)
|
||||
#define PTP_TX_CAP_INFO_TX_CH_MASK_ GENMASK(1, 0)
|
||||
#define PTP_TX_DOMAIN (0x0ABC)
|
||||
#define PTP_TX_DOMAIN_MASK_ GENMASK(23, 16)
|
||||
#define PTP_TX_DOMAIN_RANGE_EN_ BIT(15)
|
||||
#define PTP_TX_DOMAIN_RANGE_MASK_ GENMASK(7, 0)
|
||||
#define PTP_TX_SDOID (0x0AC0)
|
||||
#define PTP_TX_SDOID_MASK_ GENMASK(23, 16)
|
||||
#define PTP_TX_SDOID_RANGE_EN_ BIT(15)
|
||||
#define PTP_TX_SDOID_11_0_MASK_ GENMASK(7, 0)
|
||||
#define PTP_IO_CAP_CONFIG (0x0AC4)
|
||||
#define PTP_IO_CAP_CONFIG_LOCK_FE_(channel) BIT(24 + (channel))
|
||||
#define PTP_IO_CAP_CONFIG_LOCK_RE_(channel) BIT(16 + (channel))
|
||||
#define PTP_IO_CAP_CONFIG_FE_CAP_EN_(channel) BIT(8 + (channel))
|
||||
#define PTP_IO_CAP_CONFIG_RE_CAP_EN_(channel) BIT(0 + (channel))
|
||||
#define PTP_IO_RE_LTC_SEC_CAP_X (0x0AC8)
|
||||
#define PTP_IO_RE_LTC_NS_CAP_X (0x0ACC)
|
||||
#define PTP_IO_FE_LTC_SEC_CAP_X (0x0AD0)
|
||||
#define PTP_IO_FE_LTC_NS_CAP_X (0x0AD4)
|
||||
#define PTP_IO_EVENT_OUTPUT_CFG (0x0AD8)
|
||||
#define PTP_IO_EVENT_OUTPUT_CFG_SEL_(channel) BIT(16 + (channel))
|
||||
#define PTP_IO_EVENT_OUTPUT_CFG_EN_(channel) BIT(0 + (channel))
|
||||
#define PTP_IO_PIN_CFG (0x0ADC)
|
||||
#define PTP_IO_PIN_CFG_OBUF_TYPE_(channel) BIT(0 + (channel))
|
||||
#define PTP_LTC_RD_SEC_HI (0x0AF0)
|
||||
#define PTP_LTC_RD_SEC_HI_SEC_47_32_MASK_ GENMASK(15, 0)
|
||||
#define PTP_LTC_RD_SEC_LO (0x0AF4)
|
||||
#define PTP_LTC_RD_NS (0x0AF8)
|
||||
#define PTP_LTC_RD_NS_29_0_MASK_ GENMASK(29, 0)
|
||||
#define PTP_LTC_RD_SUBNS (0x0AFC)
|
||||
#define PTP_RX_USER_MAC_HI (0x0B00)
|
||||
#define PTP_RX_USER_MAC_HI_47_32_MASK_ GENMASK(15, 0)
|
||||
#define PTP_RX_USER_MAC_LO (0x0B04)
|
||||
#define PTP_RX_USER_IP_ADDR_0 (0x0B20)
|
||||
#define PTP_RX_USER_IP_ADDR_1 (0x0B24)
|
||||
#define PTP_RX_USER_IP_ADDR_2 (0x0B28)
|
||||
#define PTP_RX_USER_IP_ADDR_3 (0x0B2C)
|
||||
#define PTP_RX_USER_IP_MASK_0 (0x0B30)
|
||||
#define PTP_RX_USER_IP_MASK_1 (0x0B34)
|
||||
#define PTP_RX_USER_IP_MASK_2 (0x0B38)
|
||||
#define PTP_RX_USER_IP_MASK_3 (0x0B3C)
|
||||
#define PTP_TX_USER_MAC_HI (0x0B40)
|
||||
#define PTP_TX_USER_MAC_HI_47_32_MASK_ GENMASK(15, 0)
|
||||
#define PTP_TX_USER_MAC_LO (0x0B44)
|
||||
#define PTP_TX_USER_IP_ADDR_0 (0x0B60)
|
||||
#define PTP_TX_USER_IP_ADDR_1 (0x0B64)
|
||||
#define PTP_TX_USER_IP_ADDR_2 (0x0B68)
|
||||
#define PTP_TX_USER_IP_ADDR_3 (0x0B6C)
|
||||
#define PTP_TX_USER_IP_MASK_0 (0x0B70)
|
||||
#define PTP_TX_USER_IP_MASK_1 (0x0B74)
|
||||
#define PTP_TX_USER_IP_MASK_2 (0x0B78)
|
||||
#define PTP_TX_USER_IP_MASK_3 (0x0B7C)
|
||||
|
||||
#define DMAC_CFG (0xC00)
|
||||
#define DMAC_CFG_COAL_EN_ BIT(16)
|
||||
#define DMAC_CFG_CH_ARB_SEL_RX_HIGH_ (0x00000000)
|
||||
|
@ -522,6 +662,20 @@
|
|||
#define OTP_STATUS (0x1030)
|
||||
#define OTP_STATUS_BUSY_ BIT(0)
|
||||
|
||||
/* Hearthstone OTP block registers */
|
||||
#define HS_OTP_BLOCK_BASE (ETH_SYS_REG_ADDR_BASE + \
|
||||
ETH_OTP_REG_ADDR_BASE)
|
||||
#define HS_OTP_PWR_DN (HS_OTP_BLOCK_BASE + 0x0)
|
||||
#define HS_OTP_ADDR_HIGH (HS_OTP_BLOCK_BASE + 0x4)
|
||||
#define HS_OTP_ADDR_LOW (HS_OTP_BLOCK_BASE + 0x8)
|
||||
#define HS_OTP_PRGM_DATA (HS_OTP_BLOCK_BASE + 0x10)
|
||||
#define HS_OTP_PRGM_MODE (HS_OTP_BLOCK_BASE + 0x14)
|
||||
#define HS_OTP_READ_DATA (HS_OTP_BLOCK_BASE + 0x18)
|
||||
#define HS_OTP_FUNC_CMD (HS_OTP_BLOCK_BASE + 0x20)
|
||||
#define HS_OTP_TST_CMD (HS_OTP_BLOCK_BASE + 0x24)
|
||||
#define HS_OTP_CMD_GO (HS_OTP_BLOCK_BASE + 0x28)
|
||||
#define HS_OTP_STATUS (HS_OTP_BLOCK_BASE + 0x30)
|
||||
|
||||
/* MAC statistics registers */
|
||||
#define STAT_RX_FCS_ERRORS (0x1200)
|
||||
#define STAT_RX_ALIGNMENT_ERRORS (0x1204)
|
||||
|
@ -715,6 +869,7 @@ struct lan743x_tx {
|
|||
int last_tail;
|
||||
|
||||
struct napi_struct napi;
|
||||
u32 frame_count;
|
||||
|
||||
struct sk_buff *overflow_skb;
|
||||
};
|
||||
|
@ -772,6 +927,10 @@ struct lan743x_adapter {
|
|||
struct lan743x_rx rx[LAN743X_USED_RX_CHANNELS];
|
||||
bool is_pci11x1x;
|
||||
bool is_sgmii_en;
|
||||
/* protect ethernet syslock */
|
||||
spinlock_t eth_syslock_spinlock;
|
||||
bool eth_syslock_en;
|
||||
u32 eth_syslock_acquire_cnt;
|
||||
u8 max_tx_channels;
|
||||
u8 used_tx_channels;
|
||||
u8 max_vector_count;
|
||||
|
|
|
@ -25,6 +25,18 @@ static void lan743x_ptp_clock_set(struct lan743x_adapter *adapter,
|
|||
u32 seconds, u32 nano_seconds,
|
||||
u32 sub_nano_seconds);
|
||||
|
||||
static int lan743x_get_channel(u32 ch_map)
|
||||
{
|
||||
int idx;
|
||||
|
||||
for (idx = 0; idx < 32; idx++) {
|
||||
if (ch_map & (0x1 << idx))
|
||||
return idx;
|
||||
}
|
||||
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
int lan743x_gpio_init(struct lan743x_adapter *adapter)
|
||||
{
|
||||
struct lan743x_gpio *gpio = &adapter->gpio;
|
||||
|
@ -179,6 +191,8 @@ static void lan743x_ptp_release_event_ch(struct lan743x_adapter *adapter,
|
|||
static void lan743x_ptp_clock_get(struct lan743x_adapter *adapter,
|
||||
u32 *seconds, u32 *nano_seconds,
|
||||
u32 *sub_nano_seconds);
|
||||
static void lan743x_ptp_io_clock_get(struct lan743x_adapter *adapter,
|
||||
u32 *sec, u32 *nsec, u32 *sub_nsec);
|
||||
static void lan743x_ptp_clock_step(struct lan743x_adapter *adapter,
|
||||
s64 time_step_ns);
|
||||
|
||||
|
@ -407,7 +421,11 @@ static int lan743x_ptpci_gettime64(struct ptp_clock_info *ptpci,
|
|||
u32 nano_seconds = 0;
|
||||
u32 seconds = 0;
|
||||
|
||||
lan743x_ptp_clock_get(adapter, &seconds, &nano_seconds, NULL);
|
||||
if (adapter->is_pci11x1x)
|
||||
lan743x_ptp_io_clock_get(adapter, &seconds, &nano_seconds,
|
||||
NULL);
|
||||
else
|
||||
lan743x_ptp_clock_get(adapter, &seconds, &nano_seconds, NULL);
|
||||
ts->tv_sec = seconds;
|
||||
ts->tv_nsec = nano_seconds;
|
||||
|
||||
|
@ -671,6 +689,322 @@ failed:
|
|||
return ret;
|
||||
}
|
||||
|
||||
static void lan743x_ptp_io_perout_off(struct lan743x_adapter *adapter,
|
||||
u32 index)
|
||||
{
|
||||
struct lan743x_ptp *ptp = &adapter->ptp;
|
||||
int perout_pin;
|
||||
int event_ch;
|
||||
u32 gen_cfg;
|
||||
int val;
|
||||
|
||||
event_ch = ptp->ptp_io_perout[index];
|
||||
if (event_ch >= 0) {
|
||||
/* set target to far in the future, effectively disabling it */
|
||||
lan743x_csr_write(adapter,
|
||||
PTP_CLOCK_TARGET_SEC_X(event_ch),
|
||||
0xFFFF0000);
|
||||
lan743x_csr_write(adapter,
|
||||
PTP_CLOCK_TARGET_NS_X(event_ch),
|
||||
0);
|
||||
|
||||
gen_cfg = lan743x_csr_read(adapter, HS_PTP_GENERAL_CONFIG);
|
||||
gen_cfg &= ~(HS_PTP_GENERAL_CONFIG_CLOCK_EVENT_X_MASK_
|
||||
(event_ch));
|
||||
gen_cfg &= ~(HS_PTP_GENERAL_CONFIG_EVENT_POL_X_(event_ch));
|
||||
gen_cfg |= HS_PTP_GENERAL_CONFIG_RELOAD_ADD_X_(event_ch);
|
||||
lan743x_csr_write(adapter, HS_PTP_GENERAL_CONFIG, gen_cfg);
|
||||
if (event_ch)
|
||||
lan743x_csr_write(adapter, PTP_INT_STS,
|
||||
PTP_INT_TIMER_INT_B_);
|
||||
else
|
||||
lan743x_csr_write(adapter, PTP_INT_STS,
|
||||
PTP_INT_TIMER_INT_A_);
|
||||
lan743x_ptp_release_event_ch(adapter, event_ch);
|
||||
ptp->ptp_io_perout[index] = -1;
|
||||
}
|
||||
|
||||
perout_pin = ptp_find_pin(ptp->ptp_clock, PTP_PF_PEROUT, index);
|
||||
|
||||
/* Deselect Event output */
|
||||
val = lan743x_csr_read(adapter, PTP_IO_EVENT_OUTPUT_CFG);
|
||||
|
||||
/* Disables the output of Local Time Target compare events */
|
||||
val &= ~PTP_IO_EVENT_OUTPUT_CFG_EN_(perout_pin);
|
||||
lan743x_csr_write(adapter, PTP_IO_EVENT_OUTPUT_CFG, val);
|
||||
|
||||
/* Configured as an opendrain driver*/
|
||||
val = lan743x_csr_read(adapter, PTP_IO_PIN_CFG);
|
||||
val &= ~PTP_IO_PIN_CFG_OBUF_TYPE_(perout_pin);
|
||||
lan743x_csr_write(adapter, PTP_IO_PIN_CFG, val);
|
||||
/* Dummy read to make sure write operation success */
|
||||
val = lan743x_csr_read(adapter, PTP_IO_PIN_CFG);
|
||||
}
|
||||
|
||||
static int lan743x_ptp_io_perout(struct lan743x_adapter *adapter, int on,
|
||||
struct ptp_perout_request *perout_request)
|
||||
{
|
||||
struct lan743x_ptp *ptp = &adapter->ptp;
|
||||
u32 period_sec, period_nsec;
|
||||
u32 start_sec, start_nsec;
|
||||
u32 pulse_sec, pulse_nsec;
|
||||
int pulse_width;
|
||||
int perout_pin;
|
||||
int event_ch;
|
||||
u32 gen_cfg;
|
||||
u32 index;
|
||||
int val;
|
||||
|
||||
index = perout_request->index;
|
||||
event_ch = ptp->ptp_io_perout[index];
|
||||
|
||||
if (on) {
|
||||
perout_pin = ptp_find_pin(ptp->ptp_clock, PTP_PF_PEROUT, index);
|
||||
if (perout_pin < 0)
|
||||
return -EBUSY;
|
||||
} else {
|
||||
lan743x_ptp_io_perout_off(adapter, index);
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (event_ch >= LAN743X_PTP_N_EVENT_CHAN) {
|
||||
/* already on, turn off first */
|
||||
lan743x_ptp_io_perout_off(adapter, index);
|
||||
}
|
||||
|
||||
event_ch = lan743x_ptp_reserve_event_ch(adapter, index);
|
||||
if (event_ch < 0) {
|
||||
netif_warn(adapter, drv, adapter->netdev,
|
||||
"Failed to reserve event channel %d for PEROUT\n",
|
||||
index);
|
||||
goto failed;
|
||||
}
|
||||
ptp->ptp_io_perout[index] = event_ch;
|
||||
|
||||
if (perout_request->flags & PTP_PEROUT_DUTY_CYCLE) {
|
||||
pulse_sec = perout_request->on.sec;
|
||||
pulse_sec += perout_request->on.nsec / 1000000000;
|
||||
pulse_nsec = perout_request->on.nsec % 1000000000;
|
||||
} else {
|
||||
pulse_sec = perout_request->period.sec;
|
||||
pulse_sec += perout_request->period.nsec / 1000000000;
|
||||
pulse_nsec = perout_request->period.nsec % 1000000000;
|
||||
}
|
||||
|
||||
if (pulse_sec == 0) {
|
||||
if (pulse_nsec >= 400000000) {
|
||||
pulse_width = PTP_GENERAL_CONFIG_CLOCK_EVENT_200MS_;
|
||||
} else if (pulse_nsec >= 200000000) {
|
||||
pulse_width = HS_PTP_GENERAL_CONFIG_CLOCK_EVENT_100MS_;
|
||||
} else if (pulse_nsec >= 100000000) {
|
||||
pulse_width = HS_PTP_GENERAL_CONFIG_CLOCK_EVENT_50MS_;
|
||||
} else if (pulse_nsec >= 20000000) {
|
||||
pulse_width = HS_PTP_GENERAL_CONFIG_CLOCK_EVENT_10MS_;
|
||||
} else if (pulse_nsec >= 10000000) {
|
||||
pulse_width = HS_PTP_GENERAL_CONFIG_CLOCK_EVENT_5MS_;
|
||||
} else if (pulse_nsec >= 2000000) {
|
||||
pulse_width = HS_PTP_GENERAL_CONFIG_CLOCK_EVENT_1MS_;
|
||||
} else if (pulse_nsec >= 1000000) {
|
||||
pulse_width = HS_PTP_GENERAL_CONFIG_CLOCK_EVENT_500US_;
|
||||
} else if (pulse_nsec >= 200000) {
|
||||
pulse_width = HS_PTP_GENERAL_CONFIG_CLOCK_EVENT_100US_;
|
||||
} else if (pulse_nsec >= 100000) {
|
||||
pulse_width = HS_PTP_GENERAL_CONFIG_CLOCK_EVENT_50US_;
|
||||
} else if (pulse_nsec >= 20000) {
|
||||
pulse_width = HS_PTP_GENERAL_CONFIG_CLOCK_EVENT_10US_;
|
||||
} else if (pulse_nsec >= 10000) {
|
||||
pulse_width = HS_PTP_GENERAL_CONFIG_CLOCK_EVENT_5US_;
|
||||
} else if (pulse_nsec >= 2000) {
|
||||
pulse_width = HS_PTP_GENERAL_CONFIG_CLOCK_EVENT_1US_;
|
||||
} else if (pulse_nsec >= 1000) {
|
||||
pulse_width = HS_PTP_GENERAL_CONFIG_CLOCK_EVENT_500NS_;
|
||||
} else if (pulse_nsec >= 200) {
|
||||
pulse_width = HS_PTP_GENERAL_CONFIG_CLOCK_EVENT_100NS_;
|
||||
} else {
|
||||
netif_warn(adapter, drv, adapter->netdev,
|
||||
"perout period too small, min is 200nS\n");
|
||||
goto failed;
|
||||
}
|
||||
} else {
|
||||
pulse_width = HS_PTP_GENERAL_CONFIG_CLOCK_EVENT_200MS_;
|
||||
}
|
||||
|
||||
/* turn off by setting target far in future */
|
||||
lan743x_csr_write(adapter,
|
||||
PTP_CLOCK_TARGET_SEC_X(event_ch),
|
||||
0xFFFF0000);
|
||||
lan743x_csr_write(adapter,
|
||||
PTP_CLOCK_TARGET_NS_X(event_ch), 0);
|
||||
|
||||
/* Configure to pulse every period */
|
||||
gen_cfg = lan743x_csr_read(adapter, HS_PTP_GENERAL_CONFIG);
|
||||
gen_cfg &= ~(HS_PTP_GENERAL_CONFIG_CLOCK_EVENT_X_MASK_(event_ch));
|
||||
gen_cfg |= HS_PTP_GENERAL_CONFIG_CLOCK_EVENT_X_SET_
|
||||
(event_ch, pulse_width);
|
||||
gen_cfg |= HS_PTP_GENERAL_CONFIG_EVENT_POL_X_(event_ch);
|
||||
gen_cfg &= ~(HS_PTP_GENERAL_CONFIG_RELOAD_ADD_X_(event_ch));
|
||||
lan743x_csr_write(adapter, HS_PTP_GENERAL_CONFIG, gen_cfg);
|
||||
|
||||
/* set the reload to one toggle cycle */
|
||||
period_sec = perout_request->period.sec;
|
||||
period_sec += perout_request->period.nsec / 1000000000;
|
||||
period_nsec = perout_request->period.nsec % 1000000000;
|
||||
lan743x_csr_write(adapter,
|
||||
PTP_CLOCK_TARGET_RELOAD_SEC_X(event_ch),
|
||||
period_sec);
|
||||
lan743x_csr_write(adapter,
|
||||
PTP_CLOCK_TARGET_RELOAD_NS_X(event_ch),
|
||||
period_nsec);
|
||||
|
||||
start_sec = perout_request->start.sec;
|
||||
start_sec += perout_request->start.nsec / 1000000000;
|
||||
start_nsec = perout_request->start.nsec % 1000000000;
|
||||
|
||||
/* set the start time */
|
||||
lan743x_csr_write(adapter,
|
||||
PTP_CLOCK_TARGET_SEC_X(event_ch),
|
||||
start_sec);
|
||||
lan743x_csr_write(adapter,
|
||||
PTP_CLOCK_TARGET_NS_X(event_ch),
|
||||
start_nsec);
|
||||
|
||||
/* Enable LTC Target Read */
|
||||
val = lan743x_csr_read(adapter, PTP_CMD_CTL);
|
||||
val |= PTP_CMD_CTL_PTP_LTC_TARGET_READ_;
|
||||
lan743x_csr_write(adapter, PTP_CMD_CTL, val);
|
||||
|
||||
/* Configure as an push/pull driver */
|
||||
val = lan743x_csr_read(adapter, PTP_IO_PIN_CFG);
|
||||
val |= PTP_IO_PIN_CFG_OBUF_TYPE_(perout_pin);
|
||||
lan743x_csr_write(adapter, PTP_IO_PIN_CFG, val);
|
||||
|
||||
/* Select Event output */
|
||||
val = lan743x_csr_read(adapter, PTP_IO_EVENT_OUTPUT_CFG);
|
||||
if (event_ch)
|
||||
/* Channel B as the output */
|
||||
val |= PTP_IO_EVENT_OUTPUT_CFG_SEL_(perout_pin);
|
||||
else
|
||||
/* Channel A as the output */
|
||||
val &= ~PTP_IO_EVENT_OUTPUT_CFG_SEL_(perout_pin);
|
||||
|
||||
/* Enables the output of Local Time Target compare events */
|
||||
val |= PTP_IO_EVENT_OUTPUT_CFG_EN_(perout_pin);
|
||||
lan743x_csr_write(adapter, PTP_IO_EVENT_OUTPUT_CFG, val);
|
||||
|
||||
return 0;
|
||||
|
||||
failed:
|
||||
lan743x_ptp_io_perout_off(adapter, index);
|
||||
return -ENODEV;
|
||||
}
|
||||
|
||||
static void lan743x_ptp_io_extts_off(struct lan743x_adapter *adapter,
|
||||
u32 index)
|
||||
{
|
||||
struct lan743x_ptp *ptp = &adapter->ptp;
|
||||
struct lan743x_extts *extts;
|
||||
int val;
|
||||
|
||||
extts = &ptp->extts[index];
|
||||
/* PTP Interrupt Enable Clear Register */
|
||||
if (extts->flags & PTP_FALLING_EDGE)
|
||||
val = PTP_INT_EN_FE_EN_CLR_(index);
|
||||
else
|
||||
val = PTP_INT_EN_RE_EN_CLR_(index);
|
||||
lan743x_csr_write(adapter, PTP_INT_EN_CLR, val);
|
||||
|
||||
/* Disables PTP-IO edge lock */
|
||||
val = lan743x_csr_read(adapter, PTP_IO_CAP_CONFIG);
|
||||
if (extts->flags & PTP_FALLING_EDGE) {
|
||||
val &= ~PTP_IO_CAP_CONFIG_LOCK_FE_(index);
|
||||
val &= ~PTP_IO_CAP_CONFIG_FE_CAP_EN_(index);
|
||||
} else {
|
||||
val &= ~PTP_IO_CAP_CONFIG_LOCK_RE_(index);
|
||||
val &= ~PTP_IO_CAP_CONFIG_RE_CAP_EN_(index);
|
||||
}
|
||||
lan743x_csr_write(adapter, PTP_IO_CAP_CONFIG, val);
|
||||
|
||||
/* PTP-IO De-select register */
|
||||
val = lan743x_csr_read(adapter, PTP_IO_SEL);
|
||||
val &= ~PTP_IO_SEL_MASK_;
|
||||
lan743x_csr_write(adapter, PTP_IO_SEL, val);
|
||||
|
||||
/* Clear timestamp */
|
||||
memset(&extts->ts, 0, sizeof(struct timespec64));
|
||||
extts->flags = 0;
|
||||
}
|
||||
|
||||
static int lan743x_ptp_io_event_cap_en(struct lan743x_adapter *adapter,
|
||||
u32 flags, u32 channel)
|
||||
{
|
||||
struct lan743x_ptp *ptp = &adapter->ptp;
|
||||
int val;
|
||||
|
||||
if ((flags & PTP_EXTTS_EDGES) == PTP_EXTTS_EDGES)
|
||||
return -EOPNOTSUPP;
|
||||
|
||||
mutex_lock(&ptp->command_lock);
|
||||
/* PTP-IO Event Capture Enable */
|
||||
val = lan743x_csr_read(adapter, PTP_IO_CAP_CONFIG);
|
||||
if (flags & PTP_FALLING_EDGE) {
|
||||
val &= ~PTP_IO_CAP_CONFIG_LOCK_RE_(channel);
|
||||
val &= ~PTP_IO_CAP_CONFIG_RE_CAP_EN_(channel);
|
||||
val |= PTP_IO_CAP_CONFIG_LOCK_FE_(channel);
|
||||
val |= PTP_IO_CAP_CONFIG_FE_CAP_EN_(channel);
|
||||
} else {
|
||||
/* Rising eventing as Default */
|
||||
val &= ~PTP_IO_CAP_CONFIG_LOCK_FE_(channel);
|
||||
val &= ~PTP_IO_CAP_CONFIG_FE_CAP_EN_(channel);
|
||||
val |= PTP_IO_CAP_CONFIG_LOCK_RE_(channel);
|
||||
val |= PTP_IO_CAP_CONFIG_RE_CAP_EN_(channel);
|
||||
}
|
||||
lan743x_csr_write(adapter, PTP_IO_CAP_CONFIG, val);
|
||||
|
||||
/* PTP-IO Select */
|
||||
val = lan743x_csr_read(adapter, PTP_IO_SEL);
|
||||
val &= ~PTP_IO_SEL_MASK_;
|
||||
val |= channel << PTP_IO_SEL_SHIFT_;
|
||||
lan743x_csr_write(adapter, PTP_IO_SEL, val);
|
||||
|
||||
/* PTP Interrupt Enable Register */
|
||||
if (flags & PTP_FALLING_EDGE)
|
||||
val = PTP_INT_EN_FE_EN_SET_(channel);
|
||||
else
|
||||
val = PTP_INT_EN_RE_EN_SET_(channel);
|
||||
lan743x_csr_write(adapter, PTP_INT_EN_SET, val);
|
||||
|
||||
mutex_unlock(&ptp->command_lock);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int lan743x_ptp_io_extts(struct lan743x_adapter *adapter, int on,
|
||||
struct ptp_extts_request *extts_request)
|
||||
{
|
||||
struct lan743x_ptp *ptp = &adapter->ptp;
|
||||
u32 flags = extts_request->flags;
|
||||
u32 index = extts_request->index;
|
||||
struct lan743x_extts *extts;
|
||||
int extts_pin;
|
||||
int ret = 0;
|
||||
|
||||
extts = &ptp->extts[index];
|
||||
|
||||
if (on) {
|
||||
extts_pin = ptp_find_pin(ptp->ptp_clock, PTP_PF_EXTTS, index);
|
||||
if (extts_pin < 0)
|
||||
return -EBUSY;
|
||||
|
||||
ret = lan743x_ptp_io_event_cap_en(adapter, flags, index);
|
||||
if (!ret)
|
||||
extts->flags = flags;
|
||||
} else {
|
||||
lan743x_ptp_io_extts_off(adapter, index);
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int lan743x_ptpci_enable(struct ptp_clock_info *ptpci,
|
||||
struct ptp_clock_request *request, int on)
|
||||
{
|
||||
|
@ -682,11 +1016,19 @@ static int lan743x_ptpci_enable(struct ptp_clock_info *ptpci,
|
|||
if (request) {
|
||||
switch (request->type) {
|
||||
case PTP_CLK_REQ_EXTTS:
|
||||
if (request->extts.index < ptpci->n_ext_ts)
|
||||
return lan743x_ptp_io_extts(adapter, on,
|
||||
&request->extts);
|
||||
return -EINVAL;
|
||||
case PTP_CLK_REQ_PEROUT:
|
||||
if (request->perout.index < ptpci->n_per_out)
|
||||
return lan743x_ptp_perout(adapter, on,
|
||||
if (request->perout.index < ptpci->n_per_out) {
|
||||
if (adapter->is_pci11x1x)
|
||||
return lan743x_ptp_io_perout(adapter, on,
|
||||
&request->perout);
|
||||
else
|
||||
return lan743x_ptp_perout(adapter, on,
|
||||
&request->perout);
|
||||
}
|
||||
return -EINVAL;
|
||||
case PTP_CLK_REQ_PPS:
|
||||
return -EINVAL;
|
||||
|
@ -715,8 +1057,8 @@ static int lan743x_ptpci_verify_pin_config(struct ptp_clock_info *ptp,
|
|||
switch (func) {
|
||||
case PTP_PF_NONE:
|
||||
case PTP_PF_PEROUT:
|
||||
break;
|
||||
case PTP_PF_EXTTS:
|
||||
break;
|
||||
case PTP_PF_PHYSYNC:
|
||||
default:
|
||||
result = -1;
|
||||
|
@ -725,6 +1067,33 @@ static int lan743x_ptpci_verify_pin_config(struct ptp_clock_info *ptp,
|
|||
return result;
|
||||
}
|
||||
|
||||
static void lan743x_ptp_io_event_clock_get(struct lan743x_adapter *adapter,
|
||||
bool fe, u8 channel,
|
||||
struct timespec64 *ts)
|
||||
{
|
||||
struct lan743x_ptp *ptp = &adapter->ptp;
|
||||
struct lan743x_extts *extts;
|
||||
u32 sec, nsec;
|
||||
|
||||
mutex_lock(&ptp->command_lock);
|
||||
if (fe) {
|
||||
sec = lan743x_csr_read(adapter, PTP_IO_FE_LTC_SEC_CAP_X);
|
||||
nsec = lan743x_csr_read(adapter, PTP_IO_FE_LTC_NS_CAP_X);
|
||||
} else {
|
||||
sec = lan743x_csr_read(adapter, PTP_IO_RE_LTC_SEC_CAP_X);
|
||||
nsec = lan743x_csr_read(adapter, PTP_IO_RE_LTC_NS_CAP_X);
|
||||
}
|
||||
|
||||
mutex_unlock(&ptp->command_lock);
|
||||
|
||||
/* Update Local timestamp */
|
||||
extts = &ptp->extts[channel];
|
||||
extts->ts.tv_sec = sec;
|
||||
extts->ts.tv_nsec = nsec;
|
||||
ts->tv_sec = sec;
|
||||
ts->tv_nsec = nsec;
|
||||
}
|
||||
|
||||
static long lan743x_ptpci_do_aux_work(struct ptp_clock_info *ptpci)
|
||||
{
|
||||
struct lan743x_ptp *ptp =
|
||||
|
@ -733,41 +1102,121 @@ static long lan743x_ptpci_do_aux_work(struct ptp_clock_info *ptpci)
|
|||
container_of(ptp, struct lan743x_adapter, ptp);
|
||||
u32 cap_info, cause, header, nsec, seconds;
|
||||
bool new_timestamp_available = false;
|
||||
struct ptp_clock_event ptp_event;
|
||||
struct timespec64 ts;
|
||||
int ptp_int_sts;
|
||||
int count = 0;
|
||||
int channel;
|
||||
s64 ns;
|
||||
|
||||
while ((count < 100) &&
|
||||
(lan743x_csr_read(adapter, PTP_INT_STS) & PTP_INT_BIT_TX_TS_)) {
|
||||
ptp_int_sts = lan743x_csr_read(adapter, PTP_INT_STS);
|
||||
while ((count < 100) && ptp_int_sts) {
|
||||
count++;
|
||||
cap_info = lan743x_csr_read(adapter, PTP_CAP_INFO);
|
||||
|
||||
if (PTP_CAP_INFO_TX_TS_CNT_GET_(cap_info) > 0) {
|
||||
seconds = lan743x_csr_read(adapter,
|
||||
PTP_TX_EGRESS_SEC);
|
||||
nsec = lan743x_csr_read(adapter, PTP_TX_EGRESS_NS);
|
||||
cause = (nsec &
|
||||
PTP_TX_EGRESS_NS_CAPTURE_CAUSE_MASK_);
|
||||
header = lan743x_csr_read(adapter,
|
||||
PTP_TX_MSG_HEADER);
|
||||
if (ptp_int_sts & PTP_INT_BIT_TX_TS_) {
|
||||
cap_info = lan743x_csr_read(adapter, PTP_CAP_INFO);
|
||||
|
||||
if (cause == PTP_TX_EGRESS_NS_CAPTURE_CAUSE_SW_) {
|
||||
nsec &= PTP_TX_EGRESS_NS_TS_NS_MASK_;
|
||||
lan743x_ptp_tx_ts_enqueue_ts(adapter,
|
||||
seconds, nsec,
|
||||
header);
|
||||
new_timestamp_available = true;
|
||||
} else if (cause ==
|
||||
PTP_TX_EGRESS_NS_CAPTURE_CAUSE_AUTO_) {
|
||||
netif_err(adapter, drv, adapter->netdev,
|
||||
"Auto capture cause not supported\n");
|
||||
if (PTP_CAP_INFO_TX_TS_CNT_GET_(cap_info) > 0) {
|
||||
seconds = lan743x_csr_read(adapter,
|
||||
PTP_TX_EGRESS_SEC);
|
||||
nsec = lan743x_csr_read(adapter,
|
||||
PTP_TX_EGRESS_NS);
|
||||
cause = (nsec &
|
||||
PTP_TX_EGRESS_NS_CAPTURE_CAUSE_MASK_);
|
||||
header = lan743x_csr_read(adapter,
|
||||
PTP_TX_MSG_HEADER);
|
||||
|
||||
if (cause ==
|
||||
PTP_TX_EGRESS_NS_CAPTURE_CAUSE_SW_) {
|
||||
nsec &= PTP_TX_EGRESS_NS_TS_NS_MASK_;
|
||||
lan743x_ptp_tx_ts_enqueue_ts(adapter,
|
||||
seconds,
|
||||
nsec,
|
||||
header);
|
||||
new_timestamp_available = true;
|
||||
} else if (cause ==
|
||||
PTP_TX_EGRESS_NS_CAPTURE_CAUSE_AUTO_) {
|
||||
netif_err(adapter, drv, adapter->netdev,
|
||||
"Auto capture cause not supported\n");
|
||||
} else {
|
||||
netif_warn(adapter, drv, adapter->netdev,
|
||||
"unknown tx timestamp capture cause\n");
|
||||
}
|
||||
} else {
|
||||
netif_warn(adapter, drv, adapter->netdev,
|
||||
"unknown tx timestamp capture cause\n");
|
||||
"TX TS INT but no TX TS CNT\n");
|
||||
}
|
||||
} else {
|
||||
netif_warn(adapter, drv, adapter->netdev,
|
||||
"TX TS INT but no TX TS CNT\n");
|
||||
lan743x_csr_write(adapter, PTP_INT_STS,
|
||||
PTP_INT_BIT_TX_TS_);
|
||||
}
|
||||
lan743x_csr_write(adapter, PTP_INT_STS, PTP_INT_BIT_TX_TS_);
|
||||
|
||||
if (ptp_int_sts & PTP_INT_IO_FE_MASK_) {
|
||||
do {
|
||||
channel = lan743x_get_channel((ptp_int_sts &
|
||||
PTP_INT_IO_FE_MASK_) >>
|
||||
PTP_INT_IO_FE_SHIFT_);
|
||||
if (channel >= 0 &&
|
||||
channel < PCI11X1X_PTP_IO_MAX_CHANNELS) {
|
||||
lan743x_ptp_io_event_clock_get(adapter,
|
||||
true,
|
||||
channel,
|
||||
&ts);
|
||||
/* PTP Falling Event post */
|
||||
ns = timespec64_to_ns(&ts);
|
||||
ptp_event.timestamp = ns;
|
||||
ptp_event.index = channel;
|
||||
ptp_event.type = PTP_CLOCK_EXTTS;
|
||||
ptp_clock_event(ptp->ptp_clock,
|
||||
&ptp_event);
|
||||
lan743x_csr_write(adapter, PTP_INT_STS,
|
||||
PTP_INT_IO_FE_SET_
|
||||
(channel));
|
||||
ptp_int_sts &= ~(1 <<
|
||||
(PTP_INT_IO_FE_SHIFT_ +
|
||||
channel));
|
||||
} else {
|
||||
/* Clear falling event interrupts */
|
||||
lan743x_csr_write(adapter, PTP_INT_STS,
|
||||
PTP_INT_IO_FE_MASK_);
|
||||
ptp_int_sts &= ~PTP_INT_IO_FE_MASK_;
|
||||
}
|
||||
} while (ptp_int_sts & PTP_INT_IO_FE_MASK_);
|
||||
}
|
||||
|
||||
if (ptp_int_sts & PTP_INT_IO_RE_MASK_) {
|
||||
do {
|
||||
channel = lan743x_get_channel((ptp_int_sts &
|
||||
PTP_INT_IO_RE_MASK_) >>
|
||||
PTP_INT_IO_RE_SHIFT_);
|
||||
if (channel >= 0 &&
|
||||
channel < PCI11X1X_PTP_IO_MAX_CHANNELS) {
|
||||
lan743x_ptp_io_event_clock_get(adapter,
|
||||
false,
|
||||
channel,
|
||||
&ts);
|
||||
/* PTP Rising Event post */
|
||||
ns = timespec64_to_ns(&ts);
|
||||
ptp_event.timestamp = ns;
|
||||
ptp_event.index = channel;
|
||||
ptp_event.type = PTP_CLOCK_EXTTS;
|
||||
ptp_clock_event(ptp->ptp_clock,
|
||||
&ptp_event);
|
||||
lan743x_csr_write(adapter, PTP_INT_STS,
|
||||
PTP_INT_IO_RE_SET_
|
||||
(channel));
|
||||
ptp_int_sts &= ~(1 <<
|
||||
(PTP_INT_IO_RE_SHIFT_ +
|
||||
channel));
|
||||
} else {
|
||||
/* Clear Rising event interrupt */
|
||||
lan743x_csr_write(adapter, PTP_INT_STS,
|
||||
PTP_INT_IO_RE_MASK_);
|
||||
ptp_int_sts &= ~PTP_INT_IO_RE_MASK_;
|
||||
}
|
||||
} while (ptp_int_sts & PTP_INT_IO_RE_MASK_);
|
||||
}
|
||||
|
||||
ptp_int_sts = lan743x_csr_read(adapter, PTP_INT_STS);
|
||||
}
|
||||
|
||||
if (new_timestamp_available)
|
||||
|
@ -802,6 +1251,28 @@ static void lan743x_ptp_clock_get(struct lan743x_adapter *adapter,
|
|||
mutex_unlock(&ptp->command_lock);
|
||||
}
|
||||
|
||||
static void lan743x_ptp_io_clock_get(struct lan743x_adapter *adapter,
|
||||
u32 *sec, u32 *nsec, u32 *sub_nsec)
|
||||
{
|
||||
struct lan743x_ptp *ptp = &adapter->ptp;
|
||||
|
||||
mutex_lock(&ptp->command_lock);
|
||||
lan743x_csr_write(adapter, PTP_CMD_CTL, PTP_CMD_CTL_PTP_CLOCK_READ_);
|
||||
lan743x_ptp_wait_till_cmd_done(adapter, PTP_CMD_CTL_PTP_CLOCK_READ_);
|
||||
|
||||
if (sec)
|
||||
(*sec) = lan743x_csr_read(adapter, PTP_LTC_RD_SEC_LO);
|
||||
|
||||
if (nsec)
|
||||
(*nsec) = lan743x_csr_read(adapter, PTP_LTC_RD_NS);
|
||||
|
||||
if (sub_nsec)
|
||||
(*sub_nsec) =
|
||||
lan743x_csr_read(adapter, PTP_LTC_RD_SUBNS);
|
||||
|
||||
mutex_unlock(&ptp->command_lock);
|
||||
}
|
||||
|
||||
static void lan743x_ptp_clock_step(struct lan743x_adapter *adapter,
|
||||
s64 time_step_ns)
|
||||
{
|
||||
|
@ -815,8 +1286,12 @@ static void lan743x_ptp_clock_step(struct lan743x_adapter *adapter,
|
|||
|
||||
if (time_step_ns > 15000000000LL) {
|
||||
/* convert to clock set */
|
||||
lan743x_ptp_clock_get(adapter, &unsigned_seconds,
|
||||
&nano_seconds, NULL);
|
||||
if (adapter->is_pci11x1x)
|
||||
lan743x_ptp_io_clock_get(adapter, &unsigned_seconds,
|
||||
&nano_seconds, NULL);
|
||||
else
|
||||
lan743x_ptp_clock_get(adapter, &unsigned_seconds,
|
||||
&nano_seconds, NULL);
|
||||
unsigned_seconds += div_u64_rem(time_step_ns, 1000000000LL,
|
||||
&remainder);
|
||||
nano_seconds += remainder;
|
||||
|
@ -831,8 +1306,13 @@ static void lan743x_ptp_clock_step(struct lan743x_adapter *adapter,
|
|||
/* convert to clock set */
|
||||
time_step_ns = -time_step_ns;
|
||||
|
||||
lan743x_ptp_clock_get(adapter, &unsigned_seconds,
|
||||
&nano_seconds, NULL);
|
||||
if (adapter->is_pci11x1x) {
|
||||
lan743x_ptp_io_clock_get(adapter, &unsigned_seconds,
|
||||
&nano_seconds, NULL);
|
||||
} else {
|
||||
lan743x_ptp_clock_get(adapter, &unsigned_seconds,
|
||||
&nano_seconds, NULL);
|
||||
}
|
||||
unsigned_seconds -= div_u64_rem(time_step_ns, 1000000000LL,
|
||||
&remainder);
|
||||
nano_seconds_step = remainder;
|
||||
|
@ -1061,6 +1541,8 @@ int lan743x_ptp_open(struct lan743x_adapter *adapter)
|
|||
n_pins = LAN7430_N_GPIO;
|
||||
break;
|
||||
case ID_REV_ID_LAN7431_:
|
||||
case ID_REV_ID_A011_:
|
||||
case ID_REV_ID_A041_:
|
||||
n_pins = LAN7431_N_GPIO;
|
||||
break;
|
||||
default:
|
||||
|
@ -1088,10 +1570,10 @@ int lan743x_ptp_open(struct lan743x_adapter *adapter)
|
|||
adapter->netdev->dev_addr);
|
||||
ptp->ptp_clock_info.max_adj = LAN743X_PTP_MAX_FREQ_ADJ_IN_PPB;
|
||||
ptp->ptp_clock_info.n_alarm = 0;
|
||||
ptp->ptp_clock_info.n_ext_ts = 0;
|
||||
ptp->ptp_clock_info.n_ext_ts = LAN743X_PTP_N_EXTTS;
|
||||
ptp->ptp_clock_info.n_per_out = LAN743X_PTP_N_EVENT_CHAN;
|
||||
ptp->ptp_clock_info.n_pins = n_pins;
|
||||
ptp->ptp_clock_info.pps = 0;
|
||||
ptp->ptp_clock_info.pps = LAN743X_PTP_N_PPS;
|
||||
ptp->ptp_clock_info.pin_config = ptp->pin_config;
|
||||
ptp->ptp_clock_info.adjfine = lan743x_ptpci_adjfine;
|
||||
ptp->ptp_clock_info.adjfreq = lan743x_ptpci_adjfreq;
|
||||
|
|
|
@ -18,6 +18,9 @@
|
|||
*/
|
||||
#define LAN743X_PTP_N_EVENT_CHAN 2
|
||||
#define LAN743X_PTP_N_PEROUT LAN743X_PTP_N_EVENT_CHAN
|
||||
#define LAN743X_PTP_N_EXTTS 4
|
||||
#define LAN743X_PTP_N_PPS 0
|
||||
#define PCI11X1X_PTP_IO_MAX_CHANNELS 8
|
||||
|
||||
struct lan743x_adapter;
|
||||
|
||||
|
@ -60,6 +63,11 @@ struct lan743x_ptp_perout {
|
|||
int gpio_pin; /* GPIO pin where output appears */
|
||||
};
|
||||
|
||||
struct lan743x_extts {
|
||||
int flags;
|
||||
struct timespec64 ts;
|
||||
};
|
||||
|
||||
struct lan743x_ptp {
|
||||
int flags;
|
||||
|
||||
|
@ -72,6 +80,8 @@ struct lan743x_ptp {
|
|||
|
||||
unsigned long used_event_ch;
|
||||
struct lan743x_ptp_perout perout[LAN743X_PTP_N_PEROUT];
|
||||
int ptp_io_perout[LAN743X_PTP_N_PEROUT]; /* PTP event channel (0=channel A, 1=channel B) */
|
||||
struct lan743x_extts extts[LAN743X_PTP_N_EXTTS];
|
||||
|
||||
bool leds_multiplexed;
|
||||
bool led_enabled[LAN7430_N_LED];
|
||||
|
|
Загрузка…
Ссылка в новой задаче