Merge Official Source
Signed-off-by: Tianling Shen <cnsztl@immortalwrt.org>
This commit is contained in:
commit
1ea5ae7ce9
@ -10,7 +10,7 @@ include $(INCLUDE_DIR)/kernel.mk
|
||||
|
||||
PKG_NAME:=vrx518_tc
|
||||
PKG_VERSION:=1.5.12.4
|
||||
PKG_RELEASE:=3
|
||||
PKG_RELEASE:=4
|
||||
PKG_BASE_NAME:=vrx518_tc_drv
|
||||
|
||||
UGW_VERSION=8.5.2.10
|
||||
|
@ -166,7 +166,7 @@
|
||||
|
||||
- return (skb->DW0 >> 3) & 0xF;
|
||||
+// return (skb->DW0 >> 3) & 0xF;
|
||||
+ return 1;
|
||||
+ return 0; /* We use only one connection for now, so return the first connection id */
|
||||
}
|
||||
|
||||
static int atm_get_qid_by_vcc(struct net_device *dev, struct sk_buff *skb,
|
||||
|
@ -0,0 +1,144 @@
|
||||
Extra ATM traffic classes requires atm_qos struct extension and a set of
|
||||
new defines. What itself requires atm.h updates both in the kernel and
|
||||
in the toolchain. On another hand we do not have any real users of these
|
||||
traffic classes.
|
||||
|
||||
In absence of real user there are no benefits to support this
|
||||
functionality. There is only the burden of maintenance of extra patches
|
||||
all around the building framework. So just drop these extra QoS traffic
|
||||
classes in order to facilitate maintenance and avoid side effects like
|
||||
breaking compatibility with existing userspace tools like linux-atm.
|
||||
|
||||
Signed-off-by: Sergey Ryazanov <ryazanov.s.a@gmail.com>
|
||||
--
|
||||
--- a/dcdp/atm_tc.c
|
||||
+++ b/dcdp/atm_tc.c
|
||||
@@ -463,34 +463,9 @@ static void set_qsb(struct atm_priv *pri
|
||||
/* Weighted Fair Queueing Factor (WFQF) */
|
||||
switch (qos->txtp.traffic_class) {
|
||||
case ATM_CBR:
|
||||
- case ATM_VBR_RT:
|
||||
/* real time queue gets weighted fair queueing bypass */
|
||||
q_parm_tbl.bit.wfqf = 0;
|
||||
break;
|
||||
- case ATM_VBR_NRT:
|
||||
- case ATM_UBR_PLUS:
|
||||
- /* WFQF calculation here is based on virtual cell rates,
|
||||
- to reduce granularity for high rates
|
||||
- */
|
||||
- /* WFQF is maximum cell rate / garenteed cell rate */
|
||||
- /* wfqf = qsb_minimum_cell_rate * QSB_WFQ_NONUBR_MAX /
|
||||
- requested_minimum_peak_cell_rate
|
||||
- */
|
||||
- if (qos->txtp.min_pcr == 0)
|
||||
- q_parm_tbl.bit.wfqf = QSB_WFQ_NONUBR_MAX;
|
||||
- else {
|
||||
- tmp = QSB_GCR_MIN * QSB_WFQ_NONUBR_MAX /
|
||||
- qos->txtp.min_pcr;
|
||||
- if (tmp == 0)
|
||||
- q_parm_tbl.bit.wfqf = 1;
|
||||
- else if (tmp > QSB_WFQ_NONUBR_MAX)
|
||||
- q_parm_tbl.bit.wfqf
|
||||
- = QSB_WFQ_NONUBR_MAX;
|
||||
- else
|
||||
- q_parm_tbl.bit.wfqf = tmp;
|
||||
- }
|
||||
- break;
|
||||
-
|
||||
case ATM_UBR:
|
||||
default:
|
||||
q_parm_tbl.bit.wfqf = QSB_WFQ_UBR_BYPASS;
|
||||
@@ -498,42 +473,9 @@ static void set_qsb(struct atm_priv *pri
|
||||
}
|
||||
|
||||
/* Sustained Cell Rate (SCR) Leaky Bucket Shaper VBR.0/VBR.1 */
|
||||
- if (qos->txtp.traffic_class == ATM_VBR_RT ||
|
||||
- qos->txtp.traffic_class == ATM_VBR_NRT) {
|
||||
- if (qos->txtp.scr == 0) {
|
||||
- /* disable shaper */
|
||||
- q_vbr_parm_tbl.bit.taus = 0;
|
||||
- q_vbr_parm_tbl.bit.ts = 0;
|
||||
- } else {
|
||||
- /* Cell Loss Priority (CLP) */
|
||||
- if ((vcc->atm_options & ATM_ATMOPT_CLP))
|
||||
- /* CLP1 */
|
||||
- q_parm_tbl.bit.vbr = 1;
|
||||
- else
|
||||
- /* CLP0 */
|
||||
- q_parm_tbl.bit.vbr = 0;
|
||||
- /* Rate Shaper Parameter (TS) and
|
||||
- Burst Tolerance Parameter for SCR (tauS)
|
||||
- */
|
||||
- tmp = ((qsb_clk * param->qsb_tstep) >> 5) /
|
||||
- qos->txtp.scr + 1;
|
||||
- q_vbr_parm_tbl.bit.ts
|
||||
- = tmp > QSB_TP_TS_MAX ? QSB_TP_TS_MAX : tmp;
|
||||
- tmp = (qos->txtp.mbs - 1) *
|
||||
- (q_vbr_parm_tbl.bit.ts -
|
||||
- q_parm_tbl.bit.tp) / 64;
|
||||
- if (tmp == 0)
|
||||
- q_vbr_parm_tbl.bit.taus = 1;
|
||||
- else if (tmp > QSB_TAUS_MAX)
|
||||
- q_vbr_parm_tbl.bit.taus
|
||||
- = QSB_TAUS_MAX;
|
||||
- else
|
||||
- q_vbr_parm_tbl.bit.taus = tmp;
|
||||
- }
|
||||
- } else {
|
||||
- q_vbr_parm_tbl.bit.taus = 0;
|
||||
- q_vbr_parm_tbl.bit.ts = 0;
|
||||
- }
|
||||
+ /* NB: shaper disabled since there no user interface to activate it */
|
||||
+ q_vbr_parm_tbl.bit.taus = 0;
|
||||
+ q_vbr_parm_tbl.bit.ts = 0;
|
||||
|
||||
/* Queue Parameter Table (QPT) */
|
||||
tc_w32(QSB_QPT_SET_MASK, QSB_RTM);
|
||||
@@ -1064,15 +1006,6 @@ static int ppe_open(struct atm_vcc *vcc)
|
||||
/* check bandwidth */
|
||||
if ((vcc->qos.txtp.traffic_class == ATM_CBR &&
|
||||
vcc->qos.txtp.max_pcr >
|
||||
- (port->tx_max_cell_rate - port->tx_used_cell_rate))
|
||||
- || (vcc->qos.txtp.traffic_class == ATM_VBR_RT &&
|
||||
- vcc->qos.txtp.max_pcr >
|
||||
- (port->tx_max_cell_rate - port->tx_used_cell_rate))
|
||||
- || (vcc->qos.txtp.traffic_class == ATM_VBR_NRT &&
|
||||
- vcc->qos.txtp.scr >
|
||||
- (port->tx_max_cell_rate - port->tx_used_cell_rate))
|
||||
- || (vcc->qos.txtp.traffic_class == ATM_UBR_PLUS &&
|
||||
- vcc->qos.txtp.min_pcr >
|
||||
(port->tx_max_cell_rate - port->tx_used_cell_rate))) {
|
||||
tc_dbg(priv->tc_priv, MSG_INIT, "exceed TX line rate\n");
|
||||
return -EINVAL;
|
||||
@@ -1128,15 +1061,8 @@ static int ppe_open(struct atm_vcc *vcc)
|
||||
/* reserve bandwidth */
|
||||
switch (vcc->qos.txtp.traffic_class) {
|
||||
case ATM_CBR:
|
||||
- case ATM_VBR_RT:
|
||||
port->tx_used_cell_rate += vcc->qos.txtp.max_pcr;
|
||||
break;
|
||||
- case ATM_VBR_NRT:
|
||||
- port->tx_used_cell_rate += vcc->qos.txtp.scr;
|
||||
- break;
|
||||
- case ATM_UBR_PLUS:
|
||||
- port->tx_used_cell_rate += vcc->qos.txtp.min_pcr;
|
||||
- break;
|
||||
}
|
||||
|
||||
/* update atm_vcc structure */
|
||||
@@ -1222,15 +1148,8 @@ static void ppe_close(struct atm_vcc *vc
|
||||
/* release bandwidth */
|
||||
switch (vcc->qos.txtp.traffic_class) {
|
||||
case ATM_CBR:
|
||||
- case ATM_VBR_RT:
|
||||
port->tx_used_cell_rate -= vcc->qos.txtp.max_pcr;
|
||||
break;
|
||||
- case ATM_VBR_NRT:
|
||||
- port->tx_used_cell_rate -= vcc->qos.txtp.scr;
|
||||
- break;
|
||||
- case ATM_UBR_PLUS:
|
||||
- port->tx_used_cell_rate -= vcc->qos.txtp.min_pcr;
|
||||
- break;
|
||||
}
|
||||
|
||||
/* idle for a while to let parallel operation finish */
|
@ -3,7 +3,7 @@ This replaces it by a basic working implementation.
|
||||
|
||||
--- a/dcdp/atm_tc.c
|
||||
+++ b/dcdp/atm_tc.c
|
||||
@@ -603,7 +603,11 @@ static void atm_aca_init(struct atm_priv
|
||||
@@ -545,7 +545,11 @@ static void atm_aca_init(struct atm_priv
|
||||
cfg = &priv->tc_priv->cfg;
|
||||
|
||||
txin = ¶m.aca_txin;
|
||||
@ -15,7 +15,7 @@ This replaces it by a basic working implementation.
|
||||
txin->hd_size_in_dw = cfg->txin.soc_desc_dwsz;
|
||||
txin->pd_desc_base = SB_XBAR_ADDR(__ACA_TX_IN_PD_LIST_BASE);
|
||||
txin->pd_desc_num = __ACA_TX_IN_PD_LIST_NUM;
|
||||
@@ -625,7 +629,11 @@ static void atm_aca_init(struct atm_priv
|
||||
@@ -567,7 +571,11 @@ static void atm_aca_init(struct atm_priv
|
||||
txin->soc_cmlt_cnt_addr);
|
||||
|
||||
txout = ¶m.aca_txout;
|
||||
@ -27,7 +27,7 @@ This replaces it by a basic working implementation.
|
||||
txout->hd_size_in_dw = cfg->txout.soc_desc_dwsz;
|
||||
txout->pd_desc_base = SB_XBAR_ADDR(__ACA_TX_OUT_PD_LIST_BASE);
|
||||
txout->pd_desc_num = __ACA_TX_OUT_PD_LIST_NUM;
|
||||
@@ -647,7 +655,11 @@ static void atm_aca_init(struct atm_priv
|
||||
@@ -589,7 +597,11 @@ static void atm_aca_init(struct atm_priv
|
||||
txout->soc_cmlt_cnt_addr);
|
||||
|
||||
rxout = ¶m.aca_rxout;
|
||||
@ -39,7 +39,7 @@ This replaces it by a basic working implementation.
|
||||
rxout->hd_size_in_dw = cfg->rxout.soc_desc_dwsz;
|
||||
rxout->pd_desc_base = SB_XBAR_ADDR(__ACA_RX_OUT_PD_LIST_BASE);
|
||||
rxout->pd_desc_num = __ACA_RX_OUT_PD_LIST_NUM;
|
||||
@@ -669,7 +681,11 @@ static void atm_aca_init(struct atm_priv
|
||||
@@ -611,7 +623,11 @@ static void atm_aca_init(struct atm_priv
|
||||
rxout->soc_cmlt_cnt_addr);
|
||||
|
||||
rxin = ¶m.aca_rxin;
|
||||
@ -51,7 +51,7 @@ This replaces it by a basic working implementation.
|
||||
rxin->hd_size_in_dw = cfg->rxin.soc_desc_dwsz;
|
||||
rxin->pd_desc_base = SB_XBAR_ADDR(__RX_IN_PD_DES_LIST_BASE);
|
||||
rxin->pd_desc_num = __ACA_RX_IN_PD_LIST_NUM;
|
||||
@@ -1261,7 +1277,7 @@ static int ppe_ioctl(struct atm_dev *dev
|
||||
@@ -1180,7 +1196,7 @@ static int ppe_ioctl(struct atm_dev *dev
|
||||
static int ppe_send(struct atm_vcc *vcc, struct sk_buff *skb)
|
||||
{
|
||||
int ret, qid, mpoa_pt, mpoa_type, vid;
|
||||
@ -60,7 +60,7 @@ This replaces it by a basic working implementation.
|
||||
struct atm_priv *priv;
|
||||
|
||||
if (!vcc) {
|
||||
@@ -1327,12 +1343,14 @@ static int ppe_send(struct atm_vcc *vcc,
|
||||
@@ -1246,12 +1262,14 @@ static int ppe_send(struct atm_vcc *vcc,
|
||||
tc_dbg(priv->tc_priv, MSG_TX, "vid: 0x%x, qid: 0x%x\n",
|
||||
vid, qid);
|
||||
|
||||
@ -855,12 +855,12 @@ This replaces it by a basic working implementation.
|
||||
- continue;
|
||||
+
|
||||
+ // this seems to be a pointer to a DS PKT buffer
|
||||
+ phyaddr = desc->data_ptr + desc->byte_off;
|
||||
+ phyaddr = desc->data_ptr;
|
||||
+ ptr = plat_mem_virt(phyaddr);
|
||||
+
|
||||
+ len = desc->data_len;
|
||||
+
|
||||
+ dma_sync_single_range_for_cpu(pdev, phyaddr, 0, len, DMA_FROM_DEVICE);
|
||||
+ dma_sync_single_for_cpu(pdev, phyaddr, desc->byte_off + len,
|
||||
+ DMA_FROM_DEVICE);
|
||||
+
|
||||
+ skb = netdev_alloc_skb(g_plat_priv->netdev, len);
|
||||
+ if (unlikely(!skb)) {
|
||||
@ -871,7 +871,7 @@ This replaces it by a basic working implementation.
|
||||
- ring_idx_inc(rxout, idx);
|
||||
+
|
||||
+ dst = skb_put(skb, len);
|
||||
+ memcpy(dst, ptr, len);
|
||||
+ memcpy(dst, ptr + desc->byte_off, len);
|
||||
+
|
||||
+ priv->tc_ops.recv(g_plat_priv->netdev, skb);
|
||||
+
|
||||
|
@ -296,7 +296,7 @@
|
||||
priv->tc_ops.umt_start = plat_umt_start;
|
||||
--- a/dcdp/atm_tc.c
|
||||
+++ b/dcdp/atm_tc.c
|
||||
@@ -3650,7 +3650,7 @@ static void atm_aca_ring_config_init(str
|
||||
@@ -3569,7 +3569,7 @@ static void atm_aca_ring_config_init(str
|
||||
static int atm_ring_init(struct atm_priv *priv)
|
||||
{
|
||||
atm_aca_ring_config_init(priv);
|
||||
@ -305,7 +305,7 @@
|
||||
}
|
||||
|
||||
static int atm_init(struct tc_priv *tcpriv, u32 ep_id)
|
||||
@@ -4020,7 +4020,7 @@ void atm_tc_unload(void)
|
||||
@@ -3939,7 +3939,7 @@ void atm_tc_unload(void)
|
||||
/* unregister device */
|
||||
if (priv->tc_priv->tc_ops.dev_unreg != NULL)
|
||||
priv->tc_priv->tc_ops.dev_unreg(NULL,
|
||||
|
@ -1,6 +1,6 @@
|
||||
--- a/dcdp/atm_tc.c
|
||||
+++ b/dcdp/atm_tc.c
|
||||
@@ -746,7 +746,8 @@ static void atm_aca_init(struct atm_priv
|
||||
@@ -688,7 +688,8 @@ static void atm_aca_init(struct atm_priv
|
||||
ACA_TXOUT_EN | ACA_RXIN_EN | ACA_RXOUT_EN, 1);
|
||||
}
|
||||
|
||||
@ -10,7 +10,7 @@
|
||||
{
|
||||
struct tm nowtm;
|
||||
char tmbuf[64];
|
||||
@@ -765,7 +766,8 @@ static int print_datetime(char *buffer,
|
||||
@@ -707,7 +708,8 @@ static int print_datetime(char *buffer,
|
||||
nowtm.tm_hour,
|
||||
nowtm.tm_min,
|
||||
nowtm.tm_sec);
|
||||
@ -20,7 +20,7 @@
|
||||
|
||||
return 0;
|
||||
}
|
||||
@@ -967,7 +969,7 @@ void show_atm_pvc(struct seq_file *seq,
|
||||
@@ -909,7 +911,7 @@ void show_atm_pvc(struct seq_file *seq,
|
||||
char buf[64];
|
||||
|
||||
seq_printf(seq, "\tNet device: %s\n", pvc->dev->name);
|
||||
|
@ -0,0 +1,75 @@
|
||||
From: Sergey Ryazanov <ryazanov.s.a@gmail.com>
|
||||
Date: Fri, 10 Jan 2025 00:57:27 +0000
|
||||
Subject: [PATCH] vrx518_tc: atm_tc: fix crash on subif_reg absence
|
||||
|
||||
VRX518 (sw_plat) platform does not provid the subif_reg/subif_unreg ops
|
||||
in the same time ATM TC layer unconditionally calls them, what leads to
|
||||
the kernel crash on the atm_hook_mpoa_setup hook invocation from the ATM
|
||||
stack:
|
||||
|
||||
vrx518_tc:mpoa_setup_sync : sync: conn: 0, vpi: 0, vci: 35, mpoa_type: 0, mpoa_mode: 0
|
||||
Unable to handle kernel NULL pointer dereference at virtual address 00000000
|
||||
|
||||
Subif registration is optional and PTM TC do this only when the
|
||||
corresponding ops are defined. Do the same for ATM TC and call
|
||||
subif_reg/subif_unreg only if they are not NULL.
|
||||
|
||||
While at it, move subif related data preparation under the 'if' block
|
||||
in order to group and isolate that aux code.
|
||||
|
||||
Run tested with FRITZ!Box 7530.
|
||||
|
||||
Signed-off-by: Sergey Ryazanov <ryazanov.s.a@gmail.com>
|
||||
---
|
||||
--- a/dcdp/atm_tc.c
|
||||
+++ b/dcdp/atm_tc.c
|
||||
@@ -1158,8 +1158,9 @@ static void ppe_close(struct atm_vcc *vc
|
||||
validate_oam_htu_entry(priv, 0);
|
||||
spin_unlock_bh(&priv->atm_lock);
|
||||
|
||||
- priv->tc_priv->tc_ops.subif_unreg(dev, (!dev) ? dev_name : dev->name,
|
||||
- priv->conn[cid].subif_id, 0);
|
||||
+ if (priv->tc_priv->tc_ops.subif_unreg)
|
||||
+ priv->tc_priv->tc_ops.subif_unreg(dev, (!dev) ? dev_name : dev->name,
|
||||
+ priv->conn[cid].subif_id, 0);
|
||||
|
||||
memset(conn, 0, sizeof(*conn));
|
||||
|
||||
@@ -2710,24 +2711,26 @@ static void mpoa_setup_sync(struct atm_p
|
||||
struct wtx_queue_config_t tx_qcfg;
|
||||
struct uni_cell_header *cell_header;
|
||||
struct atm_vcc *vcc;
|
||||
- struct net_device *dev;
|
||||
- char dev_name[32];
|
||||
|
||||
tc_dbg(priv->tc_priv, MSG_INIT,
|
||||
"sync: conn: %d, vpi: %d, vci: %d, mpoa_type: %d, mpoa_mode: %d\n",
|
||||
conn, priv->conn[conn].vcc->vpi, priv->conn[conn].vcc->vci,
|
||||
priv->conn[conn].mpoa_type, priv->conn[conn].mpoa_mode);
|
||||
|
||||
- dev = priv->conn[conn].dev;
|
||||
+ if (priv->tc_priv->tc_ops.subif_reg) {
|
||||
+ struct net_device *dev;
|
||||
+ char dev_name[32];
|
||||
+
|
||||
+ dev = priv->conn[conn].dev;
|
||||
+ if (!dev)
|
||||
+ sprintf(dev_name, "atm_%d%d",
|
||||
+ priv->conn[conn].vcc->vpi, priv->conn[conn].vcc->vci);
|
||||
|
||||
- if (!dev)
|
||||
- sprintf(dev_name, "atm_%d%d",
|
||||
- priv->conn[conn].vcc->vpi, priv->conn[conn].vcc->vci);
|
||||
-
|
||||
- priv->tc_priv->tc_ops.subif_reg(dev, (!dev) ? dev_name : dev->name,
|
||||
- &priv->conn[conn].subif_id, 0);
|
||||
- tc_dbg(priv->tc_priv, MSG_INIT,
|
||||
- "conn[%d]subif_id[%x]", conn, priv->conn[conn].subif_id);
|
||||
+ priv->tc_priv->tc_ops.subif_reg(dev, !dev ? dev_name : dev->name,
|
||||
+ &priv->conn[conn].subif_id, 0);
|
||||
+ tc_dbg(priv->tc_priv, MSG_INIT,
|
||||
+ "conn[%d]subif_id[%x]", conn, priv->conn[conn].subif_id);
|
||||
+ }
|
||||
vcc = priv->conn[conn].vcc;
|
||||
|
||||
/* set htu entry */
|
@ -8,9 +8,9 @@ PKG_LICENSE_FILES:=
|
||||
|
||||
PKG_SOURCE_URL:=https://github.com/openwrt/mt76
|
||||
PKG_SOURCE_PROTO:=git
|
||||
PKG_SOURCE_DATE:=2025-01-14
|
||||
PKG_SOURCE_VERSION:=8e4f72b682e9070108536507c5e2720b18c3816d
|
||||
PKG_MIRROR_HASH:=fa8c5a2ece9e7287605910d9f906b601711c7863613addaadd666f9e3858a9e7
|
||||
PKG_SOURCE_DATE:=2025-01-22
|
||||
PKG_SOURCE_VERSION:=a22d59e4ad50c89326342a0736cd2c1ba32e8a0b
|
||||
PKG_MIRROR_HASH:=e8bbbada2171ea31a6788e3e46e81c409a9fe038eefe4b41f541da848a1b1bcd
|
||||
|
||||
PKG_MAINTAINER:=Felix Fietkau <nbd@nbd.name>
|
||||
PKG_USE_NINJA:=0
|
||||
|
@ -0,0 +1,139 @@
|
||||
From: Yunsheng Lin <linyunsheng@huawei.com>
|
||||
Date: Fri, 13 Oct 2023 14:48:21 +0800
|
||||
Subject: [PATCH] page_pool: fragment API support for 32-bit arch with 64-bit
|
||||
DMA
|
||||
|
||||
Currently page_pool_alloc_frag() is not supported in 32-bit
|
||||
arch with 64-bit DMA because of the overlap issue between
|
||||
pp_frag_count and dma_addr_upper in 'struct page' for those
|
||||
arches, which seems to be quite common, see [1], which means
|
||||
driver may need to handle it when using fragment API.
|
||||
|
||||
It is assumed that the combination of the above arch with an
|
||||
address space >16TB does not exist, as all those arches have
|
||||
64b equivalent, it seems logical to use the 64b version for a
|
||||
system with a large address space. It is also assumed that dma
|
||||
address is page aligned when we are dma mapping a page aligned
|
||||
buffer, see [2].
|
||||
|
||||
That means we're storing 12 bits of 0 at the lower end for a
|
||||
dma address, we can reuse those bits for the above arches to
|
||||
support 32b+12b, which is 16TB of memory.
|
||||
|
||||
If we make a wrong assumption, a warning is emitted so that
|
||||
user can report to us.
|
||||
|
||||
1. https://lore.kernel.org/all/20211117075652.58299-1-linyunsheng@huawei.com/
|
||||
2. https://lore.kernel.org/all/20230818145145.4b357c89@kernel.org/
|
||||
|
||||
Tested-by: Alexander Lobakin <aleksander.lobakin@intel.com>
|
||||
Signed-off-by: Yunsheng Lin <linyunsheng@huawei.com>
|
||||
CC: Lorenzo Bianconi <lorenzo@kernel.org>
|
||||
CC: Alexander Duyck <alexander.duyck@gmail.com>
|
||||
CC: Liang Chen <liangchen.linux@gmail.com>
|
||||
CC: Guillaume Tucker <guillaume.tucker@collabora.com>
|
||||
CC: Matthew Wilcox <willy@infradead.org>
|
||||
CC: Linux-MM <linux-mm@kvack.org>
|
||||
Link: https://lore.kernel.org/r/20231013064827.61135-2-linyunsheng@huawei.com
|
||||
Signed-off-by: Jakub Kicinski <kuba@kernel.org>
|
||||
---
|
||||
|
||||
--- a/include/linux/mm_types.h
|
||||
+++ b/include/linux/mm_types.h
|
||||
@@ -125,18 +125,7 @@ struct page {
|
||||
struct page_pool *pp;
|
||||
unsigned long _pp_mapping_pad;
|
||||
unsigned long dma_addr;
|
||||
- union {
|
||||
- /**
|
||||
- * dma_addr_upper: might require a 64-bit
|
||||
- * value on 32-bit architectures.
|
||||
- */
|
||||
- unsigned long dma_addr_upper;
|
||||
- /**
|
||||
- * For frag page support, not supported in
|
||||
- * 32-bit architectures with 64-bit DMA.
|
||||
- */
|
||||
- atomic_long_t pp_frag_count;
|
||||
- };
|
||||
+ atomic_long_t pp_frag_count;
|
||||
};
|
||||
struct { /* Tail pages of compound page */
|
||||
unsigned long compound_head; /* Bit zero is set */
|
||||
--- a/include/net/page_pool/helpers.h
|
||||
+++ b/include/net/page_pool/helpers.h
|
||||
@@ -197,7 +197,7 @@ static inline void page_pool_recycle_dir
|
||||
page_pool_put_full_page(pool, page, true);
|
||||
}
|
||||
|
||||
-#define PAGE_POOL_DMA_USE_PP_FRAG_COUNT \
|
||||
+#define PAGE_POOL_32BIT_ARCH_WITH_64BIT_DMA \
|
||||
(sizeof(dma_addr_t) > sizeof(unsigned long))
|
||||
|
||||
/**
|
||||
@@ -211,17 +211,25 @@ static inline dma_addr_t page_pool_get_d
|
||||
{
|
||||
dma_addr_t ret = page->dma_addr;
|
||||
|
||||
- if (PAGE_POOL_DMA_USE_PP_FRAG_COUNT)
|
||||
- ret |= (dma_addr_t)page->dma_addr_upper << 16 << 16;
|
||||
+ if (PAGE_POOL_32BIT_ARCH_WITH_64BIT_DMA)
|
||||
+ ret <<= PAGE_SHIFT;
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
-static inline void page_pool_set_dma_addr(struct page *page, dma_addr_t addr)
|
||||
+static inline bool page_pool_set_dma_addr(struct page *page, dma_addr_t addr)
|
||||
{
|
||||
+ if (PAGE_POOL_32BIT_ARCH_WITH_64BIT_DMA) {
|
||||
+ page->dma_addr = addr >> PAGE_SHIFT;
|
||||
+
|
||||
+ /* We assume page alignment to shave off bottom bits,
|
||||
+ * if this "compression" doesn't work we need to drop.
|
||||
+ */
|
||||
+ return addr != (dma_addr_t)page->dma_addr << PAGE_SHIFT;
|
||||
+ }
|
||||
+
|
||||
page->dma_addr = addr;
|
||||
- if (PAGE_POOL_DMA_USE_PP_FRAG_COUNT)
|
||||
- page->dma_addr_upper = upper_32_bits(addr);
|
||||
+ return false;
|
||||
}
|
||||
|
||||
static inline bool page_pool_put(struct page_pool *pool)
|
||||
--- a/net/core/page_pool.c
|
||||
+++ b/net/core/page_pool.c
|
||||
@@ -211,10 +211,6 @@ static int page_pool_init(struct page_po
|
||||
*/
|
||||
}
|
||||
|
||||
- if (PAGE_POOL_DMA_USE_PP_FRAG_COUNT &&
|
||||
- pool->p.flags & PP_FLAG_PAGE_FRAG)
|
||||
- return -EINVAL;
|
||||
-
|
||||
#ifdef CONFIG_PAGE_POOL_STATS
|
||||
pool->recycle_stats = alloc_percpu(struct page_pool_recycle_stats);
|
||||
if (!pool->recycle_stats)
|
||||
@@ -363,12 +359,20 @@ static bool page_pool_dma_map(struct pag
|
||||
if (dma_mapping_error(pool->p.dev, dma))
|
||||
return false;
|
||||
|
||||
- page_pool_set_dma_addr(page, dma);
|
||||
+ if (page_pool_set_dma_addr(page, dma))
|
||||
+ goto unmap_failed;
|
||||
|
||||
if (pool->p.flags & PP_FLAG_DMA_SYNC_DEV)
|
||||
page_pool_dma_sync_for_device(pool, page, pool->p.max_len);
|
||||
|
||||
return true;
|
||||
+
|
||||
+unmap_failed:
|
||||
+ WARN_ON_ONCE("unexpected DMA address, please report to netdev@");
|
||||
+ dma_unmap_page_attrs(pool->p.dev, dma,
|
||||
+ PAGE_SIZE << pool->p.order, pool->p.dma_dir,
|
||||
+ DMA_ATTR_SKIP_CPU_SYNC | DMA_ATTR_WEAK_ORDERING);
|
||||
+ return false;
|
||||
}
|
||||
|
||||
static void page_pool_set_pp_info(struct page_pool *pool,
|
@ -0,0 +1,183 @@
|
||||
From: Yunsheng Lin <linyunsheng@huawei.com>
|
||||
Date: Fri, 20 Oct 2023 17:59:48 +0800
|
||||
Subject: [PATCH] page_pool: unify frag_count handling in
|
||||
page_pool_is_last_frag()
|
||||
|
||||
Currently when page_pool_create() is called with
|
||||
PP_FLAG_PAGE_FRAG flag, page_pool_alloc_pages() is only
|
||||
allowed to be called under the below constraints:
|
||||
1. page_pool_fragment_page() need to be called to setup
|
||||
page->pp_frag_count immediately.
|
||||
2. page_pool_defrag_page() often need to be called to drain
|
||||
the page->pp_frag_count when there is no more user will
|
||||
be holding on to that page.
|
||||
|
||||
Those constraints exist in order to support a page to be
|
||||
split into multi fragments.
|
||||
|
||||
And those constraints have some overhead because of the
|
||||
cache line dirtying/bouncing and atomic update.
|
||||
|
||||
Those constraints are unavoidable for case when we need a
|
||||
page to be split into more than one fragment, but there is
|
||||
also case that we want to avoid the above constraints and
|
||||
their overhead when a page can't be split as it can only
|
||||
hold a fragment as requested by user, depending on different
|
||||
use cases:
|
||||
use case 1: allocate page without page splitting.
|
||||
use case 2: allocate page with page splitting.
|
||||
use case 3: allocate page with or without page splitting
|
||||
depending on the fragment size.
|
||||
|
||||
Currently page pool only provide page_pool_alloc_pages() and
|
||||
page_pool_alloc_frag() API to enable the 1 & 2 separately,
|
||||
so we can not use a combination of 1 & 2 to enable 3, it is
|
||||
not possible yet because of the per page_pool flag
|
||||
PP_FLAG_PAGE_FRAG.
|
||||
|
||||
So in order to allow allocating unsplit page without the
|
||||
overhead of split page while still allow allocating split
|
||||
page we need to remove the per page_pool flag in
|
||||
page_pool_is_last_frag(), as best as I can think of, it seems
|
||||
there are two methods as below:
|
||||
1. Add per page flag/bit to indicate a page is split or
|
||||
not, which means we might need to update that flag/bit
|
||||
everytime the page is recycled, dirtying the cache line
|
||||
of 'struct page' for use case 1.
|
||||
2. Unify the page->pp_frag_count handling for both split and
|
||||
unsplit page by assuming all pages in the page pool is split
|
||||
into a big fragment initially.
|
||||
|
||||
As page pool already supports use case 1 without dirtying the
|
||||
cache line of 'struct page' whenever a page is recyclable, we
|
||||
need to support the above use case 3 with minimal overhead,
|
||||
especially not adding any noticeable overhead for use case 1,
|
||||
and we are already doing an optimization by not updating
|
||||
pp_frag_count in page_pool_defrag_page() for the last fragment
|
||||
user, this patch chooses to unify the pp_frag_count handling
|
||||
to support the above use case 3.
|
||||
|
||||
There is no noticeable performance degradation and some
|
||||
justification for unifying the frag_count handling with this
|
||||
patch applied using a micro-benchmark testing in [1].
|
||||
|
||||
1. https://lore.kernel.org/all/bf2591f8-7b3c-4480-bb2c-31dc9da1d6ac@huawei.com/
|
||||
|
||||
Signed-off-by: Yunsheng Lin <linyunsheng@huawei.com>
|
||||
CC: Lorenzo Bianconi <lorenzo@kernel.org>
|
||||
CC: Alexander Duyck <alexander.duyck@gmail.com>
|
||||
CC: Liang Chen <liangchen.linux@gmail.com>
|
||||
CC: Alexander Lobakin <aleksander.lobakin@intel.com>
|
||||
Link: https://lore.kernel.org/r/20231020095952.11055-2-linyunsheng@huawei.com
|
||||
Signed-off-by: Jakub Kicinski <kuba@kernel.org>
|
||||
---
|
||||
|
||||
--- a/include/net/page_pool/helpers.h
|
||||
+++ b/include/net/page_pool/helpers.h
|
||||
@@ -115,28 +115,49 @@ static inline long page_pool_defrag_page
|
||||
long ret;
|
||||
|
||||
/* If nr == pp_frag_count then we have cleared all remaining
|
||||
- * references to the page. No need to actually overwrite it, instead
|
||||
- * we can leave this to be overwritten by the calling function.
|
||||
+ * references to the page:
|
||||
+ * 1. 'n == 1': no need to actually overwrite it.
|
||||
+ * 2. 'n != 1': overwrite it with one, which is the rare case
|
||||
+ * for pp_frag_count draining.
|
||||
*
|
||||
- * The main advantage to doing this is that an atomic_read is
|
||||
- * generally a much cheaper operation than an atomic update,
|
||||
- * especially when dealing with a page that may be partitioned
|
||||
- * into only 2 or 3 pieces.
|
||||
+ * The main advantage to doing this is that not only we avoid a atomic
|
||||
+ * update, as an atomic_read is generally a much cheaper operation than
|
||||
+ * an atomic update, especially when dealing with a page that may be
|
||||
+ * partitioned into only 2 or 3 pieces; but also unify the pp_frag_count
|
||||
+ * handling by ensuring all pages have partitioned into only 1 piece
|
||||
+ * initially, and only overwrite it when the page is partitioned into
|
||||
+ * more than one piece.
|
||||
*/
|
||||
- if (atomic_long_read(&page->pp_frag_count) == nr)
|
||||
+ if (atomic_long_read(&page->pp_frag_count) == nr) {
|
||||
+ /* As we have ensured nr is always one for constant case using
|
||||
+ * the BUILD_BUG_ON(), only need to handle the non-constant case
|
||||
+ * here for pp_frag_count draining, which is a rare case.
|
||||
+ */
|
||||
+ BUILD_BUG_ON(__builtin_constant_p(nr) && nr != 1);
|
||||
+ if (!__builtin_constant_p(nr))
|
||||
+ atomic_long_set(&page->pp_frag_count, 1);
|
||||
+
|
||||
return 0;
|
||||
+ }
|
||||
|
||||
ret = atomic_long_sub_return(nr, &page->pp_frag_count);
|
||||
WARN_ON(ret < 0);
|
||||
+
|
||||
+ /* We are the last user here too, reset pp_frag_count back to 1 to
|
||||
+ * ensure all pages have been partitioned into 1 piece initially,
|
||||
+ * this should be the rare case when the last two fragment users call
|
||||
+ * page_pool_defrag_page() currently.
|
||||
+ */
|
||||
+ if (unlikely(!ret))
|
||||
+ atomic_long_set(&page->pp_frag_count, 1);
|
||||
+
|
||||
return ret;
|
||||
}
|
||||
|
||||
-static inline bool page_pool_is_last_frag(struct page_pool *pool,
|
||||
- struct page *page)
|
||||
+static inline bool page_pool_is_last_frag(struct page *page)
|
||||
{
|
||||
- /* If fragments aren't enabled or count is 0 we were the last user */
|
||||
- return !(pool->p.flags & PP_FLAG_PAGE_FRAG) ||
|
||||
- (page_pool_defrag_page(page, 1) == 0);
|
||||
+ /* If page_pool_defrag_page() returns 0, we were the last user */
|
||||
+ return page_pool_defrag_page(page, 1) == 0;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -161,7 +182,7 @@ static inline void page_pool_put_page(st
|
||||
* allow registering MEM_TYPE_PAGE_POOL, but shield linker.
|
||||
*/
|
||||
#ifdef CONFIG_PAGE_POOL
|
||||
- if (!page_pool_is_last_frag(pool, page))
|
||||
+ if (!page_pool_is_last_frag(page))
|
||||
return;
|
||||
|
||||
page_pool_put_defragged_page(pool, page, dma_sync_size, allow_direct);
|
||||
--- a/net/core/page_pool.c
|
||||
+++ b/net/core/page_pool.c
|
||||
@@ -380,6 +380,14 @@ static void page_pool_set_pp_info(struct
|
||||
{
|
||||
page->pp = pool;
|
||||
page->pp_magic |= PP_SIGNATURE;
|
||||
+
|
||||
+ /* Ensuring all pages have been split into one fragment initially:
|
||||
+ * page_pool_set_pp_info() is only called once for every page when it
|
||||
+ * is allocated from the page allocator and page_pool_fragment_page()
|
||||
+ * is dirtying the same cache line as the page->pp_magic above, so
|
||||
+ * the overhead is negligible.
|
||||
+ */
|
||||
+ page_pool_fragment_page(page, 1);
|
||||
if (pool->p.init_callback)
|
||||
pool->p.init_callback(page, pool->p.init_arg);
|
||||
}
|
||||
@@ -676,7 +684,7 @@ void page_pool_put_page_bulk(struct page
|
||||
struct page *page = virt_to_head_page(data[i]);
|
||||
|
||||
/* It is not the last user for the page frag case */
|
||||
- if (!page_pool_is_last_frag(pool, page))
|
||||
+ if (!page_pool_is_last_frag(page))
|
||||
continue;
|
||||
|
||||
page = __page_pool_put_page(pool, page, -1, false);
|
||||
@@ -752,8 +760,7 @@ struct page *page_pool_alloc_frag(struct
|
||||
unsigned int max_size = PAGE_SIZE << pool->p.order;
|
||||
struct page *page = pool->frag_page;
|
||||
|
||||
- if (WARN_ON(!(pool->p.flags & PP_FLAG_PAGE_FRAG) ||
|
||||
- size > max_size))
|
||||
+ if (WARN_ON(size > max_size))
|
||||
return NULL;
|
||||
|
||||
size = ALIGN(size, dma_get_cache_alignment());
|
@ -0,0 +1,64 @@
|
||||
From 64ff63aeefb03139ae27454bd4208244579ae88e Mon Sep 17 00:00:00 2001
|
||||
From: Aleksander Jan Bajkowski <olek2@wp.pl>
|
||||
Date: Fri, 17 Jan 2025 23:24:21 +0100
|
||||
Subject: [PATCH] net: phy: realtek: HWMON support for standalone versions of
|
||||
RTL8221B and RTL8251
|
||||
|
||||
HWMON support has been added for the RTL8221/8251 PHYs integrated together
|
||||
with the MAC inside the RTL8125/8126 chips. This patch extends temperature
|
||||
reading support for standalone variants of the mentioned PHYs.
|
||||
|
||||
I don't know whether the earlier revisions of the RTL8226 also have a
|
||||
built-in temperature sensor, so they have been skipped for now.
|
||||
|
||||
Tested on RTL8221B-VB-CG.
|
||||
|
||||
Signed-off-by: Aleksander Jan Bajkowski <olek2@wp.pl>
|
||||
Reviewed-by: Andrew Lunn <andrew@lunn.ch>
|
||||
Signed-off-by: David S. Miller <davem@davemloft.net>
|
||||
---
|
||||
drivers/net/phy/realtek/realtek_main.c | 5 +++++
|
||||
1 file changed, 5 insertions(+)
|
||||
|
||||
--- a/drivers/net/phy/realtek/realtek_main.c
|
||||
+++ b/drivers/net/phy/realtek/realtek_main.c
|
||||
@@ -1474,6 +1474,7 @@ static struct phy_driver realtek_drvs[]
|
||||
}, {
|
||||
.match_phy_device = rtl8221b_vb_cg_c22_match_phy_device,
|
||||
.name = "RTL8221B-VB-CG 2.5Gbps PHY (C22)",
|
||||
+ .probe = rtl822x_probe,
|
||||
.get_features = rtl822x_get_features,
|
||||
.config_aneg = rtl822x_config_aneg,
|
||||
.config_init = rtl822xb_config_init,
|
||||
@@ -1486,6 +1487,7 @@ static struct phy_driver realtek_drvs[]
|
||||
}, {
|
||||
.match_phy_device = rtl8221b_vb_cg_c45_match_phy_device,
|
||||
.name = "RTL8221B-VB-CG 2.5Gbps PHY (C45)",
|
||||
+ .probe = rtl822x_probe,
|
||||
.config_init = rtl822xb_config_init,
|
||||
.get_rate_matching = rtl822xb_get_rate_matching,
|
||||
.get_features = rtl822x_c45_get_features,
|
||||
@@ -1496,6 +1498,7 @@ static struct phy_driver realtek_drvs[]
|
||||
}, {
|
||||
.match_phy_device = rtl8221b_vn_cg_c22_match_phy_device,
|
||||
.name = "RTL8221B-VM-CG 2.5Gbps PHY (C22)",
|
||||
+ .probe = rtl822x_probe,
|
||||
.get_features = rtl822x_get_features,
|
||||
.config_aneg = rtl822x_config_aneg,
|
||||
.config_init = rtl822xb_config_init,
|
||||
@@ -1508,6 +1511,7 @@ static struct phy_driver realtek_drvs[]
|
||||
}, {
|
||||
.match_phy_device = rtl8221b_vn_cg_c45_match_phy_device,
|
||||
.name = "RTL8221B-VN-CG 2.5Gbps PHY (C45)",
|
||||
+ .probe = rtl822x_probe,
|
||||
.config_init = rtl822xb_config_init,
|
||||
.get_rate_matching = rtl822xb_get_rate_matching,
|
||||
.get_features = rtl822x_c45_get_features,
|
||||
@@ -1518,6 +1522,7 @@ static struct phy_driver realtek_drvs[]
|
||||
}, {
|
||||
.match_phy_device = rtl8251b_c45_match_phy_device,
|
||||
.name = "RTL8251B 5Gbps PHY",
|
||||
+ .probe = rtl822x_probe,
|
||||
.get_features = rtl822x_get_features,
|
||||
.config_aneg = rtl822x_config_aneg,
|
||||
.read_status = rtl822x_read_status,
|
@ -0,0 +1,30 @@
|
||||
From b0fa00fe38f673c986633c11087274deeb7ce7b0 Mon Sep 17 00:00:00 2001
|
||||
From: Sander Vanheule <sander@svanheule.net>
|
||||
Date: Tue, 7 Jan 2025 21:16:20 +0100
|
||||
Subject: [PATCH] gpio: regmap: Use generic request/free ops
|
||||
|
||||
Set the gpiochip request and free ops to the generic implementations.
|
||||
This way a user can provide a gpio-ranges property defined for a pinmux,
|
||||
easing muxing of gpio functions. Provided that the pin controller
|
||||
implementents the pinmux op .gpio_request_enable(), pins will
|
||||
automatically be muxed to their GPIO function when requested.
|
||||
|
||||
Signed-off-by: Sander Vanheule <sander@svanheule.net>
|
||||
Acked-by: Michael Walle <mwalle@kernel.org>
|
||||
Link: https://lore.kernel.org/r/20250107201621.12467-1-sander@svanheule.net
|
||||
Signed-off-by: Bartosz Golaszewski <bartosz.golaszewski@linaro.org>
|
||||
---
|
||||
drivers/gpio/gpio-regmap.c | 2 ++
|
||||
1 file changed, 2 insertions(+)
|
||||
|
||||
--- a/drivers/gpio/gpio-regmap.c
|
||||
+++ b/drivers/gpio/gpio-regmap.c
|
||||
@@ -262,6 +262,8 @@ struct gpio_regmap *gpio_regmap_register
|
||||
chip->label = config->label ?: dev_name(config->parent);
|
||||
chip->can_sleep = regmap_might_sleep(config->regmap);
|
||||
|
||||
+ chip->request = gpiochip_generic_request;
|
||||
+ chip->free = gpiochip_generic_free;
|
||||
chip->get = gpio_regmap_get;
|
||||
if (gpio->reg_set_base && gpio->reg_clr_base)
|
||||
chip->set = gpio_regmap_set_with_clear;
|
@ -16,7 +16,7 @@ Signed-off-by: Felix Fietkau <nbd@nbd.name>
|
||||
|
||||
--- a/net/core/page_pool.c
|
||||
+++ b/net/core/page_pool.c
|
||||
@@ -862,12 +862,23 @@ static void page_pool_release_retry(stru
|
||||
@@ -873,12 +873,23 @@ static void page_pool_release_retry(stru
|
||||
{
|
||||
struct delayed_work *dwq = to_delayed_work(wq);
|
||||
struct page_pool *pool = container_of(dwq, typeof(*pool), release_dw);
|
||||
|
@ -52,30 +52,30 @@ Signed-off-by: Daniel Golle <daniel@makrotopia.org>
|
||||
.match_phy_device = rtl8221b_vb_cg_c22_match_phy_device,
|
||||
.name = "RTL8221B-VB-CG 2.5Gbps PHY (C22)",
|
||||
+ .soft_reset = genphy_soft_reset,
|
||||
.probe = rtl822x_probe,
|
||||
.get_features = rtl822x_get_features,
|
||||
.config_aneg = rtl822x_config_aneg,
|
||||
.config_init = rtl822xb_config_init,
|
||||
@@ -1486,6 +1491,7 @@ static struct phy_driver realtek_drvs[]
|
||||
@@ -1487,6 +1492,7 @@ static struct phy_driver realtek_drvs[]
|
||||
}, {
|
||||
.match_phy_device = rtl8221b_vb_cg_c45_match_phy_device,
|
||||
.name = "RTL8221B-VB-CG 2.5Gbps PHY (C45)",
|
||||
+ .soft_reset = genphy_soft_reset,
|
||||
.probe = rtl822x_probe,
|
||||
.config_init = rtl822xb_config_init,
|
||||
.get_rate_matching = rtl822xb_get_rate_matching,
|
||||
.get_features = rtl822x_c45_get_features,
|
||||
@@ -1496,6 +1502,7 @@ static struct phy_driver realtek_drvs[]
|
||||
@@ -1498,6 +1504,7 @@ static struct phy_driver realtek_drvs[]
|
||||
}, {
|
||||
.match_phy_device = rtl8221b_vn_cg_c22_match_phy_device,
|
||||
.name = "RTL8221B-VM-CG 2.5Gbps PHY (C22)",
|
||||
+ .soft_reset = genphy_soft_reset,
|
||||
.probe = rtl822x_probe,
|
||||
.get_features = rtl822x_get_features,
|
||||
.config_aneg = rtl822x_config_aneg,
|
||||
.config_init = rtl822xb_config_init,
|
||||
@@ -1508,6 +1515,7 @@ static struct phy_driver realtek_drvs[]
|
||||
@@ -1511,6 +1518,7 @@ static struct phy_driver realtek_drvs[]
|
||||
}, {
|
||||
.match_phy_device = rtl8221b_vn_cg_c45_match_phy_device,
|
||||
.name = "RTL8221B-VN-CG 2.5Gbps PHY (C45)",
|
||||
+ .soft_reset = genphy_soft_reset,
|
||||
.probe = rtl822x_probe,
|
||||
.config_init = rtl822xb_config_init,
|
||||
.get_rate_matching = rtl822xb_get_rate_matching,
|
||||
.get_features = rtl822x_c45_get_features,
|
||||
|
@ -44,7 +44,7 @@ Signed-off-by: Daniel Golle <daniel@makrotopia.org>
|
||||
+
|
||||
+ phy_write_mmd(phydev, MDIO_MMD_VEND1, RTL8221B_PHYCR1, val);
|
||||
+
|
||||
+ return 0;
|
||||
+ return rtl822x_probe(phydev);
|
||||
+}
|
||||
+
|
||||
static int rtlgen_resume(struct phy_device *phydev)
|
||||
@ -66,35 +66,39 @@ Signed-off-by: Daniel Golle <daniel@makrotopia.org>
|
||||
.soft_reset = genphy_soft_reset,
|
||||
.get_features = rtl822x_get_features,
|
||||
.config_aneg = rtl822x_config_aneg,
|
||||
@@ -1502,6 +1527,7 @@ static struct phy_driver realtek_drvs[]
|
||||
}, {
|
||||
@@ -1503,7 +1528,7 @@ static struct phy_driver realtek_drvs[]
|
||||
.match_phy_device = rtl8221b_vb_cg_c22_match_phy_device,
|
||||
.name = "RTL8221B-VB-CG 2.5Gbps PHY (C22)",
|
||||
+ .probe = rtl822x_aldps_probe,
|
||||
.soft_reset = genphy_soft_reset,
|
||||
- .probe = rtl822x_probe,
|
||||
+ .probe = rtl822x_aldps_probe,
|
||||
.get_features = rtl822x_get_features,
|
||||
.config_aneg = rtl822x_config_aneg,
|
||||
@@ -1515,6 +1541,7 @@ static struct phy_driver realtek_drvs[]
|
||||
}, {
|
||||
.config_init = rtl822xb_config_init,
|
||||
@@ -1517,7 +1542,7 @@ static struct phy_driver realtek_drvs[]
|
||||
.match_phy_device = rtl8221b_vb_cg_c45_match_phy_device,
|
||||
.name = "RTL8221B-VB-CG 2.5Gbps PHY (C45)",
|
||||
+ .probe = rtl822x_aldps_probe,
|
||||
.soft_reset = genphy_soft_reset,
|
||||
- .probe = rtl822x_probe,
|
||||
+ .probe = rtl822x_aldps_probe,
|
||||
.config_init = rtl822xb_config_init,
|
||||
.get_rate_matching = rtl822xb_get_rate_matching,
|
||||
@@ -1526,6 +1553,7 @@ static struct phy_driver realtek_drvs[]
|
||||
}, {
|
||||
.get_features = rtl822x_c45_get_features,
|
||||
@@ -1529,7 +1554,7 @@ static struct phy_driver realtek_drvs[]
|
||||
.match_phy_device = rtl8221b_vn_cg_c22_match_phy_device,
|
||||
.name = "RTL8221B-VM-CG 2.5Gbps PHY (C22)",
|
||||
+ .probe = rtl822x_aldps_probe,
|
||||
.soft_reset = genphy_soft_reset,
|
||||
- .probe = rtl822x_probe,
|
||||
+ .probe = rtl822x_aldps_probe,
|
||||
.get_features = rtl822x_get_features,
|
||||
.config_aneg = rtl822x_config_aneg,
|
||||
@@ -1539,6 +1567,7 @@ static struct phy_driver realtek_drvs[]
|
||||
}, {
|
||||
.config_init = rtl822xb_config_init,
|
||||
@@ -1543,7 +1568,7 @@ static struct phy_driver realtek_drvs[]
|
||||
.match_phy_device = rtl8221b_vn_cg_c45_match_phy_device,
|
||||
.name = "RTL8221B-VN-CG 2.5Gbps PHY (C45)",
|
||||
+ .probe = rtl822x_aldps_probe,
|
||||
.soft_reset = genphy_soft_reset,
|
||||
- .probe = rtl822x_probe,
|
||||
+ .probe = rtl822x_aldps_probe,
|
||||
.config_init = rtl822xb_config_init,
|
||||
.get_rate_matching = rtl822xb_get_rate_matching,
|
||||
.get_features = rtl822x_c45_get_features,
|
@ -70,8 +70,8 @@ Signed-off-by: Jianhui Zhao <zhaojh329@gmail.com>
|
||||
.name = "RTL8221B-VB-CG 2.5Gbps PHY (C22)",
|
||||
+ .config_intr = rtl8221b_config_intr,
|
||||
+ .handle_interrupt = rtl8221b_handle_interrupt,
|
||||
.probe = rtl822x_aldps_probe,
|
||||
.soft_reset = genphy_soft_reset,
|
||||
.probe = rtl822x_aldps_probe,
|
||||
.get_features = rtl822x_get_features,
|
||||
@@ -1563,6 +1610,8 @@ static struct phy_driver realtek_drvs[]
|
||||
}, {
|
||||
@ -79,8 +79,8 @@ Signed-off-by: Jianhui Zhao <zhaojh329@gmail.com>
|
||||
.name = "RTL8221B-VB-CG 2.5Gbps PHY (C45)",
|
||||
+ .config_intr = rtl8221b_config_intr,
|
||||
+ .handle_interrupt = rtl8221b_handle_interrupt,
|
||||
.probe = rtl822x_aldps_probe,
|
||||
.soft_reset = genphy_soft_reset,
|
||||
.probe = rtl822x_aldps_probe,
|
||||
.config_init = rtl822xb_config_init,
|
||||
@@ -1575,6 +1624,8 @@ static struct phy_driver realtek_drvs[]
|
||||
}, {
|
||||
@ -88,8 +88,8 @@ Signed-off-by: Jianhui Zhao <zhaojh329@gmail.com>
|
||||
.name = "RTL8221B-VM-CG 2.5Gbps PHY (C22)",
|
||||
+ .config_intr = rtl8221b_config_intr,
|
||||
+ .handle_interrupt = rtl8221b_handle_interrupt,
|
||||
.probe = rtl822x_aldps_probe,
|
||||
.soft_reset = genphy_soft_reset,
|
||||
.probe = rtl822x_aldps_probe,
|
||||
.get_features = rtl822x_get_features,
|
||||
@@ -1589,6 +1640,8 @@ static struct phy_driver realtek_drvs[]
|
||||
}, {
|
||||
@ -97,6 +97,6 @@ Signed-off-by: Jianhui Zhao <zhaojh329@gmail.com>
|
||||
.name = "RTL8221B-VN-CG 2.5Gbps PHY (C45)",
|
||||
+ .config_intr = rtl8221b_config_intr,
|
||||
+ .handle_interrupt = rtl8221b_handle_interrupt,
|
||||
.probe = rtl822x_aldps_probe,
|
||||
.soft_reset = genphy_soft_reset,
|
||||
.probe = rtl822x_aldps_probe,
|
||||
.config_init = rtl822xb_config_init,
|
||||
|
@ -1,131 +0,0 @@
|
||||
From patchwork Tue Jan 7 20:16:20 2025
|
||||
Content-Type: text/plain; charset="utf-8"
|
||||
MIME-Version: 1.0
|
||||
Content-Transfer-Encoding: 8bit
|
||||
X-Patchwork-Submitter: Sander Vanheule <sander@svanheule.net>
|
||||
X-Patchwork-Id: 2031059
|
||||
Return-Path:
|
||||
<linux-gpio+bounces-14582-incoming=patchwork.ozlabs.org@vger.kernel.org>
|
||||
X-Original-To: incoming@patchwork.ozlabs.org
|
||||
Delivered-To: patchwork-incoming@legolas.ozlabs.org
|
||||
Authentication-Results: legolas.ozlabs.org;
|
||||
dkim=pass (2048-bit key;
|
||||
secure) header.d=svanheule.net header.i=@svanheule.net header.a=rsa-sha256
|
||||
header.s=mail1707 header.b=YjCvLC2H;
|
||||
dkim-atps=neutral
|
||||
Authentication-Results: legolas.ozlabs.org;
|
||||
spf=pass (sender SPF authorized) smtp.mailfrom=vger.kernel.org
|
||||
(client-ip=2604:1380:4601:e00::3; helo=am.mirrors.kernel.org;
|
||||
envelope-from=linux-gpio+bounces-14582-incoming=patchwork.ozlabs.org@vger.kernel.org;
|
||||
receiver=patchwork.ozlabs.org)
|
||||
Received: from am.mirrors.kernel.org (am.mirrors.kernel.org
|
||||
[IPv6:2604:1380:4601:e00::3])
|
||||
(using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits)
|
||||
key-exchange X25519 server-signature ECDSA (secp384r1))
|
||||
(No client certificate requested)
|
||||
by legolas.ozlabs.org (Postfix) with ESMTPS id 4YSMxB3WwSz1yPG
|
||||
for <incoming@patchwork.ozlabs.org>; Wed, 8 Jan 2025 07:25:18 +1100 (AEDT)
|
||||
Received: from smtp.subspace.kernel.org (relay.kernel.org [52.25.139.140])
|
||||
(using TLSv1.2 with cipher ECDHE-ECDSA-AES256-GCM-SHA384 (256/256 bits))
|
||||
(No client certificate requested)
|
||||
by am.mirrors.kernel.org (Postfix) with ESMTPS id A7B811887AD1
|
||||
for <incoming@patchwork.ozlabs.org>; Tue, 7 Jan 2025 20:25:19 +0000 (UTC)
|
||||
Received: from localhost.localdomain (localhost.localdomain [127.0.0.1])
|
||||
by smtp.subspace.kernel.org (Postfix) with ESMTP id C09A21F63FE;
|
||||
Tue, 7 Jan 2025 20:25:11 +0000 (UTC)
|
||||
Authentication-Results: smtp.subspace.kernel.org;
|
||||
dkim=pass (2048-bit key) header.d=svanheule.net header.i=@svanheule.net
|
||||
header.b="YjCvLC2H"
|
||||
X-Original-To: linux-gpio@vger.kernel.org
|
||||
Received: from polaris.svanheule.net (polaris.svanheule.net [84.16.241.116])
|
||||
(using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits))
|
||||
(No client certificate requested)
|
||||
by smtp.subspace.kernel.org (Postfix) with ESMTPS id 8DD631DF97A
|
||||
for <linux-gpio@vger.kernel.org>; Tue, 7 Jan 2025 20:25:07 +0000 (UTC)
|
||||
Authentication-Results: smtp.subspace.kernel.org;
|
||||
arc=none smtp.client-ip=84.16.241.116
|
||||
ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116;
|
||||
t=1736281511; cv=none;
|
||||
b=Xe/s+ul4S/+nhYxSMqUWJ/GXKP+J7uJo6tFw/w5bTXcmGxkbpCXTLOiTNXAhv8PMhTfsLYSQes6VF8dzDXaJxL4c8SlQsPNfGH/PqecmSvFMbZTz1XbjP9mBUCvX9lxCH8CSRavkuPuYdhss3a56TgaFzi9GifUSHCsHGs7+xk0=
|
||||
ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org;
|
||||
s=arc-20240116; t=1736281511; c=relaxed/simple;
|
||||
bh=31kjLyaoVOzIAs1m+zMi59Ia2jUwYW56Jp1YE6hLflg=;
|
||||
h=From:To:Cc:Subject:Date:Message-ID:MIME-Version:Content-Type;
|
||||
b=q7miNkZBtMq3dcxL5HMjUpP3EFdQ7/xU/WnWIFVl6MK4rszqphqvaziMOK6avsn+UA5pAx2JJV8bDY8LfNhiVWwZtPfxbikjjZFm1HYlCDWmGudasM0b//K3/On625L4iqFWmVmLUdEdhvwIkJKSL4wTfN0OMz27EI272o5ygLg=
|
||||
ARC-Authentication-Results: i=1; smtp.subspace.kernel.org;
|
||||
dmarc=pass (p=none dis=none) header.from=svanheule.net;
|
||||
spf=pass smtp.mailfrom=svanheule.net;
|
||||
dkim=pass (2048-bit key) header.d=svanheule.net header.i=@svanheule.net
|
||||
header.b=YjCvLC2H; arc=none smtp.client-ip=84.16.241.116
|
||||
Authentication-Results: smtp.subspace.kernel.org;
|
||||
dmarc=pass (p=none dis=none) header.from=svanheule.net
|
||||
Authentication-Results: smtp.subspace.kernel.org;
|
||||
spf=pass smtp.mailfrom=svanheule.net
|
||||
Received: from terra.vega.svanheule.net (unknown [94.110.49.146])
|
||||
(using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits)
|
||||
key-exchange X25519 server-signature RSA-PSS (2048 bits) server-digest
|
||||
SHA256)
|
||||
(No client certificate requested)
|
||||
(Authenticated sender: sander@svanheule.net)
|
||||
by polaris.svanheule.net (Postfix) with ESMTPSA id 1E18459A0D6;
|
||||
Tue, 7 Jan 2025 21:17:02 +0100 (CET)
|
||||
DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=svanheule.net;
|
||||
s=mail1707; t=1736281022;
|
||||
h=from:from:reply-to:subject:subject:date:date:message-id:message-id:
|
||||
to:to:cc:cc:mime-version:mime-version:content-type:content-type:
|
||||
content-transfer-encoding:content-transfer-encoding;
|
||||
bh=yNGIiTe7uonx3NZIc6+B7LVjvR8RnIV2zq++EO7NLhg=;
|
||||
b=YjCvLC2HqArIGWGFkNYmh+oloGi7ZFo7WZGlTbxuHqrQVJ6mLNoLCTCkPkX1EJWEQyNysD
|
||||
Jj+7tBnAYyCrJ0NuSTD9CPW1+KwKP4wlvWpBUlayCdUJyU4rzjqmlYAI5vJ1UX8FOnvEpn
|
||||
KeWjgjbeMI6dvIE7ATPFkDvMrDxR9KSEe/1pfzY3E5jh1T8tcnTRMQKTll7hSUBN63dVfJ
|
||||
U7wnHRLvwx8ESIjrHDKOlsSohmV6lyQTrgEeE2RCM6SpZPNoSpPVjTinF1kPuMHNWHV+Th
|
||||
6eDOblXxt859JECDowM0NjF87XJqjgph22+A1WUV4iaePO4GIWo9DQ3KhP/Pyg==
|
||||
From: Sander Vanheule <sander@svanheule.net>
|
||||
To: Michael Walle <mwalle@kernel.org>,
|
||||
Linus Walleij <linus.walleij@linaro.org>,
|
||||
Bartosz Golaszewski <brgl@bgdev.pl>,
|
||||
linux-gpio@vger.kernel.org,
|
||||
linux-kernel@vger.kernel.org
|
||||
Cc: =?utf-8?q?=C3=81lvaro_Fern=C3=A1ndez_Rojas?= <noltari@gmail.com>,
|
||||
jonas.gorski@gmail.com, kylehendrydev@gmail.com,
|
||||
florian.fainelli@broadcom.com, Sander Vanheule <sander@svanheule.net>
|
||||
Subject: [PATCH] gpio: regmap: Use generic request/free ops
|
||||
Date: Tue, 7 Jan 2025 21:16:20 +0100
|
||||
Message-ID: <20250107201621.12467-1-sander@svanheule.net>
|
||||
X-Mailer: git-send-email 2.47.1
|
||||
Precedence: bulk
|
||||
X-Mailing-List: linux-gpio@vger.kernel.org
|
||||
List-Id: <linux-gpio.vger.kernel.org>
|
||||
List-Subscribe: <mailto:linux-gpio+subscribe@vger.kernel.org>
|
||||
List-Unsubscribe: <mailto:linux-gpio+unsubscribe@vger.kernel.org>
|
||||
MIME-Version: 1.0
|
||||
|
||||
Set the gpiochip request and free ops to the generic implementations.
|
||||
This way a user can provide a gpio-ranges property defined for a pinmux,
|
||||
easing muxing of gpio functions. Provided that the pin controller
|
||||
implementents the pinmux op .gpio_request_enable(), pins will
|
||||
automatically be muxed to their GPIO function when requested.
|
||||
|
||||
Signed-off-by: Sander Vanheule <sander@svanheule.net>
|
||||
Acked-by: Michael Walle <mwalle@kernel.org>
|
||||
---
|
||||
Álvaro has submitted a similar patch today. My implementation's impact
|
||||
is more limited, but I hadn't gotten around to submitting it yet.
|
||||
|
||||
For the original (short) discussion, see:
|
||||
https://lore.kernel.org/linux-gpio/20250107102735.317446-1-noltari@gmail.com/T/#t
|
||||
|
||||
drivers/gpio/gpio-regmap.c | 2 ++
|
||||
1 file changed, 2 insertions(+)
|
||||
|
||||
--- a/drivers/gpio/gpio-regmap.c
|
||||
+++ b/drivers/gpio/gpio-regmap.c
|
||||
@@ -262,6 +262,8 @@ struct gpio_regmap *gpio_regmap_register
|
||||
chip->label = config->label ?: dev_name(config->parent);
|
||||
chip->can_sleep = regmap_might_sleep(config->regmap);
|
||||
|
||||
+ chip->request = gpiochip_generic_request;
|
||||
+ chip->free = gpiochip_generic_free;
|
||||
chip->get = gpio_regmap_get;
|
||||
if (gpio->reg_set_base && gpio->reg_clr_base)
|
||||
chip->set = gpio_regmap_set_with_clear;
|
@ -1,43 +0,0 @@
|
||||
From: John Crispin <blogic@openwrt.org>
|
||||
Date: Fri, 3 Aug 2012 10:27:25 +0200
|
||||
Subject: [PATCH 04/36] MIPS: lantiq: add atm hack
|
||||
|
||||
Signed-off-by: John Crispin <blogic@openwrt.org>
|
||||
--- a/include/uapi/linux/atm.h
|
||||
+++ b/include/uapi/linux/atm.h
|
||||
@@ -131,8 +131,14 @@
|
||||
#define ATM_ABR 4
|
||||
#define ATM_ANYCLASS 5 /* compatible with everything */
|
||||
|
||||
+#define ATM_VBR_NRT ATM_VBR
|
||||
+#define ATM_VBR_RT 6
|
||||
+#define ATM_UBR_PLUS 7
|
||||
+#define ATM_GFR 8
|
||||
+
|
||||
#define ATM_MAX_PCR -1 /* maximum available PCR */
|
||||
|
||||
+
|
||||
struct atm_trafprm {
|
||||
unsigned char traffic_class; /* traffic class (ATM_UBR, ...) */
|
||||
int max_pcr; /* maximum PCR in cells per second */
|
||||
@@ -155,6 +161,9 @@ struct atm_trafprm {
|
||||
unsigned int adtf :10; /* ACR Decrease Time Factor (10-bit) */
|
||||
unsigned int cdf :3; /* Cutoff Decrease Factor (3-bit) */
|
||||
unsigned int spare :9; /* spare bits */
|
||||
+ int scr; /* sustained rate in cells per second */
|
||||
+ int mbs; /* maximum burst size (MBS) in cells */
|
||||
+ int cdv; /* Cell delay variation */
|
||||
};
|
||||
|
||||
struct atm_qos {
|
||||
--- a/net/atm/proc.c
|
||||
+++ b/net/atm/proc.c
|
||||
@@ -141,7 +141,7 @@ static void *vcc_seq_next(struct seq_fil
|
||||
static void pvc_info(struct seq_file *seq, struct atm_vcc *vcc)
|
||||
{
|
||||
static const char *const class_name[] = {
|
||||
- "off", "UBR", "CBR", "VBR", "ABR"};
|
||||
+ "off","UBR","CBR","NTR-VBR","ABR","ANY","RT-VBR","UBR+","GFR"};
|
||||
static const char *const aal_name[] = {
|
||||
"---", "1", "2", "3/4", /* 0- 3 */
|
||||
"???", "5", "???", "???", /* 4- 7 */
|
@ -133,8 +133,8 @@
|
||||
reg = <0>;
|
||||
|
||||
spi-max-frequency = <52000000>;
|
||||
spi-tx-buswidth = <4>;
|
||||
spi-rx-buswidth = <4>;
|
||||
spi-tx-bus-width = <4>;
|
||||
spi-rx-bus-width = <4>;
|
||||
|
||||
spi-cal-enable;
|
||||
spi-cal-mode = "read-data";
|
||||
|
@ -8,7 +8,7 @@
|
||||
|
||||
/ {
|
||||
model = "Cudy AP3000 Outdoor v1";
|
||||
compatible = "cudy,ap3000outdoor-v1", "mediatek,mt7981-spim-snand-rfb";
|
||||
compatible = "cudy,ap3000outdoor-v1", "mediatek,mt7981";
|
||||
|
||||
aliases {
|
||||
label-mac-device = &wifi;
|
||||
@ -42,18 +42,19 @@
|
||||
leds {
|
||||
compatible = "gpio-leds";
|
||||
|
||||
led_status_green: led@0 {
|
||||
led_status_green: led-0 {
|
||||
function = LED_FUNCTION_STATUS;
|
||||
color = <LED_COLOR_ID_GREEN>;
|
||||
gpios = <&pio 10 GPIO_ACTIVE_HIGH>;
|
||||
};
|
||||
|
||||
led_status_red: led_1 {
|
||||
led_status_red: led-1 {
|
||||
function = LED_FUNCTION_POWER;
|
||||
color = <LED_COLOR_ID_RED>;
|
||||
gpios = <&pio 11 GPIO_ACTIVE_HIGH>;
|
||||
};
|
||||
};
|
||||
|
||||
gpio_export {
|
||||
compatible = "gpio-export";
|
||||
#size-cells = <0>;
|
||||
@ -89,7 +90,6 @@
|
||||
ð {
|
||||
pinctrl-names = "default";
|
||||
pinctrl-0 = <&mdio_pins>;
|
||||
|
||||
status = "okay";
|
||||
|
||||
gmac1: mac@1 {
|
||||
@ -148,6 +148,7 @@
|
||||
label = "Factory";
|
||||
reg = <0x180000 0x0200000>;
|
||||
read-only;
|
||||
|
||||
nvmem-layout {
|
||||
compatible = "fixed-layout";
|
||||
#address-cells = <1>;
|
||||
@ -163,6 +164,7 @@
|
||||
label = "bdinfo";
|
||||
reg = <0x380000 0x0040000>;
|
||||
read-only;
|
||||
|
||||
nvmem-layout {
|
||||
compatible = "fixed-layout";
|
||||
#address-cells = <1>;
|
||||
@ -174,25 +176,23 @@
|
||||
#nvmem-cell-cells = <1>;
|
||||
};
|
||||
};
|
||||
|
||||
};
|
||||
|
||||
partition@3C0000 {
|
||||
partition@3c0000 {
|
||||
label = "FIP";
|
||||
reg = <0x3C0000 0x0200000>;
|
||||
reg = <0x3c0000 0x0200000>;
|
||||
read-only;
|
||||
};
|
||||
|
||||
partition@580000 {
|
||||
partition@5c0000 {
|
||||
label = "ubi";
|
||||
reg = <0x5C0000 0x4000000>;
|
||||
reg = <0x5c0000 0x4000000>;
|
||||
compatible = "linux,ubi";
|
||||
};
|
||||
};
|
||||
};
|
||||
};
|
||||
|
||||
|
||||
&pio {
|
||||
spi0_flash_pins: spi0-pins {
|
||||
mux {
|
||||
|
@ -6,7 +6,7 @@
|
||||
|
||||
/ {
|
||||
model = "Cudy M3000 v1";
|
||||
compatible = "cudy,m3000-v1", "mediatek,mt7981-spim-snand-rfb";
|
||||
compatible = "cudy,m3000-v1", "mediatek,mt7981";
|
||||
|
||||
aliases {
|
||||
label-mac-device = &gmac0;
|
||||
@ -77,7 +77,6 @@
|
||||
ð {
|
||||
pinctrl-names = "default";
|
||||
pinctrl-0 = <&mdio_pins>;
|
||||
|
||||
status = "okay";
|
||||
|
||||
gmac0: mac@0 {
|
||||
@ -105,19 +104,17 @@
|
||||
rtl8221b_phy: ethernet-phy@1 {
|
||||
compatible = "ethernet-phy-ieee802.3-c45";
|
||||
reg = <1>;
|
||||
|
||||
reset-gpios = <&pio 39 GPIO_ACTIVE_LOW>;
|
||||
|
||||
interrupts = <38 IRQ_TYPE_LEVEL_LOW>;
|
||||
reset-assert-us = <100000>;
|
||||
reset-deassert-us = <100000>;
|
||||
reset-gpios = <&pio 39 GPIO_ACTIVE_LOW>;
|
||||
interrupts = <38 IRQ_TYPE_LEVEL_LOW>;
|
||||
interrupt-parent = <&pio>;
|
||||
};
|
||||
};
|
||||
|
||||
&spi0 {
|
||||
pinctrl-names = "default";
|
||||
pinctrl-0 = <&spi0_flash_pins>;
|
||||
|
||||
status = "okay";
|
||||
|
||||
spi_nand: spi_nand@0 {
|
||||
@ -127,18 +124,18 @@
|
||||
reg = <0>;
|
||||
|
||||
spi-max-frequency = <52000000>;
|
||||
spi-tx-buswidth = <4>;
|
||||
spi-rx-buswidth = <4>;
|
||||
spi-tx-bus-width = <4>;
|
||||
spi-rx-bus-width = <4>;
|
||||
|
||||
mediatek,nmbm;
|
||||
mediatek,bmt-max-ratio = <1>;
|
||||
mediatek,bmt-max-reserved-blocks = <64>;
|
||||
|
||||
partitions {
|
||||
compatible = "fixed-partitions";
|
||||
#address-cells = <1>;
|
||||
#size-cells = <1>;
|
||||
|
||||
mediatek,nmbm;
|
||||
mediatek,bmt-max-ratio = <1>;
|
||||
mediatek,bmt-max-reserved-blocks = <64>;
|
||||
|
||||
partition@0 {
|
||||
label = "BL2";
|
||||
reg = <0x0000000 0x0100000>;
|
||||
@ -177,6 +174,7 @@
|
||||
partition@3c0000 {
|
||||
label = "FIP";
|
||||
reg = <0x03c0000 0x0200000>;
|
||||
read-only;
|
||||
};
|
||||
|
||||
partition@5c0000 {
|
||||
|
@ -1,16 +1,18 @@
|
||||
// SPDX-License-Identifier: (GPL-2.0 OR MIT)
|
||||
|
||||
/dts-v1/;
|
||||
|
||||
#include <dt-bindings/leds/common.h>
|
||||
|
||||
#include "mt7981.dtsi"
|
||||
|
||||
/ {
|
||||
aliases {
|
||||
label-mac-device = &gmac1;
|
||||
led-boot = &led_status;
|
||||
led-failsafe = &led_status;
|
||||
led-running = &led_status;
|
||||
led-upgrade = &led_status;
|
||||
led-boot = &led_sys_red;
|
||||
led-failsafe = &led_sys_red;
|
||||
led-running = &led_sys_white;
|
||||
led-upgrade = &led_sys_white;
|
||||
serial0 = &uart0;
|
||||
};
|
||||
|
||||
@ -29,8 +31,8 @@
|
||||
|
||||
mode {
|
||||
label = "mode";
|
||||
linux,input-type = <EV_SW>;
|
||||
linux,code = <BTN_0>;
|
||||
linux,input-type = <EV_SW>;
|
||||
gpios = <&pio 0 GPIO_ACTIVE_LOW>;
|
||||
debounce-interval = <60>;
|
||||
};
|
||||
@ -39,36 +41,40 @@
|
||||
leds {
|
||||
compatible = "gpio-leds";
|
||||
|
||||
led_status: led_0 {
|
||||
led_sys_red: led-0 {
|
||||
function = LED_FUNCTION_POWER;
|
||||
color = <LED_COLOR_ID_RED>;
|
||||
gpios = <&pio 11 GPIO_ACTIVE_LOW>;
|
||||
};
|
||||
|
||||
led_1 {
|
||||
led_sys_white: led-1 {
|
||||
function = LED_FUNCTION_STATUS;
|
||||
color = <LED_COLOR_ID_WHITE>;
|
||||
gpios = <&pio 10 GPIO_ACTIVE_LOW>;
|
||||
};
|
||||
|
||||
};
|
||||
|
||||
usb_vbus: regulator-usb {
|
||||
compatible = "regulator-fixed";
|
||||
|
||||
regulator-name = "usb-vbus";
|
||||
regulator-min-microvolt = <5000000>;
|
||||
regulator-max-microvolt = <5000000>;
|
||||
|
||||
gpios = <&pio 9 GPIO_ACTIVE_LOW>;
|
||||
regulator-boot-on;
|
||||
};
|
||||
};
|
||||
|
||||
&uart0 {
|
||||
status = "okay";
|
||||
};
|
||||
|
||||
&watchdog {
|
||||
status = "okay";
|
||||
};
|
||||
|
||||
ð {
|
||||
pinctrl-names = "default";
|
||||
pinctrl-0 = <&mdio_pins>;
|
||||
|
||||
status = "okay";
|
||||
|
||||
gmac0: mac@0 {
|
||||
@ -92,26 +98,17 @@
|
||||
|
||||
&mdio_bus {
|
||||
phy1: phy@1 {
|
||||
reg = <1>;
|
||||
compatible = "ethernet-phy-ieee802.3-c45";
|
||||
phy-mode = "2500base-x";
|
||||
reset-gpios = <&pio 39 GPIO_ACTIVE_LOW>;
|
||||
interrupts = <38 IRQ_TYPE_LEVEL_LOW>;
|
||||
reg = <1>;
|
||||
reset-assert-us = <100000>;
|
||||
reset-deassert-us = <100000>;
|
||||
reset-gpios = <&pio 39 GPIO_ACTIVE_LOW>;
|
||||
interrupts = <38 IRQ_TYPE_LEVEL_LOW>;
|
||||
interrupt-parent = <&pio>;
|
||||
realtek,aldps-enable;
|
||||
};
|
||||
};
|
||||
|
||||
&pio {
|
||||
spi0_flash_pins: spi0-pins {
|
||||
mux {
|
||||
function = "spi";
|
||||
groups = "spi0", "spi0_wp_hold";
|
||||
};
|
||||
};
|
||||
};
|
||||
|
||||
&spi0 {
|
||||
pinctrl-names = "default";
|
||||
pinctrl-0 = <&spi0_flash_pins>;
|
||||
@ -122,6 +119,7 @@
|
||||
#size-cells = <1>;
|
||||
compatible = "spi-nand";
|
||||
reg = <0>;
|
||||
|
||||
spi-max-frequency = <52000000>;
|
||||
spi-tx-bus-width = <4>;
|
||||
spi-rx-bus-width = <4>;
|
||||
@ -147,6 +145,7 @@
|
||||
label = "Factory";
|
||||
reg = <0x180000 0x0200000>;
|
||||
read-only;
|
||||
|
||||
nvmem-layout {
|
||||
compatible = "fixed-layout";
|
||||
#address-cells = <1>;
|
||||
@ -162,6 +161,7 @@
|
||||
label = "bdinfo";
|
||||
reg = <0x380000 0x0040000>;
|
||||
read-only;
|
||||
|
||||
nvmem-layout {
|
||||
compatible = "fixed-layout";
|
||||
#address-cells = <1>;
|
||||
@ -173,7 +173,6 @@
|
||||
#nvmem-cell-cells = <1>;
|
||||
};
|
||||
};
|
||||
|
||||
};
|
||||
|
||||
partition@3c0000 {
|
||||
@ -190,16 +189,22 @@
|
||||
};
|
||||
};
|
||||
|
||||
&uart0 {
|
||||
status = "okay";
|
||||
&pio {
|
||||
spi0_flash_pins: spi0-pins {
|
||||
mux {
|
||||
function = "spi";
|
||||
groups = "spi0", "spi0_wp_hold";
|
||||
};
|
||||
};
|
||||
};
|
||||
|
||||
&usb_phy {
|
||||
status = "okay";
|
||||
};
|
||||
|
||||
&watchdog {
|
||||
&xhci {
|
||||
status = "okay";
|
||||
vbus-supply = <&usb_vbus>;
|
||||
};
|
||||
|
||||
&wifi {
|
||||
@ -207,8 +212,3 @@
|
||||
nvmem-cells = <&eeprom_factory_0>;
|
||||
nvmem-cell-names = "eeprom";
|
||||
};
|
||||
|
||||
&xhci {
|
||||
status = "okay";
|
||||
vbus-supply = <&usb_vbus>;
|
||||
};
|
||||
|
@ -8,7 +8,7 @@
|
||||
|
||||
/ {
|
||||
model = "Cudy WR3000H v1";
|
||||
compatible = "cudy,wr3000h-v1", "mediatek,mt7981-spim-snand-rfb";
|
||||
compatible = "cudy,wr3000h-v1", "mediatek,mt7981";
|
||||
|
||||
aliases {
|
||||
label-mac-device = &gmac0;
|
||||
@ -39,82 +39,70 @@
|
||||
};
|
||||
};
|
||||
|
||||
gpio-export {
|
||||
compatible = "gpio-export";
|
||||
#size-cells = <0>;
|
||||
|
||||
phyreset {
|
||||
gpio-export,name = "phyreset";
|
||||
gpio-export,output = <1>;
|
||||
gpios = <&pio 3 GPIO_ACTIVE_LOW>;
|
||||
};
|
||||
};
|
||||
|
||||
leds {
|
||||
compatible = "gpio-leds";
|
||||
|
||||
led_status: led@0 {
|
||||
led_status: led-status {
|
||||
function = LED_FUNCTION_STATUS;
|
||||
color = <LED_COLOR_ID_WHITE>;
|
||||
gpios = <&pio 5 GPIO_ACTIVE_LOW>;
|
||||
};
|
||||
|
||||
|
||||
led_internet {
|
||||
led-internet {
|
||||
function = LED_FUNCTION_WAN_ONLINE;
|
||||
color = <LED_COLOR_ID_WHITE>;
|
||||
gpios = <&pio 11 GPIO_ACTIVE_LOW>;
|
||||
};
|
||||
|
||||
led_wps {
|
||||
led-wps {
|
||||
function = LED_FUNCTION_WPS;
|
||||
color = <LED_COLOR_ID_WHITE>;
|
||||
gpios = <&pio 9 GPIO_ACTIVE_LOW>;
|
||||
};
|
||||
|
||||
led_wlan2g {
|
||||
led-wlan2g {
|
||||
function = LED_FUNCTION_WLAN_2GHZ;
|
||||
color = <LED_COLOR_ID_WHITE>;
|
||||
gpios = <&pio 6 GPIO_ACTIVE_LOW>;
|
||||
linux,default-trigger = "phy0tpt";
|
||||
};
|
||||
|
||||
led_wlan5g {
|
||||
led-wlan5g {
|
||||
function = LED_FUNCTION_WLAN_5GHZ;
|
||||
color = <LED_COLOR_ID_WHITE>;
|
||||
gpios = <&pio 7 GPIO_ACTIVE_LOW>;
|
||||
linux,default-trigger = "phy1tpt";
|
||||
};
|
||||
|
||||
led_lan1 {
|
||||
led-lan1 {
|
||||
function = LED_FUNCTION_LAN;
|
||||
function-enumerator = <1>;
|
||||
color = <LED_COLOR_ID_WHITE>;
|
||||
gpios = <&pio 8 GPIO_ACTIVE_LOW>;
|
||||
};
|
||||
|
||||
led_lan2 {
|
||||
led-lan2 {
|
||||
function = LED_FUNCTION_LAN;
|
||||
function-enumerator = <2>;
|
||||
color = <LED_COLOR_ID_WHITE>;
|
||||
gpios = <&pio 10 GPIO_ACTIVE_LOW>;
|
||||
};
|
||||
|
||||
led_lan3 {
|
||||
led-lan3 {
|
||||
function = LED_FUNCTION_LAN;
|
||||
function-enumerator = <3>;
|
||||
color = <LED_COLOR_ID_WHITE>;
|
||||
gpios = <&pio 12 GPIO_ACTIVE_LOW>;
|
||||
};
|
||||
|
||||
led_lan4 {
|
||||
led-lan4 {
|
||||
function = LED_FUNCTION_LAN;
|
||||
function-enumerator = <4>;
|
||||
color = <LED_COLOR_ID_WHITE>;
|
||||
gpios = <&pio 13 GPIO_ACTIVE_LOW>;
|
||||
};
|
||||
|
||||
led_wan {
|
||||
led-wan {
|
||||
function = LED_FUNCTION_WAN;
|
||||
color = <LED_COLOR_ID_WHITE>;
|
||||
gpios = <&pio 35 GPIO_ACTIVE_LOW>;
|
||||
@ -133,7 +121,6 @@
|
||||
ð {
|
||||
pinctrl-names = "default";
|
||||
pinctrl-0 = <&mdio_pins>;
|
||||
|
||||
status = "okay";
|
||||
|
||||
gmac0: mac@0 {
|
||||
@ -142,7 +129,6 @@
|
||||
phy-mode = "2500base-x";
|
||||
nvmem-cell-names = "mac-address";
|
||||
nvmem-cells = <&macaddr_bdinfo_de00 0>;
|
||||
label = "lan";
|
||||
|
||||
fixed-link {
|
||||
speed = <2500>;
|
||||
@ -160,7 +146,6 @@
|
||||
nvmem-cells = <&macaddr_bdinfo_de00 1>;
|
||||
label = "wan";
|
||||
};
|
||||
|
||||
};
|
||||
|
||||
&mdio_bus {
|
||||
@ -173,12 +158,14 @@
|
||||
interrupt-parent = <&pio>;
|
||||
interrupts = <38 IRQ_TYPE_LEVEL_HIGH>;
|
||||
};
|
||||
phy6: ethernet-phy@6 {
|
||||
compatible = "ethernet-phy-ieee802.3-c22"; // [RTL8221B-VB-CG 2.5Gbps PHY (C22)]
|
||||
reg = <6>;
|
||||
phy-mode = "2500base-x";
|
||||
};
|
||||
|
||||
phy6: ethernet-phy@6 {
|
||||
compatible = "ethernet-phy-ieee802.3-c22";
|
||||
reg = <6>;
|
||||
reset-assert-us = <100000>;
|
||||
reset-deassert-us = <100000>;
|
||||
reset-gpios = <&pio 3 GPIO_ACTIVE_LOW>;
|
||||
};
|
||||
};
|
||||
|
||||
&spi0 {
|
||||
@ -227,6 +214,7 @@
|
||||
label = "Factory";
|
||||
reg = <0x180000 0x0200000>;
|
||||
read-only;
|
||||
|
||||
nvmem-layout {
|
||||
compatible = "fixed-layout";
|
||||
#address-cells = <1>;
|
||||
@ -242,6 +230,7 @@
|
||||
label = "bdinfo";
|
||||
reg = <0x380000 0x0040000>;
|
||||
read-only;
|
||||
|
||||
nvmem-layout {
|
||||
compatible = "fixed-layout";
|
||||
#address-cells = <1>;
|
||||
@ -255,15 +244,15 @@
|
||||
};
|
||||
};
|
||||
|
||||
partition@3C0000 {
|
||||
partition@3c0000 {
|
||||
label = "FIP";
|
||||
reg = <0x3C0000 0x0200000>;
|
||||
reg = <0x3c0000 0x0200000>;
|
||||
read-only;
|
||||
};
|
||||
|
||||
partition@580000 {
|
||||
partition@5c0000 {
|
||||
label = "ubi";
|
||||
reg = <0x5C0000 0x4000000>;
|
||||
reg = <0x5c0000 0x4000000>;
|
||||
compatible = "linux,ubi";
|
||||
};
|
||||
};
|
||||
|
@ -8,7 +8,7 @@
|
||||
|
||||
/ {
|
||||
model = "Cudy WR3000S v1";
|
||||
compatible = "cudy,wr3000s-v1", "mediatek,mt7981-spim-snand-rfb";
|
||||
compatible = "cudy,wr3000s-v1", "mediatek,mt7981";
|
||||
|
||||
aliases {
|
||||
label-mac-device = &gmac0;
|
||||
@ -42,33 +42,32 @@
|
||||
leds {
|
||||
compatible = "gpio-leds";
|
||||
|
||||
led_status: led@0 {
|
||||
led_status: led-status {
|
||||
function = LED_FUNCTION_STATUS;
|
||||
color = <LED_COLOR_ID_WHITE>;
|
||||
gpios = <&pio 10 GPIO_ACTIVE_LOW>;
|
||||
};
|
||||
|
||||
|
||||
led_internet {
|
||||
led-internet {
|
||||
function = LED_FUNCTION_WAN_ONLINE;
|
||||
color = <LED_COLOR_ID_WHITE>;
|
||||
gpios = <&pio 11 GPIO_ACTIVE_LOW>;
|
||||
};
|
||||
|
||||
led_wps {
|
||||
led-wps {
|
||||
function = LED_FUNCTION_WPS;
|
||||
color = <LED_COLOR_ID_WHITE>;
|
||||
gpios = <&pio 9 GPIO_ACTIVE_LOW>;
|
||||
};
|
||||
|
||||
led_wlan2g {
|
||||
led-wlan2g {
|
||||
function = LED_FUNCTION_WLAN_2GHZ;
|
||||
color = <LED_COLOR_ID_WHITE>;
|
||||
gpios = <&pio 6 GPIO_ACTIVE_LOW>;
|
||||
linux,default-trigger = "phy0tpt";
|
||||
};
|
||||
|
||||
led_wlan5g {
|
||||
led-wlan5g {
|
||||
function = LED_FUNCTION_WLAN_5GHZ;
|
||||
color = <LED_COLOR_ID_WHITE>;
|
||||
gpios = <&pio 7 GPIO_ACTIVE_LOW>;
|
||||
@ -88,7 +87,6 @@
|
||||
ð {
|
||||
pinctrl-names = "default";
|
||||
pinctrl-0 = <&mdio_pins>;
|
||||
|
||||
status = "okay";
|
||||
|
||||
gmac0: mac@0 {
|
||||
@ -165,6 +163,7 @@
|
||||
label = "Factory";
|
||||
reg = <0x180000 0x0200000>;
|
||||
read-only;
|
||||
|
||||
nvmem-layout {
|
||||
compatible = "fixed-layout";
|
||||
#address-cells = <1>;
|
||||
@ -180,6 +179,7 @@
|
||||
label = "bdinfo";
|
||||
reg = <0x380000 0x0040000>;
|
||||
read-only;
|
||||
|
||||
nvmem-layout {
|
||||
compatible = "fixed-layout";
|
||||
#address-cells = <1>;
|
||||
@ -193,15 +193,15 @@
|
||||
};
|
||||
};
|
||||
|
||||
partition@3C0000 {
|
||||
partition@3c0000 {
|
||||
label = "FIP";
|
||||
reg = <0x3C0000 0x0200000>;
|
||||
reg = <0x3c0000 0x0200000>;
|
||||
read-only;
|
||||
};
|
||||
|
||||
partition@580000 {
|
||||
partition@5c0000 {
|
||||
label = "ubi";
|
||||
reg = <0x5C0000 0x4000000>;
|
||||
reg = <0x5c0000 0x4000000>;
|
||||
compatible = "linux,ubi";
|
||||
};
|
||||
};
|
||||
|
@ -83,6 +83,11 @@
|
||||
interrupt-parent = <&pio>;
|
||||
interrupts = <38 IRQ_TYPE_LEVEL_HIGH>;
|
||||
};
|
||||
|
||||
mfd: mfd@1 {
|
||||
compatible = "airoha,an8855-mfd";
|
||||
reg = <1>;
|
||||
};
|
||||
};
|
||||
|
||||
&switch {
|
||||
@ -124,6 +129,181 @@
|
||||
};
|
||||
};
|
||||
|
||||
&mfd {
|
||||
efuse {
|
||||
compatible = "airoha,an8855-efuse";
|
||||
#nvmem-cell-cells = <0>;
|
||||
|
||||
nvmem-layout {
|
||||
compatible = "fixed-layout";
|
||||
#address-cells = <1>;
|
||||
#size-cells = <1>;
|
||||
|
||||
shift_sel_port0_tx_a: shift-sel-port0-tx-a@c {
|
||||
reg = <0xc 0x4>;
|
||||
};
|
||||
|
||||
shift_sel_port0_tx_b: shift-sel-port0-tx-b@10 {
|
||||
reg = <0x10 0x4>;
|
||||
};
|
||||
|
||||
shift_sel_port0_tx_c: shift-sel-port0-tx-c@14 {
|
||||
reg = <0x14 0x4>;
|
||||
};
|
||||
|
||||
shift_sel_port0_tx_d: shift-sel-port0-tx-d@18 {
|
||||
reg = <0x18 0x4>;
|
||||
};
|
||||
|
||||
shift_sel_port1_tx_a: shift-sel-port1-tx-a@1c {
|
||||
reg = <0x1c 0x4>;
|
||||
};
|
||||
|
||||
shift_sel_port1_tx_b: shift-sel-port1-tx-b@20 {
|
||||
reg = <0x20 0x4>;
|
||||
};
|
||||
|
||||
shift_sel_port1_tx_c: shift-sel-port1-tx-c@24 {
|
||||
reg = <0x24 0x4>;
|
||||
};
|
||||
|
||||
shift_sel_port1_tx_d: shift-sel-port1-tx-d@28 {
|
||||
reg = <0x28 0x4>;
|
||||
};
|
||||
|
||||
shift_sel_port2_tx_a: shift-sel-port2-tx-a@2c {
|
||||
reg = <0x2c 0x4>;
|
||||
};
|
||||
|
||||
shift_sel_port2_tx_b: shift-sel-port2-tx-b@30 {
|
||||
reg = <0x30 0x4>;
|
||||
};
|
||||
|
||||
shift_sel_port2_tx_c: shift-sel-port2-tx-c@34 {
|
||||
reg = <0x34 0x4>;
|
||||
};
|
||||
|
||||
shift_sel_port2_tx_d: shift-sel-port2-tx-d@38 {
|
||||
reg = <0x38 0x4>;
|
||||
};
|
||||
|
||||
shift_sel_port3_tx_a: shift-sel-port3-tx-a@4c {
|
||||
reg = <0x4c 0x4>;
|
||||
};
|
||||
|
||||
shift_sel_port3_tx_b: shift-sel-port3-tx-b@50 {
|
||||
reg = <0x50 0x4>;
|
||||
};
|
||||
|
||||
shift_sel_port3_tx_c: shift-sel-port3-tx-c@54 {
|
||||
reg = <0x54 0x4>;
|
||||
};
|
||||
|
||||
shift_sel_port3_tx_d: shift-sel-port3-tx-d@58 {
|
||||
reg = <0x58 0x4>;
|
||||
};
|
||||
};
|
||||
};
|
||||
|
||||
ethernet-switch {
|
||||
compatible = "airoha,an8855-switch";
|
||||
reset-gpios = <&pio 39 GPIO_ACTIVE_HIGH>;
|
||||
airoha,ext-surge;
|
||||
|
||||
ports {
|
||||
#address-cells = <1>;
|
||||
#size-cells = <0>;
|
||||
|
||||
port@0 {
|
||||
reg = <0>;
|
||||
label = "wan";
|
||||
phy-mode = "internal";
|
||||
phy-handle = <&internal_phy1>;
|
||||
};
|
||||
|
||||
port@1 {
|
||||
reg = <1>;
|
||||
label = "lan2";
|
||||
phy-mode = "internal";
|
||||
phy-handle = <&internal_phy2>;
|
||||
};
|
||||
|
||||
port@2 {
|
||||
reg = <2>;
|
||||
label = "lan3";
|
||||
phy-mode = "internal";
|
||||
phy-handle = <&internal_phy3>;
|
||||
};
|
||||
|
||||
port@3 {
|
||||
reg = <3>;
|
||||
label = "lan4";
|
||||
phy-mode = "internal";
|
||||
phy-handle = <&internal_phy4>;
|
||||
};
|
||||
|
||||
port@5 {
|
||||
reg = <5>;
|
||||
label = "cpu";
|
||||
ethernet = <&gmac0>;
|
||||
phy-mode = "2500base-x";
|
||||
|
||||
fixed-link {
|
||||
speed = <2500>;
|
||||
full-duplex;
|
||||
pause;
|
||||
};
|
||||
};
|
||||
};
|
||||
};
|
||||
|
||||
mdio {
|
||||
compatible = "airoha,an8855-mdio";
|
||||
#address-cells = <1>;
|
||||
#size-cells = <0>;
|
||||
|
||||
internal_phy1: phy@1 {
|
||||
reg = <1>;
|
||||
|
||||
nvmem-cells = <&shift_sel_port0_tx_a>,
|
||||
<&shift_sel_port0_tx_b>,
|
||||
<&shift_sel_port0_tx_c>,
|
||||
<&shift_sel_port0_tx_d>;
|
||||
nvmem-cell-names = "tx_a", "tx_b", "tx_c", "tx_d";
|
||||
};
|
||||
|
||||
internal_phy2: phy@2 {
|
||||
reg = <2>;
|
||||
|
||||
nvmem-cells = <&shift_sel_port1_tx_a>,
|
||||
<&shift_sel_port1_tx_b>,
|
||||
<&shift_sel_port1_tx_c>,
|
||||
<&shift_sel_port1_tx_d>;
|
||||
nvmem-cell-names = "tx_a", "tx_b", "tx_c", "tx_d";
|
||||
};
|
||||
|
||||
internal_phy3: phy@3 {
|
||||
reg = <3>;
|
||||
|
||||
nvmem-cells = <&shift_sel_port2_tx_a>,
|
||||
<&shift_sel_port2_tx_b>,
|
||||
<&shift_sel_port2_tx_c>,
|
||||
<&shift_sel_port2_tx_d>;
|
||||
nvmem-cell-names = "tx_a", "tx_b", "tx_c", "tx_d";
|
||||
};
|
||||
|
||||
internal_phy4: phy@4 {
|
||||
reg = <4>;
|
||||
|
||||
nvmem-cells = <&shift_sel_port3_tx_a>,
|
||||
<&shift_sel_port3_tx_b>,
|
||||
<&shift_sel_port3_tx_c>,
|
||||
<&shift_sel_port3_tx_d>;
|
||||
nvmem-cell-names = "tx_a", "tx_b", "tx_c", "tx_d";
|
||||
};
|
||||
};
|
||||
};
|
||||
|
||||
&spi0 {
|
||||
pinctrl-names = "default";
|
||||
pinctrl-0 = <&spi0_flash_pins>;
|
||||
|
278
target/linux/mediatek/files-6.6/drivers/mfd/airoha-an8855.c
Normal file
278
target/linux/mediatek/files-6.6/drivers/mfd/airoha-an8855.c
Normal file
@ -0,0 +1,278 @@
|
||||
// SPDX-License-Identifier: GPL-2.0+
|
||||
/*
|
||||
* MFD driver for Airoha AN8855 Switch
|
||||
*/
|
||||
|
||||
#include <linux/mfd/airoha-an8855-mfd.h>
|
||||
#include <linux/mfd/core.h>
|
||||
#include <linux/mdio.h>
|
||||
#include <linux/module.h>
|
||||
#include <linux/phy.h>
|
||||
#include <linux/regmap.h>
|
||||
|
||||
static const struct mfd_cell an8855_mfd_devs[] = {
|
||||
{
|
||||
.name = "an8855-efuse",
|
||||
.of_compatible = "airoha,an8855-efuse",
|
||||
}, {
|
||||
.name = "an8855-switch",
|
||||
.of_compatible = "airoha,an8855-switch",
|
||||
}, {
|
||||
.name = "an8855-mdio",
|
||||
.of_compatible = "airoha,an8855-mdio",
|
||||
}
|
||||
};
|
||||
|
||||
int an8855_mii_set_page(struct an8855_mfd_priv *priv, u8 phy_id,
|
||||
u8 page) __must_hold(&priv->bus->mdio_lock)
|
||||
{
|
||||
struct mii_bus *bus = priv->bus;
|
||||
int ret;
|
||||
|
||||
ret = __mdiobus_write(bus, phy_id, AN8855_PHY_SELECT_PAGE, page);
|
||||
if (ret < 0)
|
||||
dev_err_ratelimited(&bus->dev,
|
||||
"failed to set an8855 mii page\n");
|
||||
|
||||
/* Cache current page if next mii read/write is for switch */
|
||||
priv->current_page = page;
|
||||
return ret < 0 ? ret : 0;
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(an8855_mii_set_page);
|
||||
|
||||
static int an8855_mii_read32(struct mii_bus *bus, u8 phy_id, u32 reg,
|
||||
u32 *val) __must_hold(&bus->mdio_lock)
|
||||
{
|
||||
int lo, hi, ret;
|
||||
|
||||
ret = __mdiobus_write(bus, phy_id, AN8855_PBUS_MODE,
|
||||
AN8855_PBUS_MODE_ADDR_FIXED);
|
||||
if (ret < 0)
|
||||
goto err;
|
||||
|
||||
ret = __mdiobus_write(bus, phy_id, AN8855_PBUS_RD_ADDR_HIGH,
|
||||
upper_16_bits(reg));
|
||||
if (ret < 0)
|
||||
goto err;
|
||||
ret = __mdiobus_write(bus, phy_id, AN8855_PBUS_RD_ADDR_LOW,
|
||||
lower_16_bits(reg));
|
||||
if (ret < 0)
|
||||
goto err;
|
||||
|
||||
hi = __mdiobus_read(bus, phy_id, AN8855_PBUS_RD_DATA_HIGH);
|
||||
if (hi < 0) {
|
||||
ret = hi;
|
||||
goto err;
|
||||
}
|
||||
lo = __mdiobus_read(bus, phy_id, AN8855_PBUS_RD_DATA_LOW);
|
||||
if (lo < 0) {
|
||||
ret = lo;
|
||||
goto err;
|
||||
}
|
||||
|
||||
*val = ((u16)hi << 16) | ((u16)lo & 0xffff);
|
||||
|
||||
return 0;
|
||||
err:
|
||||
dev_err_ratelimited(&bus->dev,
|
||||
"failed to read an8855 register\n");
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int an8855_regmap_read(void *ctx, uint32_t reg, uint32_t *val)
|
||||
{
|
||||
struct an8855_mfd_priv *priv = ctx;
|
||||
struct mii_bus *bus = priv->bus;
|
||||
u16 addr = priv->switch_addr;
|
||||
int ret;
|
||||
|
||||
mutex_lock_nested(&bus->mdio_lock, MDIO_MUTEX_NESTED);
|
||||
ret = an8855_mii_set_page(priv, addr, AN8855_PHY_PAGE_EXTENDED_4);
|
||||
if (ret < 0)
|
||||
goto exit;
|
||||
|
||||
ret = an8855_mii_read32(bus, addr, reg, val);
|
||||
|
||||
exit:
|
||||
mutex_unlock(&bus->mdio_lock);
|
||||
|
||||
return ret < 0 ? ret : 0;
|
||||
}
|
||||
|
||||
static int an8855_mii_write32(struct mii_bus *bus, u8 phy_id, u32 reg,
|
||||
u32 val) __must_hold(&bus->mdio_lock)
|
||||
{
|
||||
int ret;
|
||||
|
||||
ret = __mdiobus_write(bus, phy_id, AN8855_PBUS_MODE,
|
||||
AN8855_PBUS_MODE_ADDR_FIXED);
|
||||
if (ret < 0)
|
||||
goto err;
|
||||
|
||||
ret = __mdiobus_write(bus, phy_id, AN8855_PBUS_WR_ADDR_HIGH,
|
||||
upper_16_bits(reg));
|
||||
if (ret < 0)
|
||||
goto err;
|
||||
ret = __mdiobus_write(bus, phy_id, AN8855_PBUS_WR_ADDR_LOW,
|
||||
lower_16_bits(reg));
|
||||
if (ret < 0)
|
||||
goto err;
|
||||
|
||||
ret = __mdiobus_write(bus, phy_id, AN8855_PBUS_WR_DATA_HIGH,
|
||||
upper_16_bits(val));
|
||||
if (ret < 0)
|
||||
goto err;
|
||||
ret = __mdiobus_write(bus, phy_id, AN8855_PBUS_WR_DATA_LOW,
|
||||
lower_16_bits(val));
|
||||
if (ret < 0)
|
||||
goto err;
|
||||
|
||||
return 0;
|
||||
err:
|
||||
dev_err_ratelimited(&bus->dev,
|
||||
"failed to write an8855 register\n");
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int
|
||||
an8855_regmap_write(void *ctx, uint32_t reg, uint32_t val)
|
||||
{
|
||||
struct an8855_mfd_priv *priv = ctx;
|
||||
struct mii_bus *bus = priv->bus;
|
||||
u16 addr = priv->switch_addr;
|
||||
int ret;
|
||||
|
||||
mutex_lock_nested(&bus->mdio_lock, MDIO_MUTEX_NESTED);
|
||||
ret = an8855_mii_set_page(priv, addr, AN8855_PHY_PAGE_EXTENDED_4);
|
||||
if (ret < 0)
|
||||
goto exit;
|
||||
|
||||
ret = an8855_mii_write32(bus, addr, reg, val);
|
||||
|
||||
exit:
|
||||
mutex_unlock(&bus->mdio_lock);
|
||||
|
||||
return ret < 0 ? ret : 0;
|
||||
}
|
||||
|
||||
static int an8855_regmap_update_bits(void *ctx, uint32_t reg, uint32_t mask,
|
||||
uint32_t write_val)
|
||||
{
|
||||
struct an8855_mfd_priv *priv = ctx;
|
||||
struct mii_bus *bus = priv->bus;
|
||||
u16 addr = priv->switch_addr;
|
||||
u32 val;
|
||||
int ret;
|
||||
|
||||
mutex_lock_nested(&bus->mdio_lock, MDIO_MUTEX_NESTED);
|
||||
ret = an8855_mii_set_page(priv, addr, AN8855_PHY_PAGE_EXTENDED_4);
|
||||
if (ret < 0)
|
||||
goto exit;
|
||||
|
||||
ret = an8855_mii_read32(bus, addr, reg, &val);
|
||||
if (ret < 0)
|
||||
goto exit;
|
||||
|
||||
val &= ~mask;
|
||||
val |= write_val;
|
||||
ret = an8855_mii_write32(bus, addr, reg, val);
|
||||
|
||||
exit:
|
||||
mutex_unlock(&bus->mdio_lock);
|
||||
|
||||
return ret < 0 ? ret : 0;
|
||||
}
|
||||
|
||||
static const struct regmap_range an8855_readable_ranges[] = {
|
||||
regmap_reg_range(0x10000000, 0x10000fff), /* SCU */
|
||||
regmap_reg_range(0x10001000, 0x10001fff), /* RBUS */
|
||||
regmap_reg_range(0x10002000, 0x10002fff), /* MCU */
|
||||
regmap_reg_range(0x10005000, 0x10005fff), /* SYS SCU */
|
||||
regmap_reg_range(0x10007000, 0x10007fff), /* I2C Slave */
|
||||
regmap_reg_range(0x10008000, 0x10008fff), /* I2C Master */
|
||||
regmap_reg_range(0x10009000, 0x10009fff), /* PDMA */
|
||||
regmap_reg_range(0x1000a100, 0x1000a2ff), /* General Purpose Timer */
|
||||
regmap_reg_range(0x1000a200, 0x1000a2ff), /* GPU timer */
|
||||
regmap_reg_range(0x1000a300, 0x1000a3ff), /* GPIO */
|
||||
regmap_reg_range(0x1000a400, 0x1000a5ff), /* EFUSE */
|
||||
regmap_reg_range(0x1000c000, 0x1000cfff), /* GDMP CSR */
|
||||
regmap_reg_range(0x10010000, 0x1001ffff), /* GDMP SRAM */
|
||||
regmap_reg_range(0x10200000, 0x10203fff), /* Switch - ARL Global */
|
||||
regmap_reg_range(0x10204000, 0x10207fff), /* Switch - BMU */
|
||||
regmap_reg_range(0x10208000, 0x1020bfff), /* Switch - ARL Port */
|
||||
regmap_reg_range(0x1020c000, 0x1020cfff), /* Switch - SCH */
|
||||
regmap_reg_range(0x10210000, 0x10213fff), /* Switch - MAC */
|
||||
regmap_reg_range(0x10214000, 0x10217fff), /* Switch - MIB */
|
||||
regmap_reg_range(0x10218000, 0x1021bfff), /* Switch - Port Control */
|
||||
regmap_reg_range(0x1021c000, 0x1021ffff), /* Switch - TOP */
|
||||
regmap_reg_range(0x10220000, 0x1022ffff), /* SerDes */
|
||||
regmap_reg_range(0x10286000, 0x10286fff), /* RG Batcher */
|
||||
regmap_reg_range(0x1028c000, 0x1028ffff), /* ETHER_SYS */
|
||||
regmap_reg_range(0x30000000, 0x37ffffff), /* I2C EEPROM */
|
||||
regmap_reg_range(0x38000000, 0x3fffffff), /* BOOT_ROM */
|
||||
regmap_reg_range(0xa0000000, 0xbfffffff), /* GPHY */
|
||||
};
|
||||
|
||||
static const struct regmap_access_table an8855_readable_table = {
|
||||
.yes_ranges = an8855_readable_ranges,
|
||||
.n_yes_ranges = ARRAY_SIZE(an8855_readable_ranges),
|
||||
};
|
||||
|
||||
static const struct regmap_config an8855_regmap_config = {
|
||||
.reg_bits = 32,
|
||||
.val_bits = 32,
|
||||
.reg_stride = 4,
|
||||
.max_register = 0xbfffffff,
|
||||
.reg_read = an8855_regmap_read,
|
||||
.reg_write = an8855_regmap_write,
|
||||
.reg_update_bits = an8855_regmap_update_bits,
|
||||
.disable_locking = true,
|
||||
.rd_table = &an8855_readable_table,
|
||||
};
|
||||
|
||||
static int an8855_mfd_probe(struct mdio_device *mdiodev)
|
||||
{
|
||||
struct an8855_mfd_priv *priv;
|
||||
struct regmap *regmap;
|
||||
|
||||
priv = devm_kzalloc(&mdiodev->dev, sizeof(*priv), GFP_KERNEL);
|
||||
if (!priv)
|
||||
return -ENOMEM;
|
||||
|
||||
priv->bus = mdiodev->bus;
|
||||
priv->dev = &mdiodev->dev;
|
||||
priv->switch_addr = mdiodev->addr;
|
||||
/* no DMA for mdiobus, mute warning for DMA mask not set */
|
||||
priv->dev->dma_mask = &priv->dev->coherent_dma_mask;
|
||||
|
||||
regmap = devm_regmap_init(priv->dev, NULL, priv,
|
||||
&an8855_regmap_config);
|
||||
if (IS_ERR(regmap))
|
||||
dev_err_probe(priv->dev, PTR_ERR(priv->dev),
|
||||
"regmap initialization failed\n");
|
||||
|
||||
dev_set_drvdata(&mdiodev->dev, priv);
|
||||
|
||||
return devm_mfd_add_devices(priv->dev, PLATFORM_DEVID_AUTO, an8855_mfd_devs,
|
||||
ARRAY_SIZE(an8855_mfd_devs), NULL, 0,
|
||||
NULL);
|
||||
}
|
||||
|
||||
static const struct of_device_id an8855_mfd_of_match[] = {
|
||||
{ .compatible = "airoha,an8855-mfd" },
|
||||
{ /* sentinel */ }
|
||||
};
|
||||
MODULE_DEVICE_TABLE(of, an8855_mfd_of_match);
|
||||
|
||||
static struct mdio_driver an8855_mfd_driver = {
|
||||
.probe = an8855_mfd_probe,
|
||||
.mdiodrv.driver = {
|
||||
.name = "an8855",
|
||||
.of_match_table = an8855_mfd_of_match,
|
||||
},
|
||||
};
|
||||
mdio_module_driver(an8855_mfd_driver);
|
||||
|
||||
MODULE_AUTHOR("Christian Marangi <ansuelsmth@gmail.com>");
|
||||
MODULE_DESCRIPTION("Driver for Airoha AN8855 MFD");
|
||||
MODULE_LICENSE("GPL");
|
2311
target/linux/mediatek/files-6.6/drivers/net/dsa/an8855.c
Normal file
2311
target/linux/mediatek/files-6.6/drivers/net/dsa/an8855.c
Normal file
File diff suppressed because it is too large
Load Diff
783
target/linux/mediatek/files-6.6/drivers/net/dsa/an8855.h
Normal file
783
target/linux/mediatek/files-6.6/drivers/net/dsa/an8855.h
Normal file
@ -0,0 +1,783 @@
|
||||
/* SPDX-License-Identifier: GPL-2.0-only */
|
||||
/*
|
||||
* Copyright (C) 2023 Min Yao <min.yao@airoha.com>
|
||||
* Copyright (C) 2024 Christian Marangi <ansuelsmth@gmail.com>
|
||||
*/
|
||||
|
||||
#ifndef __AN8855_H
|
||||
#define __AN8855_H
|
||||
|
||||
#include <linux/bitfield.h>
|
||||
|
||||
#define AN8855_NUM_PORTS 6
|
||||
#define AN8855_CPU_PORT 5
|
||||
#define AN8855_NUM_FDB_RECORDS 2048
|
||||
#define AN8855_GPHY_SMI_ADDR_DEFAULT 1
|
||||
#define AN8855_PORT_VID_DEFAULT 0
|
||||
|
||||
#define MTK_TAG_LEN 4
|
||||
#define AN8855_MAX_MTU (15360 - ETH_HLEN - ETH_FCS_LEN - MTK_TAG_LEN)
|
||||
|
||||
#define AN8855_L2_AGING_MS_CONSTANT 1024
|
||||
|
||||
#define AN8855_PHY_FLAGS_EN_CALIBRATION BIT(0)
|
||||
|
||||
/* AN8855_SCU 0x10000000 */
|
||||
#define AN8855_RG_GPIO_LED_MODE 0x10000054
|
||||
#define AN8855_RG_GPIO_LED_SEL(i) (0x10000000 + (0x0058 + ((i) * 4)))
|
||||
#define AN8855_RG_INTB_MODE 0x10000080
|
||||
#define AN8855_RG_RGMII_TXCK_C 0x100001d0
|
||||
|
||||
#define AN8855_PKG_SEL 0x10000094
|
||||
#define AN8855_PAG_SEL_AN8855H 0x2
|
||||
|
||||
/* Register for hw trap status */
|
||||
#define AN8855_HWTRAP 0x1000009c
|
||||
|
||||
#define AN8855_RG_GPIO_L_INV 0x10000010
|
||||
#define AN8855_RG_GPIO_CTRL 0x1000a300
|
||||
#define AN8855_RG_GPIO_DATA 0x1000a304
|
||||
#define AN8855_RG_GPIO_OE 0x1000a314
|
||||
|
||||
#define AN8855_CREV 0x10005000
|
||||
#define AN8855_ID 0x8855
|
||||
|
||||
/* Register for system reset */
|
||||
#define AN8855_RST_CTRL 0x100050c0
|
||||
#define AN8855_SYS_CTRL_SYS_RST BIT(31)
|
||||
|
||||
#define AN8855_INT_MASK 0x100050f0
|
||||
#define AN8855_INT_SYS BIT(15)
|
||||
|
||||
#define AN8855_RG_CLK_CPU_ICG 0x10005034
|
||||
#define AN8855_MCU_ENABLE BIT(3)
|
||||
|
||||
#define AN8855_RG_TIMER_CTL 0x1000a100
|
||||
#define AN8855_WDOG_ENABLE BIT(25)
|
||||
|
||||
#define AN8855_RG_GDMP_RAM 0x10010000
|
||||
|
||||
/* Registers to mac forward control for unknown frames */
|
||||
#define AN8855_MFC 0x10200010
|
||||
#define AN8855_CPU_EN BIT(15)
|
||||
#define AN8855_CPU_PORT_IDX GENMASK(12, 8)
|
||||
|
||||
#define AN8855_PAC 0x10200024
|
||||
#define AN8855_TAG_PAE_MANG_FR BIT(30)
|
||||
#define AN8855_TAG_PAE_BPDU_FR BIT(28)
|
||||
#define AN8855_TAG_PAE_EG_TAG GENMASK(27, 25)
|
||||
#define AN8855_TAG_PAE_LKY_VLAN BIT(24)
|
||||
#define AN8855_TAG_PAE_PRI_HIGH BIT(23)
|
||||
#define AN8855_TAG_PAE_MIR GENMASK(20, 19)
|
||||
#define AN8855_TAG_PAE_PORT_FW GENMASK(18, 16)
|
||||
#define AN8855_PAE_MANG_FR BIT(14)
|
||||
#define AN8855_PAE_BPDU_FR BIT(12)
|
||||
#define AN8855_PAE_EG_TAG GENMASK(11, 9)
|
||||
#define AN8855_PAE_LKY_VLAN BIT(8)
|
||||
#define AN8855_PAE_PRI_HIGH BIT(7)
|
||||
#define AN8855_PAE_MIR GENMASK(4, 3)
|
||||
#define AN8855_PAE_PORT_FW GENMASK(2, 0)
|
||||
|
||||
#define AN8855_RGAC1 0x10200028
|
||||
#define AN8855_R02_MANG_FR BIT(30)
|
||||
#define AN8855_R02_BPDU_FR BIT(28)
|
||||
#define AN8855_R02_EG_TAG GENMASK(27, 25)
|
||||
#define AN8855_R02_LKY_VLAN BIT(24)
|
||||
#define AN8855_R02_PRI_HIGH BIT(23)
|
||||
#define AN8855_R02_MIR GENMASK(20, 19)
|
||||
#define AN8855_R02_PORT_FW GENMASK(18, 16)
|
||||
#define AN8855_R01_MANG_FR BIT(14)
|
||||
#define AN8855_R01_BPDU_FR BIT(12)
|
||||
#define AN8855_R01_EG_TAG GENMASK(11, 9)
|
||||
#define AN8855_R01_LKY_VLAN BIT(8)
|
||||
#define AN8855_R01_PRI_HIGH BIT(7)
|
||||
#define AN8855_R01_MIR GENMASK(4, 3)
|
||||
#define AN8855_R01_PORT_FW GENMASK(2, 0)
|
||||
|
||||
#define AN8855_RGAC2 0x1020002c
|
||||
#define AN8855_R0E_MANG_FR BIT(30)
|
||||
#define AN8855_R0E_BPDU_FR BIT(28)
|
||||
#define AN8855_R0E_EG_TAG GENMASK(27, 25)
|
||||
#define AN8855_R0E_LKY_VLAN BIT(24)
|
||||
#define AN8855_R0E_PRI_HIGH BIT(23)
|
||||
#define AN8855_R0E_MIR GENMASK(20, 19)
|
||||
#define AN8855_R0E_PORT_FW GENMASK(18, 16)
|
||||
#define AN8855_R03_MANG_FR BIT(14)
|
||||
#define AN8855_R03_BPDU_FR BIT(12)
|
||||
#define AN8855_R03_EG_TAG GENMASK(11, 9)
|
||||
#define AN8855_R03_LKY_VLAN BIT(8)
|
||||
#define AN8855_R03_PRI_HIGH BIT(7)
|
||||
#define AN8855_R03_MIR GENMASK(4, 3)
|
||||
#define AN8855_R03_PORT_FW GENMASK(2, 0)
|
||||
|
||||
#define AN8855_AAC 0x102000a0
|
||||
#define AN8855_MAC_AUTO_FLUSH BIT(28)
|
||||
/* Control Address Table Age time.
|
||||
* (AN8855_AGE_CNT + 1) * ( AN8855_AGE_UNIT + 1 ) * AN8855_L2_AGING_MS_CONSTANT
|
||||
*/
|
||||
#define AN8855_AGE_CNT GENMASK(20, 12)
|
||||
/* Value in seconds. Value is always incremented of 1 */
|
||||
#define AN8855_AGE_UNIT GENMASK(10, 0)
|
||||
|
||||
/* Registers for ARL Unknown Unicast Forward control */
|
||||
#define AN8855_UNUF 0x102000b4
|
||||
|
||||
/* Registers for ARL Unknown Multicast Forward control */
|
||||
#define AN8855_UNMF 0x102000b8
|
||||
|
||||
/* Registers for ARL Broadcast forward control */
|
||||
#define AN8855_BCF 0x102000bc
|
||||
|
||||
/* Registers for port address age disable */
|
||||
#define AN8855_AGDIS 0x102000c0
|
||||
|
||||
/* Registers for mirror port control */
|
||||
#define AN8855_MIR 0x102000cc
|
||||
#define AN8855_MIRROR_EN BIT(7)
|
||||
#define AN8855_MIRROR_PORT GENMASK(4, 0)
|
||||
|
||||
/* Registers for BPDU and PAE frame control*/
|
||||
#define AN8855_BPC 0x102000d0
|
||||
#define AN8855_BPDU_MANG_FR BIT(14)
|
||||
#define AN8855_BPDU_BPDU_FR BIT(12)
|
||||
#define AN8855_BPDU_EG_TAG GENMASK(11, 9)
|
||||
#define AN8855_BPDU_LKY_VLAN BIT(8)
|
||||
#define AN8855_BPDU_PRI_HIGH BIT(7)
|
||||
#define AN8855_BPDU_MIR GENMASK(4, 3)
|
||||
#define AN8855_BPDU_PORT_FW GENMASK(2, 0)
|
||||
|
||||
/* Registers for IP Unknown Multicast Forward control */
|
||||
#define AN8855_UNIPMF 0x102000dc
|
||||
|
||||
enum an8855_bpdu_port_fw {
|
||||
AN8855_BPDU_FOLLOW_MFC = 0,
|
||||
AN8855_BPDU_CPU_EXCLUDE = 4,
|
||||
AN8855_BPDU_CPU_INCLUDE = 5,
|
||||
AN8855_BPDU_CPU_ONLY = 6,
|
||||
AN8855_BPDU_DROP = 7,
|
||||
};
|
||||
|
||||
/* Register for address table control */
|
||||
#define AN8855_ATC 0x10200300
|
||||
#define AN8855_ATC_BUSY BIT(31)
|
||||
#define AN8855_ATC_HASH GENMASK(24, 16)
|
||||
#define AN8855_ATC_HIT GENMASK(15, 12)
|
||||
#define AN8855_ATC_MAT_MASK GENMASK(11, 7)
|
||||
#define AN8855_ATC_MAT(x) FIELD_PREP(AN8855_ATC_MAT_MASK, x)
|
||||
#define AN8855_ATC_SAT GENMASK(5, 4)
|
||||
#define AN8855_ATC_CMD GENMASK(2, 0)
|
||||
|
||||
enum an8855_fdb_mat_cmds {
|
||||
AND8855_FDB_MAT_ALL = 0,
|
||||
AND8855_FDB_MAT_MAC, /* All MAC address */
|
||||
AND8855_FDB_MAT_DYNAMIC_MAC, /* All Dynamic MAC address */
|
||||
AND8855_FDB_MAT_STATIC_MAC, /* All Static Mac Address */
|
||||
AND8855_FDB_MAT_DIP, /* All DIP/GA address */
|
||||
AND8855_FDB_MAT_DIP_IPV4, /* All DIP/GA IPv4 address */
|
||||
AND8855_FDB_MAT_DIP_IPV6, /* All DIP/GA IPv6 address */
|
||||
AND8855_FDB_MAT_DIP_SIP, /* All DIP_SIP address */
|
||||
AND8855_FDB_MAT_DIP_SIP_IPV4, /* All DIP_SIP IPv4 address */
|
||||
AND8855_FDB_MAT_DIP_SIP_IPV6, /* All DIP_SIP IPv6 address */
|
||||
AND8855_FDB_MAT_MAC_CVID, /* All MAC address with CVID */
|
||||
AND8855_FDB_MAT_MAC_FID, /* All MAC address with Filter ID */
|
||||
AND8855_FDB_MAT_MAC_PORT, /* All MAC address with port */
|
||||
AND8855_FDB_MAT_DIP_SIP_DIP_IPV4, /* All DIP_SIP address with DIP_IPV4 */
|
||||
AND8855_FDB_MAT_DIP_SIP_SIP_IPV4, /* All DIP_SIP address with SIP_IPV4 */
|
||||
AND8855_FDB_MAT_DIP_SIP_DIP_IPV6, /* All DIP_SIP address with DIP_IPV6 */
|
||||
AND8855_FDB_MAT_DIP_SIP_SIP_IPV6, /* All DIP_SIP address with SIP_IPV6 */
|
||||
/* All MAC address with MAC type (dynamic or static) with CVID */
|
||||
AND8855_FDB_MAT_MAC_TYPE_CVID,
|
||||
/* All MAC address with MAC type (dynamic or static) with Filter ID */
|
||||
AND8855_FDB_MAT_MAC_TYPE_FID,
|
||||
/* All MAC address with MAC type (dynamic or static) with port */
|
||||
AND8855_FDB_MAT_MAC_TYPE_PORT,
|
||||
};
|
||||
|
||||
enum an8855_fdb_cmds {
|
||||
AN8855_FDB_READ = 0,
|
||||
AN8855_FDB_WRITE = 1,
|
||||
AN8855_FDB_FLUSH = 2,
|
||||
AN8855_FDB_START = 4,
|
||||
AN8855_FDB_NEXT = 5,
|
||||
};
|
||||
|
||||
/* Registers for address table access */
|
||||
#define AN8855_ATA1 0x10200304
|
||||
#define AN8855_ATA1_MAC0 GENMASK(31, 24)
|
||||
#define AN8855_ATA1_MAC1 GENMASK(23, 16)
|
||||
#define AN8855_ATA1_MAC2 GENMASK(15, 8)
|
||||
#define AN8855_ATA1_MAC3 GENMASK(7, 0)
|
||||
#define AN8855_ATA2 0x10200308
|
||||
#define AN8855_ATA2_MAC4 GENMASK(31, 24)
|
||||
#define AN8855_ATA2_MAC5 GENMASK(23, 16)
|
||||
#define AN8855_ATA2_UNAUTH BIT(10)
|
||||
#define AN8855_ATA2_TYPE BIT(9) /* 1: dynamic, 0: static */
|
||||
#define AN8855_ATA2_AGE GENMASK(8, 0)
|
||||
|
||||
/* Register for address table write data */
|
||||
#define AN8855_ATWD 0x10200324
|
||||
#define AN8855_ATWD_FID GENMASK(31, 28)
|
||||
#define AN8855_ATWD_VID GENMASK(27, 16)
|
||||
#define AN8855_ATWD_IVL BIT(15)
|
||||
#define AN8855_ATWD_EG_TAG GENMASK(14, 12)
|
||||
#define AN8855_ATWD_SA_MIR GENMASK(9, 8)
|
||||
#define AN8855_ATWD_SA_FWD GENMASK(7, 5)
|
||||
#define AN8855_ATWD_UPRI GENMASK(4, 2)
|
||||
#define AN8855_ATWD_LEAKY BIT(1)
|
||||
#define AN8855_ATWD_VLD BIT(0) /* vid LOAD */
|
||||
#define AN8855_ATWD2 0x10200328
|
||||
#define AN8855_ATWD2_PORT GENMASK(7, 0)
|
||||
|
||||
/* Registers for table search read address */
|
||||
#define AN8855_ATRDS 0x10200330
|
||||
#define AN8855_ATRD_SEL GENMASK(1, 0)
|
||||
#define AN8855_ATRD0 0x10200334
|
||||
#define AN8855_ATRD0_FID GENMASK(28, 25)
|
||||
#define AN8855_ATRD0_VID GENMASK(21, 10)
|
||||
#define AN8855_ATRD0_IVL BIT(9)
|
||||
#define AN8855_ATRD0_TYPE GENMASK(4, 3)
|
||||
#define AN8855_ATRD0_ARP GENMASK(2, 1)
|
||||
#define AN8855_ATRD0_LIVE BIT(0)
|
||||
#define AN8855_ATRD1 0x10200338
|
||||
#define AN8855_ATRD1_MAC4 GENMASK(31, 24)
|
||||
#define AN8855_ATRD1_MAC5 GENMASK(23, 16)
|
||||
#define AN8855_ATRD1_AGING GENMASK(11, 3)
|
||||
#define AN8855_ATRD2 0x1020033c
|
||||
#define AN8855_ATRD2_MAC0 GENMASK(31, 24)
|
||||
#define AN8855_ATRD2_MAC1 GENMASK(23, 16)
|
||||
#define AN8855_ATRD2_MAC2 GENMASK(15, 8)
|
||||
#define AN8855_ATRD2_MAC3 GENMASK(7, 0)
|
||||
#define AN8855_ATRD3 0x10200340
|
||||
#define AN8855_ATRD3_PORTMASK GENMASK(7, 0)
|
||||
|
||||
enum an8855_fdb_type {
|
||||
AN8855_MAC_TB_TY_MAC = 0,
|
||||
AN8855_MAC_TB_TY_DIP = 1,
|
||||
AN8855_MAC_TB_TY_DIP_SIP = 2,
|
||||
};
|
||||
|
||||
/* Register for vlan table control */
|
||||
#define AN8855_VTCR 0x10200600
|
||||
#define AN8855_VTCR_BUSY BIT(31)
|
||||
#define AN8855_VTCR_FUNC GENMASK(15, 12)
|
||||
#define AN8855_VTCR_VID GENMASK(11, 0)
|
||||
|
||||
enum an8855_vlan_cmd {
|
||||
/* Read/Write the specified VID entry from VAWD register based
|
||||
* on VID.
|
||||
*/
|
||||
AN8855_VTCR_RD_VID = 0,
|
||||
AN8855_VTCR_WR_VID = 1,
|
||||
};
|
||||
|
||||
/* Register for setup vlan write data */
|
||||
#define AN8855_VAWD0 0x10200604
|
||||
/* VLAN Member Control */
|
||||
#define AN8855_VA0_PORT GENMASK(31, 26)
|
||||
/* Egress Tag Control */
|
||||
#define AN8855_VA0_ETAG GENMASK(23, 12)
|
||||
#define AN8855_VA0_ETAG_PORT GENMASK(13, 12)
|
||||
#define AN8855_VA0_ETAG_PORT_SHIFT(port) ((port) * 2)
|
||||
#define AN8855_VA0_ETAG_PORT_MASK(port) (AN8855_VA0_ETAG_PORT << \
|
||||
AN8855_VA0_ETAG_PORT_SHIFT(port))
|
||||
#define AN8855_VA0_ETAG_PORT_VAL(port, val) (FIELD_PREP(AN8855_VA0_ETAG_PORT, (val)) << \
|
||||
AN8855_VA0_ETAG_PORT_SHIFT(port))
|
||||
#define AN8855_VA0_EG_CON BIT(11)
|
||||
#define AN8855_VA0_VTAG_EN BIT(10) /* Per VLAN Egress Tag Control */
|
||||
#define AN8855_VA0_IVL_MAC BIT(5) /* Independent VLAN Learning */
|
||||
#define AN8855_VA0_FID GENMASK(4, 1)
|
||||
#define AN8855_VA0_VLAN_VALID BIT(0) /* VLAN Entry Valid */
|
||||
#define AN8855_VAWD1 0x10200608
|
||||
#define AN8855_VA1_PORT_STAG BIT(1)
|
||||
|
||||
enum an8855_fid {
|
||||
AN8855_FID_STANDALONE = 0,
|
||||
AN8855_FID_BRIDGED = 1,
|
||||
};
|
||||
|
||||
/* Same register field of VAWD0 */
|
||||
#define AN8855_VARD0 0x10200618
|
||||
|
||||
enum an8855_vlan_egress_attr {
|
||||
AN8855_VLAN_EGRESS_UNTAG = 0,
|
||||
AN8855_VLAN_EGRESS_TAG = 2,
|
||||
AN8855_VLAN_EGRESS_STACK = 3,
|
||||
};
|
||||
|
||||
/* Register for port STP state control */
|
||||
#define AN8855_SSP_P(x) (0x10208000 + ((x) * 0x200))
|
||||
/* Up to 16 FID supported, each with the same mask */
|
||||
#define AN8855_FID_PST GENMASK(1, 0)
|
||||
#define AN8855_FID_PST_SHIFT(fid) (2 * (fid))
|
||||
#define AN8855_FID_PST_MASK(fid) (AN8855_FID_PST << \
|
||||
AN8855_FID_PST_SHIFT(fid))
|
||||
#define AN8855_FID_PST_VAL(fid, val) (FIELD_PREP(AN8855_FID_PST, (val)) << \
|
||||
AN8855_FID_PST_SHIFT(fid))
|
||||
|
||||
enum an8855_stp_state {
|
||||
AN8855_STP_DISABLED = 0,
|
||||
AN8855_STP_BLOCKING = 1,
|
||||
AN8855_STP_LISTENING = AN8855_STP_BLOCKING,
|
||||
AN8855_STP_LEARNING = 2,
|
||||
AN8855_STP_FORWARDING = 3
|
||||
};
|
||||
|
||||
/* Register for port control */
|
||||
#define AN8855_PCR_P(x) (0x10208004 + ((x) * 0x200))
|
||||
#define AN8855_EG_TAG GENMASK(29, 28)
|
||||
#define AN8855_PORT_PRI GENMASK(26, 24)
|
||||
#define AN8855_PORT_TX_MIR BIT(20)
|
||||
#define AN8855_PORT_RX_MIR BIT(16)
|
||||
#define AN8855_PORT_VLAN GENMASK(1, 0)
|
||||
|
||||
enum an8855_port_mode {
|
||||
/* Port Matrix Mode: Frames are forwarded by the PCR_MATRIX members. */
|
||||
AN8855_PORT_MATRIX_MODE = 0,
|
||||
|
||||
/* Fallback Mode: Forward received frames with ingress ports that do
|
||||
* not belong to the VLAN member. Frames whose VID is not listed on
|
||||
* the VLAN table are forwarded by the PCR_MATRIX members.
|
||||
*/
|
||||
AN8855_PORT_FALLBACK_MODE = 1,
|
||||
|
||||
/* Check Mode: Forward received frames whose ingress do not
|
||||
* belong to the VLAN member. Discard frames if VID ismiddes on the
|
||||
* VLAN table.
|
||||
*/
|
||||
AN8855_PORT_CHECK_MODE = 2,
|
||||
|
||||
/* Security Mode: Discard any frame due to ingress membership
|
||||
* violation or VID missed on the VLAN table.
|
||||
*/
|
||||
AN8855_PORT_SECURITY_MODE = 3,
|
||||
};
|
||||
|
||||
/* Register for port security control */
|
||||
#define AN8855_PSC_P(x) (0x1020800c + ((x) * 0x200))
|
||||
#define AN8855_SA_DIS BIT(4)
|
||||
|
||||
/* Register for port vlan control */
|
||||
#define AN8855_PVC_P(x) (0x10208010 + ((x) * 0x200))
|
||||
#define AN8855_PORT_SPEC_REPLACE_MODE BIT(11)
|
||||
#define AN8855_PVC_EG_TAG GENMASK(10, 8)
|
||||
#define AN8855_VLAN_ATTR GENMASK(7, 6)
|
||||
#define AN8855_PORT_SPEC_TAG BIT(5)
|
||||
#define AN8855_ACC_FRM GENMASK(1, 0)
|
||||
|
||||
enum an8855_vlan_port_eg_tag {
|
||||
AN8855_VLAN_EG_DISABLED = 0,
|
||||
AN8855_VLAN_EG_CONSISTENT = 1,
|
||||
AN8855_VLAN_EG_UNTAGGED = 4,
|
||||
AN8855_VLAN_EG_SWAP = 5,
|
||||
AN8855_VLAN_EG_TAGGED = 6,
|
||||
AN8855_VLAN_EG_STACK = 7,
|
||||
};
|
||||
|
||||
enum an8855_vlan_port_attr {
|
||||
AN8855_VLAN_USER = 0,
|
||||
AN8855_VLAN_STACK = 1,
|
||||
AN8855_VLAN_TRANSPARENT = 3,
|
||||
};
|
||||
|
||||
enum an8855_vlan_port_acc_frm {
|
||||
AN8855_VLAN_ACC_ALL = 0,
|
||||
AN8855_VLAN_ACC_TAGGED = 1,
|
||||
AN8855_VLAN_ACC_UNTAGGED = 2,
|
||||
};
|
||||
|
||||
#define AN8855_PPBV1_P(x) (0x10208014 + ((x) * 0x200))
|
||||
#define AN8855_PPBV_G0_PORT_VID GENMASK(11, 0)
|
||||
|
||||
#define AN8855_PORTMATRIX_P(x) (0x10208044 + ((x) * 0x200))
|
||||
#define AN8855_PORTMATRIX GENMASK(5, 0)
|
||||
/* Port matrix without the CPU port that should never be removed */
|
||||
#define AN8855_USER_PORTMATRIX GENMASK(4, 0)
|
||||
|
||||
/* Register for port PVID */
|
||||
#define AN8855_PVID_P(x) (0x10208048 + ((x) * 0x200))
|
||||
#define AN8855_G0_PORT_VID GENMASK(11, 0)
|
||||
|
||||
/* Register for port MAC control register */
|
||||
#define AN8855_PMCR_P(x) (0x10210000 + ((x) * 0x200))
|
||||
#define AN8855_PMCR_FORCE_MODE BIT(31)
|
||||
#define AN8855_PMCR_FORCE_SPEED GENMASK(30, 28)
|
||||
#define AN8855_PMCR_FORCE_SPEED_5000 FIELD_PREP_CONST(AN8855_PMCR_FORCE_SPEED, 0x4)
|
||||
#define AN8855_PMCR_FORCE_SPEED_2500 FIELD_PREP_CONST(AN8855_PMCR_FORCE_SPEED, 0x3)
|
||||
#define AN8855_PMCR_FORCE_SPEED_1000 FIELD_PREP_CONST(AN8855_PMCR_FORCE_SPEED, 0x2)
|
||||
#define AN8855_PMCR_FORCE_SPEED_100 FIELD_PREP_CONST(AN8855_PMCR_FORCE_SPEED, 0x1)
|
||||
#define AN8855_PMCR_FORCE_SPEED_10 FIELD_PREP_CONST(AN8855_PMCR_FORCE_SPEED, 0x1)
|
||||
#define AN8855_PMCR_FORCE_FDX BIT(25)
|
||||
#define AN8855_PMCR_FORCE_LNK BIT(24)
|
||||
#define AN8855_PMCR_IFG_XMIT GENMASK(21, 20)
|
||||
#define AN8855_PMCR_EXT_PHY BIT(19)
|
||||
#define AN8855_PMCR_MAC_MODE BIT(18)
|
||||
#define AN8855_PMCR_TX_EN BIT(16)
|
||||
#define AN8855_PMCR_RX_EN BIT(15)
|
||||
#define AN8855_PMCR_BACKOFF_EN BIT(12)
|
||||
#define AN8855_PMCR_BACKPR_EN BIT(11)
|
||||
#define AN8855_PMCR_FORCE_EEE5G BIT(9)
|
||||
#define AN8855_PMCR_FORCE_EEE2P5G BIT(8)
|
||||
#define AN8855_PMCR_FORCE_EEE1G BIT(7)
|
||||
#define AN8855_PMCR_FORCE_EEE100 BIT(6)
|
||||
#define AN8855_PMCR_TX_FC_EN BIT(5)
|
||||
#define AN8855_PMCR_RX_FC_EN BIT(4)
|
||||
|
||||
#define AN8855_PMSR_P(x) (0x10210010 + (x) * 0x200)
|
||||
#define AN8855_PMSR_SPEED GENMASK(30, 28)
|
||||
#define AN8855_PMSR_SPEED_5000 FIELD_PREP_CONST(AN8855_PMSR_SPEED, 0x4)
|
||||
#define AN8855_PMSR_SPEED_2500 FIELD_PREP_CONST(AN8855_PMSR_SPEED, 0x3)
|
||||
#define AN8855_PMSR_SPEED_1000 FIELD_PREP_CONST(AN8855_PMSR_SPEED, 0x2)
|
||||
#define AN8855_PMSR_SPEED_100 FIELD_PREP_CONST(AN8855_PMSR_SPEED, 0x1)
|
||||
#define AN8855_PMSR_SPEED_10 FIELD_PREP_CONST(AN8855_PMSR_SPEED, 0x0)
|
||||
#define AN8855_PMSR_DPX BIT(25)
|
||||
#define AN8855_PMSR_LNK BIT(24)
|
||||
#define AN8855_PMSR_EEE1G BIT(7)
|
||||
#define AN8855_PMSR_EEE100M BIT(6)
|
||||
#define AN8855_PMSR_RX_FC BIT(5)
|
||||
#define AN8855_PMSR_TX_FC BIT(4)
|
||||
|
||||
#define AN8855_PMEEECR_P(x) (0x10210004 + (x) * 0x200)
|
||||
#define AN8855_LPI_MODE_EN BIT(31)
|
||||
#define AN8855_WAKEUP_TIME_2500 GENMASK(23, 16)
|
||||
#define AN8855_WAKEUP_TIME_1000 GENMASK(15, 8)
|
||||
#define AN8855_WAKEUP_TIME_100 GENMASK(7, 0)
|
||||
#define AN8855_PMEEECR2_P(x) (0x10210008 + (x) * 0x200)
|
||||
#define AN8855_WAKEUP_TIME_5000 GENMASK(7, 0)
|
||||
|
||||
#define AN8855_GMACCR 0x10213e00
|
||||
#define AN8855_MAX_RX_JUMBO GENMASK(7, 4)
|
||||
/* 2K for 0x0, 0x1, 0x2 */
|
||||
#define AN8855_MAX_RX_JUMBO_2K FIELD_PREP_CONST(AN8855_MAX_RX_JUMBO, 0x0)
|
||||
#define AN8855_MAX_RX_JUMBO_3K FIELD_PREP_CONST(AN8855_MAX_RX_JUMBO, 0x3)
|
||||
#define AN8855_MAX_RX_JUMBO_4K FIELD_PREP_CONST(AN8855_MAX_RX_JUMBO, 0x4)
|
||||
#define AN8855_MAX_RX_JUMBO_5K FIELD_PREP_CONST(AN8855_MAX_RX_JUMBO, 0x5)
|
||||
#define AN8855_MAX_RX_JUMBO_6K FIELD_PREP_CONST(AN8855_MAX_RX_JUMBO, 0x6)
|
||||
#define AN8855_MAX_RX_JUMBO_7K FIELD_PREP_CONST(AN8855_MAX_RX_JUMBO, 0x7)
|
||||
#define AN8855_MAX_RX_JUMBO_8K FIELD_PREP_CONST(AN8855_MAX_RX_JUMBO, 0x8)
|
||||
#define AN8855_MAX_RX_JUMBO_9K FIELD_PREP_CONST(AN8855_MAX_RX_JUMBO, 0x9)
|
||||
#define AN8855_MAX_RX_JUMBO_12K FIELD_PREP_CONST(AN8855_MAX_RX_JUMBO, 0xa)
|
||||
#define AN8855_MAX_RX_JUMBO_15K FIELD_PREP_CONST(AN8855_MAX_RX_JUMBO, 0xb)
|
||||
#define AN8855_MAX_RX_JUMBO_16K FIELD_PREP_CONST(AN8855_MAX_RX_JUMBO, 0xc)
|
||||
#define AN8855_MAX_RX_PKT_LEN GENMASK(1, 0)
|
||||
#define AN8855_MAX_RX_PKT_1518_1522 FIELD_PREP_CONST(AN8855_MAX_RX_PKT_LEN, 0x0)
|
||||
#define AN8855_MAX_RX_PKT_1536 FIELD_PREP_CONST(AN8855_MAX_RX_PKT_LEN, 0x1)
|
||||
#define AN8855_MAX_RX_PKT_1552 FIELD_PREP_CONST(AN8855_MAX_RX_PKT_LEN, 0x2)
|
||||
#define AN8855_MAX_RX_PKT_JUMBO FIELD_PREP_CONST(AN8855_MAX_RX_PKT_LEN, 0x3)
|
||||
|
||||
#define AN8855_CKGCR 0x10213e1c
|
||||
#define AN8855_LPI_TXIDLE_THD_MASK GENMASK(31, 14)
|
||||
#define AN8855_CKG_LNKDN_PORT_STOP BIT(1)
|
||||
#define AN8855_CKG_LNKDN_GLB_STOP BIT(0)
|
||||
|
||||
/* Register for MIB */
|
||||
#define AN8855_PORT_MIB_COUNTER(x) (0x10214000 + (x) * 0x200)
|
||||
/* Each define is an offset of AN8855_PORT_MIB_COUNTER */
|
||||
#define AN8855_PORT_MIB_TX_DROP 0x00
|
||||
#define AN8855_PORT_MIB_TX_CRC_ERR 0x04
|
||||
#define AN8855_PORT_MIB_TX_UNICAST 0x08
|
||||
#define AN8855_PORT_MIB_TX_MULTICAST 0x0c
|
||||
#define AN8855_PORT_MIB_TX_BROADCAST 0x10
|
||||
#define AN8855_PORT_MIB_TX_COLLISION 0x14
|
||||
#define AN8855_PORT_MIB_TX_SINGLE_COLLISION 0x18
|
||||
#define AN8855_PORT_MIB_TX_MULTIPLE_COLLISION 0x1c
|
||||
#define AN8855_PORT_MIB_TX_DEFERRED 0x20
|
||||
#define AN8855_PORT_MIB_TX_LATE_COLLISION 0x24
|
||||
#define AN8855_PORT_MIB_TX_EXCESSIVE_COLLISION 0x28
|
||||
#define AN8855_PORT_MIB_TX_PAUSE 0x2c
|
||||
#define AN8855_PORT_MIB_TX_PKT_SZ_64 0x30
|
||||
#define AN8855_PORT_MIB_TX_PKT_SZ_65_TO_127 0x34
|
||||
#define AN8855_PORT_MIB_TX_PKT_SZ_128_TO_255 0x38
|
||||
#define AN8855_PORT_MIB_TX_PKT_SZ_256_TO_511 0x3
|
||||
#define AN8855_PORT_MIB_TX_PKT_SZ_512_TO_1023 0x40
|
||||
#define AN8855_PORT_MIB_TX_PKT_SZ_1024_TO_1518 0x44
|
||||
#define AN8855_PORT_MIB_TX_PKT_SZ_1519_TO_MAX 0x48
|
||||
#define AN8855_PORT_MIB_TX_BYTES 0x4c /* 64 bytes */
|
||||
#define AN8855_PORT_MIB_TX_OVERSIZE_DROP 0x54
|
||||
#define AN8855_PORT_MIB_TX_BAD_PKT_BYTES 0x58 /* 64 bytes */
|
||||
#define AN8855_PORT_MIB_RX_DROP 0x80
|
||||
#define AN8855_PORT_MIB_RX_FILTERING 0x84
|
||||
#define AN8855_PORT_MIB_RX_UNICAST 0x88
|
||||
#define AN8855_PORT_MIB_RX_MULTICAST 0x8c
|
||||
#define AN8855_PORT_MIB_RX_BROADCAST 0x90
|
||||
#define AN8855_PORT_MIB_RX_ALIGN_ERR 0x94
|
||||
#define AN8855_PORT_MIB_RX_CRC_ERR 0x98
|
||||
#define AN8855_PORT_MIB_RX_UNDER_SIZE_ERR 0x9c
|
||||
#define AN8855_PORT_MIB_RX_FRAG_ERR 0xa0
|
||||
#define AN8855_PORT_MIB_RX_OVER_SZ_ERR 0xa4
|
||||
#define AN8855_PORT_MIB_RX_JABBER_ERR 0xa8
|
||||
#define AN8855_PORT_MIB_RX_PAUSE 0xac
|
||||
#define AN8855_PORT_MIB_RX_PKT_SZ_64 0xb0
|
||||
#define AN8855_PORT_MIB_RX_PKT_SZ_65_TO_127 0xb4
|
||||
#define AN8855_PORT_MIB_RX_PKT_SZ_128_TO_255 0xb8
|
||||
#define AN8855_PORT_MIB_RX_PKT_SZ_256_TO_511 0xbc
|
||||
#define AN8855_PORT_MIB_RX_PKT_SZ_512_TO_1023 0xc0
|
||||
#define AN8855_PORT_MIB_RX_PKT_SZ_1024_TO_1518 0xc4
|
||||
#define AN8855_PORT_MIB_RX_PKT_SZ_1519_TO_MAX 0xc8
|
||||
#define AN8855_PORT_MIB_RX_BYTES 0xcc /* 64 bytes */
|
||||
#define AN8855_PORT_MIB_RX_CTRL_DROP 0xd4
|
||||
#define AN8855_PORT_MIB_RX_INGRESS_DROP 0xd8
|
||||
#define AN8855_PORT_MIB_RX_ARL_DROP 0xdc
|
||||
#define AN8855_PORT_MIB_FLOW_CONTROL_DROP 0xe0
|
||||
#define AN8855_PORT_MIB_WRED_DROP 0xe4
|
||||
#define AN8855_PORT_MIB_MIRROR_DROP 0xe8
|
||||
#define AN8855_PORT_MIB_RX_BAD_PKT_BYTES 0xec /* 64 bytes */
|
||||
#define AN8855_PORT_MIB_RXS_FLOW_SAMPLING_PKT_DROP 0xf4
|
||||
#define AN8855_PORT_MIB_RXS_FLOW_TOTAL_PKT_DROP 0xf8
|
||||
#define AN8855_PORT_MIB_PORT_CONTROL_DROP 0xfc
|
||||
#define AN8855_MIB_CCR 0x10213e30
|
||||
#define AN8855_CCR_MIB_ENABLE BIT(31)
|
||||
#define AN8855_CCR_RX_OCT_CNT_GOOD BIT(7)
|
||||
#define AN8855_CCR_RX_OCT_CNT_BAD BIT(6)
|
||||
#define AN8855_CCR_TX_OCT_CNT_GOOD BIT(5)
|
||||
#define AN8855_CCR_TX_OCT_CNT_BAD BIT(4)
|
||||
#define AN8855_CCR_RX_OCT_CNT_GOOD_2 BIT(3)
|
||||
#define AN8855_CCR_RX_OCT_CNT_BAD_2 BIT(2)
|
||||
#define AN8855_CCR_TX_OCT_CNT_GOOD_2 BIT(1)
|
||||
#define AN8855_CCR_TX_OCT_CNT_BAD_2 BIT(0)
|
||||
#define AN8855_CCR_MIB_ACTIVATE (AN8855_CCR_MIB_ENABLE | \
|
||||
AN8855_CCR_RX_OCT_CNT_GOOD | \
|
||||
AN8855_CCR_RX_OCT_CNT_BAD | \
|
||||
AN8855_CCR_TX_OCT_CNT_GOOD | \
|
||||
AN8855_CCR_TX_OCT_CNT_BAD | \
|
||||
AN8855_CCR_RX_OCT_CNT_BAD_2 | \
|
||||
AN8855_CCR_TX_OCT_CNT_BAD_2)
|
||||
#define AN8855_MIB_CLR 0x10213e34
|
||||
#define AN8855_MIB_PORT6_CLR BIT(6)
|
||||
#define AN8855_MIB_PORT5_CLR BIT(5)
|
||||
#define AN8855_MIB_PORT4_CLR BIT(4)
|
||||
#define AN8855_MIB_PORT3_CLR BIT(3)
|
||||
#define AN8855_MIB_PORT2_CLR BIT(2)
|
||||
#define AN8855_MIB_PORT1_CLR BIT(1)
|
||||
#define AN8855_MIB_PORT0_CLR BIT(0)
|
||||
|
||||
/* HSGMII/SGMII Configuration register */
|
||||
/* AN8855_HSGMII_AN_CSR_BASE 0x10220000 */
|
||||
#define AN8855_SGMII_REG_AN0 0x10220000
|
||||
/* AN8855_SGMII_AN_ENABLE BMCR_ANENABLE */
|
||||
/* AN8855_SGMII_AN_RESTART BMCR_ANRESTART */
|
||||
#define AN8855_SGMII_REG_AN_13 0x10220034
|
||||
#define AN8855_SGMII_REMOTE_FAULT_DIS BIT(8)
|
||||
#define AN8855_SGMII_IF_MODE GENMASK(5, 0)
|
||||
#define AN8855_SGMII_REG_AN_FORCE_CL37 0x10220060
|
||||
#define AN8855_RG_FORCE_AN_DONE BIT(0)
|
||||
|
||||
/* AN8855_HSGMII_CSR_PCS_BASE 0x10220000 */
|
||||
#define AN8855_RG_HSGMII_PCS_CTROL_1 0x10220a00
|
||||
#define AN8855_RG_TBI_10B_MODE BIT(30)
|
||||
#define AN8855_RG_AN_SGMII_MODE_FORCE 0x10220a24
|
||||
#define AN8855_RG_FORCE_CUR_SGMII_MODE GENMASK(5, 4)
|
||||
#define AN8855_RG_FORCE_CUR_SGMII_SEL BIT(0)
|
||||
|
||||
/* AN8855_MULTI_SGMII_CSR_BASE 0x10224000 */
|
||||
#define AN8855_SGMII_STS_CTRL_0 0x10224018
|
||||
#define AN8855_RG_LINK_MODE_P0 GENMASK(5, 4)
|
||||
#define AN8855_RG_LINK_MODE_P0_SPEED_2500 FIELD_PREP_CONST(AN8855_RG_LINK_MODE_P0, 0x3)
|
||||
#define AN8855_RG_LINK_MODE_P0_SPEED_1000 FIELD_PREP_CONST(AN8855_RG_LINK_MODE_P0, 0x2)
|
||||
#define AN8855_RG_LINK_MODE_P0_SPEED_100 FIELD_PREP_CONST(AN8855_RG_LINK_MODE_P0, 0x1)
|
||||
#define AN8855_RG_LINK_MODE_P0_SPEED_10 FIELD_PREP_CONST(AN8855_RG_LINK_MODE_P0, 0x0)
|
||||
#define AN8855_RG_FORCE_SPD_MODE_P0 BIT(2)
|
||||
#define AN8855_MSG_RX_CTRL_0 0x10224100
|
||||
#define AN8855_MSG_RX_LIK_STS_0 0x10224514
|
||||
#define AN8855_RG_DPX_STS_P3 BIT(24)
|
||||
#define AN8855_RG_DPX_STS_P2 BIT(16)
|
||||
#define AN8855_RG_EEE1G_STS_P1 BIT(12)
|
||||
#define AN8855_RG_DPX_STS_P1 BIT(8)
|
||||
#define AN8855_RG_TXFC_STS_P0 BIT(2)
|
||||
#define AN8855_RG_RXFC_STS_P0 BIT(1)
|
||||
#define AN8855_RG_DPX_STS_P0 BIT(0)
|
||||
#define AN8855_MSG_RX_LIK_STS_2 0x1022451c
|
||||
#define AN8855_RG_RXFC_AN_BYPASS_P3 BIT(11)
|
||||
#define AN8855_RG_RXFC_AN_BYPASS_P2 BIT(10)
|
||||
#define AN8855_RG_RXFC_AN_BYPASS_P1 BIT(9)
|
||||
#define AN8855_RG_TXFC_AN_BYPASS_P3 BIT(7)
|
||||
#define AN8855_RG_TXFC_AN_BYPASS_P2 BIT(6)
|
||||
#define AN8855_RG_TXFC_AN_BYPASS_P1 BIT(5)
|
||||
#define AN8855_RG_DPX_AN_BYPASS_P3 BIT(3)
|
||||
#define AN8855_RG_DPX_AN_BYPASS_P2 BIT(2)
|
||||
#define AN8855_RG_DPX_AN_BYPASS_P1 BIT(1)
|
||||
#define AN8855_RG_DPX_AN_BYPASS_P0 BIT(0)
|
||||
#define AN8855_PHY_RX_FORCE_CTRL_0 0x10224520
|
||||
#define AN8855_RG_FORCE_TXC_SEL BIT(4)
|
||||
|
||||
/* AN8855_XFI_CSR_PCS_BASE 0x10225000 */
|
||||
#define AN8855_RG_USXGMII_AN_CONTROL_0 0x10225bf8
|
||||
|
||||
/* AN8855_MULTI_PHY_RA_CSR_BASE 0x10226000 */
|
||||
#define AN8855_RG_RATE_ADAPT_CTRL_0 0x10226000
|
||||
#define AN8855_RG_RATE_ADAPT_RX_BYPASS BIT(27)
|
||||
#define AN8855_RG_RATE_ADAPT_TX_BYPASS BIT(26)
|
||||
#define AN8855_RG_RATE_ADAPT_RX_EN BIT(4)
|
||||
#define AN8855_RG_RATE_ADAPT_TX_EN BIT(0)
|
||||
#define AN8855_RATE_ADP_P0_CTRL_0 0x10226100
|
||||
#define AN8855_RG_P0_DIS_MII_MODE BIT(31)
|
||||
#define AN8855_RG_P0_MII_MODE BIT(28)
|
||||
#define AN8855_RG_P0_MII_RA_RX_EN BIT(3)
|
||||
#define AN8855_RG_P0_MII_RA_TX_EN BIT(2)
|
||||
#define AN8855_RG_P0_MII_RA_RX_MODE BIT(1)
|
||||
#define AN8855_RG_P0_MII_RA_TX_MODE BIT(0)
|
||||
#define AN8855_MII_RA_AN_ENABLE 0x10226300
|
||||
#define AN8855_RG_P0_RA_AN_EN BIT(0)
|
||||
|
||||
/* AN8855_QP_DIG_CSR_BASE 0x1022a000 */
|
||||
#define AN8855_QP_CK_RST_CTRL_4 0x1022a310
|
||||
#define AN8855_QP_DIG_MODE_CTRL_0 0x1022a324
|
||||
#define AN8855_RG_SGMII_MODE GENMASK(5, 4)
|
||||
#define AN8855_RG_SGMII_AN_EN BIT(0)
|
||||
#define AN8855_QP_DIG_MODE_CTRL_1 0x1022a330
|
||||
#define AN8855_RG_TPHY_SPEED GENMASK(3, 2)
|
||||
|
||||
/* AN8855_SERDES_WRAPPER_BASE 0x1022c000 */
|
||||
#define AN8855_USGMII_CTRL_0 0x1022c000
|
||||
|
||||
/* AN8855_QP_PMA_TOP_BASE 0x1022e000 */
|
||||
#define AN8855_PON_RXFEDIG_CTRL_0 0x1022e100
|
||||
#define AN8855_RG_QP_EQ_RX500M_CK_SEL BIT(12)
|
||||
#define AN8855_PON_RXFEDIG_CTRL_9 0x1022e124
|
||||
#define AN8855_RG_QP_EQ_LEQOSC_DLYCNT GENMASK(2, 0)
|
||||
|
||||
#define AN8855_SS_LCPLL_PWCTL_SETTING_2 0x1022e208
|
||||
#define AN8855_RG_NCPO_ANA_MSB GENMASK(17, 16)
|
||||
#define AN8855_SS_LCPLL_TDC_FLT_2 0x1022e230
|
||||
#define AN8855_RG_LCPLL_NCPO_VALUE GENMASK(30, 0)
|
||||
#define AN8855_SS_LCPLL_TDC_FLT_5 0x1022e23c
|
||||
#define AN8855_RG_LCPLL_NCPO_CHG BIT(24)
|
||||
#define AN8855_SS_LCPLL_TDC_PCW_1 0x1022e248
|
||||
#define AN8855_RG_LCPLL_PON_HRDDS_PCW_NCPO_GPON GENMASK(30, 0)
|
||||
#define AN8855_INTF_CTRL_8 0x1022e320
|
||||
#define AN8855_INTF_CTRL_9 0x1022e324
|
||||
#define AN8855_INTF_CTRL_10 0x1022e328
|
||||
#define AN8855_RG_DA_QP_TX_FIR_C2_SEL BIT(29)
|
||||
#define AN8855_RG_DA_QP_TX_FIR_C2_FORCE GENMASK(28, 24)
|
||||
#define AN8855_RG_DA_QP_TX_FIR_C1_SEL BIT(21)
|
||||
#define AN8855_RG_DA_QP_TX_FIR_C1_FORCE GENMASK(20, 16)
|
||||
#define AN8855_INTF_CTRL_11 0x1022e32c
|
||||
#define AN8855_RG_DA_QP_TX_FIR_C0B_SEL BIT(6)
|
||||
#define AN8855_RG_DA_QP_TX_FIR_C0B_FORCE GENMASK(5, 0)
|
||||
#define AN8855_PLL_CTRL_0 0x1022e400
|
||||
#define AN8855_RG_PHYA_AUTO_INIT BIT(0)
|
||||
#define AN8855_PLL_CTRL_2 0x1022e408
|
||||
#define AN8855_RG_DA_QP_PLL_SDM_IFM_INTF BIT(30)
|
||||
#define AN8855_RG_DA_QP_PLL_RICO_SEL_INTF BIT(29)
|
||||
#define AN8855_RG_DA_QP_PLL_POSTDIV_EN_INTF BIT(28)
|
||||
#define AN8855_RG_DA_QP_PLL_PHY_CK_EN_INTF BIT(27)
|
||||
#define AN8855_RG_DA_QP_PLL_PFD_OFFSET_EN_INTRF BIT(26)
|
||||
#define AN8855_RG_DA_QP_PLL_PFD_OFFSET_INTF GENMASK(25, 24)
|
||||
#define AN8855_RG_DA_QP_PLL_PCK_SEL_INTF BIT(22)
|
||||
#define AN8855_RG_DA_QP_PLL_KBAND_PREDIV_INTF GENMASK(21, 20)
|
||||
#define AN8855_RG_DA_QP_PLL_IR_INTF GENMASK(19, 16)
|
||||
#define AN8855_RG_DA_QP_PLL_ICOIQ_EN_INTF BIT(14)
|
||||
#define AN8855_RG_DA_QP_PLL_FBKSEL_INTF GENMASK(13, 12)
|
||||
#define AN8855_RG_DA_QP_PLL_BR_INTF GENMASK(10, 8)
|
||||
#define AN8855_RG_DA_QP_PLL_BPD_INTF GENMASK(7, 6)
|
||||
#define AN8855_RG_DA_QP_PLL_BPA_INTF GENMASK(4, 2)
|
||||
#define AN8855_RG_DA_QP_PLL_BC_INTF GENMASK(1, 0)
|
||||
#define AN8855_PLL_CTRL_3 0x1022e40c
|
||||
#define AN8855_RG_DA_QP_PLL_SSC_PERIOD_INTF GENMASK(31, 16)
|
||||
#define AN8855_RG_DA_QP_PLL_SSC_DELTA_INTF GENMASK(15, 0)
|
||||
#define AN8855_PLL_CTRL_4 0x1022e410
|
||||
#define AN8855_RG_DA_QP_PLL_SDM_HREN_INTF GENMASK(4, 3)
|
||||
#define AN8855_RG_DA_QP_PLL_ICOLP_EN_INTF BIT(2)
|
||||
#define AN8855_RG_DA_QP_PLL_SSC_DIR_DLY_INTF GENMASK(1, 0)
|
||||
#define AN8855_PLL_CK_CTRL_0 0x1022e414
|
||||
#define AN8855_RG_DA_QP_PLL_TDC_TXCK_SEL_INTF BIT(9)
|
||||
#define AN8855_RG_DA_QP_PLL_SDM_DI_EN_INTF BIT(8)
|
||||
#define AN8855_RX_DLY_0 0x1022e614
|
||||
#define AN8855_RG_QP_RX_SAOSC_EN_H_DLY GENMASK(13, 8)
|
||||
#define AN8855_RG_QP_RX_PI_CAL_EN_H_DLY GENMASK(7, 0)
|
||||
#define AN8855_RX_CTRL_2 0x1022e630
|
||||
#define AN8855_RG_QP_RX_EQ_EN_H_DLY GENMASK(28, 16)
|
||||
#define AN8855_RX_CTRL_5 0x1022e63c
|
||||
#define AN8855_RG_FREDET_CHK_CYCLE GENMASK(29, 10)
|
||||
#define AN8855_RX_CTRL_6 0x1022e640
|
||||
#define AN8855_RG_FREDET_GOLDEN_CYCLE GENMASK(19, 0)
|
||||
#define AN8855_RX_CTRL_7 0x1022e644
|
||||
#define AN8855_RG_FREDET_TOLERATE_CYCLE GENMASK(19, 0)
|
||||
#define AN8855_RX_CTRL_8 0x1022e648
|
||||
#define AN8855_RG_DA_QP_SAOSC_DONE_TIME GENMASK(27, 16)
|
||||
#define AN8855_RG_DA_QP_LEQOS_EN_TIME GENMASK(14, 0)
|
||||
#define AN8855_RX_CTRL_26 0x1022e690
|
||||
#define AN8855_RG_QP_EQ_RETRAIN_ONLY_EN BIT(26)
|
||||
#define AN8855_RG_LINK_NE_EN BIT(24)
|
||||
#define AN8855_RG_LINK_ERRO_EN BIT(23)
|
||||
#define AN8855_RX_CTRL_42 0x1022e6d0
|
||||
#define AN8855_RG_QP_EQ_EN_DLY GENMASK(12, 0)
|
||||
|
||||
/* AN8855_QP_ANA_CSR_BASE 0x1022f000 */
|
||||
#define AN8855_RG_QP_RX_DAC_EN 0x1022f000
|
||||
#define AN8855_RG_QP_SIGDET_HF GENMASK(17, 16)
|
||||
#define AN8855_RG_QP_RXAFE_RESERVE 0x1022f004
|
||||
#define AN8855_RG_QP_CDR_PD_10B_EN BIT(11)
|
||||
#define AN8855_RG_QP_CDR_LPF_BOT_LIM 0x1022f008
|
||||
#define AN8855_RG_QP_CDR_LPF_KP_GAIN GENMASK(26, 24)
|
||||
#define AN8855_RG_QP_CDR_LPF_KI_GAIN GENMASK(22, 20)
|
||||
#define AN8855_RG_QP_CDR_LPF_MJV_LIM 0x1022f00c
|
||||
#define AN8855_RG_QP_CDR_LPF_RATIO GENMASK(5, 4)
|
||||
#define AN8855_RG_QP_CDR_LPF_SETVALUE 0x1022f014
|
||||
#define AN8855_RG_QP_CDR_PR_BUF_IN_SR GENMASK(31, 29)
|
||||
#define AN8855_RG_QP_CDR_PR_BETA_SEL GENMASK(28, 25)
|
||||
#define AN8855_RG_QP_CDR_PR_CKREF_DIV1 0x1022f018
|
||||
#define AN8855_RG_QP_CDR_PR_KBAND_DIV GENMASK(26, 24)
|
||||
#define AN8855_RG_QP_CDR_PR_DAC_BAND GENMASK(12, 8)
|
||||
#define AN8855_RG_QP_CDR_PR_KBAND_DIV_PCIE 0x1022f01c
|
||||
#define AN8855_RG_QP_CDR_PR_XFICK_EN BIT(30)
|
||||
#define AN8855_RG_QP_CDR_PR_KBAND_PCIE_MODE BIT(6)
|
||||
#define AN8855_RG_QP_CDR_PR_KBAND_DIV_PCIE_MASK GENMASK(5, 0)
|
||||
#define AN8855_RG_QP_CDR_FORCE_IBANDLPF_R_OFF 0x1022f020
|
||||
#define AN8855_RG_QP_CDR_PHYCK_SEL GENMASK(17, 16)
|
||||
#define AN8855_RG_QP_CDR_PHYCK_RSTB BIT(13)
|
||||
#define AN8855_RG_QP_CDR_PHYCK_DIV GENMASK(12, 6)
|
||||
#define AN8855_RG_QP_TX_MODE 0x1022f028
|
||||
#define AN8855_RG_QP_TX_RESERVE GENMASK(31, 16)
|
||||
#define AN8855_RG_QP_TX_MODE_16B_EN BIT(0)
|
||||
#define AN8855_RG_QP_PLL_IPLL_DIG_PWR_SEL 0x1022f03c
|
||||
#define AN8855_RG_QP_PLL_SDM_ORD 0x1022f040
|
||||
#define AN8855_RG_QP_PLL_SSC_PHASE_INI BIT(4)
|
||||
#define AN8855_RG_QP_PLL_SSC_TRI_EN BIT(3)
|
||||
|
||||
/* AN8855_ETHER_SYS_BASE 0x1028c800 */
|
||||
#define AN8855_RG_GPHY_AFE_PWD 0x1028c840
|
||||
#define AN8855_RG_GPHY_SMI_ADDR 0x1028c848
|
||||
|
||||
#define MIB_DESC(_s, _o, _n) \
|
||||
{ \
|
||||
.size = (_s), \
|
||||
.offset = (_o), \
|
||||
.name = (_n), \
|
||||
}
|
||||
|
||||
struct an8855_mib_desc {
|
||||
unsigned int size;
|
||||
unsigned int offset;
|
||||
const char *name;
|
||||
};
|
||||
|
||||
struct an8855_fdb {
|
||||
u16 vid;
|
||||
u8 port_mask;
|
||||
u16 aging;
|
||||
u8 mac[6];
|
||||
bool noarp;
|
||||
u8 live;
|
||||
u8 type;
|
||||
u8 fid;
|
||||
u8 ivl;
|
||||
};
|
||||
|
||||
struct an8855_priv {
|
||||
struct device *dev;
|
||||
struct dsa_switch *ds;
|
||||
struct regmap *regmap;
|
||||
struct gpio_desc *reset_gpio;
|
||||
/* Protect ATU or VLAN table access */
|
||||
struct mutex reg_mutex;
|
||||
|
||||
struct phylink_pcs pcs;
|
||||
|
||||
u8 mirror_rx;
|
||||
u8 mirror_tx;
|
||||
u8 port_isolated_map;
|
||||
|
||||
bool phy_require_calib;
|
||||
};
|
||||
|
||||
#endif /* __AN8855_H */
|
113
target/linux/mediatek/files-6.6/drivers/net/mdio/mdio-an8855.c
Normal file
113
target/linux/mediatek/files-6.6/drivers/net/mdio/mdio-an8855.c
Normal file
@ -0,0 +1,113 @@
|
||||
// SPDX-License-Identifier: GPL-2.0+
|
||||
/*
|
||||
* MDIO passthrough driver for Airoha AN8855 Switch
|
||||
*/
|
||||
|
||||
#include <linux/mfd/airoha-an8855-mfd.h>
|
||||
#include <linux/module.h>
|
||||
#include <linux/of_mdio.h>
|
||||
#include <linux/platform_device.h>
|
||||
|
||||
static int an855_phy_restore_page(struct an8855_mfd_priv *priv,
|
||||
int phy) __must_hold(&priv->bus->mdio_lock)
|
||||
{
|
||||
/* Check PHY page only for addr shared with switch */
|
||||
if (phy != priv->switch_addr)
|
||||
return 0;
|
||||
|
||||
/* Don't restore page if it's not set to switch page */
|
||||
if (priv->current_page != FIELD_GET(AN8855_PHY_PAGE,
|
||||
AN8855_PHY_PAGE_EXTENDED_4))
|
||||
return 0;
|
||||
|
||||
/* Restore page to 0, PHY might change page right after but that
|
||||
* will be ignored as it won't be a switch page.
|
||||
*/
|
||||
return an8855_mii_set_page(priv, phy, AN8855_PHY_PAGE_STANDARD);
|
||||
}
|
||||
|
||||
static int an8855_phy_read(struct mii_bus *bus, int phy, int regnum)
|
||||
{
|
||||
struct an8855_mfd_priv *priv = bus->priv;
|
||||
struct mii_bus *real_bus = priv->bus;
|
||||
int ret;
|
||||
|
||||
mutex_lock_nested(&real_bus->mdio_lock, MDIO_MUTEX_NESTED);
|
||||
|
||||
ret = an855_phy_restore_page(priv, phy);
|
||||
if (ret)
|
||||
goto exit;
|
||||
|
||||
ret = __mdiobus_read(real_bus, phy, regnum);
|
||||
exit:
|
||||
mutex_unlock(&real_bus->mdio_lock);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int an8855_phy_write(struct mii_bus *bus, int phy, int regnum, u16 val)
|
||||
{
|
||||
struct an8855_mfd_priv *priv = bus->priv;
|
||||
struct mii_bus *real_bus = priv->bus;
|
||||
int ret;
|
||||
|
||||
mutex_lock_nested(&real_bus->mdio_lock, MDIO_MUTEX_NESTED);
|
||||
|
||||
ret = an855_phy_restore_page(priv, phy);
|
||||
if (ret)
|
||||
goto exit;
|
||||
|
||||
ret = __mdiobus_write(real_bus, phy, regnum, val);
|
||||
exit:
|
||||
mutex_unlock(&real_bus->mdio_lock);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int an8855_mdio_probe(struct platform_device *pdev)
|
||||
{
|
||||
struct device *dev = &pdev->dev;
|
||||
struct an8855_mfd_priv *priv;
|
||||
struct mii_bus *bus;
|
||||
int ret;
|
||||
|
||||
/* Get priv of MFD */
|
||||
priv = dev_get_drvdata(dev->parent);
|
||||
|
||||
bus = devm_mdiobus_alloc(dev);
|
||||
if (!bus)
|
||||
return -ENOMEM;
|
||||
|
||||
bus->priv = priv;
|
||||
bus->name = KBUILD_MODNAME "-mii";
|
||||
snprintf(bus->id, MII_BUS_ID_SIZE, KBUILD_MODNAME "-%d",
|
||||
priv->switch_addr);
|
||||
bus->parent = dev;
|
||||
bus->read = an8855_phy_read;
|
||||
bus->write = an8855_phy_write;
|
||||
|
||||
ret = devm_of_mdiobus_register(dev, bus, dev->of_node);
|
||||
if (ret)
|
||||
return dev_err_probe(dev, ret, "failed to register MDIO bus\n");
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static const struct of_device_id an8855_mdio_of_match[] = {
|
||||
{ .compatible = "airoha,an8855-mdio", },
|
||||
{ /* sentinel */ }
|
||||
};
|
||||
MODULE_DEVICE_TABLE(of, an8855_mdio_of_match);
|
||||
|
||||
static struct platform_driver an8855_mdio_driver = {
|
||||
.probe = an8855_mdio_probe,
|
||||
.driver = {
|
||||
.name = "an8855-mdio",
|
||||
.of_match_table = an8855_mdio_of_match,
|
||||
},
|
||||
};
|
||||
module_platform_driver(an8855_mdio_driver);
|
||||
|
||||
MODULE_AUTHOR("Christian Marangi <ansuelsmth@gmail.com>");
|
||||
MODULE_DESCRIPTION("Driver for AN8855 MDIO passthrough");
|
||||
MODULE_LICENSE("GPL");
|
267
target/linux/mediatek/files-6.6/drivers/net/phy/air_an8855.c
Normal file
267
target/linux/mediatek/files-6.6/drivers/net/phy/air_an8855.c
Normal file
@ -0,0 +1,267 @@
|
||||
// SPDX-License-Identifier: GPL-2.0+
|
||||
/*
|
||||
* Copyright (C) 2024 Christian Marangi <ansuelsmth@gmail.com>
|
||||
*/
|
||||
|
||||
#include <linux/bitfield.h>
|
||||
#include <linux/module.h>
|
||||
#include <linux/nvmem-consumer.h>
|
||||
#include <linux/phy.h>
|
||||
|
||||
#define AN8855_PHY_SELECT_PAGE 0x1f
|
||||
#define AN8855_PHY_PAGE GENMASK(2, 0)
|
||||
#define AN8855_PHY_PAGE_STANDARD FIELD_PREP_CONST(AN8855_PHY_PAGE, 0x0)
|
||||
#define AN8855_PHY_PAGE_EXTENDED_1 FIELD_PREP_CONST(AN8855_PHY_PAGE, 0x1)
|
||||
|
||||
/* MII Registers Page 1 */
|
||||
#define AN8855_PHY_EXT_REG_14 0x14
|
||||
#define AN8855_PHY_EN_DOWN_SHIFT BIT(4)
|
||||
|
||||
/* R50 Calibration regs in MDIO_MMD_VEND1 */
|
||||
#define AN8855_PHY_R500HM_RSEL_TX_AB 0x174
|
||||
#define AN8855_PHY_R50OHM_RSEL_TX_A_EN BIT(15)
|
||||
#define AN8855_PHY_R50OHM_RSEL_TX_A GENMASK(14, 8)
|
||||
#define AN8855_PHY_R50OHM_RSEL_TX_B_EN BIT(7)
|
||||
#define AN8855_PHY_R50OHM_RSEL_TX_B GENMASK(6, 0)
|
||||
#define AN8855_PHY_R500HM_RSEL_TX_CD 0x175
|
||||
#define AN8855_PHY_R50OHM_RSEL_TX_C_EN BIT(15)
|
||||
#define AN8855_PHY_R50OHM_RSEL_TX_C GENMASK(14, 8)
|
||||
#define AN8855_PHY_R50OHM_RSEL_TX_D_EN BIT(7)
|
||||
#define AN8855_PHY_R50OHM_RSEL_TX_D GENMASK(6, 0)
|
||||
|
||||
#define AN8855_SWITCH_EFUSE_R50O GENMASK(30, 24)
|
||||
|
||||
/* PHY TX PAIR DELAY SELECT Register */
|
||||
#define AN8855_PHY_TX_PAIR_DLY_SEL_GBE 0x013
|
||||
#define AN8855_PHY_CR_DA_TX_PAIR_DELKAY_SEL_A_GBE GENMASK(14, 12)
|
||||
#define AN8855_PHY_CR_DA_TX_PAIR_DELKAY_SEL_B_GBE GENMASK(10, 8)
|
||||
#define AN8855_PHY_CR_DA_TX_PAIR_DELKAY_SEL_C_GBE GENMASK(6, 4)
|
||||
#define AN8855_PHY_CR_DA_TX_PAIR_DELKAY_SEL_D_GBE GENMASK(2, 0)
|
||||
/* PHY ADC Register */
|
||||
#define AN8855_PHY_RXADC_CTRL 0x0d8
|
||||
#define AN8855_PHY_RG_AD_SAMNPLE_PHSEL_A BIT(12)
|
||||
#define AN8855_PHY_RG_AD_SAMNPLE_PHSEL_B BIT(8)
|
||||
#define AN8855_PHY_RG_AD_SAMNPLE_PHSEL_C BIT(4)
|
||||
#define AN8855_PHY_RG_AD_SAMNPLE_PHSEL_D BIT(0)
|
||||
#define AN8855_PHY_RXADC_REV_0 0x0d9
|
||||
#define AN8855_PHY_RG_AD_RESERVE0_A GENMASK(15, 8)
|
||||
#define AN8855_PHY_RG_AD_RESERVE0_B GENMASK(7, 0)
|
||||
#define AN8855_PHY_RXADC_REV_1 0x0da
|
||||
#define AN8855_PHY_RG_AD_RESERVE0_C GENMASK(15, 8)
|
||||
#define AN8855_PHY_RG_AD_RESERVE0_D GENMASK(7, 0)
|
||||
|
||||
#define AN8855_PHY_ID 0xc0ff0410
|
||||
|
||||
#define AN8855_PHY_FLAGS_EN_CALIBRATION BIT(0)
|
||||
|
||||
struct air_an8855_priv {
|
||||
u8 calibration_data[4];
|
||||
};
|
||||
|
||||
static const u8 dsa_r50ohm_table[] = {
|
||||
127, 127, 127, 127, 127, 127, 127, 127, 127, 127,
|
||||
127, 127, 127, 127, 127, 127, 127, 126, 122, 117,
|
||||
112, 109, 104, 101, 97, 94, 90, 88, 84, 80,
|
||||
78, 74, 72, 68, 66, 64, 61, 58, 56, 53,
|
||||
51, 48, 47, 44, 42, 40, 38, 36, 34, 32,
|
||||
31, 28, 27, 24, 24, 22, 20, 18, 16, 16,
|
||||
14, 12, 11, 9
|
||||
};
|
||||
|
||||
static int en8855_get_r50ohm_val(struct device *dev, const char *calib_name,
|
||||
u8 *dest)
|
||||
{
|
||||
u32 shift_sel, val;
|
||||
int ret;
|
||||
int i;
|
||||
|
||||
ret = nvmem_cell_read_u32(dev, calib_name, &val);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
shift_sel = FIELD_GET(AN8855_SWITCH_EFUSE_R50O, val);
|
||||
for (i = 0; i < ARRAY_SIZE(dsa_r50ohm_table); i++)
|
||||
if (dsa_r50ohm_table[i] == shift_sel)
|
||||
break;
|
||||
|
||||
if (i < 8 || i >= ARRAY_SIZE(dsa_r50ohm_table))
|
||||
*dest = dsa_r50ohm_table[25];
|
||||
else
|
||||
*dest = dsa_r50ohm_table[i - 8];
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int an8855_probe(struct phy_device *phydev)
|
||||
{
|
||||
struct device *dev = &phydev->mdio.dev;
|
||||
struct device_node *node = dev->of_node;
|
||||
struct air_an8855_priv *priv;
|
||||
|
||||
/* If we don't have a node, skip calib */
|
||||
if (!node)
|
||||
return 0;
|
||||
|
||||
priv = devm_kzalloc(dev, sizeof(*priv), GFP_KERNEL);
|
||||
if (!priv)
|
||||
return -ENOMEM;
|
||||
|
||||
phydev->priv = priv;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int an8855_get_downshift(struct phy_device *phydev, u8 *data)
|
||||
{
|
||||
int val;
|
||||
|
||||
val = phy_read_paged(phydev, AN8855_PHY_PAGE_EXTENDED_1, AN8855_PHY_EXT_REG_14);
|
||||
if (val < 0)
|
||||
return val;
|
||||
|
||||
*data = val & AN8855_PHY_EN_DOWN_SHIFT ? DOWNSHIFT_DEV_DEFAULT_COUNT :
|
||||
DOWNSHIFT_DEV_DISABLE;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int an8855_set_downshift(struct phy_device *phydev, u8 cnt)
|
||||
{
|
||||
u16 ds = cnt != DOWNSHIFT_DEV_DISABLE ? AN8855_PHY_EN_DOWN_SHIFT : 0;
|
||||
|
||||
return phy_modify_paged(phydev, AN8855_PHY_PAGE_EXTENDED_1,
|
||||
AN8855_PHY_EXT_REG_14, AN8855_PHY_EN_DOWN_SHIFT,
|
||||
ds);
|
||||
}
|
||||
|
||||
static int an8855_config_init(struct phy_device *phydev)
|
||||
{
|
||||
struct air_an8855_priv *priv = phydev->priv;
|
||||
struct device *dev = &phydev->mdio.dev;
|
||||
int ret;
|
||||
|
||||
/* Enable HW auto downshift */
|
||||
ret = an8855_set_downshift(phydev, DOWNSHIFT_DEV_DEFAULT_COUNT);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
/* Apply calibration values, if needed.
|
||||
* AN8855_PHY_FLAGS_EN_CALIBRATION signal this.
|
||||
*/
|
||||
if (priv && phydev->dev_flags & AN8855_PHY_FLAGS_EN_CALIBRATION) {
|
||||
u8 *calibration_data = priv->calibration_data;
|
||||
|
||||
ret = en8855_get_r50ohm_val(dev, "tx_a", &calibration_data[0]);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
ret = en8855_get_r50ohm_val(dev, "tx_b", &calibration_data[1]);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
ret = en8855_get_r50ohm_val(dev, "tx_c", &calibration_data[2]);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
ret = en8855_get_r50ohm_val(dev, "tx_d", &calibration_data[3]);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
ret = phy_modify_mmd(phydev, MDIO_MMD_VEND1, AN8855_PHY_R500HM_RSEL_TX_AB,
|
||||
AN8855_PHY_R50OHM_RSEL_TX_A | AN8855_PHY_R50OHM_RSEL_TX_B,
|
||||
FIELD_PREP(AN8855_PHY_R50OHM_RSEL_TX_A, calibration_data[0]) |
|
||||
FIELD_PREP(AN8855_PHY_R50OHM_RSEL_TX_B, calibration_data[1]));
|
||||
if (ret)
|
||||
return ret;
|
||||
ret = phy_modify_mmd(phydev, MDIO_MMD_VEND1, AN8855_PHY_R500HM_RSEL_TX_CD,
|
||||
AN8855_PHY_R50OHM_RSEL_TX_C | AN8855_PHY_R50OHM_RSEL_TX_D,
|
||||
FIELD_PREP(AN8855_PHY_R50OHM_RSEL_TX_C, calibration_data[2]) |
|
||||
FIELD_PREP(AN8855_PHY_R50OHM_RSEL_TX_D, calibration_data[3]));
|
||||
if (ret)
|
||||
return ret;
|
||||
}
|
||||
|
||||
/* Apply values to reduce signal noise */
|
||||
ret = phy_write_mmd(phydev, MDIO_MMD_VEND1, AN8855_PHY_TX_PAIR_DLY_SEL_GBE,
|
||||
FIELD_PREP(AN8855_PHY_CR_DA_TX_PAIR_DELKAY_SEL_A_GBE, 0x4) |
|
||||
FIELD_PREP(AN8855_PHY_CR_DA_TX_PAIR_DELKAY_SEL_C_GBE, 0x4));
|
||||
if (ret)
|
||||
return ret;
|
||||
ret = phy_write_mmd(phydev, MDIO_MMD_VEND1, AN8855_PHY_RXADC_CTRL,
|
||||
AN8855_PHY_RG_AD_SAMNPLE_PHSEL_A |
|
||||
AN8855_PHY_RG_AD_SAMNPLE_PHSEL_C);
|
||||
if (ret)
|
||||
return ret;
|
||||
ret = phy_write_mmd(phydev, MDIO_MMD_VEND1, AN8855_PHY_RXADC_REV_0,
|
||||
FIELD_PREP(AN8855_PHY_RG_AD_RESERVE0_A, 0x1));
|
||||
if (ret)
|
||||
return ret;
|
||||
ret = phy_write_mmd(phydev, MDIO_MMD_VEND1, AN8855_PHY_RXADC_REV_1,
|
||||
FIELD_PREP(AN8855_PHY_RG_AD_RESERVE0_C, 0x1));
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int an8855_get_tunable(struct phy_device *phydev,
|
||||
struct ethtool_tunable *tuna, void *data)
|
||||
{
|
||||
switch (tuna->id) {
|
||||
case ETHTOOL_PHY_DOWNSHIFT:
|
||||
return an8855_get_downshift(phydev, data);
|
||||
default:
|
||||
return -EOPNOTSUPP;
|
||||
}
|
||||
}
|
||||
|
||||
static int an8855_set_tunable(struct phy_device *phydev,
|
||||
struct ethtool_tunable *tuna, const void *data)
|
||||
{
|
||||
switch (tuna->id) {
|
||||
case ETHTOOL_PHY_DOWNSHIFT:
|
||||
return an8855_set_downshift(phydev, *(const u8 *)data);
|
||||
default:
|
||||
return -EOPNOTSUPP;
|
||||
}
|
||||
}
|
||||
|
||||
static int an8855_read_page(struct phy_device *phydev)
|
||||
{
|
||||
return __phy_read(phydev, AN8855_PHY_SELECT_PAGE);
|
||||
}
|
||||
|
||||
static int an8855_write_page(struct phy_device *phydev, int page)
|
||||
{
|
||||
return __phy_write(phydev, AN8855_PHY_SELECT_PAGE, page);
|
||||
}
|
||||
|
||||
static struct phy_driver an8855_driver[] = {
|
||||
{
|
||||
PHY_ID_MATCH_EXACT(AN8855_PHY_ID),
|
||||
.name = "Airoha AN8855 internal PHY",
|
||||
/* PHY_GBIT_FEATURES */
|
||||
.flags = PHY_IS_INTERNAL,
|
||||
.probe = an8855_probe,
|
||||
.config_init = an8855_config_init,
|
||||
.soft_reset = genphy_soft_reset,
|
||||
.get_tunable = an8855_get_tunable,
|
||||
.set_tunable = an8855_set_tunable,
|
||||
.suspend = genphy_suspend,
|
||||
.resume = genphy_resume,
|
||||
.read_page = an8855_read_page,
|
||||
.write_page = an8855_write_page,
|
||||
}, };
|
||||
|
||||
module_phy_driver(an8855_driver);
|
||||
|
||||
static struct mdio_device_id __maybe_unused an8855_tbl[] = {
|
||||
{ PHY_ID_MATCH_EXACT(AN8855_PHY_ID) },
|
||||
{ }
|
||||
};
|
||||
|
||||
MODULE_DEVICE_TABLE(mdio, an8855_tbl);
|
||||
|
||||
MODULE_DESCRIPTION("Airoha AN8855 PHY driver");
|
||||
MODULE_AUTHOR("Christian Marangi <ansuelsmth@gmail.com>");
|
||||
MODULE_LICENSE("GPL");
|
63
target/linux/mediatek/files-6.6/drivers/nvmem/an8855-efuse.c
Normal file
63
target/linux/mediatek/files-6.6/drivers/nvmem/an8855-efuse.c
Normal file
@ -0,0 +1,63 @@
|
||||
// SPDX-License-Identifier: GPL-2.0
|
||||
/*
|
||||
* Airoha AN8855 Switch EFUSE Driver
|
||||
*/
|
||||
|
||||
#include <linux/mod_devicetable.h>
|
||||
#include <linux/module.h>
|
||||
#include <linux/nvmem-provider.h>
|
||||
#include <linux/platform_device.h>
|
||||
#include <linux/regmap.h>
|
||||
|
||||
#define AN8855_EFUSE_CELL 50
|
||||
|
||||
#define AN8855_EFUSE_DATA0 0x1000a500
|
||||
#define AN8855_EFUSE_R50O GENMASK(30, 24)
|
||||
|
||||
static int an8855_efuse_read(void *context, unsigned int offset,
|
||||
void *val, size_t bytes)
|
||||
{
|
||||
struct regmap *regmap = context;
|
||||
|
||||
return regmap_bulk_read(regmap, AN8855_EFUSE_DATA0 + offset,
|
||||
val, bytes / sizeof(u32));
|
||||
}
|
||||
|
||||
static int an8855_efuse_probe(struct platform_device *pdev)
|
||||
{
|
||||
struct nvmem_config an8855_nvmem_config = {
|
||||
.name = "an8855-efuse",
|
||||
.size = AN8855_EFUSE_CELL * sizeof(u32),
|
||||
.stride = sizeof(u32),
|
||||
.word_size = sizeof(u32),
|
||||
.reg_read = an8855_efuse_read,
|
||||
};
|
||||
struct device *dev = &pdev->dev;
|
||||
struct nvmem_device *nvmem;
|
||||
|
||||
/* Assign NVMEM priv to MFD regmap */
|
||||
an8855_nvmem_config.priv = dev_get_regmap(dev->parent, NULL);
|
||||
an8855_nvmem_config.dev = dev;
|
||||
nvmem = devm_nvmem_register(dev, &an8855_nvmem_config);
|
||||
|
||||
return PTR_ERR_OR_ZERO(nvmem);
|
||||
}
|
||||
|
||||
static const struct of_device_id an8855_efuse_of_match[] = {
|
||||
{ .compatible = "airoha,an8855-efuse", },
|
||||
{ /* sentinel */ }
|
||||
};
|
||||
MODULE_DEVICE_TABLE(of, an8855_efuse_of_match);
|
||||
|
||||
static struct platform_driver an8855_efuse_driver = {
|
||||
.probe = an8855_efuse_probe,
|
||||
.driver = {
|
||||
.name = "an8855-efuse",
|
||||
.of_match_table = an8855_efuse_of_match,
|
||||
},
|
||||
};
|
||||
module_platform_driver(an8855_efuse_driver);
|
||||
|
||||
MODULE_AUTHOR("Christian Marangi <ansuelsmth@gmail.com>");
|
||||
MODULE_DESCRIPTION("Driver for AN8855 Switch EFUSE");
|
||||
MODULE_LICENSE("GPL");
|
@ -0,0 +1,41 @@
|
||||
/* SPDX-License-Identifier: GPL-2.0-only */
|
||||
/*
|
||||
* MFD driver for Airoha AN8855 Switch
|
||||
*/
|
||||
#ifndef _LINUX_INCLUDE_MFD_AIROHA_AN8855_MFD_H
|
||||
#define _LINUX_INCLUDE_MFD_AIROHA_AN8855_MFD_H
|
||||
|
||||
#include <linux/bitfield.h>
|
||||
|
||||
/* MII Registers */
|
||||
#define AN8855_PHY_SELECT_PAGE 0x1f
|
||||
#define AN8855_PHY_PAGE GENMASK(2, 0)
|
||||
#define AN8855_PHY_PAGE_STANDARD FIELD_PREP_CONST(AN8855_PHY_PAGE, 0x0)
|
||||
#define AN8855_PHY_PAGE_EXTENDED_1 FIELD_PREP_CONST(AN8855_PHY_PAGE, 0x1)
|
||||
#define AN8855_PHY_PAGE_EXTENDED_4 FIELD_PREP_CONST(AN8855_PHY_PAGE, 0x4)
|
||||
|
||||
/* MII Registers Page 4 */
|
||||
#define AN8855_PBUS_MODE 0x10
|
||||
#define AN8855_PBUS_MODE_ADDR_FIXED 0x0
|
||||
#define AN8855_PBUS_MODE_ADDR_INCR BIT(15)
|
||||
#define AN8855_PBUS_WR_ADDR_HIGH 0x11
|
||||
#define AN8855_PBUS_WR_ADDR_LOW 0x12
|
||||
#define AN8855_PBUS_WR_DATA_HIGH 0x13
|
||||
#define AN8855_PBUS_WR_DATA_LOW 0x14
|
||||
#define AN8855_PBUS_RD_ADDR_HIGH 0x15
|
||||
#define AN8855_PBUS_RD_ADDR_LOW 0x16
|
||||
#define AN8855_PBUS_RD_DATA_HIGH 0x17
|
||||
#define AN8855_PBUS_RD_DATA_LOW 0x18
|
||||
|
||||
struct an8855_mfd_priv {
|
||||
struct device *dev;
|
||||
struct mii_bus *bus;
|
||||
|
||||
unsigned int switch_addr;
|
||||
u16 current_page;
|
||||
};
|
||||
|
||||
int an8855_mii_set_page(struct an8855_mfd_priv *priv, u8 phy_id,
|
||||
u8 page);
|
||||
|
||||
#endif
|
@ -1,5 +1,6 @@
|
||||
CONFIG_64BIT=y
|
||||
# CONFIG_AHCI_MTK is not set
|
||||
CONFIG_AIR_AN8855_PHY=y
|
||||
CONFIG_AIROHA_EN8801SC_PHY=y
|
||||
CONFIG_ARCH_BINFMT_ELF_EXTRA_PHDRS=y
|
||||
CONFIG_ARCH_CORRECT_STACKTRACE_ON_KRETPROBE=y
|
||||
@ -237,12 +238,14 @@ CONFIG_MAXLINEAR_GPHY=y
|
||||
CONFIG_MDIO_BUS=y
|
||||
CONFIG_MDIO_DEVICE=y
|
||||
CONFIG_MDIO_DEVRES=y
|
||||
CONFIG_MDIO_AN8855=y
|
||||
CONFIG_MEDIATEK_2P5GE_PHY=y
|
||||
CONFIG_MEDIATEK_GE_PHY=y
|
||||
CONFIG_MEDIATEK_GE_SOC_PHY=y
|
||||
CONFIG_MEDIATEK_WATCHDOG=y
|
||||
CONFIG_MESSAGE_LOGLEVEL_DEFAULT=7
|
||||
CONFIG_MFD_SYSCON=y
|
||||
CONFIG_MFD_AIROHA_AN8855=y
|
||||
CONFIG_MIGRATION=y
|
||||
# CONFIG_MITIGATE_SPECTRE_BRANCH_HISTORY is not set
|
||||
CONFIG_MMC=y
|
||||
@ -292,6 +295,7 @@ CONFIG_NEED_DMA_MAP_STATE=y
|
||||
CONFIG_NEED_SG_DMA_LENGTH=y
|
||||
CONFIG_NET_DEVLINK=y
|
||||
CONFIG_NET_DSA=y
|
||||
CONFIG_NET_DSA_AN8855=y
|
||||
CONFIG_NET_DSA_MT7530=y
|
||||
CONFIG_NET_DSA_MT7530_MDIO=y
|
||||
CONFIG_NET_DSA_MT7530_MMIO=y
|
||||
@ -310,6 +314,7 @@ CONFIG_NO_HZ_COMMON=y
|
||||
CONFIG_NO_HZ_IDLE=y
|
||||
CONFIG_NR_CPUS=4
|
||||
CONFIG_NVMEM=y
|
||||
CONFIG_NVMEM_AN8855_EFUSE=y
|
||||
CONFIG_NVMEM_BLOCK=y
|
||||
CONFIG_NVMEM_LAYOUTS=y
|
||||
CONFIG_NVMEM_LAYOUT_ADTRAN=y
|
||||
|
@ -1,5 +1,6 @@
|
||||
CONFIG_64BIT=y
|
||||
# CONFIG_AHCI_MTK is not set
|
||||
# CONFIG_AIR_AN8855_PHY is not set
|
||||
# CONFIG_AIROHA_EN8801SC_PHY is not set
|
||||
CONFIG_AQUANTIA_PHY=y
|
||||
CONFIG_ARCH_BINFMT_ELF_EXTRA_PHDRS=y
|
||||
@ -240,12 +241,14 @@ CONFIG_MAXLINEAR_GPHY=y
|
||||
CONFIG_MDIO_BUS=y
|
||||
CONFIG_MDIO_DEVICE=y
|
||||
CONFIG_MDIO_DEVRES=y
|
||||
# CONFIG_MDIO_AN8855 is not set
|
||||
# CONFIG_MEDIATEK_2P5GE_PHY is not set
|
||||
CONFIG_MEDIATEK_GE_PHY=y
|
||||
# CONFIG_MEDIATEK_GE_SOC_PHY is not set
|
||||
CONFIG_MEDIATEK_WATCHDOG=y
|
||||
CONFIG_MESSAGE_LOGLEVEL_DEFAULT=7
|
||||
CONFIG_MFD_SYSCON=y
|
||||
# CONFIG_MFD_AIROHA_AN8855 is not set
|
||||
CONFIG_MIGRATION=y
|
||||
# CONFIG_MITIGATE_SPECTRE_BRANCH_HISTORY is not set
|
||||
CONFIG_MMC=y
|
||||
@ -294,6 +297,7 @@ CONFIG_NEED_DMA_MAP_STATE=y
|
||||
CONFIG_NEED_SG_DMA_LENGTH=y
|
||||
CONFIG_NET_DEVLINK=y
|
||||
CONFIG_NET_DSA=y
|
||||
# CONFIG_NET_DSA_AN8855 is not set
|
||||
CONFIG_NET_DSA_MT7530=y
|
||||
CONFIG_NET_DSA_MT7530_MDIO=y
|
||||
# CONFIG_NET_DSA_MT7530_MMIO is not set
|
||||
@ -312,6 +316,7 @@ CONFIG_NO_HZ_COMMON=y
|
||||
CONFIG_NO_HZ_IDLE=y
|
||||
CONFIG_NR_CPUS=2
|
||||
CONFIG_NVMEM=y
|
||||
# CONFIG_NVMEM_AN8855_EFUSE is not set
|
||||
CONFIG_NVMEM_BLOCK=y
|
||||
CONFIG_NVMEM_LAYOUTS=y
|
||||
CONFIG_NVMEM_LAYOUT_ADTRAN=y
|
||||
|
@ -1,4 +1,5 @@
|
||||
# CONFIG_AIO is not set
|
||||
# CONFIG_AIR_AN8855_PHY is not set
|
||||
# CONFIG_AIROHA_EN8801SC_PHY is not set
|
||||
CONFIG_ALIGNMENT_TRAP=y
|
||||
CONFIG_ARCH_32BIT_OFF_T=y
|
||||
@ -352,6 +353,7 @@ CONFIG_MDIO_BITBANG=y
|
||||
CONFIG_MDIO_BUS=y
|
||||
CONFIG_MDIO_DEVICE=y
|
||||
CONFIG_MDIO_DEVRES=y
|
||||
# CONFIG_MDIO_AN8855 is not set
|
||||
CONFIG_MDIO_GPIO=y
|
||||
CONFIG_MEDIATEK_GE_PHY=y
|
||||
CONFIG_MEDIATEK_MT6577_AUXADC=y
|
||||
@ -361,6 +363,7 @@ CONFIG_MFD_CORE=y
|
||||
# CONFIG_MFD_HI6421_SPMI is not set
|
||||
CONFIG_MFD_MT6397=y
|
||||
CONFIG_MFD_SYSCON=y
|
||||
# CONFIG_MFD_AIROHA_AN8855 is not set
|
||||
CONFIG_MIGHT_HAVE_CACHE_L2X0=y
|
||||
CONFIG_MIGRATION=y
|
||||
CONFIG_MMC=y
|
||||
@ -410,6 +413,7 @@ CONFIG_NEED_SRCU_NMI_SAFE=y
|
||||
CONFIG_NEON=y
|
||||
CONFIG_NET_DEVLINK=y
|
||||
CONFIG_NET_DSA=y
|
||||
# CONFIG_NET_DSA_AN8855 is not set
|
||||
CONFIG_NET_DSA_MT7530=y
|
||||
CONFIG_NET_DSA_MT7530_MDIO=y
|
||||
# CONFIG_NET_DSA_MT7530_MMIO is not set
|
||||
@ -431,6 +435,7 @@ CONFIG_NO_HZ_COMMON=y
|
||||
CONFIG_NO_HZ_IDLE=y
|
||||
CONFIG_NR_CPUS=4
|
||||
CONFIG_NVMEM=y
|
||||
# CONFIG_NVMEM_AN8855_EFUSE is not set
|
||||
CONFIG_NVMEM_LAYOUTS=y
|
||||
# CONFIG_NVMEM_LAYOUT_ADTRAN is not set
|
||||
CONFIG_NVMEM_MTK_EFUSE=y
|
||||
|
@ -1,3 +1,4 @@
|
||||
# CONFIG_AIR_AN8855_PHY is not set
|
||||
# CONFIG_AIROHA_EN8801SC_PHY is not set
|
||||
CONFIG_ALIGNMENT_TRAP=y
|
||||
CONFIG_ARCH_32BIT_OFF_T=y
|
||||
@ -181,9 +182,11 @@ CONFIG_MACH_MT7629=y
|
||||
CONFIG_MDIO_BUS=y
|
||||
CONFIG_MDIO_DEVICE=y
|
||||
CONFIG_MDIO_DEVRES=y
|
||||
# CONFIG_MDIO_AN8855 is not set
|
||||
CONFIG_MEDIATEK_GE_PHY=y
|
||||
CONFIG_MEDIATEK_WATCHDOG=y
|
||||
CONFIG_MFD_SYSCON=y
|
||||
# CONFIG_MFD_AIROHA_AN8855 is not set
|
||||
CONFIG_MIGHT_HAVE_CACHE_L2X0=y
|
||||
CONFIG_MIGRATION=y
|
||||
CONFIG_MMU_LAZY_TLB_REFCOUNT=y
|
||||
@ -216,6 +219,7 @@ CONFIG_NETFILTER=y
|
||||
CONFIG_NETFILTER_BPF_LINK=y
|
||||
CONFIG_NET_DEVLINK=y
|
||||
CONFIG_NET_DSA=y
|
||||
# CONFIG_NET_DSA_AN8855 is not set
|
||||
CONFIG_NET_DSA_MT7530=y
|
||||
CONFIG_NET_DSA_MT7530_MDIO=y
|
||||
# CONFIG_NET_DSA_MT7530_MMIO is not set
|
||||
@ -234,6 +238,7 @@ CONFIG_NO_HZ_COMMON=y
|
||||
CONFIG_NO_HZ_IDLE=y
|
||||
CONFIG_NR_CPUS=2
|
||||
CONFIG_NVMEM=y
|
||||
# CONFIG_NVMEM_AN8855_EFUSE is not set
|
||||
CONFIG_NVMEM_LAYOUTS=y
|
||||
# CONFIG_NVMEM_LAYOUT_ADTRAN is not set
|
||||
# CONFIG_NVMEM_MTK_EFUSE is not set
|
||||
|
@ -0,0 +1,309 @@
|
||||
From: Christian Marangi <ansuelsmth@gmail.com>
|
||||
To: Christian Marangi <ansuelsmth@gmail.com>,
|
||||
Lee Jones <lee@kernel.org>, Rob Herring <robh@kernel.org>,
|
||||
Krzysztof Kozlowski <krzk+dt@kernel.org>,
|
||||
Conor Dooley <conor+dt@kernel.org>,
|
||||
Andrew Lunn <andrew+netdev@lunn.ch>,
|
||||
"David S. Miller" <davem@davemloft.net>,
|
||||
Eric Dumazet <edumazet@google.com>,
|
||||
Jakub Kicinski <kuba@kernel.org>, Paolo Abeni <pabeni@redhat.com>,
|
||||
Vladimir Oltean <olteanv@gmail.com>,
|
||||
Srinivas Kandagatla <srinivas.kandagatla@linaro.org>,
|
||||
Heiner Kallweit <hkallweit1@gmail.com>,
|
||||
Russell King <linux@armlinux.org.uk>,
|
||||
Matthias Brugger <matthias.bgg@gmail.com>,
|
||||
AngeloGioacchino Del Regno
|
||||
<angelogioacchino.delregno@collabora.com>,
|
||||
linux-arm-kernel@lists.infradead.org,
|
||||
linux-mediatek@lists.infradead.org, netdev@vger.kernel.org,
|
||||
devicetree@vger.kernel.org, linux-kernel@vger.kernel.org,
|
||||
upstream@airoha.com
|
||||
Subject: [net-next PATCH v11 0/9] net: dsa: Add Airoha AN8855 support
|
||||
Date: Mon, 9 Dec 2024 14:44:17 +0100 [thread overview]
|
||||
Message-ID: <20241209134459.27110-1-ansuelsmth@gmail.com> (raw)
|
||||
|
||||
This small series add the initial support for the Airoha AN8855 Switch.
|
||||
|
||||
It's a 5 port Gigabit Switch with SGMII/HSGMII upstream port.
|
||||
|
||||
This is starting to get in the wild and there are already some router
|
||||
having this switch chip.
|
||||
|
||||
It's conceptually similar to mediatek switch but register and bits
|
||||
are different. And there is that massive Hell that is the PCS
|
||||
configuration.
|
||||
Saddly for that part we have absolutely NO documentation currently.
|
||||
|
||||
There is this special thing where PHY needs to be calibrated with values
|
||||
from the switch efuse. (the thing have a whole cpu timer and MCU)
|
||||
|
||||
Changes v11:
|
||||
- Address reviews from Christophe (spell mistake + dev_err_probe)
|
||||
- Fix kconfig dependency for MFD driver (depends on MDIO_DEVICE instead of MDIO)
|
||||
(indirectly fix link error for mdio APIs)
|
||||
- Fix copy-paste error for MFD driver of_table
|
||||
- Fix compilation error for PHY (move NVMEM to .config)
|
||||
- Drop unneeded NVMEM node from MDIO example schema (from Andrew)
|
||||
- Adapt MFD example schema to MDIO reg property restrictions
|
||||
Changes v10:
|
||||
- Entire rework to MFD + split to MDIO, EFUSE, SWITCH separate drivers
|
||||
- Drop EEE OPs (while Russell finish RFC for EEE changes)
|
||||
- Use new pcs_inpand OPs
|
||||
- Drop AN restart function and move to pcs_config
|
||||
- Enable assisted_learning and disable CPU learn (preparation for fdb_isolation)
|
||||
- Move EFUSE read in Internal PHY driver to .config to handle EPROBE_DEFER
|
||||
(needed now that NVMEM driver is register externally instead of internally to switch
|
||||
node)
|
||||
Changes v9:
|
||||
- Error out on using 5G speed as currently not supported
|
||||
- Add missing MAC_2500FD in phylink mac_capabilities
|
||||
- Add comment and improve if condition for an8855_phylink_mac_config
|
||||
Changes v8:
|
||||
- Add port Fast Age support
|
||||
- Add support for Port Isolation
|
||||
- Use correct register for Learning Disable
|
||||
- Add support for Ageing Time OP
|
||||
- Set default PVID to 0 by default
|
||||
- Add mdb OPs
|
||||
- Add port change MTU
|
||||
- Fix support for Upper VLAN
|
||||
Changes v7:
|
||||
- Fix devm_dsa_register_switch wrong export symbol
|
||||
Changes v6:
|
||||
- Drop standard MIB and handle with ethtool OPs (as requested by Jakub)
|
||||
- Cosmetic: use bool instead of 0 or 1
|
||||
Changes v5:
|
||||
- Add devm_dsa_register_switch() patch
|
||||
- Add Reviewed-by tag for DT patch
|
||||
Changes v4:
|
||||
- Set regmap readable_table static (mute compilation warning)
|
||||
- Add support for port_bridge flags (LEARNING, FLOOD)
|
||||
- Reset fdb struct in fdb_dump
|
||||
- Drop support_asym_pause in port_enable
|
||||
- Add define for get_phy_flags
|
||||
- Fix bug for port not inititially part of a bridge
|
||||
(in an8855_setup the port matrix was always cleared but
|
||||
the CPU port was never initially added)
|
||||
- Disable learning and flood for user port by default
|
||||
- Set CPU port to flood and learning by default
|
||||
- Correctly AND force duplex and flow control in an8855_phylink_mac_link_up
|
||||
- Drop RGMII from pcs_config
|
||||
- Check ret in "Disable AN if not in autoneg"
|
||||
- Use devm_mutex_init
|
||||
- Fix typo for AN8855_PORT_CHECK_MODE
|
||||
- Better define AN8855_STP_LISTENING = AN8855_STP_BLOCKING
|
||||
- Fix typo in AN8855_PHY_EN_DOWN_SHIFT
|
||||
- Use paged helper for PHY
|
||||
- Skip calibration in config_init if priv not defined
|
||||
Changes v3:
|
||||
- Out of RFC
|
||||
- Switch PHY code to select_page API
|
||||
- Better describe masks and bits in PHY driver for ADC register
|
||||
- Drop raw values and use define for mii read/write
|
||||
- Switch to absolute PHY address
|
||||
- Replace raw values with mask and bits for pcs_config
|
||||
- Fix typo for ext-surge property name
|
||||
- Drop support for relocating Switch base PHY address on the bus
|
||||
Changes v2:
|
||||
- Drop mutex guard patch
|
||||
- Drop guard usage in DSA driver
|
||||
- Use __mdiobus_write/read
|
||||
- Check return condition and return errors for mii read/write
|
||||
- Fix wrong logic for EEE
|
||||
- Fix link_down (don't force link down with autoneg)
|
||||
- Fix forcing speed on sgmii autoneg
|
||||
- Better document link speed for sgmii reg
|
||||
- Use standard define for sgmii reg
|
||||
- Imlement nvmem support to expose switch EFUSE
|
||||
- Rework PHY calibration with the use of NVMEM producer/consumer
|
||||
- Update DT with new NVMEM property
|
||||
- Move aneg validation for 2500-basex in pcs_config
|
||||
- Move r50Ohm table and function to PHY driver
|
||||
|
||||
Christian Marangi (9):
|
||||
dt-bindings: nvmem: Document support for Airoha AN8855 Switch EFUSE
|
||||
dt-bindings: net: Document support for Airoha AN8855 Switch Virtual
|
||||
MDIO
|
||||
dt-bindings: net: dsa: Document support for Airoha AN8855 DSA Switch
|
||||
dt-bindings: mfd: Document support for Airoha AN8855 Switch SoC
|
||||
mfd: an8855: Add support for Airoha AN8855 Switch MFD
|
||||
net: mdio: Add Airoha AN8855 Switch MDIO Passtrough
|
||||
nvmem: an8855: Add support for Airoha AN8855 Switch EFUSE
|
||||
net: dsa: Add Airoha AN8855 5-Port Gigabit DSA Switch driver
|
||||
net: phy: Add Airoha AN8855 Internal Switch Gigabit PHY
|
||||
|
||||
.../bindings/mfd/airoha,an8855-mfd.yaml | 178 ++
|
||||
.../bindings/net/airoha,an8855-mdio.yaml | 56 +
|
||||
.../net/dsa/airoha,an8855-switch.yaml | 105 +
|
||||
.../bindings/nvmem/airoha,an8855-efuse.yaml | 123 +
|
||||
MAINTAINERS | 17 +
|
||||
drivers/mfd/Kconfig | 10 +
|
||||
drivers/mfd/Makefile | 1 +
|
||||
drivers/mfd/airoha-an8855.c | 278 ++
|
||||
drivers/net/dsa/Kconfig | 9 +
|
||||
drivers/net/dsa/Makefile | 1 +
|
||||
drivers/net/dsa/an8855.c | 2310 +++++++++++++++++
|
||||
drivers/net/dsa/an8855.h | 783 ++++++
|
||||
drivers/net/mdio/Kconfig | 9 +
|
||||
drivers/net/mdio/Makefile | 1 +
|
||||
drivers/net/mdio/mdio-an8855.c | 113 +
|
||||
drivers/net/phy/Kconfig | 5 +
|
||||
drivers/net/phy/Makefile | 1 +
|
||||
drivers/net/phy/air_an8855.c | 267 ++
|
||||
drivers/nvmem/Kconfig | 11 +
|
||||
drivers/nvmem/Makefile | 2 +
|
||||
drivers/nvmem/an8855-efuse.c | 63 +
|
||||
include/linux/mfd/airoha-an8855-mfd.h | 41 +
|
||||
22 files changed, 4384 insertions(+)
|
||||
create mode 100644 Documentation/devicetree/bindings/mfd/airoha,an8855-mfd.yaml
|
||||
create mode 100644 Documentation/devicetree/bindings/net/airoha,an8855-mdio.yaml
|
||||
create mode 100644 Documentation/devicetree/bindings/net/dsa/airoha,an8855-switch.yaml
|
||||
create mode 100644 Documentation/devicetree/bindings/nvmem/airoha,an8855-efuse.yaml
|
||||
create mode 100644 drivers/mfd/airoha-an8855.c
|
||||
create mode 100644 drivers/net/dsa/an8855.c
|
||||
create mode 100644 drivers/net/dsa/an8855.h
|
||||
create mode 100644 drivers/net/mdio/mdio-an8855.c
|
||||
create mode 100644 drivers/net/phy/air_an8855.c
|
||||
create mode 100644 drivers/nvmem/an8855-efuse.c
|
||||
create mode 100644 include/linux/mfd/airoha-an8855-mfd.h
|
||||
|
||||
--- a/drivers/mfd/Kconfig
|
||||
+++ b/drivers/mfd/Kconfig
|
||||
@@ -41,6 +41,16 @@ config MFD_ALTERA_SYSMGR
|
||||
using regmap_mmio accesses for ARM32 parts and SMC calls to
|
||||
EL3 for ARM64 parts.
|
||||
|
||||
+config MFD_AIROHA_AN8855
|
||||
+ tristate "Airoha AN8855 Switch MFD"
|
||||
+ select MFD_CORE
|
||||
+ select MDIO_DEVICE
|
||||
+ depends on NETDEVICES && OF
|
||||
+ help
|
||||
+ Support for the Airoha AN8855 Switch MFD. This is a SoC Switch
|
||||
+ that provides various peripherals. Currently it provides a
|
||||
+ DSA switch and a NVMEM provider.
|
||||
+
|
||||
config MFD_ACT8945A
|
||||
tristate "Active-semi ACT8945A"
|
||||
select MFD_CORE
|
||||
--- a/drivers/mfd/Makefile
|
||||
+++ b/drivers/mfd/Makefile
|
||||
@@ -7,6 +7,7 @@
|
||||
obj-$(CONFIG_MFD_88PM860X) += 88pm860x.o
|
||||
obj-$(CONFIG_MFD_88PM800) += 88pm800.o 88pm80x.o
|
||||
obj-$(CONFIG_MFD_88PM805) += 88pm805.o 88pm80x.o
|
||||
+obj-$(CONFIG_MFD_AIROHA_AN8855) += airoha-an8855.o
|
||||
obj-$(CONFIG_MFD_ACT8945A) += act8945a.o
|
||||
obj-$(CONFIG_MFD_SM501) += sm501.o
|
||||
obj-$(CONFIG_ARCH_BCM2835) += bcm2835-pm.o
|
||||
--- a/drivers/net/dsa/Kconfig
|
||||
+++ b/drivers/net/dsa/Kconfig
|
||||
@@ -24,6 +24,15 @@ config NET_DSA_LOOP
|
||||
This enables support for a fake mock-up switch chip which
|
||||
exercises the DSA APIs.
|
||||
|
||||
+config NET_DSA_AN8855
|
||||
+ tristate "Airoha AN8855 Ethernet switch support"
|
||||
+ depends on MFD_AIROHA_AN8855
|
||||
+ depends on NET_DSA
|
||||
+ select NET_DSA_TAG_MTK
|
||||
+ help
|
||||
+ This enables support for the Airoha AN8855 Ethernet switch
|
||||
+ chip.
|
||||
+
|
||||
source "drivers/net/dsa/hirschmann/Kconfig"
|
||||
|
||||
config NET_DSA_LANTIQ_GSWIP
|
||||
--- a/drivers/net/dsa/Makefile
|
||||
+++ b/drivers/net/dsa/Makefile
|
||||
@@ -5,6 +5,7 @@ obj-$(CONFIG_NET_DSA_LOOP) += dsa_loop.o
|
||||
ifdef CONFIG_NET_DSA_LOOP
|
||||
obj-$(CONFIG_FIXED_PHY) += dsa_loop_bdinfo.o
|
||||
endif
|
||||
+obj-$(CONFIG_NET_DSA_AN8855) += an8855.o
|
||||
obj-$(CONFIG_NET_DSA_LANTIQ_GSWIP) += lantiq_gswip.o
|
||||
obj-$(CONFIG_NET_DSA_MT7530) += mt7530.o
|
||||
obj-$(CONFIG_NET_DSA_MT7530_MDIO) += mt7530-mdio.o
|
||||
--- a/drivers/net/mdio/Kconfig
|
||||
+++ b/drivers/net/mdio/Kconfig
|
||||
@@ -61,6 +61,15 @@ config MDIO_XGENE
|
||||
This module provides a driver for the MDIO busses found in the
|
||||
APM X-Gene SoC's.
|
||||
|
||||
+config MDIO_AN8855
|
||||
+ tristate "Airoha AN8855 Switch MDIO bus controller"
|
||||
+ depends on MFD_AIROHA_AN8855
|
||||
+ depends on OF_MDIO
|
||||
+ help
|
||||
+ This module provides a driver for the Airoha AN8855 Switch
|
||||
+ that requires a MDIO passtrough as switch address is shared
|
||||
+ with the internal PHYs and requires additional page handling.
|
||||
+
|
||||
config MDIO_ASPEED
|
||||
tristate "ASPEED MDIO bus controller"
|
||||
depends on ARCH_ASPEED || COMPILE_TEST
|
||||
--- a/drivers/net/mdio/Makefile
|
||||
+++ b/drivers/net/mdio/Makefile
|
||||
@@ -5,6 +5,7 @@ obj-$(CONFIG_ACPI_MDIO) += acpi_mdio.o
|
||||
obj-$(CONFIG_FWNODE_MDIO) += fwnode_mdio.o
|
||||
obj-$(CONFIG_OF_MDIO) += of_mdio.o
|
||||
|
||||
+obj-$(CONFIG_MDIO_AN8855) += mdio-an8855.o
|
||||
obj-$(CONFIG_MDIO_ASPEED) += mdio-aspeed.o
|
||||
obj-$(CONFIG_MDIO_BCM_IPROC) += mdio-bcm-iproc.o
|
||||
obj-$(CONFIG_MDIO_BCM_UNIMAC) += mdio-bcm-unimac.o
|
||||
--- a/drivers/net/phy/Kconfig
|
||||
+++ b/drivers/net/phy/Kconfig
|
||||
@@ -147,6 +147,11 @@ config AIROHA_EN8801SC_PHY
|
||||
help
|
||||
Currently supports the Airoha EN8801SC PHY.
|
||||
|
||||
+config AIR_AN8855_PHY
|
||||
+ tristate "Airoha AN8855 Internal Gigabit PHY"
|
||||
+ help
|
||||
+ Currently supports the internal Airoha AN8855 Switch PHY.
|
||||
+
|
||||
config AIR_EN8811H_PHY
|
||||
tristate "Airoha EN8811H 2.5 Gigabit PHY"
|
||||
help
|
||||
--- a/drivers/net/phy/Makefile
|
||||
+++ b/drivers/net/phy/Makefile
|
||||
@@ -50,6 +50,7 @@ obj-y += $(sfp-obj-y) $(sfp-obj-m)
|
||||
obj-$(CONFIG_ADIN_PHY) += adin.o
|
||||
obj-$(CONFIG_ADIN1100_PHY) += adin1100.o
|
||||
obj-$(CONFIG_AIROHA_EN8801SC_PHY) += en8801sc.o
|
||||
+obj-$(CONFIG_AIR_AN8855_PHY) += air_an8855.o
|
||||
obj-$(CONFIG_AIR_EN8811H_PHY) += air_en8811h.o
|
||||
obj-$(CONFIG_AMD_PHY) += amd.o
|
||||
obj-$(CONFIG_AQUANTIA_PHY) += aquantia/
|
||||
--- a/drivers/nvmem/Kconfig
|
||||
+++ b/drivers/nvmem/Kconfig
|
||||
@@ -29,6 +29,17 @@ source "drivers/nvmem/layouts/Kconfig"
|
||||
|
||||
# Devices
|
||||
|
||||
+config NVMEM_AN8855_EFUSE
|
||||
+ tristate "Airoha AN8855 eFuse support"
|
||||
+ depends on MFD_AIROHA_AN8855 || COMPILE_TEST
|
||||
+ help
|
||||
+ Say y here to enable support for reading eFuses on Airoha AN8855
|
||||
+ Switch. These are e.g. used to store factory programmed
|
||||
+ calibration data required for the PHY.
|
||||
+
|
||||
+ This driver can also be built as a module. If so, the module will
|
||||
+ be called nvmem-an8855-efuse.
|
||||
+
|
||||
config NVMEM_APPLE_EFUSES
|
||||
tristate "Apple eFuse support"
|
||||
depends on ARCH_APPLE || COMPILE_TEST
|
||||
--- a/drivers/nvmem/Makefile
|
||||
+++ b/drivers/nvmem/Makefile
|
||||
@@ -10,6 +10,8 @@ nvmem_layouts-y := layouts.o
|
||||
obj-y += layouts/
|
||||
|
||||
# Devices
|
||||
+obj-$(CONFIG_NVMEM_AN8855_EFUSE) += nvmem-an8855-efuse.o
|
||||
+nvmem-an8855-efuse-y := an8855-efuse.o
|
||||
obj-$(CONFIG_NVMEM_APPLE_EFUSES) += nvmem-apple-efuses.o
|
||||
nvmem-apple-efuses-y := apple-efuses.o
|
||||
obj-$(CONFIG_NVMEM_BCM_OCOTP) += nvmem-bcm-ocotp.o
|
@ -0,0 +1,166 @@
|
||||
From 5e5401d6612ef599ad45785b941eebda7effc90f Mon Sep 17 00:00:00 2001
|
||||
From: "Russell King (Oracle)" <rmk+kernel@armlinux.org.uk>
|
||||
Date: Thu, 4 Jan 2024 09:47:36 +0000
|
||||
Subject: [PATCH] net: phylink: move phylink_pcs_neg_mode() into phylink.c
|
||||
|
||||
Move phylink_pcs_neg_mode() from the header file into the .c file since
|
||||
nothing should be using it.
|
||||
|
||||
Signed-off-by: Russell King (Oracle) <rmk+kernel@armlinux.org.uk>
|
||||
Reviewed-by: Andrew Lunn <andrew@lunn.ch>
|
||||
Signed-off-by: David S. Miller <davem@davemloft.net>
|
||||
---
|
||||
drivers/net/phy/phylink.c | 66 +++++++++++++++++++++++++++++++++++++++
|
||||
include/linux/phylink.h | 66 ---------------------------------------
|
||||
2 files changed, 66 insertions(+), 66 deletions(-)
|
||||
|
||||
--- a/drivers/net/phy/phylink.c
|
||||
+++ b/drivers/net/phy/phylink.c
|
||||
@@ -1150,6 +1150,72 @@ static void phylink_pcs_an_restart(struc
|
||||
pl->pcs->ops->pcs_an_restart(pl->pcs);
|
||||
}
|
||||
|
||||
+/**
|
||||
+ * phylink_pcs_neg_mode() - helper to determine PCS inband mode
|
||||
+ * @mode: one of %MLO_AN_FIXED, %MLO_AN_PHY, %MLO_AN_INBAND.
|
||||
+ * @interface: interface mode to be used
|
||||
+ * @advertising: adertisement ethtool link mode mask
|
||||
+ *
|
||||
+ * Determines the negotiation mode to be used by the PCS, and returns
|
||||
+ * one of:
|
||||
+ *
|
||||
+ * - %PHYLINK_PCS_NEG_NONE: interface mode does not support inband
|
||||
+ * - %PHYLINK_PCS_NEG_OUTBAND: an out of band mode (e.g. reading the PHY)
|
||||
+ * will be used.
|
||||
+ * - %PHYLINK_PCS_NEG_INBAND_DISABLED: inband mode selected but autoneg
|
||||
+ * disabled
|
||||
+ * - %PHYLINK_PCS_NEG_INBAND_ENABLED: inband mode selected and autoneg enabled
|
||||
+ *
|
||||
+ * Note: this is for cases where the PCS itself is involved in negotiation
|
||||
+ * (e.g. Clause 37, SGMII and similar) not Clause 73.
|
||||
+ */
|
||||
+static unsigned int phylink_pcs_neg_mode(unsigned int mode,
|
||||
+ phy_interface_t interface,
|
||||
+ const unsigned long *advertising)
|
||||
+{
|
||||
+ unsigned int neg_mode;
|
||||
+
|
||||
+ switch (interface) {
|
||||
+ case PHY_INTERFACE_MODE_SGMII:
|
||||
+ case PHY_INTERFACE_MODE_QSGMII:
|
||||
+ case PHY_INTERFACE_MODE_QUSGMII:
|
||||
+ case PHY_INTERFACE_MODE_USXGMII:
|
||||
+ /* These protocols are designed for use with a PHY which
|
||||
+ * communicates its negotiation result back to the MAC via
|
||||
+ * inband communication. Note: there exist PHYs that run
|
||||
+ * with SGMII but do not send the inband data.
|
||||
+ */
|
||||
+ if (!phylink_autoneg_inband(mode))
|
||||
+ neg_mode = PHYLINK_PCS_NEG_OUTBAND;
|
||||
+ else
|
||||
+ neg_mode = PHYLINK_PCS_NEG_INBAND_ENABLED;
|
||||
+ break;
|
||||
+
|
||||
+ case PHY_INTERFACE_MODE_1000BASEX:
|
||||
+ case PHY_INTERFACE_MODE_2500BASEX:
|
||||
+ /* 1000base-X is designed for use media-side for Fibre
|
||||
+ * connections, and thus the Autoneg bit needs to be
|
||||
+ * taken into account. We also do this for 2500base-X
|
||||
+ * as well, but drivers may not support this, so may
|
||||
+ * need to override this.
|
||||
+ */
|
||||
+ if (!phylink_autoneg_inband(mode))
|
||||
+ neg_mode = PHYLINK_PCS_NEG_OUTBAND;
|
||||
+ else if (linkmode_test_bit(ETHTOOL_LINK_MODE_Autoneg_BIT,
|
||||
+ advertising))
|
||||
+ neg_mode = PHYLINK_PCS_NEG_INBAND_ENABLED;
|
||||
+ else
|
||||
+ neg_mode = PHYLINK_PCS_NEG_INBAND_DISABLED;
|
||||
+ break;
|
||||
+
|
||||
+ default:
|
||||
+ neg_mode = PHYLINK_PCS_NEG_NONE;
|
||||
+ break;
|
||||
+ }
|
||||
+
|
||||
+ return neg_mode;
|
||||
+}
|
||||
+
|
||||
static void phylink_major_config(struct phylink *pl, bool restart,
|
||||
const struct phylink_link_state *state)
|
||||
{
|
||||
--- a/include/linux/phylink.h
|
||||
+++ b/include/linux/phylink.h
|
||||
@@ -99,72 +99,6 @@ static inline bool phylink_autoneg_inban
|
||||
}
|
||||
|
||||
/**
|
||||
- * phylink_pcs_neg_mode() - helper to determine PCS inband mode
|
||||
- * @mode: one of %MLO_AN_FIXED, %MLO_AN_PHY, %MLO_AN_INBAND.
|
||||
- * @interface: interface mode to be used
|
||||
- * @advertising: adertisement ethtool link mode mask
|
||||
- *
|
||||
- * Determines the negotiation mode to be used by the PCS, and returns
|
||||
- * one of:
|
||||
- *
|
||||
- * - %PHYLINK_PCS_NEG_NONE: interface mode does not support inband
|
||||
- * - %PHYLINK_PCS_NEG_OUTBAND: an out of band mode (e.g. reading the PHY)
|
||||
- * will be used.
|
||||
- * - %PHYLINK_PCS_NEG_INBAND_DISABLED: inband mode selected but autoneg
|
||||
- * disabled
|
||||
- * - %PHYLINK_PCS_NEG_INBAND_ENABLED: inband mode selected and autoneg enabled
|
||||
- *
|
||||
- * Note: this is for cases where the PCS itself is involved in negotiation
|
||||
- * (e.g. Clause 37, SGMII and similar) not Clause 73.
|
||||
- */
|
||||
-static inline unsigned int phylink_pcs_neg_mode(unsigned int mode,
|
||||
- phy_interface_t interface,
|
||||
- const unsigned long *advertising)
|
||||
-{
|
||||
- unsigned int neg_mode;
|
||||
-
|
||||
- switch (interface) {
|
||||
- case PHY_INTERFACE_MODE_SGMII:
|
||||
- case PHY_INTERFACE_MODE_QSGMII:
|
||||
- case PHY_INTERFACE_MODE_QUSGMII:
|
||||
- case PHY_INTERFACE_MODE_USXGMII:
|
||||
- /* These protocols are designed for use with a PHY which
|
||||
- * communicates its negotiation result back to the MAC via
|
||||
- * inband communication. Note: there exist PHYs that run
|
||||
- * with SGMII but do not send the inband data.
|
||||
- */
|
||||
- if (!phylink_autoneg_inband(mode))
|
||||
- neg_mode = PHYLINK_PCS_NEG_OUTBAND;
|
||||
- else
|
||||
- neg_mode = PHYLINK_PCS_NEG_INBAND_ENABLED;
|
||||
- break;
|
||||
-
|
||||
- case PHY_INTERFACE_MODE_1000BASEX:
|
||||
- case PHY_INTERFACE_MODE_2500BASEX:
|
||||
- /* 1000base-X is designed for use media-side for Fibre
|
||||
- * connections, and thus the Autoneg bit needs to be
|
||||
- * taken into account. We also do this for 2500base-X
|
||||
- * as well, but drivers may not support this, so may
|
||||
- * need to override this.
|
||||
- */
|
||||
- if (!phylink_autoneg_inband(mode))
|
||||
- neg_mode = PHYLINK_PCS_NEG_OUTBAND;
|
||||
- else if (linkmode_test_bit(ETHTOOL_LINK_MODE_Autoneg_BIT,
|
||||
- advertising))
|
||||
- neg_mode = PHYLINK_PCS_NEG_INBAND_ENABLED;
|
||||
- else
|
||||
- neg_mode = PHYLINK_PCS_NEG_INBAND_DISABLED;
|
||||
- break;
|
||||
-
|
||||
- default:
|
||||
- neg_mode = PHYLINK_PCS_NEG_NONE;
|
||||
- break;
|
||||
- }
|
||||
-
|
||||
- return neg_mode;
|
||||
-}
|
||||
-
|
||||
-/**
|
||||
* struct phylink_link_state - link state structure
|
||||
* @advertising: ethtool bitmask containing advertised link modes
|
||||
* @lp_advertising: ethtool bitmask containing link partner advertised link
|
File diff suppressed because it is too large
Load Diff
Loading…
x
Reference in New Issue
Block a user