Skip to content

Commit 4b40f99

Browse files
author
CKI KWF Bot
committed
Merge: net: atlantic: rebase for RHEL 10.1
MR: https://gitlab.com/redhat/centos-stream/src/kernel/centos-stream-10/-/merge_requests/1264 net: atlantic: rebase for RHEL 10.1 JIRA: https://issues.redhat.com/browse/RHEL-105363 Signed-off-by: Izabela Bakollari <ibakolla@redhat.com> Approved-by: Michal Schmidt <mschmidt@redhat.com> Approved-by: Murphy Zhou <xzhou@redhat.com> Approved-by: CKI KWF Bot <cki-ci-bot+kwf-gitlab-com@redhat.com> Merged-by: CKI GitLab Kmaint Pipeline Bot <26919896-cki-kmaint-pipeline-bot@users.noreply.gitlab.com>
2 parents f318c6f + 0c8ae62 commit 4b40f99

File tree

10 files changed

+317
-3
lines changed

10 files changed

+317
-3
lines changed

drivers/net/ethernet/aquantia/atlantic/aq_ethtool.c

Lines changed: 73 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@
1515
#include "aq_macsec.h"
1616
#include "aq_main.h"
1717

18+
#include <linux/ethtool.h>
1819
#include <linux/linkmode.h>
1920
#include <linux/ptp_clock_kernel.h>
2021

@@ -977,6 +978,76 @@ static int aq_ethtool_set_phy_tunable(struct net_device *ndev,
977978
return err;
978979
}
979980

981+
static int aq_ethtool_get_module_info(struct net_device *ndev,
982+
struct ethtool_modinfo *modinfo)
983+
{
984+
struct aq_nic_s *aq_nic = netdev_priv(ndev);
985+
u8 compliance_val, dom_type;
986+
int err;
987+
988+
/* Module EEPROM is only supported for controllers with external PHY */
989+
if (aq_nic->aq_nic_cfg.aq_hw_caps->media_type != AQ_HW_MEDIA_TYPE_FIBRE ||
990+
!aq_nic->aq_hw_ops->hw_read_module_eeprom)
991+
return -EOPNOTSUPP;
992+
993+
err = aq_nic->aq_hw_ops->hw_read_module_eeprom(aq_nic->aq_hw,
994+
SFF_8472_ID_ADDR, SFF_8472_COMP_ADDR, 1, &compliance_val);
995+
if (err)
996+
return err;
997+
998+
err = aq_nic->aq_hw_ops->hw_read_module_eeprom(aq_nic->aq_hw,
999+
SFF_8472_ID_ADDR, SFF_8472_DOM_TYPE_ADDR, 1, &dom_type);
1000+
if (err)
1001+
return err;
1002+
1003+
if (dom_type & SFF_8472_ADDRESS_CHANGE_REQ_MASK || compliance_val == 0x00) {
1004+
modinfo->type = ETH_MODULE_SFF_8079;
1005+
modinfo->eeprom_len = ETH_MODULE_SFF_8079_LEN;
1006+
} else {
1007+
modinfo->type = ETH_MODULE_SFF_8472;
1008+
modinfo->eeprom_len = ETH_MODULE_SFF_8472_LEN;
1009+
}
1010+
return 0;
1011+
}
1012+
1013+
static int aq_ethtool_get_module_eeprom(struct net_device *ndev,
1014+
struct ethtool_eeprom *ee, unsigned char *data)
1015+
{
1016+
struct aq_nic_s *aq_nic = netdev_priv(ndev);
1017+
unsigned int first, last, len;
1018+
int err;
1019+
1020+
if (!aq_nic->aq_hw_ops->hw_read_module_eeprom)
1021+
return -EOPNOTSUPP;
1022+
1023+
first = ee->offset;
1024+
last = ee->offset + ee->len;
1025+
1026+
if (first < ETH_MODULE_SFF_8079_LEN) {
1027+
len = min(last, ETH_MODULE_SFF_8079_LEN);
1028+
len -= first;
1029+
1030+
err = aq_nic->aq_hw_ops->hw_read_module_eeprom(aq_nic->aq_hw,
1031+
SFF_8472_ID_ADDR, first, len, data);
1032+
if (err)
1033+
return err;
1034+
1035+
first += len;
1036+
data += len;
1037+
}
1038+
if (first < ETH_MODULE_SFF_8472_LEN && last > ETH_MODULE_SFF_8079_LEN) {
1039+
len = min(last, ETH_MODULE_SFF_8472_LEN);
1040+
len -= first;
1041+
first -= ETH_MODULE_SFF_8079_LEN;
1042+
1043+
err = aq_nic->aq_hw_ops->hw_read_module_eeprom(aq_nic->aq_hw,
1044+
SFF_8472_DIAGNOSTICS_ADDR, first, len, data);
1045+
if (err)
1046+
return err;
1047+
}
1048+
return 0;
1049+
}
1050+
9801051
const struct ethtool_ops aq_ethtool_ops = {
9811052
.supported_coalesce_params = ETHTOOL_COALESCE_USECS |
9821053
ETHTOOL_COALESCE_MAX_FRAMES,
@@ -1014,4 +1085,6 @@ const struct ethtool_ops aq_ethtool_ops = {
10141085
.get_ts_info = aq_ethtool_get_ts_info,
10151086
.get_phy_tunable = aq_ethtool_get_phy_tunable,
10161087
.set_phy_tunable = aq_ethtool_set_phy_tunable,
1088+
.get_module_info = aq_ethtool_get_module_info,
1089+
.get_module_eeprom = aq_ethtool_get_module_eeprom,
10171090
};

drivers/net/ethernet/aquantia/atlantic/aq_ethtool.h

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,4 +14,12 @@
1414
extern const struct ethtool_ops aq_ethtool_ops;
1515
#define AQ_PRIV_FLAGS_MASK (AQ_HW_LOOPBACK_MASK)
1616

17+
#define SFF_8472_ID_ADDR 0x50
18+
#define SFF_8472_DIAGNOSTICS_ADDR 0x51
19+
20+
#define SFF_8472_COMP_ADDR 0x5e
21+
#define SFF_8472_DOM_TYPE_ADDR 0x5c
22+
23+
#define SFF_8472_ADDRESS_CHANGE_REQ_MASK 0x4
24+
1725
#endif /* AQ_ETHTOOL_H */

drivers/net/ethernet/aquantia/atlantic/aq_hw.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -340,6 +340,9 @@ struct aq_hw_ops {
340340
int (*hw_set_loopback)(struct aq_hw_s *self, u32 mode, bool enable);
341341

342342
int (*hw_get_mac_temp)(struct aq_hw_s *self, u32 *temp);
343+
344+
int (*hw_read_module_eeprom)(struct aq_hw_s *self, u8 dev_addr,
345+
u8 reg_start_addr, int len, u8 *data);
343346
};
344347

345348
struct aq_fw_ops {

drivers/net/ethernet/aquantia/atlantic/aq_main.c

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -123,7 +123,6 @@ static netdev_tx_t aq_ndev_start_xmit(struct sk_buff *skb, struct net_device *nd
123123
}
124124
#endif
125125

126-
skb_tx_timestamp(skb);
127126
return aq_nic_xmit(aq_nic, skb);
128127
}
129128

drivers/net/ethernet/aquantia/atlantic/aq_nic.c

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -898,6 +898,8 @@ int aq_nic_xmit(struct aq_nic_s *self, struct sk_buff *skb)
898898

899899
frags = aq_nic_map_skb(self, skb, ring);
900900

901+
skb_tx_timestamp(skb);
902+
901903
if (likely(frags)) {
902904
err = self->aq_hw_ops->hw_ring_tx_xmit(self->aq_hw,
903905
ring, frags);
@@ -1441,7 +1443,9 @@ void aq_nic_deinit(struct aq_nic_s *self, bool link_down)
14411443
aq_ptp_ring_free(self);
14421444
aq_ptp_free(self);
14431445

1444-
if (likely(self->aq_fw_ops->deinit) && link_down) {
1446+
/* May be invoked during hot unplug. */
1447+
if (pci_device_is_present(self->pdev) &&
1448+
likely(self->aq_fw_ops->deinit) && link_down) {
14451449
mutex_lock(&self->fwreq_mutex);
14461450
self->aq_fw_ops->deinit(self->aq_hw);
14471451
mutex_unlock(&self->fwreq_mutex);

drivers/net/ethernet/aquantia/atlantic/hw_atl/hw_atl_b0.c

Lines changed: 132 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1654,6 +1654,137 @@ static int hw_atl_b0_get_mac_temp(struct aq_hw_s *self, u32 *temp)
16541654
return 0;
16551655
}
16561656

1657+
#define START_TRANSMIT 0x5001
1658+
#define START_READ_TRANSMIT 0x5101
1659+
#define STOP_TRANSMIT 0x3001
1660+
#define REPEAT_TRANSMIT 0x1001
1661+
#define REPEAT_NACK_TRANSMIT 0x1011
1662+
1663+
static int hw_atl_b0_smb0_wait_result(struct aq_hw_s *self, bool expect_ack)
1664+
{
1665+
int err;
1666+
u32 val;
1667+
1668+
err = readx_poll_timeout(hw_atl_smb0_byte_transfer_complete_get,
1669+
self, val, val == 1, 100U, 10000U);
1670+
if (err)
1671+
return err;
1672+
if (hw_atl_smb0_receive_acknowledged_get(self) != expect_ack)
1673+
return -EIO;
1674+
return 0;
1675+
}
1676+
1677+
/* Starts an I2C/SMBUS write to a given address. addr is in 7-bit format,
1678+
* the read/write bit is not part of it.
1679+
*/
1680+
static int hw_atl_b0_smb0_start_write(struct aq_hw_s *self, u32 addr)
1681+
{
1682+
hw_atl_smb0_tx_data_set(self, (addr << 1) | 0);
1683+
hw_atl_smb0_provisioning2_set(self, START_TRANSMIT);
1684+
return hw_atl_b0_smb0_wait_result(self, 0);
1685+
}
1686+
1687+
/* Writes a single byte as part of an ongoing write started by start_write. */
1688+
static int hw_atl_b0_smb0_write_byte(struct aq_hw_s *self, u32 data)
1689+
{
1690+
hw_atl_smb0_tx_data_set(self, data);
1691+
hw_atl_smb0_provisioning2_set(self, REPEAT_TRANSMIT);
1692+
return hw_atl_b0_smb0_wait_result(self, 0);
1693+
}
1694+
1695+
/* Starts an I2C/SMBUS read to a given address. addr is in 7-bit format,
1696+
* the read/write bit is not part of it.
1697+
*/
1698+
static int hw_atl_b0_smb0_start_read(struct aq_hw_s *self, u32 addr)
1699+
{
1700+
int err;
1701+
1702+
hw_atl_smb0_tx_data_set(self, (addr << 1) | 1);
1703+
hw_atl_smb0_provisioning2_set(self, START_READ_TRANSMIT);
1704+
err = hw_atl_b0_smb0_wait_result(self, 0);
1705+
if (err)
1706+
return err;
1707+
if (hw_atl_smb0_repeated_start_detect_get(self) == 0)
1708+
return -EIO;
1709+
return 0;
1710+
}
1711+
1712+
/* Reads a single byte as part of an ongoing read started by start_read. */
1713+
static int hw_atl_b0_smb0_read_byte(struct aq_hw_s *self)
1714+
{
1715+
int err;
1716+
1717+
hw_atl_smb0_provisioning2_set(self, REPEAT_TRANSMIT);
1718+
err = hw_atl_b0_smb0_wait_result(self, 0);
1719+
if (err)
1720+
return err;
1721+
return hw_atl_smb0_rx_data_get(self);
1722+
}
1723+
1724+
/* Reads the last byte of an ongoing read. */
1725+
static int hw_atl_b0_smb0_read_byte_nack(struct aq_hw_s *self)
1726+
{
1727+
int err;
1728+
1729+
hw_atl_smb0_provisioning2_set(self, REPEAT_NACK_TRANSMIT);
1730+
err = hw_atl_b0_smb0_wait_result(self, 1);
1731+
if (err)
1732+
return err;
1733+
return hw_atl_smb0_rx_data_get(self);
1734+
}
1735+
1736+
/* Sends a stop condition and ends a transfer. */
1737+
static void hw_atl_b0_smb0_stop(struct aq_hw_s *self)
1738+
{
1739+
hw_atl_smb0_provisioning2_set(self, STOP_TRANSMIT);
1740+
}
1741+
1742+
static int hw_atl_b0_read_module_eeprom(struct aq_hw_s *self, u8 dev_addr,
1743+
u8 reg_start_addr, int len, u8 *data)
1744+
{
1745+
int i, b;
1746+
int err;
1747+
u32 val;
1748+
1749+
/* Wait for SMBUS0 to be idle */
1750+
err = readx_poll_timeout(hw_atl_smb0_bus_busy_get, self,
1751+
val, val == 0, 100U, 10000U);
1752+
if (err)
1753+
return err;
1754+
1755+
err = hw_atl_b0_smb0_start_write(self, dev_addr);
1756+
if (err)
1757+
goto out;
1758+
1759+
err = hw_atl_b0_smb0_write_byte(self, reg_start_addr);
1760+
if (err)
1761+
goto out;
1762+
1763+
err = hw_atl_b0_smb0_start_read(self, dev_addr);
1764+
if (err)
1765+
goto out;
1766+
1767+
for (i = 0; i < len - 1; i++) {
1768+
b = hw_atl_b0_smb0_read_byte(self);
1769+
if (b < 0) {
1770+
err = b;
1771+
goto out;
1772+
}
1773+
data[i] = (u8)b;
1774+
}
1775+
1776+
b = hw_atl_b0_smb0_read_byte_nack(self);
1777+
if (b < 0) {
1778+
err = b;
1779+
goto out;
1780+
}
1781+
data[i] = (u8)b;
1782+
1783+
out:
1784+
hw_atl_b0_smb0_stop(self);
1785+
return err;
1786+
}
1787+
16571788
const struct aq_hw_ops hw_atl_ops_b0 = {
16581789
.hw_soft_reset = hw_atl_utils_soft_reset,
16591790
.hw_prepare = hw_atl_utils_initfw,
@@ -1712,4 +1843,5 @@ const struct aq_hw_ops hw_atl_ops_b0 = {
17121843
.hw_set_fc = hw_atl_b0_set_fc,
17131844

17141845
.hw_get_mac_temp = hw_atl_b0_get_mac_temp,
1846+
.hw_read_module_eeprom = hw_atl_b0_read_module_eeprom,
17151847
};

drivers/net/ethernet/aquantia/atlantic/hw_atl/hw_atl_llh.c

Lines changed: 43 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -57,6 +57,49 @@ u32 hw_atl_ts_data_get(struct aq_hw_s *aq_hw)
5757
HW_ATL_TS_DATA_OUT_SHIFT);
5858
}
5959

60+
u32 hw_atl_smb0_bus_busy_get(struct aq_hw_s *aq_hw)
61+
{
62+
return aq_hw_read_reg_bit(aq_hw, HW_ATL_SMB0_BUS_BUSY_ADR,
63+
HW_ATL_SMB0_BUS_BUSY_MSK,
64+
HW_ATL_SMB0_BUS_BUSY_SHIFT);
65+
}
66+
67+
u32 hw_atl_smb0_byte_transfer_complete_get(struct aq_hw_s *aq_hw)
68+
{
69+
return aq_hw_read_reg_bit(aq_hw, HW_ATL_SMB0_BYTE_TRANSFER_COMPLETE_ADR,
70+
HW_ATL_SMB0_BYTE_TRANSFER_COMPLETE_MSK,
71+
HW_ATL_SMB0_BYTE_TRANSFER_COMPLETE_SHIFT);
72+
}
73+
74+
u32 hw_atl_smb0_receive_acknowledged_get(struct aq_hw_s *aq_hw)
75+
{
76+
return aq_hw_read_reg_bit(aq_hw, HW_ATL_SMB0_RX_ACKNOWLEDGED_ADR,
77+
HW_ATL_SMB0_RX_ACKNOWLEDGED_MSK,
78+
HW_ATL_SMB0_RX_ACKNOWLEDGED_SHIFT);
79+
}
80+
81+
u32 hw_atl_smb0_repeated_start_detect_get(struct aq_hw_s *aq_hw)
82+
{
83+
return aq_hw_read_reg_bit(aq_hw, HW_ATL_SMB0_REPEATED_START_DETECT_ADR,
84+
HW_ATL_SMB0_REPEATED_START_DETECT_MSK,
85+
HW_ATL_SMB0_REPEATED_START_DETECT_SHIFT);
86+
}
87+
88+
u32 hw_atl_smb0_rx_data_get(struct aq_hw_s *aq_hw)
89+
{
90+
return aq_hw_read_reg(aq_hw, HW_ATL_SMB0_RECEIVED_DATA_ADR);
91+
}
92+
93+
void hw_atl_smb0_tx_data_set(struct aq_hw_s *aq_hw, u32 data)
94+
{
95+
return aq_hw_write_reg(aq_hw, HW_ATL_SMB0_TRANSMITTED_DATA_ADR, data);
96+
}
97+
98+
void hw_atl_smb0_provisioning2_set(struct aq_hw_s *aq_hw, u32 data)
99+
{
100+
return aq_hw_write_reg(aq_hw, HW_ATL_SMB0_PROVISIONING2_ADR, data);
101+
}
102+
60103
/* global */
61104
void hw_atl_reg_glb_cpu_sem_set(struct aq_hw_s *aq_hw, u32 glb_cpu_sem,
62105
u32 semaphore)

drivers/net/ethernet/aquantia/atlantic/hw_atl/hw_atl_llh.h

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,27 @@ u32 hw_atl_ts_ready_latch_high_get(struct aq_hw_s *aq_hw);
3434
/* get temperature sense data */
3535
u32 hw_atl_ts_data_get(struct aq_hw_s *aq_hw);
3636

37+
/* SMBUS0 bus busy */
38+
u32 hw_atl_smb0_bus_busy_get(struct aq_hw_s *aq_hw);
39+
40+
/* SMBUS0 byte transfer complete */
41+
u32 hw_atl_smb0_byte_transfer_complete_get(struct aq_hw_s *aq_hw);
42+
43+
/* SMBUS0 receive acknowledged */
44+
u32 hw_atl_smb0_receive_acknowledged_get(struct aq_hw_s *aq_hw);
45+
46+
/* SMBUS0 set transmitted data (only leftmost byte of data valid) */
47+
void hw_atl_smb0_tx_data_set(struct aq_hw_s *aq_hw, u32 data);
48+
49+
/* SMBUS0 provisioning2 command register */
50+
void hw_atl_smb0_provisioning2_set(struct aq_hw_s *aq_hw, u32 data);
51+
52+
/* SMBUS0 repeated start detect */
53+
u32 hw_atl_smb0_repeated_start_detect_get(struct aq_hw_s *aq_hw);
54+
55+
/* SMBUS0 received data register */
56+
u32 hw_atl_smb0_rx_data_get(struct aq_hw_s *aq_hw);
57+
3758
/* global */
3859

3960
/* set global microprocessor semaphore */

0 commit comments

Comments
 (0)