Merge Official Source

Signed-off-by: Tianling Shen <cnsztl@immortalwrt.org>
This commit is contained in:
Tianling Shen 2021-10-12 14:39:40 +08:00
commit cf49626f45
No known key found for this signature in database
GPG Key ID: 6850B6345C862176
104 changed files with 7958 additions and 2331 deletions

View File

@ -6,11 +6,11 @@ ifdef CONFIG_TESTING_KERNEL
KERNEL_PATCHVER:=$(KERNEL_TESTING_PATCHVER)
endif
LINUX_VERSION-5.4 = .150
LINUX_VERSION-5.10 = .70
LINUX_VERSION-5.4 = .152
LINUX_VERSION-5.10 = .72
LINUX_KERNEL_HASH-5.4.150 = f424a9bbb05007f04c17f96a2e4f041a8001554a9060d2c291606e8a97c62aa2
LINUX_KERNEL_HASH-5.10.70 = 75736c33711d7f298889ee4981b18774882045323e5c46af9ad3b022082db232
LINUX_KERNEL_HASH-5.4.152 = 8044c7134c5eed21af9662f1c5399a5d8781b5bc2d8979e9ad06b4435a0a5ed5
LINUX_KERNEL_HASH-5.10.72 = b4d635afe7646ac6a6617c738e747ba0a6006675cd9735d18f672f8b1fba4c7c
remove_uri_prefix=$(subst git://,,$(subst http://,,$(subst https://,,$(1))))
sanitize_uri=$(call qstrip,$(subst @,_,$(subst :,_,$(subst .,_,$(subst -,_,$(subst /,_,$(1)))))))

View File

@ -19,7 +19,6 @@
#
# Host packages are built in the same fashion, just use these vars instead:
#
# HOST_BUILD_DEPENDS:=meson/host
# MESON_HOST_ARGS+=-Dfoo -Dbar=baz
# MESON_HOST_VARS+=FOO=bar
@ -57,7 +56,7 @@ MESON_CPU:="$(CPU_TYPE)$(if $(CPU_SUBTYPE),+$(CPU_SUBTYPE))"
endif
define Meson
$(2) $(STAGING_DIR_HOST)/bin/$(PYTHON) $(MESON_DIR)/meson.py $(1)
$(2) $(STAGING_DIR_HOST)/bin/$(PYTHON) $(STAGING_DIR_HOST)/bin/meson $(1)
endef
define Meson/CreateNativeFile

View File

@ -162,7 +162,7 @@ $(eval $(call SetupHostCommand,python,Please install Python >= 3.6, \
python3.8 -V 2>&1 | grep 'Python 3', \
python3.7 -V 2>&1 | grep 'Python 3', \
python3.6 -V 2>&1 | grep 'Python 3', \
python3 -V 2>&1 | grep -E 'Python 3\.[6-9]\.?'))
python3 -V 2>&1 | grep -E 'Python 3\.([6-9]|10)\.?'))
$(eval $(call SetupHostCommand,python3,Please install Python >= 3.6, \
python3.10 -V 2>&1 | grep 'Python 3', \
@ -170,7 +170,7 @@ $(eval $(call SetupHostCommand,python3,Please install Python >= 3.6, \
python3.8 -V 2>&1 | grep 'Python 3', \
python3.7 -V 2>&1 | grep 'Python 3', \
python3.6 -V 2>&1 | grep 'Python 3', \
python3 -V 2>&1 | grep -E 'Python 3\.[6-9]\.?'))
python3 -V 2>&1 | grep -E 'Python 3\.([6-9]|10)\.?'))
$(eval $(call TestHostCommand,python3-distutils, \
Please install the Python3 distutils module, \

View File

@ -33,6 +33,16 @@ else
DEFAULT_PACKAGES+=busybox procd
endif
# include ujail on systems with enough storage
ifeq ($(CONFIG_SMALL_FLASH),)
DEFAULT_PACKAGES+=procd-ujail
endif
# include seccomp ld-preload hooks if kernel supports it
ifneq ($(CONFIG_KERNEL_SECCOMP),)
DEFAULT_PACKAGES+=procd-seccomp
endif
# For the basic set
DEFAULT_PACKAGES.basic:=
# For nas targets

View File

@ -78,7 +78,7 @@ define U-Boot/rock-pi-4-rk3399
BUILD_SUBTARGET:=armv8
NAME:=Rock Pi 4
BUILD_DEVICES:= \
radxa_rock-pi-4
radxa_rock-pi-4a
DEPENDS:=+PACKAGE_u-boot-rock-pi-4-rk3399:arm-trusted-firmware-rockchip
PKG_BUILD_DEPENDS:=arm-trusted-firmware-rockchip
ATF:=rk3399_bl31.elf

View File

@ -0,0 +1,112 @@
From: Lorenzo Bianconi <lorenzo@kernel.org>
Date: Mon, 23 Aug 2021 20:02:38 +0200
Subject: [PATCH] ieee80211: add TWT element definitions
Introduce TWT definitions and TWT Information element structure
in ieee80211.h
Tested-by: Peter Chiu <chui-hao.chiu@mediatek.com>
Signed-off-by: Lorenzo Bianconi <lorenzo@kernel.org>
Link: https://lore.kernel.org/r/71d8b581fe4b5abc5b92f8d77ac2de3e2f7591b6.1629741512.git.lorenzo@kernel.org
Signed-off-by: Johannes Berg <johannes.berg@intel.com>
---
--- a/include/linux/ieee80211.h
+++ b/include/linux/ieee80211.h
@@ -1088,6 +1088,48 @@ struct ieee80211_ext {
} u;
} __packed __aligned(2);
+#define IEEE80211_TWT_CONTROL_NDP BIT(0)
+#define IEEE80211_TWT_CONTROL_RESP_MODE BIT(1)
+#define IEEE80211_TWT_CONTROL_NEG_TYPE_BROADCAST BIT(3)
+#define IEEE80211_TWT_CONTROL_RX_DISABLED BIT(4)
+#define IEEE80211_TWT_CONTROL_WAKE_DUR_UNIT BIT(5)
+
+#define IEEE80211_TWT_REQTYPE_REQUEST BIT(0)
+#define IEEE80211_TWT_REQTYPE_SETUP_CMD GENMASK(3, 1)
+#define IEEE80211_TWT_REQTYPE_TRIGGER BIT(4)
+#define IEEE80211_TWT_REQTYPE_IMPLICIT BIT(5)
+#define IEEE80211_TWT_REQTYPE_FLOWTYPE BIT(6)
+#define IEEE80211_TWT_REQTYPE_FLOWID GENMASK(9, 7)
+#define IEEE80211_TWT_REQTYPE_WAKE_INT_EXP GENMASK(14, 10)
+#define IEEE80211_TWT_REQTYPE_PROTECTION BIT(15)
+
+enum ieee80211_twt_setup_cmd {
+ TWT_SETUP_CMD_REQUEST,
+ TWT_SETUP_CMD_SUGGEST,
+ TWT_SETUP_CMD_DEMAND,
+ TWT_SETUP_CMD_GROUPING,
+ TWT_SETUP_CMD_ACCEPT,
+ TWT_SETUP_CMD_ALTERNATE,
+ TWT_SETUP_CMD_DICTATE,
+ TWT_SETUP_CMD_REJECT,
+};
+
+struct ieee80211_twt_params {
+ __le16 req_type;
+ __le64 twt;
+ u8 min_twt_dur;
+ __le16 mantissa;
+ u8 channel;
+} __packed;
+
+struct ieee80211_twt_setup {
+ u8 dialog_token;
+ u8 element_id;
+ u8 length;
+ u8 control;
+ u8 params[];
+} __packed;
+
struct ieee80211_mgmt {
__le16 frame_control;
__le16 duration;
@@ -1252,6 +1294,10 @@ struct ieee80211_mgmt {
__le16 toa_error;
u8 variable[0];
} __packed ftm;
+ struct {
+ u8 action_code;
+ u8 variable[];
+ } __packed s1g;
} u;
} __packed action;
} u;
@@ -2880,6 +2926,7 @@ enum ieee80211_eid {
WLAN_EID_AID_RESPONSE = 211,
WLAN_EID_S1G_BCN_COMPAT = 213,
WLAN_EID_S1G_SHORT_BCN_INTERVAL = 214,
+ WLAN_EID_S1G_TWT = 216,
WLAN_EID_S1G_CAPABILITIES = 217,
WLAN_EID_VENDOR_SPECIFIC = 221,
WLAN_EID_QOS_PARAMETER = 222,
@@ -2948,6 +2995,7 @@ enum ieee80211_category {
WLAN_CATEGORY_FST = 18,
WLAN_CATEGORY_UNPROT_DMG = 20,
WLAN_CATEGORY_VHT = 21,
+ WLAN_CATEGORY_S1G = 22,
WLAN_CATEGORY_VENDOR_SPECIFIC_PROTECTED = 126,
WLAN_CATEGORY_VENDOR_SPECIFIC = 127,
};
@@ -3021,6 +3069,20 @@ enum ieee80211_key_len {
WLAN_KEY_LEN_BIP_GMAC_256 = 32,
};
+enum ieee80211_s1g_actioncode {
+ WLAN_S1G_AID_SWITCH_REQUEST,
+ WLAN_S1G_AID_SWITCH_RESPONSE,
+ WLAN_S1G_SYNC_CONTROL,
+ WLAN_S1G_STA_INFO_ANNOUNCE,
+ WLAN_S1G_EDCA_PARAM_SET,
+ WLAN_S1G_EL_OPERATION,
+ WLAN_S1G_TWT_SETUP,
+ WLAN_S1G_TWT_TEARDOWN,
+ WLAN_S1G_SECT_GROUP_ID_LIST,
+ WLAN_S1G_SECT_ID_FEEDBACK,
+ WLAN_S1G_TWT_INFORMATION = 11,
+};
+
#define IEEE80211_WEP_IV_LEN 4
#define IEEE80211_WEP_ICV_LEN 4
#define IEEE80211_CCMP_HDR_LEN 8

View File

@ -0,0 +1,576 @@
From: Lorenzo Bianconi <lorenzo@kernel.org>
Date: Mon, 23 Aug 2021 20:02:39 +0200
Subject: [PATCH] mac80211: introduce individual TWT support in AP mode
Introduce TWT action frames parsing support to mac80211.
Currently just individual TWT agreement are support in AP mode.
Whenever the AP receives a TWT action frame from an associated client,
after performing sanity checks, it will notify the underlay driver with
requested parameters in order to check if they are supported and if there
is enough room for a new agreement. The driver is expected to set the
agreement result and report it to mac80211.
Drivers supporting this have two new callbacks:
- add_twt_setup (mandatory)
- twt_teardown_request (optional)
mac80211 will send an action frame reply according to the result
reported by the driver.
Tested-by: Peter Chiu <chui-hao.chiu@mediatek.com>
Signed-off-by: Lorenzo Bianconi <lorenzo@kernel.org>
Link: https://lore.kernel.org/r/257512f2e22ba42b9f2624942a128dd8f141de4b.1629741512.git.lorenzo@kernel.org
[use le16p_replace_bits(), minor cleanups, use (void *) casts,
fix to use ieee80211_get_he_iftype_cap() correctly]
Signed-off-by: Johannes Berg <johannes.berg@intel.com>
---
--- a/include/net/mac80211.h
+++ b/include/net/mac80211.h
@@ -4219,6 +4219,11 @@ struct ieee80211_ops {
void (*sta_set_decap_offload)(struct ieee80211_hw *hw,
struct ieee80211_vif *vif,
struct ieee80211_sta *sta, bool enabled);
+ void (*add_twt_setup)(struct ieee80211_hw *hw,
+ struct ieee80211_sta *sta,
+ struct ieee80211_twt_setup *twt);
+ void (*twt_teardown_request)(struct ieee80211_hw *hw,
+ struct ieee80211_sta *sta, u8 flowid);
};
/**
--- a/net/mac80211/driver-ops.h
+++ b/net/mac80211/driver-ops.h
@@ -1429,4 +1429,40 @@ static inline void drv_sta_set_decap_off
trace_drv_return_void(local);
}
+static inline void drv_add_twt_setup(struct ieee80211_local *local,
+ struct ieee80211_sub_if_data *sdata,
+ struct ieee80211_sta *sta,
+ struct ieee80211_twt_setup *twt)
+{
+ struct ieee80211_twt_params *twt_agrt;
+
+ might_sleep();
+
+ if (!check_sdata_in_driver(sdata))
+ return;
+
+ twt_agrt = (void *)twt->params;
+
+ trace_drv_add_twt_setup(local, sta, twt, twt_agrt);
+ local->ops->add_twt_setup(&local->hw, sta, twt);
+ trace_drv_return_void(local);
+}
+
+static inline void drv_twt_teardown_request(struct ieee80211_local *local,
+ struct ieee80211_sub_if_data *sdata,
+ struct ieee80211_sta *sta,
+ u8 flowid)
+{
+ might_sleep();
+ if (!check_sdata_in_driver(sdata))
+ return;
+
+ if (!local->ops->twt_teardown_request)
+ return;
+
+ trace_drv_twt_teardown_request(local, sta, flowid);
+ local->ops->twt_teardown_request(&local->hw, sta, flowid);
+ trace_drv_return_void(local);
+}
+
#endif /* __MAC80211_DRIVER_OPS */
--- a/net/mac80211/ieee80211_i.h
+++ b/net/mac80211/ieee80211_i.h
@@ -954,6 +954,7 @@ struct ieee80211_sub_if_data {
struct work_struct work;
struct sk_buff_head skb_queue;
+ struct sk_buff_head status_queue;
u8 needed_rx_chains;
enum ieee80211_smps_mode smps_mode;
@@ -2093,6 +2094,11 @@ ieee80211_he_op_ie_to_bss_conf(struct ie
/* S1G */
void ieee80211_s1g_sta_rate_init(struct sta_info *sta);
+bool ieee80211_s1g_is_twt_setup(struct sk_buff *skb);
+void ieee80211_s1g_rx_twt_action(struct ieee80211_sub_if_data *sdata,
+ struct sk_buff *skb);
+void ieee80211_s1g_status_twt_action(struct ieee80211_sub_if_data *sdata,
+ struct sk_buff *skb);
/* Spectrum management */
void ieee80211_process_measurement_req(struct ieee80211_sub_if_data *sdata,
--- a/net/mac80211/iface.c
+++ b/net/mac80211/iface.c
@@ -563,6 +563,7 @@ static void ieee80211_do_stop(struct iee
*/
ieee80211_free_keys(sdata, true);
skb_queue_purge(&sdata->skb_queue);
+ skb_queue_purge(&sdata->status_queue);
}
spin_lock_irqsave(&local->queue_stop_reason_lock, flags);
@@ -1070,6 +1071,7 @@ int ieee80211_add_virtual_monitor(struct
}
skb_queue_head_init(&sdata->skb_queue);
+ skb_queue_head_init(&sdata->status_queue);
INIT_WORK(&sdata->work, ieee80211_iface_work);
return 0;
@@ -1442,6 +1444,24 @@ static void ieee80211_if_setup_no_queue(
#endif
}
+static void ieee80211_iface_process_status(struct ieee80211_sub_if_data *sdata,
+ struct sk_buff *skb)
+{
+ struct ieee80211_mgmt *mgmt = (void *)skb->data;
+
+ if (ieee80211_is_action(mgmt->frame_control) &&
+ mgmt->u.action.category == WLAN_CATEGORY_S1G) {
+ switch (mgmt->u.action.u.s1g.action_code) {
+ case WLAN_S1G_TWT_TEARDOWN:
+ case WLAN_S1G_TWT_SETUP:
+ ieee80211_s1g_status_twt_action(sdata, skb);
+ break;
+ default:
+ break;
+ }
+ }
+}
+
static void ieee80211_iface_work(struct work_struct *work)
{
struct ieee80211_sub_if_data *sdata =
@@ -1519,6 +1539,16 @@ static void ieee80211_iface_work(struct
WARN_ON(1);
break;
}
+ } else if (ieee80211_is_action(mgmt->frame_control) &&
+ mgmt->u.action.category == WLAN_CATEGORY_S1G) {
+ switch (mgmt->u.action.u.s1g.action_code) {
+ case WLAN_S1G_TWT_TEARDOWN:
+ case WLAN_S1G_TWT_SETUP:
+ ieee80211_s1g_rx_twt_action(sdata, skb);
+ break;
+ default:
+ break;
+ }
} else if (ieee80211_is_ext(mgmt->frame_control)) {
if (sdata->vif.type == NL80211_IFTYPE_STATION)
ieee80211_sta_rx_queued_ext(sdata, skb);
@@ -1574,6 +1604,12 @@ static void ieee80211_iface_work(struct
kfree_skb(skb);
}
+ /* process status queue */
+ while ((skb = skb_dequeue(&sdata->status_queue))) {
+ ieee80211_iface_process_status(sdata, skb);
+ kfree_skb(skb);
+ }
+
/* then other type-dependent work */
switch (sdata->vif.type) {
case NL80211_IFTYPE_STATION:
@@ -1637,6 +1677,7 @@ static void ieee80211_setup_sdata(struct
}
skb_queue_head_init(&sdata->skb_queue);
+ skb_queue_head_init(&sdata->status_queue);
INIT_WORK(&sdata->work, ieee80211_iface_work);
INIT_WORK(&sdata->recalc_smps, ieee80211_recalc_smps_work);
INIT_WORK(&sdata->csa_finalize_work, ieee80211_csa_finalize_work);
--- a/net/mac80211/rx.c
+++ b/net/mac80211/rx.c
@@ -3208,6 +3208,68 @@ ieee80211_rx_h_mgmt_check(struct ieee802
return RX_CONTINUE;
}
+static bool
+ieee80211_process_rx_twt_action(struct ieee80211_rx_data *rx)
+{
+ struct ieee80211_mgmt *mgmt = (struct ieee80211_mgmt *)rx->skb->data;
+ struct ieee80211_rx_status *status = IEEE80211_SKB_RXCB(rx->skb);
+ struct ieee80211_sub_if_data *sdata = rx->sdata;
+ const struct ieee80211_sta_he_cap *hecap;
+ struct ieee80211_supported_band *sband;
+
+ /* TWT actions are only supported in AP for the moment */
+ if (sdata->vif.type != NL80211_IFTYPE_AP)
+ return false;
+
+ if (!rx->local->ops->add_twt_setup)
+ return false;
+
+ sband = rx->local->hw.wiphy->bands[status->band];
+ hecap = ieee80211_get_he_iftype_cap(sband,
+ ieee80211_vif_type_p2p(&sdata->vif));
+ if (!hecap)
+ return false;
+
+ if (!(hecap->he_cap_elem.mac_cap_info[0] &
+ IEEE80211_HE_MAC_CAP0_TWT_RES))
+ return false;
+
+ if (!rx->sta)
+ return false;
+
+ switch (mgmt->u.action.u.s1g.action_code) {
+ case WLAN_S1G_TWT_SETUP: {
+ struct ieee80211_twt_setup *twt;
+
+ if (rx->skb->len < IEEE80211_MIN_ACTION_SIZE +
+ 1 + /* action code */
+ sizeof(struct ieee80211_twt_setup) +
+ 2 /* TWT req_type agrt */)
+ break;
+
+ twt = (void *)mgmt->u.action.u.s1g.variable;
+ if (twt->element_id != WLAN_EID_S1G_TWT)
+ break;
+
+ if (rx->skb->len < IEEE80211_MIN_ACTION_SIZE +
+ 4 + /* action code + token + tlv */
+ twt->length)
+ break;
+
+ return true; /* queue the frame */
+ }
+ case WLAN_S1G_TWT_TEARDOWN:
+ if (rx->skb->len < IEEE80211_MIN_ACTION_SIZE + 2)
+ break;
+
+ return true; /* queue the frame */
+ default:
+ break;
+ }
+
+ return false;
+}
+
static ieee80211_rx_result debug_noinline
ieee80211_rx_h_action(struct ieee80211_rx_data *rx)
{
@@ -3487,6 +3549,17 @@ ieee80211_rx_h_action(struct ieee80211_r
!mesh_path_sel_is_hwmp(sdata))
break;
goto queue;
+ case WLAN_CATEGORY_S1G:
+ switch (mgmt->u.action.u.s1g.action_code) {
+ case WLAN_S1G_TWT_SETUP:
+ case WLAN_S1G_TWT_TEARDOWN:
+ if (ieee80211_process_rx_twt_action(rx))
+ goto queue;
+ break;
+ default:
+ break;
+ }
+ break;
}
return RX_CONTINUE;
--- a/net/mac80211/s1g.c
+++ b/net/mac80211/s1g.c
@@ -6,6 +6,7 @@
#include <linux/ieee80211.h>
#include <net/mac80211.h>
#include "ieee80211_i.h"
+#include "driver-ops.h"
void ieee80211_s1g_sta_rate_init(struct sta_info *sta)
{
@@ -14,3 +15,182 @@ void ieee80211_s1g_sta_rate_init(struct
sta->rx_stats.last_rate =
STA_STATS_FIELD(TYPE, STA_STATS_RATE_TYPE_S1G);
}
+
+bool ieee80211_s1g_is_twt_setup(struct sk_buff *skb)
+{
+ struct ieee80211_mgmt *mgmt = (struct ieee80211_mgmt *)skb->data;
+
+ if (likely(!ieee80211_is_action(mgmt->frame_control)))
+ return false;
+
+ if (likely(mgmt->u.action.category != WLAN_CATEGORY_S1G))
+ return false;
+
+ return mgmt->u.action.u.s1g.action_code == WLAN_S1G_TWT_SETUP;
+}
+
+static void
+ieee80211_s1g_send_twt_setup(struct ieee80211_sub_if_data *sdata, const u8 *da,
+ const u8 *bssid, struct ieee80211_twt_setup *twt)
+{
+ int len = IEEE80211_MIN_ACTION_SIZE + 4 + twt->length;
+ struct ieee80211_local *local = sdata->local;
+ struct ieee80211_mgmt *mgmt;
+ struct sk_buff *skb;
+
+ skb = dev_alloc_skb(local->hw.extra_tx_headroom + len);
+ if (!skb)
+ return;
+
+ skb_reserve(skb, local->hw.extra_tx_headroom);
+ mgmt = skb_put_zero(skb, len);
+ mgmt->frame_control = cpu_to_le16(IEEE80211_FTYPE_MGMT |
+ IEEE80211_STYPE_ACTION);
+ memcpy(mgmt->da, da, ETH_ALEN);
+ memcpy(mgmt->sa, sdata->vif.addr, ETH_ALEN);
+ memcpy(mgmt->bssid, bssid, ETH_ALEN);
+
+ mgmt->u.action.category = WLAN_CATEGORY_S1G;
+ mgmt->u.action.u.s1g.action_code = WLAN_S1G_TWT_SETUP;
+ memcpy(mgmt->u.action.u.s1g.variable, twt, 3 + twt->length);
+
+ IEEE80211_SKB_CB(skb)->flags |= IEEE80211_TX_INTFL_DONT_ENCRYPT |
+ IEEE80211_TX_INTFL_MLME_CONN_TX |
+ IEEE80211_TX_CTL_REQ_TX_STATUS;
+ ieee80211_tx_skb(sdata, skb);
+}
+
+static void
+ieee80211_s1g_send_twt_teardown(struct ieee80211_sub_if_data *sdata,
+ const u8 *da, const u8 *bssid, u8 flowid)
+{
+ struct ieee80211_local *local = sdata->local;
+ struct ieee80211_mgmt *mgmt;
+ struct sk_buff *skb;
+ u8 *id;
+
+ skb = dev_alloc_skb(local->hw.extra_tx_headroom +
+ IEEE80211_MIN_ACTION_SIZE + 2);
+ if (!skb)
+ return;
+
+ skb_reserve(skb, local->hw.extra_tx_headroom);
+ mgmt = skb_put_zero(skb, IEEE80211_MIN_ACTION_SIZE + 2);
+ mgmt->frame_control = cpu_to_le16(IEEE80211_FTYPE_MGMT |
+ IEEE80211_STYPE_ACTION);
+ memcpy(mgmt->da, da, ETH_ALEN);
+ memcpy(mgmt->sa, sdata->vif.addr, ETH_ALEN);
+ memcpy(mgmt->bssid, bssid, ETH_ALEN);
+
+ mgmt->u.action.category = WLAN_CATEGORY_S1G;
+ mgmt->u.action.u.s1g.action_code = WLAN_S1G_TWT_TEARDOWN;
+ id = (u8 *)mgmt->u.action.u.s1g.variable;
+ *id = flowid;
+
+ IEEE80211_SKB_CB(skb)->flags |= IEEE80211_TX_INTFL_DONT_ENCRYPT |
+ IEEE80211_TX_CTL_REQ_TX_STATUS;
+ ieee80211_tx_skb(sdata, skb);
+}
+
+static void
+ieee80211_s1g_rx_twt_setup(struct ieee80211_sub_if_data *sdata,
+ struct sta_info *sta, struct sk_buff *skb)
+{
+ struct ieee80211_mgmt *mgmt = (void *)skb->data;
+ struct ieee80211_twt_setup *twt = (void *)mgmt->u.action.u.s1g.variable;
+ struct ieee80211_twt_params *twt_agrt = (void *)twt->params;
+
+ twt_agrt->req_type &= cpu_to_le16(~IEEE80211_TWT_REQTYPE_REQUEST);
+
+ /* broadcast TWT not supported yet */
+ if (twt->control & IEEE80211_TWT_CONTROL_NEG_TYPE_BROADCAST) {
+ le16p_replace_bits(&twt_agrt->req_type,
+ TWT_SETUP_CMD_REJECT,
+ IEEE80211_TWT_REQTYPE_SETUP_CMD);
+ goto out;
+ }
+
+ drv_add_twt_setup(sdata->local, sdata, &sta->sta, twt);
+out:
+ ieee80211_s1g_send_twt_setup(sdata, mgmt->sa, sdata->vif.addr, twt);
+}
+
+static void
+ieee80211_s1g_rx_twt_teardown(struct ieee80211_sub_if_data *sdata,
+ struct sta_info *sta, struct sk_buff *skb)
+{
+ struct ieee80211_mgmt *mgmt = (struct ieee80211_mgmt *)skb->data;
+
+ drv_twt_teardown_request(sdata->local, sdata, &sta->sta,
+ mgmt->u.action.u.s1g.variable[0]);
+}
+
+static void
+ieee80211_s1g_tx_twt_setup_fail(struct ieee80211_sub_if_data *sdata,
+ struct sta_info *sta, struct sk_buff *skb)
+{
+ struct ieee80211_mgmt *mgmt = (struct ieee80211_mgmt *)skb->data;
+ struct ieee80211_twt_setup *twt = (void *)mgmt->u.action.u.s1g.variable;
+ struct ieee80211_twt_params *twt_agrt = (void *)twt->params;
+ u8 flowid = le16_get_bits(twt_agrt->req_type,
+ IEEE80211_TWT_REQTYPE_FLOWID);
+
+ drv_twt_teardown_request(sdata->local, sdata, &sta->sta, flowid);
+
+ ieee80211_s1g_send_twt_teardown(sdata, mgmt->sa, sdata->vif.addr,
+ flowid);
+}
+
+void ieee80211_s1g_rx_twt_action(struct ieee80211_sub_if_data *sdata,
+ struct sk_buff *skb)
+{
+ struct ieee80211_mgmt *mgmt = (struct ieee80211_mgmt *)skb->data;
+ struct ieee80211_local *local = sdata->local;
+ struct sta_info *sta;
+
+ mutex_lock(&local->sta_mtx);
+
+ sta = sta_info_get_bss(sdata, mgmt->sa);
+ if (!sta)
+ goto out;
+
+ switch (mgmt->u.action.u.s1g.action_code) {
+ case WLAN_S1G_TWT_SETUP:
+ ieee80211_s1g_rx_twt_setup(sdata, sta, skb);
+ break;
+ case WLAN_S1G_TWT_TEARDOWN:
+ ieee80211_s1g_rx_twt_teardown(sdata, sta, skb);
+ break;
+ default:
+ break;
+ }
+
+out:
+ mutex_unlock(&local->sta_mtx);
+}
+
+void ieee80211_s1g_status_twt_action(struct ieee80211_sub_if_data *sdata,
+ struct sk_buff *skb)
+{
+ struct ieee80211_mgmt *mgmt = (struct ieee80211_mgmt *)skb->data;
+ struct ieee80211_local *local = sdata->local;
+ struct sta_info *sta;
+
+ mutex_lock(&local->sta_mtx);
+
+ sta = sta_info_get_bss(sdata, mgmt->da);
+ if (!sta)
+ goto out;
+
+ switch (mgmt->u.action.u.s1g.action_code) {
+ case WLAN_S1G_TWT_SETUP:
+ /* process failed twt setup frames */
+ ieee80211_s1g_tx_twt_setup_fail(sdata, sta, skb);
+ break;
+ default:
+ break;
+ }
+
+out:
+ mutex_unlock(&local->sta_mtx);
+}
--- a/net/mac80211/status.c
+++ b/net/mac80211/status.c
@@ -705,13 +705,26 @@ static void ieee80211_report_used_skb(st
/* Check to see if packet is a TDLS teardown packet */
if (ieee80211_is_data(hdr->frame_control) &&
(ieee80211_get_tdls_action(skb, hdr_size) ==
- WLAN_TDLS_TEARDOWN))
+ WLAN_TDLS_TEARDOWN)) {
ieee80211_tdls_td_tx_handle(local, sdata, skb,
info->flags);
- else
+ } else if (ieee80211_s1g_is_twt_setup(skb)) {
+ if (!acked) {
+ struct sk_buff *qskb;
+
+ qskb = skb_clone(skb, GFP_ATOMIC);
+ if (qskb) {
+ skb_queue_tail(&sdata->status_queue,
+ qskb);
+ ieee80211_queue_work(&local->hw,
+ &sdata->work);
+ }
+ }
+ } else {
ieee80211_mgd_conn_tx_status(sdata,
hdr->frame_control,
acked);
+ }
}
rcu_read_unlock();
--- a/net/mac80211/trace.h
+++ b/net/mac80211/trace.h
@@ -2804,6 +2804,73 @@ DEFINE_EVENT(sta_flag_evt, drv_sta_set_d
TP_ARGS(local, sdata, sta, enabled)
);
+TRACE_EVENT(drv_add_twt_setup,
+ TP_PROTO(struct ieee80211_local *local,
+ struct ieee80211_sta *sta,
+ struct ieee80211_twt_setup *twt,
+ struct ieee80211_twt_params *twt_agrt),
+
+ TP_ARGS(local, sta, twt, twt_agrt),
+
+ TP_STRUCT__entry(
+ LOCAL_ENTRY
+ STA_ENTRY
+ __field(u8, dialog_token)
+ __field(u8, control)
+ __field(__le16, req_type)
+ __field(__le64, twt)
+ __field(u8, duration)
+ __field(__le16, mantissa)
+ __field(u8, channel)
+ ),
+
+ TP_fast_assign(
+ LOCAL_ASSIGN;
+ STA_ASSIGN;
+ __entry->dialog_token = twt->dialog_token;
+ __entry->control = twt->control;
+ __entry->req_type = twt_agrt->req_type;
+ __entry->twt = twt_agrt->twt;
+ __entry->duration = twt_agrt->min_twt_dur;
+ __entry->mantissa = twt_agrt->mantissa;
+ __entry->channel = twt_agrt->channel;
+ ),
+
+ TP_printk(
+ LOCAL_PR_FMT STA_PR_FMT
+ " token:%d control:0x%02x req_type:0x%04x"
+ " twt:%llu duration:%d mantissa:%d channel:%d",
+ LOCAL_PR_ARG, STA_PR_ARG, __entry->dialog_token,
+ __entry->control, le16_to_cpu(__entry->req_type),
+ le64_to_cpu(__entry->twt), __entry->duration,
+ le16_to_cpu(__entry->mantissa), __entry->channel
+ )
+);
+
+TRACE_EVENT(drv_twt_teardown_request,
+ TP_PROTO(struct ieee80211_local *local,
+ struct ieee80211_sta *sta, u8 flowid),
+
+ TP_ARGS(local, sta, flowid),
+
+ TP_STRUCT__entry(
+ LOCAL_ENTRY
+ STA_ENTRY
+ __field(u8, flowid)
+ ),
+
+ TP_fast_assign(
+ LOCAL_ASSIGN;
+ STA_ASSIGN;
+ __entry->flowid = flowid;
+ ),
+
+ TP_printk(
+ LOCAL_PR_FMT STA_PR_FMT " flowid:%d",
+ LOCAL_PR_ARG, STA_PR_ARG, __entry->flowid
+ )
+);
+
#endif /* !__MAC80211_DRIVER_TRACE || TRACE_HEADER_MULTI_READ */
#undef TRACE_INCLUDE_PATH

View File

@ -87,7 +87,7 @@
CFG80211_TESTMODE_CMD(ieee80211_testmode_cmd)
--- a/net/mac80211/ieee80211_i.h
+++ b/net/mac80211/ieee80211_i.h
@@ -1434,6 +1434,7 @@ struct ieee80211_local {
@@ -1435,6 +1435,7 @@ struct ieee80211_local {
int dynamic_ps_forced_timeout;
int user_power_level; /* in dBm, for all interfaces */

View File

@ -8,9 +8,9 @@ PKG_LICENSE_FILES:=
PKG_SOURCE_URL:=https://github.com/openwrt/mt76
PKG_SOURCE_PROTO:=git
PKG_SOURCE_DATE:=2021-07-15
PKG_SOURCE_VERSION:=bbebea7d6dc64313132226adc3f7369d36e9359d
PKG_MIRROR_HASH:=17cd74e72c1f6c8742b698bf6772afacc6fba71b233af8c4d59530600cf44d5b
PKG_SOURCE_DATE:=2021-10-11
PKG_SOURCE_VERSION:=1af0242d1241cba761415c492e5ed9673beaa13f
PKG_MIRROR_HASH:=39346f1ef24fbd62f447fc116e1ed411dc2b60787a3df9edfe048adc79150232
PKG_MAINTAINER:=Felix Fietkau <nbd@nbd.name>
PKG_USE_NINJA:=0

View File

@ -1,206 +0,0 @@
From 83216e3988cd196183542937c9bd58b279f946af Mon Sep 17 00:00:00 2001
From: Michael Walle <michael@walle.cc>
Date: Mon, 12 Apr 2021 19:47:17 +0200
Subject: of: net: pass the dst buffer to of_get_mac_address()
of_get_mac_address() returns a "const void*" pointer to a MAC address.
Lately, support to fetch the MAC address by an NVMEM provider was added.
But this will only work with platform devices. It will not work with
PCI devices (e.g. of an integrated root complex) and esp. not with DSA
ports.
There is an of_* variant of the nvmem binding which works without
devices. The returned data of a nvmem_cell_read() has to be freed after
use. On the other hand the return of_get_mac_address() points to some
static data without a lifetime. The trick for now, was to allocate a
device resource managed buffer which is then returned. This will only
work if we have an actual device.
Change it, so that the caller of of_get_mac_address() has to supply a
buffer where the MAC address is written to. Unfortunately, this will
touch all drivers which use the of_get_mac_address().
Usually the code looks like:
const char *addr;
addr = of_get_mac_address(np);
if (!IS_ERR(addr))
ether_addr_copy(ndev->dev_addr, addr);
This can then be simply rewritten as:
of_get_mac_address(np, ndev->dev_addr);
Sometimes is_valid_ether_addr() is used to test the MAC address.
of_get_mac_address() already makes sure, it just returns a valid MAC
address. Thus we can just test its return code. But we have to be
careful if there are still other sources for the MAC address before the
of_get_mac_address(). In this case we have to keep the
is_valid_ether_addr() call.
The following coccinelle patch was used to convert common cases to the
new style. Afterwards, I've manually gone over the drivers and fixed the
return code variable: either used a new one or if one was already
available use that. Mansour Moufid, thanks for that coccinelle patch!
<spml>
@a@
identifier x;
expression y, z;
@@
- x = of_get_mac_address(y);
+ x = of_get_mac_address(y, z);
<...
- ether_addr_copy(z, x);
...>
@@
identifier a.x;
@@
- if (<+... x ...+>) {}
@@
identifier a.x;
@@
if (<+... x ...+>) {
...
}
- else {}
@@
identifier a.x;
expression e;
@@
- if (<+... x ...+>@e)
- {}
- else
+ if (!(e))
{...}
@@
expression x, y, z;
@@
- x = of_get_mac_address(y, z);
+ of_get_mac_address(y, z);
... when != x
</spml>
All drivers, except drivers/net/ethernet/aeroflex/greth.c, were
compile-time tested.
Suggested-by: Andrew Lunn <andrew@lunn.ch>
Signed-off-by: Michael Walle <michael@walle.cc>
Reviewed-by: Andrew Lunn <andrew@lunn.ch>
Signed-off-by: David S. Miller <davem@davemloft.net>
---
arch/arm/mach-mvebu/kirkwood.c | 3 +-
arch/powerpc/sysdev/tsi108_dev.c | 5 +-
drivers/net/ethernet/aeroflex/greth.c | 6 +--
drivers/net/ethernet/allwinner/sun4i-emac.c | 10 ++--
drivers/net/ethernet/altera/altera_tse_main.c | 7 +--
drivers/net/ethernet/arc/emac_main.c | 8 +--
drivers/net/ethernet/atheros/ag71xx.c | 7 +--
drivers/net/ethernet/broadcom/bcm4908_enet.c | 7 +--
drivers/net/ethernet/broadcom/bcmsysport.c | 7 +--
drivers/net/ethernet/broadcom/bgmac-bcma.c | 10 ++--
drivers/net/ethernet/broadcom/bgmac-platform.c | 11 ++--
drivers/net/ethernet/cadence/macb_main.c | 11 ++--
drivers/net/ethernet/cavium/octeon/octeon_mgmt.c | 8 +--
drivers/net/ethernet/cavium/thunder/thunder_bgx.c | 5 +-
drivers/net/ethernet/davicom/dm9000.c | 10 ++--
drivers/net/ethernet/ethoc.c | 6 +--
drivers/net/ethernet/ezchip/nps_enet.c | 7 +--
drivers/net/ethernet/freescale/fec_main.c | 7 +--
drivers/net/ethernet/freescale/fec_mpc52xx.c | 7 +--
drivers/net/ethernet/freescale/fman/mac.c | 9 ++--
.../net/ethernet/freescale/fs_enet/fs_enet-main.c | 5 +-
drivers/net/ethernet/freescale/gianfar.c | 8 +--
drivers/net/ethernet/freescale/ucc_geth.c | 5 +-
drivers/net/ethernet/hisilicon/hisi_femac.c | 7 +--
drivers/net/ethernet/hisilicon/hix5hd2_gmac.c | 7 +--
drivers/net/ethernet/lantiq_xrx200.c | 7 +--
drivers/net/ethernet/marvell/mv643xx_eth.c | 5 +-
drivers/net/ethernet/marvell/mvneta.c | 6 +--
.../net/ethernet/marvell/prestera/prestera_main.c | 11 ++--
drivers/net/ethernet/marvell/pxa168_eth.c | 9 +---
drivers/net/ethernet/marvell/sky2.c | 8 ++-
drivers/net/ethernet/mediatek/mtk_eth_soc.c | 11 ++--
drivers/net/ethernet/micrel/ks8851_common.c | 7 ++-
drivers/net/ethernet/microchip/lan743x_main.c | 5 +-
drivers/net/ethernet/nxp/lpc_eth.c | 4 +-
drivers/net/ethernet/qualcomm/qca_spi.c | 10 ++--
drivers/net/ethernet/qualcomm/qca_uart.c | 9 +---
drivers/net/ethernet/renesas/ravb_main.c | 12 +++--
drivers/net/ethernet/renesas/sh_eth.c | 5 +-
.../net/ethernet/samsung/sxgbe/sxgbe_platform.c | 13 ++---
drivers/net/ethernet/socionext/sni_ave.c | 10 ++--
.../net/ethernet/stmicro/stmmac/dwmac-anarion.c | 2 +-
.../ethernet/stmicro/stmmac/dwmac-dwc-qos-eth.c | 2 +-
.../net/ethernet/stmicro/stmmac/dwmac-generic.c | 2 +-
drivers/net/ethernet/stmicro/stmmac/dwmac-imx.c | 2 +-
.../net/ethernet/stmicro/stmmac/dwmac-intel-plat.c | 2 +-
.../net/ethernet/stmicro/stmmac/dwmac-ipq806x.c | 2 +-
.../net/ethernet/stmicro/stmmac/dwmac-lpc18xx.c | 2 +-
.../net/ethernet/stmicro/stmmac/dwmac-mediatek.c | 2 +-
drivers/net/ethernet/stmicro/stmmac/dwmac-meson.c | 2 +-
.../net/ethernet/stmicro/stmmac/dwmac-meson8b.c | 2 +-
drivers/net/ethernet/stmicro/stmmac/dwmac-oxnas.c | 2 +-
.../ethernet/stmicro/stmmac/dwmac-qcom-ethqos.c | 2 +-
drivers/net/ethernet/stmicro/stmmac/dwmac-rk.c | 2 +-
.../net/ethernet/stmicro/stmmac/dwmac-socfpga.c | 2 +-
drivers/net/ethernet/stmicro/stmmac/dwmac-sti.c | 2 +-
drivers/net/ethernet/stmicro/stmmac/dwmac-stm32.c | 2 +-
drivers/net/ethernet/stmicro/stmmac/dwmac-sun8i.c | 2 +-
drivers/net/ethernet/stmicro/stmmac/dwmac-sunxi.c | 2 +-
.../net/ethernet/stmicro/stmmac/dwmac-visconti.c | 2 +-
drivers/net/ethernet/stmicro/stmmac/stmmac.h | 2 +-
drivers/net/ethernet/stmicro/stmmac/stmmac_main.c | 2 +-
.../net/ethernet/stmicro/stmmac/stmmac_platform.c | 14 ++---
.../net/ethernet/stmicro/stmmac/stmmac_platform.h | 2 +-
drivers/net/ethernet/ti/am65-cpsw-nuss.c | 19 ++++---
drivers/net/ethernet/ti/cpsw.c | 7 +--
drivers/net/ethernet/ti/cpsw_new.c | 7 +--
drivers/net/ethernet/ti/davinci_emac.c | 8 +--
drivers/net/ethernet/ti/netcp_core.c | 7 +--
drivers/net/ethernet/wiznet/w5100-spi.c | 8 ++-
drivers/net/ethernet/wiznet/w5100.c | 2 +-
drivers/net/ethernet/xilinx/ll_temac_main.c | 8 +--
drivers/net/ethernet/xilinx/xilinx_axienet_main.c | 15 +++---
drivers/net/ethernet/xilinx/xilinx_emaclite.c | 8 +--
drivers/net/wireless/ath/ath9k/init.c | 5 +-
drivers/net/wireless/mediatek/mt76/eeprom.c | 9 +---
drivers/net/wireless/ralink/rt2x00/rt2x00dev.c | 6 +--
drivers/of/of_net.c | 60 ++++++++++------------
drivers/staging/octeon/ethernet.c | 10 ++--
drivers/staging/wfx/main.c | 7 ++-
include/linux/of_net.h | 6 +--
include/net/dsa.h | 2 +-
net/dsa/dsa2.c | 2 +-
net/dsa/slave.c | 2 +-
net/ethernet/eth.c | 11 ++--
85 files changed, 218 insertions(+), 364 deletions(-)
diff --git a/drivers/net/wireless/mediatek/mt76/eeprom.c b/drivers/net/wireless/mediatek/mt76/eeprom.c
index 665b54c5c8ae5..6d895738222ad 100644
--- a/eeprom.c
+++ b/eeprom.c
@@ -91,15 +91,9 @@ void
{
struct mt76_dev *dev = phy->dev;
-#ifdef CONFIG_OF
struct device_node *np = dev->dev->of_node;
- const u8 *mac = NULL;
- if (np)
- mac = of_get_mac_address(np);
- if (!IS_ERR_OR_NULL(mac))
- ether_addr_copy(phy->macaddr, mac);
-#endif
+ of_get_mac_address(np, phy->macaddr);
if (!is_valid_ether_addr(phy->macaddr)) {
eth_random_addr(phy->macaddr);
--
cgit 1.2.3-1.el7

View File

@ -20,6 +20,9 @@
"fstat",
"getsockname",
"ioctl",
"mmap",
"mmap2",
"munmap",
"open",
"openat",
"pipe",

View File

@ -27,6 +27,7 @@ find $TARGETS -type f -a -exec file {} \; | \
while read F S; do
echo "$SELF: $F: $S"
[ "${S}" = "relocatable" ] && {
[ "${F##*.}" == "o" ] && continue
eval "$STRIP_KMOD $F"
} || {
b=$(stat -c '%a' $F)

View File

@ -9,8 +9,7 @@ CPU_TYPE:=464fp
FEATURES:=fpu dt gpio ramdisk squashfs usb
SUBTARGETS:=nand sata
KERNEL_PATCHVER:=5.4
KERNEL_TESTING_PATCHVER:=5.10
KERNEL_PATCHVER:=5.10
define Target/Description
Build images for AppliedMicro APM821xx based boards.

View File

@ -1,11 +1,10 @@
# CONFIG_40x is not set
CONFIG_44x=y
CONFIG_460EX=y
CONFIG_4xx=y
CONFIG_4xx_SOC=y
# CONFIG_ADVANCED_OPTIONS is not set
CONFIG_APM821xx=y
CONFIG_APOLLO3G=y
# CONFIG_APOLLO3G is not set
# CONFIG_ARCHES is not set
CONFIG_ARCH_32BIT_OFF_T=y
CONFIG_ARCH_DMA_ADDR_T_64BIT=y
@ -26,7 +25,6 @@ CONFIG_AUDIT_ARCH=y
# CONFIG_BAMBOO is not set
# CONFIG_BLK_DEV_INITRD is not set
CONFIG_BLK_MQ_PCI=y
CONFIG_BLK_PM=y
CONFIG_BLUESTONE=y
CONFIG_BOOKE=y
CONFIG_BOOKE_WDT=y
@ -41,47 +39,28 @@ CONFIG_CPU_BIG_ENDIAN=y
CONFIG_CRC16=y
# CONFIG_CRC32_SARWATE is not set
CONFIG_CRC32_SLICEBY8=y
CONFIG_CRYPTO_ACOMP2=y
CONFIG_CRYPTO_AEAD=y
CONFIG_CRYPTO_AEAD2=y
CONFIG_CRYPTO_AUTHENC=y
CONFIG_CRYPTO_CCM=y
CONFIG_CRYPTO_CFB=y
CONFIG_CRYPTO_CTR=y
CONFIG_CRYPTO_DEFLATE=y
CONFIG_CRYPTO_DEV_PPC4XX=y
CONFIG_CRYPTO_DRBG=y
CONFIG_CRYPTO_DRBG_HMAC=y
CONFIG_CRYPTO_DRBG_MENU=y
CONFIG_CRYPTO_ECB=y
CONFIG_CRYPTO_ESSIV=y
CONFIG_CRYPTO_GCM=y
CONFIG_CRYPTO_GF128MUL=y
CONFIG_CRYPTO_GHASH=y
CONFIG_CRYPTO_HASH=y
CONFIG_CRYPTO_HASH2=y
CONFIG_CRYPTO_HMAC=y
CONFIG_CRYPTO_HW=y
CONFIG_CRYPTO_JITTERENTROPY=y
CONFIG_CRYPTO_LIB_POLY1305_RSIZE=1
CONFIG_CRYPTO_LIB_SHA256=y
CONFIG_CRYPTO_LZO=y
CONFIG_CRYPTO_MANAGER=y
CONFIG_CRYPTO_MANAGER2=y
CONFIG_CRYPTO_MD5_PPC=y
CONFIG_CRYPTO_NULL=y
# CONFIG_CRYPTO_MD5_PPC is not set
CONFIG_CRYPTO_NULL2=y
CONFIG_CRYPTO_OFB=y
CONFIG_CRYPTO_RNG=y
CONFIG_CRYPTO_RNG2=y
CONFIG_CRYPTO_RNG_DEFAULT=y
CONFIG_CRYPTO_SEQIV=y
CONFIG_CRYPTO_SHA1_PPC=y
CONFIG_CRYPTO_SHA256=y
# CONFIG_CRYPTO_SHA1_PPC is not set
CONFIG_DATA_SHIFT=12
CONFIG_DEBUG_MISC=y
CONFIG_DMADEVICES=y
CONFIG_DMA_DIRECT_REMAP=y
CONFIG_DMA_ENGINE=y
CONFIG_DMA_OF=y
CONFIG_DMA_REMAP=y
CONFIG_DTC=y
CONFIG_DW_DMAC=y
CONFIG_DW_DMAC_CORE=y
# CONFIG_E200 is not set
CONFIG_EARLY_PRINTK=y
# CONFIG_EBONY is not set
@ -91,17 +70,8 @@ CONFIG_EDAC_SUPPORT=y
CONFIG_EXTRA_TARGETS="uImage"
CONFIG_FIXED_PHY=y
CONFIG_FORCE_PCI=y
CONFIG_FREEZER=y
# CONFIG_FSL_LBC is not set
CONFIG_FW_CACHE=y
CONFIG_FW_LOADER_PAGED_BUF=y
CONFIG_GCC_PLUGINS=y
# CONFIG_GCC_PLUGIN_CYC_COMPLEXITY is not set
# CONFIG_GCC_PLUGIN_LATENT_ENTROPY is not set
# CONFIG_GCC_PLUGIN_RANDSTRUCT is not set
# CONFIG_GCC_PLUGIN_STRUCTLEAK_BYREF is not set
# CONFIG_GCC_PLUGIN_STRUCTLEAK_BYREF_ALL is not set
# CONFIG_GCC_PLUGIN_STRUCTLEAK_USER is not set
CONFIG_GENERIC_ALLOCATOR=y
CONFIG_GENERIC_ATOMIC64=y
CONFIG_GENERIC_BUG=y
@ -163,6 +133,7 @@ CONFIG_LZO_DECOMPRESS=y
# CONFIG_MATH_EMULATION is not set
CONFIG_MDIO_BUS=y
CONFIG_MDIO_DEVICE=y
CONFIG_MDIO_DEVRES=y
CONFIG_MEMFD_CREATE=y
CONFIG_MIGRATION=y
CONFIG_MMU_GATHER_PAGE_SIZE=y
@ -197,7 +168,6 @@ CONFIG_PAGE_OFFSET=0xc0000000
CONFIG_PCI=y
CONFIG_PCIEAER=y
CONFIG_PCIEPORTBUS=y
CONFIG_PCIE_PME=y
CONFIG_PCI_DISABLE_COMMON_QUIRKS=y
CONFIG_PCI_DOMAINS=y
CONFIG_PCI_MSI=y
@ -208,18 +178,10 @@ CONFIG_PHYLIB=y
CONFIG_PHYSICAL_START=0x00000000
CONFIG_PHYS_64BIT=y
CONFIG_PHYS_ADDR_T_64BIT=y
CONFIG_PM=y
# CONFIG_PMU_SYSFS is not set
CONFIG_PM_AUTOSLEEP=y
CONFIG_PM_CLK=y
CONFIG_PM_SLEEP=y
CONFIG_PM_WAKELOCKS=y
CONFIG_PM_WAKELOCKS_GC=y
CONFIG_PM_WAKELOCKS_LIMIT=100
CONFIG_PPC=y
CONFIG_PPC32=y
CONFIG_PPC44x_SIMPLE=y
CONFIG_PPC4xx_CPM=y
CONFIG_PPC4xx_GPIO=y
CONFIG_PPC4xx_MSI=y
CONFIG_PPC4xx_PCI_EXPRESS=y
@ -255,16 +217,12 @@ CONFIG_RSEQ=y
# CONFIG_SAM440EP is not set
# CONFIG_SCOM_DEBUGFS is not set
# CONFIG_SEQUOIA is not set
CONFIG_SERIAL_8250_EXTENDED=y
CONFIG_SERIAL_8250_FSL=y
CONFIG_SERIAL_8250_SHARE_IRQ=y
CONFIG_SERIAL_MCTRL_GPIO=y
CONFIG_SERIAL_OF_PLATFORM=y
CONFIG_SGL_ALLOC=y
CONFIG_SPARSE_IRQ=y
CONFIG_SRCU=y
CONFIG_SUSPEND=y
CONFIG_SUSPEND_FREEZER=y
CONFIG_SWPHY=y
CONFIG_SYSCTL_EXCEPTION_TRACE=y
# CONFIG_TAISHAN is not set

View File

@ -61,12 +61,12 @@
* offset (0x110000) for an uImage binary.
*/
label = "kernel";
reg = <0x00110000 0x003f0000>;
reg = <0x00110000 0x005f0000>;
};
partition@500000 {
partition@700000 {
label = "ubi";
reg = <0x00500000 0x016d0000>;
reg = <0x00700000 0x014d0000>;
};
partition@1bd0000 {
@ -83,13 +83,13 @@
partition@1be0000 {
label = "var";
reg = <0x01be0000 0x0400000>;
reg = <0x01be0000 0x00400000>;
read-only;
};
partition@1fe0000 {
label = "manudata";
reg = <0x01fe0000 0x20000 >;
reg = <0x01fe0000 0x00020000>;
read-only;
};
};

View File

@ -41,6 +41,7 @@ endef
TARGET_DEVICES += meraki_mr24
define Device/meraki_mx60
DEFAULT := n
DEVICE_VENDOR := Cisco Meraki
DEVICE_MODEL := MX60/MX60W
DEVICE_PACKAGES := kmod-spi-gpio kmod-usb-ledtrig-usbport kmod-usb-dwc2 \
@ -68,11 +69,14 @@ define Device/netgear_wndap6x0
DTB_SIZE := 32768
IMAGE_SIZE := 27392k
IMAGES := sysupgrade.bin factory.img
KERNEL_SIZE := 4032k
KERNEL_SIZE := 6080k
KERNEL := dtb | kernel-bin | gzip | MuImage-initramfs gzip
IMAGE/sysupgrade.bin := sysupgrade-tar | append-metadata
IMAGE/factory.img := append-kernel | pad-to $$$$(KERNEL_SIZE) | append-ubi
UBINIZE_OPTS := -E 5
DEVICE_COMPAT_VERSION := 2.0
DEVICE_COMPAT_MESSAGE := kernel and ubi partitions had to be resized. \
Upgrade via sysupgrade mechanism is not possible.
endef
define Device/netgear_wndap620

View File

@ -1,11 +1,6 @@
CONFIG_AT803X_PHY=y
CONFIG_AR8216_PHY=y
CONFIG_DMADEVICES=y
CONFIG_DMA_ENGINE=y
CONFIG_DW_DMAC_CORE=y
CONFIG_DW_DMAC=y
# CONFIG_SATA_DWC_OLD_DMA is not set
# CONFIG_DW_DMAC_PCI is not set
CONFIG_IKAREM=y
CONFIG_ATA=y
CONFIG_ATA_SFF=y

View File

@ -1,12 +1,7 @@
CONFIG_APOLLO3G=y
CONFIG_BROADCOM_PHY=y
CONFIG_EXT4_FS=y
CONFIG_DMADEVICES=y
CONFIG_DMA_ENGINE=y
CONFIG_DW_DMAC_CORE=y
CONFIG_DW_DMAC=y
# CONFIG_SATA_DWC_OLD_DMA is not set
# CONFIG_DW_DMAC_PCI is not set
CONFIG_ATA=y
CONFIG_ATA_SFF=y
CONFIG_ATA_BMDMA=y
@ -14,10 +9,15 @@ CONFIG_SATA_PMP=y
CONFIG_GENERIC_PHY=y
CONFIG_SATA_DWC=y
# CONFIG_SATA_DWC_DEBUG is not set
CONFIG_CRYPTO_MD5_PPC=y
CONFIG_CRYPTO_SHA1_PPC=y
CONFIG_EXT4_FS=y
CONFIG_F2FS_FS=y
CONFIG_FREEZER=y
CONFIG_FW_CACHE=y
CONFIG_SCSI=y
CONFIG_BLK_DEV_SD=y
CONFIG_BLK_PM=y
CONFIG_GPIOLIB=y
CONFIG_GPIO_GENERIC=y
CONFIG_GPIO_GENERIC_PLATFORM=y
@ -35,9 +35,19 @@ CONFIG_MD_RAID0=y
CONFIG_MD_RAID1=y
# CONFIG_MD_RAID10 is not set
# CONFIG_MD_RAID456 is not set
CONFIG_PM=y
CONFIG_PM_AUTOSLEEP=y
CONFIG_PM_CLK=y
CONFIG_PM_SLEEP=y
CONFIG_PM_WAKELOCKS=y
CONFIG_PM_WAKELOCKS_GC=y
CONFIG_PM_WAKELOCKS_LIMIT=100
CONFIG_PPC_EARLY_DEBUG=y
CONFIG_PPC_EARLY_DEBUG_44x=y
# CONFIG_PPC_EARLY_DEBUG_MEMCONS is not set
CONFIG_PPC_EARLY_DEBUG_44x_PHYSHIGH=0x4
CONFIG_PPC_EARLY_DEBUG_44x_PHYSLOW=0xef600300
CONFIG_PPC4xx_CPM=y
CONFIG_REGULATOR_FIXED_VOLTAGE=y
CONFIG_SUSPEND=y
CONFIG_SUSPEND_FREEZER=y

View File

@ -171,7 +171,7 @@
#define UDP_CORK 1 /* Never send partially complete segments */
--- a/net/netfilter/nf_conntrack_core.c
+++ b/net/netfilter/nf_conntrack_core.c
@@ -268,8 +268,8 @@ nf_ct_get_tuple(const struct sk_buff *sk
@@ -271,8 +271,8 @@ nf_ct_get_tuple(const struct sk_buff *sk
switch (l3num) {
case NFPROTO_IPV4:

View File

@ -25,7 +25,7 @@ Signed-off-by: Steve Glendinning <steve.glendinning@smsc.com>
static int __must_check __smsc95xx_read_reg(struct usbnet *dev, u32 index,
u32 *data, int in_pm)
{
@@ -1827,7 +1831,8 @@ static int smsc95xx_rx_fixup(struct usbn
@@ -1830,7 +1834,8 @@ static int smsc95xx_rx_fixup(struct usbn
if (dev->net->features & NETIF_F_RXCSUM)
smsc95xx_rx_csum_offload(skb);
skb_trim(skb, skb->len - 4); /* remove fcs */
@ -35,7 +35,7 @@ Signed-off-by: Steve Glendinning <steve.glendinning@smsc.com>
return 1;
}
@@ -1845,7 +1850,8 @@ static int smsc95xx_rx_fixup(struct usbn
@@ -1848,7 +1853,8 @@ static int smsc95xx_rx_fixup(struct usbn
if (dev->net->features & NETIF_F_RXCSUM)
smsc95xx_rx_csum_offload(ax_skb);
skb_trim(ax_skb, ax_skb->len - 4); /* remove fcs */

View File

@ -201,7 +201,7 @@ Link: https://patchwork.freedesktop.org/patch/msgid/20201028123222.1732139-1-max
--- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c
+++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c
@@ -5601,17 +5601,19 @@ static void dm_update_crtc_active_planes
@@ -5602,17 +5602,19 @@ static void dm_update_crtc_active_planes
}
static int dm_crtc_helper_atomic_check(struct drm_crtc *crtc,
@ -225,7 +225,7 @@ Link: https://patchwork.freedesktop.org/patch/msgid/20201028123222.1732139-1-max
WARN_ON(1);
return ret;
}
@@ -5622,8 +5624,8 @@ static int dm_crtc_helper_atomic_check(s
@@ -5623,8 +5625,8 @@ static int dm_crtc_helper_atomic_check(s
* planes are disabled, which is not supported by the hardware. And there is legacy
* userspace which stops using the HW cursor altogether in response to the resulting EINVAL.
*/

View File

@ -22,7 +22,7 @@ Signed-off-by: Maxime Ripard <maxime@cerno.tech>
--- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c
+++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c
@@ -6524,9 +6524,7 @@ void amdgpu_dm_connector_init_helper(str
@@ -6525,9 +6525,7 @@ void amdgpu_dm_connector_init_helper(str
if (connector_type == DRM_MODE_CONNECTOR_HDMIA ||
connector_type == DRM_MODE_CONNECTOR_DisplayPort ||
connector_type == DRM_MODE_CONNECTOR_eDP) {

View File

@ -21,7 +21,7 @@ Signed-off-by: Maxime Ripard <maxime@cerno.tech>
--- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c
+++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c
@@ -5472,25 +5472,6 @@ static int fill_hdr_info_packet(const st
@@ -5473,25 +5473,6 @@ static int fill_hdr_info_packet(const st
return 0;
}
@ -47,7 +47,7 @@ Signed-off-by: Maxime Ripard <maxime@cerno.tech>
static int
amdgpu_dm_connector_atomic_check(struct drm_connector *conn,
struct drm_atomic_state *state)
@@ -5506,7 +5487,7 @@ amdgpu_dm_connector_atomic_check(struct
@@ -5507,7 +5488,7 @@ amdgpu_dm_connector_atomic_check(struct
if (!crtc)
return 0;

View File

@ -42,7 +42,7 @@ Link: https://patchwork.freedesktop.org/patch/msgid/20201211114237.213288-2-tomi
--- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c
+++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c
@@ -4988,7 +4988,6 @@ static void dm_disable_vblank(struct drm
@@ -4989,7 +4989,6 @@ static void dm_disable_vblank(struct drm
static const struct drm_crtc_funcs amdgpu_dm_crtc_funcs = {
.reset = dm_crtc_reset_state,
.destroy = amdgpu_dm_crtc_destroy,

View File

@ -0,0 +1,9 @@
# SPDX-License-Identifier: GPL-2.0-only
# OpenWRT splash screen if using framebuffer console
if [ ! -d /sys/class/graphics/fbcon ] ; then
exit 0
fi
echo 0 > /sys/class/graphics/fbcon/cursor_blink
cat /etc/banner > /dev/tty0

View File

@ -1,7 +1,8 @@
From 029497e66bdc762e001880e4c85a91f35a54b1e2 Mon Sep 17 00:00:00 2001
From: Christian Lamparter <chunkeey@gmail.com>
Date: Sun, 19 Sep 2021 13:57:25 +0200
Subject: net: bgmac-bcma: handle deferred probe error due to mac-address
Subject: [PATCH] net: bgmac-bcma: handle deferred probe error due to
mac-address
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit

View File

@ -0,0 +1,36 @@
From 763716a55cb1f480ffe1a9702e6b5d9ea1a80a24 Mon Sep 17 00:00:00 2001
From: Matthew Hagan <mnhagan88@gmail.com>
Date: Sat, 25 Sep 2021 11:36:27 +0000
Subject: [PATCH] net: bgmac-platform: handle mac-address deferral
This patch is a replication of Christian Lamparter's "net: bgmac-bcma:
handle deferred probe error due to mac-address" patch for the
bgmac-platform driver [1].
As is the case with the bgmac-bcma driver, this change is to cover the
scenario where the MAC address cannot yet be discovered due to reliance
on an nvmem provider which is yet to be instantiated, resulting in a
random address being assigned that has to be manually overridden.
[1] https://lore.kernel.org/netdev/20210919115725.29064-1-chunkeey@gmail.com
Signed-off-by: Matthew Hagan <mnhagan88@gmail.com>
Reviewed-by: Andrew Lunn <andrew@lunn.ch>
Reviewed-by: Florian Fainelli <f.fainelli@gmail.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
---
drivers/net/ethernet/broadcom/bgmac-platform.c | 3 +++
1 file changed, 3 insertions(+)
--- a/drivers/net/ethernet/broadcom/bgmac-platform.c
+++ b/drivers/net/ethernet/broadcom/bgmac-platform.c
@@ -193,6 +193,9 @@ static int bgmac_probe(struct platform_d
bgmac->dma_dev = &pdev->dev;
ret = of_get_mac_address(np, bgmac->net_dev->dev_addr);
+ if (ret == -EPROBE_DEFER)
+ return ret;
+
if (ret)
dev_warn(&pdev->dev,
"MAC address not present in device tree\n");

View File

@ -0,0 +1,84 @@
From b5375509184dc23d2b7fa0c5ed8763899ccc9674 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Rafa=C5=82=20Mi=C5=82ecki?= <rafal@milecki.pl>
Date: Sat, 2 Oct 2021 19:58:11 +0200
Subject: [PATCH] net: bgmac: improve handling PHY
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
1. Use info from DT if available
It allows describing for example a fixed link. It's more accurate than
just guessing there may be one (depending on a chipset).
2. Verify PHY ID before trying to connect PHY
PHY addr 0x1e (30) is special in Broadcom routers and means a switch
connected as MDIO devices instead of a real PHY. Don't try connecting to
it.
Signed-off-by: Rafał Miłecki <rafal@milecki.pl>
Signed-off-by: David S. Miller <davem@davemloft.net>
---
drivers/net/ethernet/broadcom/bgmac-bcma.c | 33 ++++++++++++++--------
1 file changed, 21 insertions(+), 12 deletions(-)
--- a/drivers/net/ethernet/broadcom/bgmac-bcma.c
+++ b/drivers/net/ethernet/broadcom/bgmac-bcma.c
@@ -11,6 +11,7 @@
#include <linux/bcma/bcma.h>
#include <linux/brcmphy.h>
#include <linux/etherdevice.h>
+#include <linux/of_mdio.h>
#include <linux/of_net.h>
#include "bgmac.h"
@@ -86,17 +87,28 @@ static int bcma_phy_connect(struct bgmac
struct phy_device *phy_dev;
char bus_id[MII_BUS_ID_SIZE + 3];
+ /* DT info should be the most accurate */
+ phy_dev = of_phy_get_and_connect(bgmac->net_dev, bgmac->dev->of_node,
+ bgmac_adjust_link);
+ if (phy_dev)
+ return 0;
+
/* Connect to the PHY */
- snprintf(bus_id, sizeof(bus_id), PHY_ID_FMT, bgmac->mii_bus->id,
- bgmac->phyaddr);
- phy_dev = phy_connect(bgmac->net_dev, bus_id, bgmac_adjust_link,
- PHY_INTERFACE_MODE_MII);
- if (IS_ERR(phy_dev)) {
- dev_err(bgmac->dev, "PHY connection failed\n");
- return PTR_ERR(phy_dev);
+ if (bgmac->mii_bus && bgmac->phyaddr != BGMAC_PHY_NOREGS) {
+ snprintf(bus_id, sizeof(bus_id), PHY_ID_FMT, bgmac->mii_bus->id,
+ bgmac->phyaddr);
+ phy_dev = phy_connect(bgmac->net_dev, bus_id, bgmac_adjust_link,
+ PHY_INTERFACE_MODE_MII);
+ if (IS_ERR(phy_dev)) {
+ dev_err(bgmac->dev, "PHY connection failed\n");
+ return PTR_ERR(phy_dev);
+ }
+
+ return 0;
}
- return 0;
+ /* Assume a fixed link to the switch port */
+ return bgmac_phy_connect_direct(bgmac);
}
static const struct bcma_device_id bgmac_bcma_tbl[] = {
@@ -297,10 +309,7 @@ static int bgmac_probe(struct bcma_devic
bgmac->cco_ctl_maskset = bcma_bgmac_cco_ctl_maskset;
bgmac->get_bus_clock = bcma_bgmac_get_bus_clock;
bgmac->cmn_maskset32 = bcma_bgmac_cmn_maskset32;
- if (bgmac->mii_bus)
- bgmac->phy_connect = bcma_phy_connect;
- else
- bgmac->phy_connect = bgmac_phy_connect_direct;
+ bgmac->phy_connect = bcma_phy_connect;
err = bgmac_enet_probe(bgmac);
if (err)

View File

@ -0,0 +1,54 @@
From 45c9d966688e7fad7f24bfc450547d91e4304d0b Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Rafa=C5=82=20Mi=C5=82ecki?= <rafal@milecki.pl>
Date: Sat, 2 Oct 2021 19:58:12 +0200
Subject: [PATCH] net: bgmac: support MDIO described in DT
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
Check ethernet controller DT node for "mdio" subnode and use it with
of_mdiobus_register() when present. That allows specifying MDIO and its
PHY devices in a standard DT based way.
This is required for BCM53573 SoC support. That family is sometimes
called Northstar (by marketing?) but is quite different from it. It uses
different CPU(s) and many different hw blocks.
One of shared blocks in BCM53573 is Ethernet controller. Switch however
is not SRAB accessible (as it Northstar) but is MDIO attached.
Signed-off-by: Rafał Miłecki <rafal@milecki.pl>
Signed-off-by: David S. Miller <davem@davemloft.net>
---
drivers/net/ethernet/broadcom/bgmac-bcma-mdio.c | 6 +++++-
1 file changed, 5 insertions(+), 1 deletion(-)
--- a/drivers/net/ethernet/broadcom/bgmac-bcma-mdio.c
+++ b/drivers/net/ethernet/broadcom/bgmac-bcma-mdio.c
@@ -10,6 +10,7 @@
#include <linux/bcma/bcma.h>
#include <linux/brcmphy.h>
+#include <linux/of_mdio.h>
#include "bgmac.h"
static bool bcma_mdio_wait_value(struct bcma_device *core, u16 reg, u32 mask,
@@ -211,6 +212,7 @@ struct mii_bus *bcma_mdio_mii_register(s
{
struct bcma_device *core = bgmac->bcma.core;
struct mii_bus *mii_bus;
+ struct device_node *np;
int err;
mii_bus = mdiobus_alloc();
@@ -229,7 +231,9 @@ struct mii_bus *bcma_mdio_mii_register(s
mii_bus->parent = &core->dev;
mii_bus->phy_mask = ~(1 << bgmac->phyaddr);
- err = mdiobus_register(mii_bus);
+ np = of_get_child_by_name(core->dev.of_node, "mdio");
+
+ err = of_mdiobus_register(mii_bus, np);
if (err) {
dev_err(&core->dev, "Registration of mii bus failed\n");
goto err_free_bus;

View File

@ -0,0 +1,138 @@
From bea7907837c57a0aaac009931eb14efb056dafab Mon Sep 17 00:00:00 2001
From: Vladimir Oltean <vladimir.oltean@nxp.com>
Date: Thu, 29 Jul 2021 17:56:00 +0300
Subject: [PATCH] net: dsa: don't set skb->offload_fwd_mark when not offloading
the bridge
DSA has gained the recent ability to deal gracefully with upper
interfaces it cannot offload, such as the bridge, bonding or team
drivers. When such uppers exist, the ports are still in standalone mode
as far as the hardware is concerned.
But when we deliver packets to the software bridge in order for that to
do the forwarding, there is an unpleasant surprise in that the bridge
will refuse to forward them. This is because we unconditionally set
skb->offload_fwd_mark = true, meaning that the bridge thinks the frames
were already forwarded in hardware by us.
Since dp->bridge_dev is populated only when there is hardware offload
for it, but not in the software fallback case, let's introduce a new
helper that can be called from the tagger data path which sets the
skb->offload_fwd_mark accordingly to zero when there is no hardware
offload for bridging. This lets the bridge forward packets back to other
interfaces of our switch, if needed.
Signed-off-by: Vladimir Oltean <vladimir.oltean@nxp.com>
Reviewed-by: Tobias Waldekranz <tobias@waldekranz.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
---
net/dsa/dsa_priv.h | 14 ++++++++++++++
net/dsa/tag_brcm.c | 4 ++--
net/dsa/tag_dsa.c | 15 +++++++++++----
net/dsa/tag_ksz.c | 2 +-
net/dsa/tag_lan9303.c | 3 ++-
net/dsa/tag_mtk.c | 2 +-
net/dsa/tag_ocelot.c | 2 +-
net/dsa/tag_rtl4_a.c | 2 +-
net/dsa/tag_sja1105.c | 20 ++++++++++++++------
9 files changed, 47 insertions(+), 17 deletions(-)
--- a/net/dsa/dsa_priv.h
+++ b/net/dsa/dsa_priv.h
@@ -266,6 +266,20 @@ static inline struct sk_buff *dsa_untag_
return skb;
}
+/* If the ingress port offloads the bridge, we mark the frame as autonomously
+ * forwarded by hardware, so the software bridge doesn't forward in twice, back
+ * to us, because we already did. However, if we're in fallback mode and we do
+ * software bridging, we are not offloading it, therefore the dp->bridge_dev
+ * pointer is not populated, and flooding needs to be done by software (we are
+ * effectively operating in standalone ports mode).
+ */
+static inline void dsa_default_offload_fwd_mark(struct sk_buff *skb)
+{
+ struct dsa_port *dp = dsa_slave_to_port(skb->dev);
+
+ skb->offload_fwd_mark = !!(dp->bridge_dev);
+}
+
/* switch.c */
int dsa_switch_register_notifier(struct dsa_switch *ds);
void dsa_switch_unregister_notifier(struct dsa_switch *ds);
--- a/net/dsa/tag_brcm.c
+++ b/net/dsa/tag_brcm.c
@@ -166,7 +166,7 @@ static struct sk_buff *brcm_tag_rcv_ll(s
/* Remove Broadcom tag and update checksum */
skb_pull_rcsum(skb, BRCM_TAG_LEN);
- skb->offload_fwd_mark = 1;
+ dsa_default_offload_fwd_mark(skb);
return skb;
}
@@ -270,7 +270,7 @@ static struct sk_buff *brcm_leg_tag_rcv(
/* Remove Broadcom tag and update checksum */
skb_pull_rcsum(skb, BRCM_LEG_TAG_LEN);
- skb->offload_fwd_mark = 1;
+ dsa_default_offload_fwd_mark(skb);
/* Move the Ethernet DA and SA */
memmove(skb->data - ETH_HLEN,
--- a/net/dsa/tag_ksz.c
+++ b/net/dsa/tag_ksz.c
@@ -24,7 +24,7 @@ static struct sk_buff *ksz_common_rcv(st
pskb_trim_rcsum(skb, skb->len - len);
- skb->offload_fwd_mark = true;
+ dsa_default_offload_fwd_mark(skb);
return skb;
}
--- a/net/dsa/tag_lan9303.c
+++ b/net/dsa/tag_lan9303.c
@@ -115,7 +115,8 @@ static struct sk_buff *lan9303_rcv(struc
skb_pull_rcsum(skb, 2 + 2);
memmove(skb->data - ETH_HLEN, skb->data - (ETH_HLEN + LAN9303_TAG_LEN),
2 * ETH_ALEN);
- skb->offload_fwd_mark = !(lan9303_tag1 & LAN9303_TAG_RX_TRAPPED_TO_CPU);
+ if (!(lan9303_tag1 & LAN9303_TAG_RX_TRAPPED_TO_CPU))
+ dsa_default_offload_fwd_mark(skb);
return skb;
}
--- a/net/dsa/tag_mtk.c
+++ b/net/dsa/tag_mtk.c
@@ -104,7 +104,7 @@ static struct sk_buff *mtk_tag_rcv(struc
/* Only unicast or broadcast frames are offloaded */
if (likely(!is_multicast_skb))
- skb->offload_fwd_mark = 1;
+ dsa_default_offload_fwd_mark(skb);
return skb;
}
--- a/net/dsa/tag_ocelot.c
+++ b/net/dsa/tag_ocelot.c
@@ -225,7 +225,7 @@ static struct sk_buff *ocelot_rcv(struct
*/
return NULL;
- skb->offload_fwd_mark = 1;
+ dsa_default_offload_fwd_mark(skb);
skb->priority = qos_class;
/* Ocelot switches copy frames unmodified to the CPU. However, it is
--- a/net/dsa/tag_rtl4_a.c
+++ b/net/dsa/tag_rtl4_a.c
@@ -115,7 +115,7 @@ static struct sk_buff *rtl4a_tag_rcv(str
skb->data - ETH_HLEN - RTL4_A_HDR_LEN,
2 * ETH_ALEN);
- skb->offload_fwd_mark = 1;
+ dsa_default_offload_fwd_mark(skb);
return skb;
}

View File

@ -361,26 +361,6 @@ static int b53_phy_read_status(struct phy_device *phydev)
return 0;
}
static const struct of_device_id b53_of_match_1[] = {
{ .compatible = "brcm,bcm5325" },
{ .compatible = "brcm,bcm5395" },
{ .compatible = "brcm,bcm5397" },
{ .compatible = "brcm,bcm5398" },
{ /* sentinel */ },
};
static const struct of_device_id b53_of_match_2[] = {
{ .compatible = "brcm,bcm53115" },
{ .compatible = "brcm,bcm53125" },
{ .compatible = "brcm,bcm53128" },
{ /* sentinel */ },
};
static const struct of_device_id b53_of_match_3[] = {
{ .compatible = "brcm,bcm5365" },
{ /* sentinel */ },
};
/* BCM5325, BCM539x */
static struct phy_driver b53_phy_driver_id1 = {
.phy_id = 0x0143bc00,
@ -392,10 +372,6 @@ static struct phy_driver b53_phy_driver_id1 = {
.config_aneg = b53_phy_config_aneg,
.config_init = b53_phy_config_init,
.read_status = b53_phy_read_status,
.mdiodrv.driver = {
.name = "bcm539x",
.of_match_table = b53_of_match_1,
},
};
/* BCM53125, BCM53128 */
@ -409,10 +385,6 @@ static struct phy_driver b53_phy_driver_id2 = {
.config_aneg = b53_phy_config_aneg,
.config_init = b53_phy_config_init,
.read_status = b53_phy_read_status,
.mdiodrv.driver = {
.name = "bcm531xx",
.of_match_table = b53_of_match_2,
},
};
/* BCM5365 */
@ -426,10 +398,6 @@ static struct phy_driver b53_phy_driver_id3 = {
.config_aneg = b53_phy_config_aneg,
.config_init = b53_phy_config_init,
.read_status = b53_phy_read_status,
.mdiodrv.driver = {
.name = "bcm5365",
.of_match_table = b53_of_match_3,
},
};
int __init b53_phy_driver_register(void)

View File

@ -0,0 +1,142 @@
From: Birger Koblitz <git@birger-koblitz.de>
Date: Sun, 5 Sep 2021 15:13:10 +0200
Subject: [PATCH] kernel: Add AQR113C and AQR813 support
This hack adds support for the Aquantia 4th generation, 10GBit
PHYs AQR113C and AQR813.
Signed-off-by: Birger Koblitz <git@birger-koblitz.de>
--- a/drivers/net/phy/aquantia_main.c
+++ b/drivers/net/phy/aquantia_main.c
@@ -20,8 +20,10 @@
#define PHY_ID_AQR105 0x03a1b4a2
#define PHY_ID_AQR106 0x03a1b4d0
#define PHY_ID_AQR107 0x03a1b4e0
+#define PHY_ID_AQR113C 0x31c31c12
#define PHY_ID_AQCS109 0x03a1b5c2
#define PHY_ID_AQR405 0x03a1b4b0
+#define PHY_ID_AQR813 0x31c31cb2
#define MDIO_PHYXS_VEND_IF_STATUS 0xe812
#define MDIO_PHYXS_VEND_IF_STATUS_TYPE_MASK GENMASK(7, 3)
@@ -330,6 +332,49 @@ static int aqr107_read_rate(struct phy_d
return 0;
}
+static int aqr113c_read_status(struct phy_device *phydev)
+{
+ int val, ret;
+
+ ret = aqr_read_status(phydev);
+ if (ret)
+ return ret;
+
+ if (!phydev->link || phydev->autoneg == AUTONEG_DISABLE)
+ return 0;
+
+ // On AQR113C, the speed returned by aqr_read_status is wrong
+ aqr107_read_rate(phydev);
+
+ val = phy_read_mmd(phydev, MDIO_MMD_PHYXS, MDIO_PHYXS_VEND_IF_STATUS);
+ if (val < 0)
+ return val;
+
+ switch (FIELD_GET(MDIO_PHYXS_VEND_IF_STATUS_TYPE_MASK, val)) {
+ case MDIO_PHYXS_VEND_IF_STATUS_TYPE_KR:
+ phydev->interface = PHY_INTERFACE_MODE_10GKR;
+ break;
+ case MDIO_PHYXS_VEND_IF_STATUS_TYPE_XFI:
+ phydev->interface = PHY_INTERFACE_MODE_10GBASER;
+ break;
+ case MDIO_PHYXS_VEND_IF_STATUS_TYPE_USXGMII:
+ phydev->interface = PHY_INTERFACE_MODE_USXGMII;
+ break;
+ case MDIO_PHYXS_VEND_IF_STATUS_TYPE_SGMII:
+ phydev->interface = PHY_INTERFACE_MODE_SGMII;
+ break;
+ case MDIO_PHYXS_VEND_IF_STATUS_TYPE_OCSGMII:
+ phydev->interface = PHY_INTERFACE_MODE_2500BASEX;
+ break;
+ default:
+ phydev->interface = PHY_INTERFACE_MODE_NA;
+ break;
+ }
+
+ /* Read downshifted rate from vendor register */
+ return aqr107_read_rate(phydev);
+}
+
static int aqr107_read_status(struct phy_device *phydev)
{
int val, ret;
@@ -460,7 +505,7 @@ static void aqr107_chip_info(struct phy_
build_id = FIELD_GET(VEND1_GLOBAL_RSVD_STAT1_FW_BUILD_ID, val);
prov_id = FIELD_GET(VEND1_GLOBAL_RSVD_STAT1_PROV_ID, val);
- phydev_dbg(phydev, "FW %u.%u, Build %u, Provisioning %u\n",
+ phydev_info(phydev, "FW %u.%u, Build %u, Provisioning %u\n",
fw_major, fw_minor, build_id, prov_id);
}
@@ -632,6 +677,24 @@ static struct phy_driver aqr_driver[] =
.link_change_notify = aqr107_link_change_notify,
},
{
+ PHY_ID_MATCH_MODEL(PHY_ID_AQR113C),
+ .name = "Aquantia AQR113C",
+ .probe = aqr107_probe,
+ .config_init = aqr107_config_init,
+ .config_aneg = aqr_config_aneg,
+ .config_intr = aqr_config_intr,
+ .ack_interrupt = aqr_ack_interrupt,
+ .read_status = aqr113c_read_status,
+ .get_tunable = aqr107_get_tunable,
+ .set_tunable = aqr107_set_tunable,
+ .suspend = aqr107_suspend,
+ .resume = aqr107_resume,
+ .get_sset_count = aqr107_get_sset_count,
+ .get_strings = aqr107_get_strings,
+ .get_stats = aqr107_get_stats,
+ .link_change_notify = aqr107_link_change_notify,
+},
+{
PHY_ID_MATCH_MODEL(PHY_ID_AQCS109),
.name = "Aquantia AQCS109",
.probe = aqr107_probe,
@@ -657,6 +720,24 @@ static struct phy_driver aqr_driver[] =
.ack_interrupt = aqr_ack_interrupt,
.read_status = aqr_read_status,
},
+{
+ PHY_ID_MATCH_MODEL(PHY_ID_AQR813),
+ .name = "Aquantia AQR813",
+ .probe = aqr107_probe,
+ .config_init = aqr107_config_init,
+ .config_aneg = aqr_config_aneg,
+ .config_intr = aqr_config_intr,
+ .ack_interrupt = aqr_ack_interrupt,
+ .read_status = aqr113c_read_status,
+ .get_tunable = aqr107_get_tunable,
+ .set_tunable = aqr107_set_tunable,
+ .suspend = aqr107_suspend,
+ .resume = aqr107_resume,
+ .get_sset_count = aqr107_get_sset_count,
+ .get_strings = aqr107_get_strings,
+ .get_stats = aqr107_get_stats,
+ .link_change_notify = aqr107_link_change_notify,
+},
};
module_phy_driver(aqr_driver);
@@ -667,8 +748,10 @@ static struct mdio_device_id __maybe_unu
{ PHY_ID_MATCH_MODEL(PHY_ID_AQR105) },
{ PHY_ID_MATCH_MODEL(PHY_ID_AQR106) },
{ PHY_ID_MATCH_MODEL(PHY_ID_AQR107) },
+ { PHY_ID_MATCH_MODEL(PHY_ID_AQR113C) },
{ PHY_ID_MATCH_MODEL(PHY_ID_AQCS109) },
{ PHY_ID_MATCH_MODEL(PHY_ID_AQR405) },
+ { PHY_ID_MATCH_MODEL(PHY_ID_AQR813) },
{ }
};

View File

@ -14,7 +14,7 @@ Signed-off-by: Hauke Mehrtens <hauke@hauke-m.de>
--- a/drivers/net/ethernet/broadcom/bgmac-bcma.c
+++ b/drivers/net/ethernet/broadcom/bgmac-bcma.c
@@ -266,6 +266,7 @@ static int bgmac_probe(struct bcma_devic
@@ -280,6 +280,7 @@ static int bgmac_probe(struct bcma_devic
bgmac->feature_flags |= BGMAC_FEAT_CLKCTLST;
bgmac->feature_flags |= BGMAC_FEAT_NO_RESET;
bgmac->feature_flags |= BGMAC_FEAT_FORCE_SPEED_2500;

View File

@ -77,7 +77,7 @@ Signed-off-by: Felix Fietkau <nbd@nbd.name>
struct dst_entry *__sk_dst_check(struct sock *sk, u32 cookie)
{
struct dst_entry *dst = __sk_dst_get(sk);
@@ -1816,9 +1830,11 @@ static void __sk_free(struct sock *sk)
@@ -1834,9 +1848,11 @@ static void __sk_free(struct sock *sk)
if (likely(sk->sk_net_refcnt))
sock_inuse_add(sock_net(sk), -1);

View File

@ -330,7 +330,7 @@ Signed-off-by: Felix Fietkau <nbd@nbd.name>
--- a/net/core/sock.c
+++ b/net/core/sock.c
@@ -3682,6 +3682,8 @@ static __net_initdata struct pernet_oper
@@ -3702,6 +3702,8 @@ static __net_initdata struct pernet_oper
static int __init proto_init(void)
{

View File

@ -69,7 +69,7 @@ Signed-off-by: Felix Fietkau <nbd@nbd.name>
struct dst_entry *__sk_dst_check(struct sock *sk, u32 cookie)
{
struct dst_entry *dst = __sk_dst_get(sk);
@@ -1742,9 +1755,11 @@ static void __sk_free(struct sock *sk)
@@ -1760,9 +1773,11 @@ static void __sk_free(struct sock *sk)
if (likely(sk->sk_net_refcnt))
sock_inuse_add(sock_net(sk), -1);

View File

@ -330,7 +330,7 @@ Signed-off-by: Felix Fietkau <nbd@nbd.name>
--- a/net/core/sock.c
+++ b/net/core/sock.c
@@ -3623,6 +3623,8 @@ static __net_initdata struct pernet_oper
@@ -3643,6 +3643,8 @@ static __net_initdata struct pernet_oper
static int __init proto_init(void)
{

View File

@ -185,7 +185,7 @@ Signed-off-by: Jonas Gorski <jogo@openwrt.org>
cfg->fc_flags |= RTF_REJECT;
if (rtm->rtm_type == RTN_LOCAL)
@@ -6079,6 +6110,8 @@ static int ip6_route_dev_notify(struct n
@@ -6080,6 +6111,8 @@ static int ip6_route_dev_notify(struct n
#ifdef CONFIG_IPV6_MULTIPLE_TABLES
net->ipv6.ip6_prohibit_entry->dst.dev = dev;
net->ipv6.ip6_prohibit_entry->rt6i_idev = in6_dev_get(dev);
@ -194,7 +194,7 @@ Signed-off-by: Jonas Gorski <jogo@openwrt.org>
net->ipv6.ip6_blk_hole_entry->dst.dev = dev;
net->ipv6.ip6_blk_hole_entry->rt6i_idev = in6_dev_get(dev);
#endif
@@ -6090,6 +6123,7 @@ static int ip6_route_dev_notify(struct n
@@ -6091,6 +6124,7 @@ static int ip6_route_dev_notify(struct n
in6_dev_put_clear(&net->ipv6.ip6_null_entry->rt6i_idev);
#ifdef CONFIG_IPV6_MULTIPLE_TABLES
in6_dev_put_clear(&net->ipv6.ip6_prohibit_entry->rt6i_idev);
@ -202,7 +202,7 @@ Signed-off-by: Jonas Gorski <jogo@openwrt.org>
in6_dev_put_clear(&net->ipv6.ip6_blk_hole_entry->rt6i_idev);
#endif
}
@@ -6281,6 +6315,8 @@ static int __net_init ip6_route_net_init
@@ -6282,6 +6316,8 @@ static int __net_init ip6_route_net_init
#ifdef CONFIG_IPV6_MULTIPLE_TABLES
net->ipv6.fib6_has_custom_rules = false;
@ -211,7 +211,7 @@ Signed-off-by: Jonas Gorski <jogo@openwrt.org>
net->ipv6.ip6_prohibit_entry = kmemdup(&ip6_prohibit_entry_template,
sizeof(*net->ipv6.ip6_prohibit_entry),
GFP_KERNEL);
@@ -6291,11 +6327,21 @@ static int __net_init ip6_route_net_init
@@ -6292,11 +6328,21 @@ static int __net_init ip6_route_net_init
ip6_template_metrics, true);
INIT_LIST_HEAD(&net->ipv6.ip6_prohibit_entry->rt6i_uncached);
@ -234,7 +234,7 @@ Signed-off-by: Jonas Gorski <jogo@openwrt.org>
net->ipv6.ip6_blk_hole_entry->dst.ops = &net->ipv6.ip6_dst_ops;
dst_init_metrics(&net->ipv6.ip6_blk_hole_entry->dst,
ip6_template_metrics, true);
@@ -6322,6 +6368,8 @@ out:
@@ -6323,6 +6369,8 @@ out:
return ret;
#ifdef CONFIG_IPV6_MULTIPLE_TABLES
@ -243,7 +243,7 @@ Signed-off-by: Jonas Gorski <jogo@openwrt.org>
out_ip6_prohibit_entry:
kfree(net->ipv6.ip6_prohibit_entry);
out_ip6_null_entry:
@@ -6341,6 +6389,7 @@ static void __net_exit ip6_route_net_exi
@@ -6342,6 +6390,7 @@ static void __net_exit ip6_route_net_exi
kfree(net->ipv6.ip6_null_entry);
#ifdef CONFIG_IPV6_MULTIPLE_TABLES
kfree(net->ipv6.ip6_prohibit_entry);
@ -251,7 +251,7 @@ Signed-off-by: Jonas Gorski <jogo@openwrt.org>
kfree(net->ipv6.ip6_blk_hole_entry);
#endif
dst_entries_destroy(&net->ipv6.ip6_dst_ops);
@@ -6418,6 +6467,9 @@ void __init ip6_route_init_special_entri
@@ -6419,6 +6468,9 @@ void __init ip6_route_init_special_entri
init_net.ipv6.ip6_prohibit_entry->rt6i_idev = in6_dev_get(init_net.loopback_dev);
init_net.ipv6.ip6_blk_hole_entry->dst.dev = init_net.loopback_dev;
init_net.ipv6.ip6_blk_hole_entry->rt6i_idev = in6_dev_get(init_net.loopback_dev);

View File

@ -1,102 +0,0 @@
From 6f8e5369ae054ec6c9265581d5a7e39738a5cd84 Mon Sep 17 00:00:00 2001
From: Ansuel Smith <ansuelsmth@gmail.com>
Date: Tue, 30 Mar 2021 13:16:38 +0200
Subject: [PATCH 1/2] NET: add mtd-mac-address support to of_get_mac_address()
Many embedded devices have information such as mac addresses stored inside mtd
devices. This patch allows us to add a property inside a node describing a
network interface. The new property points at a mtd partition with an offset
where the mac address can be found.
Signed-off-by: John Crispin <blogic@openwrt.org>
Signed-off-by: Felix Fietkau <nbd@nbd.name>
Signed-off-by: Ansuel Smith <ansuelsmth@gmail.com>
---
drivers/of/of_net.c | 75 ++++++++++++++++++++++++++++++++++++++++++++-
1 file changed, 74 insertions(+), 1 deletion(-)
--- a/drivers/of/of_net.c
+++ b/drivers/of/of_net.c
@@ -12,6 +12,7 @@
#include <linux/export.h>
#include <linux/device.h>
#include <linux/nvmem-consumer.h>
+#include <linux/mtd/mtd.h>
/**
* of_get_phy_mode - Get phy mode for given device_node
@@ -95,6 +96,52 @@ static int of_get_mac_addr_nvmem(struct
return 0;
}
+static int of_get_mac_address_mtd(struct device_node *np, u8 *addr)
+{
+#ifdef CONFIG_MTD
+ struct platform_device *pdev = of_find_device_by_node(np);
+ struct device_node *mtd_np = NULL;
+ size_t retlen;
+ int size, ret;
+ struct mtd_info *mtd;
+ const char *part;
+ const __be32 *list;
+ phandle phandle;
+ u8 mac[ETH_ALEN];
+
+ list = of_get_property(np, "mtd-mac-address", &size);
+ if (!list || (size != (2 * sizeof(*list))))
+ return -ENODEV;
+
+ phandle = be32_to_cpup(list++);
+ if (phandle)
+ mtd_np = of_find_node_by_phandle(phandle);
+
+ if (!mtd_np)
+ return -ENODEV;
+
+ part = of_get_property(mtd_np, "label", NULL);
+ if (!part)
+ part = mtd_np->name;
+
+ mtd = get_mtd_device_nm(part);
+ if (IS_ERR(mtd))
+ return -ENODEV;
+
+ ret = mtd_read(mtd, be32_to_cpup(list), 6, &retlen, mac);
+ put_mtd_device(mtd);
+
+ if (!is_valid_ether_addr(mac))
+ return -EINVAL;
+
+ memcpy(addr, mac, ETH_ALEN);
+
+ return 0;
+#endif
+ return -EINVAL;
+}
+
+
/**
* Search the device tree for the best MAC address to use. 'mac-address' is
* checked first, because that is supposed to contain to "most recent" MAC
@@ -115,6 +162,10 @@ static int of_get_mac_addr_nvmem(struct
* this case, the real MAC is in 'local-mac-address', and 'mac-address' exists
* but is all zeros.
*
+ *
+ * If a mtd-mac-address property exists, try to fetch the MAC address from the
+ * specified mtd device.
+ *
* Return: 0 on success and errno in case of error.
*/
int of_get_mac_address(struct device_node *np, u8 *addr)
@@ -136,6 +187,10 @@ int of_get_mac_address(struct device_nod
if (!ret)
return 0;
+ ret = of_get_mac_address_mtd(np, addr);
+ if (!ret)
+ return 0;
+
return of_get_mac_addr_nvmem(np, addr);
}
EXPORT_SYMBOL(of_get_mac_address);

View File

@ -20,9 +20,9 @@ Signed-off-by: Ansuel Smith <ansuelsmth@gmail.com>
--- a/drivers/of/of_net.c
+++ b/drivers/of/of_net.c
@@ -166,31 +166,56 @@ static int of_get_mac_address_mtd(struct
* If a mtd-mac-address property exists, try to fetch the MAC address from the
* specified mtd device.
@@ -115,27 +115,52 @@ static int of_get_mac_addr_nvmem(struct
* this case, the real MAC is in 'local-mac-address', and 'mac-address' exists
* but is all zeros.
*
+ * DT can tell the system to increment the mac-address after is extracted by
+ * using:
@ -63,11 +63,6 @@ Signed-off-by: Ansuel Smith <ansuelsmth@gmail.com>
ret = of_get_mac_addr(np, "address", addr);
if (!ret)
- return 0;
+ goto found;
ret = of_get_mac_address_mtd(np, addr);
if (!ret)
- return 0;
+ goto found;
+
+ ret = of_get_mac_addr_nvmem(np, addr);

View File

@ -1,7 +1,7 @@
--- a/drivers/of/of_net.c
+++ b/drivers/of/of_net.c
@@ -141,6 +141,26 @@ static int of_get_mac_address_mtd(struct
return -EINVAL;
@@ -95,6 +95,27 @@ static int of_get_mac_addr_nvmem(struct
return 0;
}
+static int of_add_mac_address(struct device_node *np, u8* addr)
@ -24,10 +24,11 @@
+ kfree(prop);
+ return -ENOMEM;
+}
+
/**
* Search the device tree for the best MAC address to use. 'mac-address' is
@@ -216,6 +236,7 @@ found:
* checked first, because that is supposed to contain to "most recent" MAC
@@ -161,6 +182,7 @@ found:
if (!of_property_read_u32(np, "mac-address-increment", &mac_inc))
addr[inc_idx] += mac_inc;

View File

@ -17,7 +17,7 @@ Signed-off-by: DENG Qingfang <dqfext@gmail.com>
--- a/drivers/net/dsa/mv88e6xxx/chip.c
+++ b/drivers/net/dsa/mv88e6xxx/chip.c
@@ -2857,6 +2857,7 @@ static int mv88e6xxx_setup(struct dsa_sw
@@ -2860,6 +2860,7 @@ static int mv88e6xxx_setup(struct dsa_sw
chip->ds = ds;
ds->slave_mii_bus = mv88e6xxx_default_mdio_bus(chip);

View File

@ -17,7 +17,7 @@ Signed-off-by: Tobias Waldekranz <tobias@waldekranz.com>
--- a/drivers/net/dsa/mv88e6xxx/chip.c
+++ b/drivers/net/dsa/mv88e6xxx/chip.c
@@ -5419,6 +5419,7 @@ static int mv88e6xxx_register_switch(str
@@ -5422,6 +5422,7 @@ static int mv88e6xxx_register_switch(str
ds->ops = &mv88e6xxx_switch_ops;
ds->ageing_time_min = chip->info->age_time_coeff;
ds->ageing_time_max = chip->info->age_time_coeff * U8_MAX;

View File

@ -65,7 +65,7 @@ Signed-off-by: Daniel Golle <daniel@makrotopia.org>
/**
* ata_build_rw_tf - Build ATA taskfile for given read/write request
* @tf: Target ATA taskfile
@@ -4517,6 +4530,9 @@ struct ata_queued_cmd *ata_qc_new_init(s
@@ -4545,6 +4558,9 @@ struct ata_queued_cmd *ata_qc_new_init(s
if (tag < 0)
return NULL;
}
@ -75,7 +75,7 @@ Signed-off-by: Daniel Golle <daniel@makrotopia.org>
qc = __ata_qc_from_tag(ap, tag);
qc->tag = qc->hw_tag = tag;
@@ -5295,6 +5311,9 @@ struct ata_port *ata_port_alloc(struct a
@@ -5323,6 +5339,9 @@ struct ata_port *ata_port_alloc(struct a
ap->stats.unhandled_irq = 1;
ap->stats.idle_irq = 1;
#endif
@ -85,7 +85,7 @@ Signed-off-by: Daniel Golle <daniel@makrotopia.org>
ata_sff_port_init(ap);
return ap;
@@ -5330,6 +5349,12 @@ static void ata_host_release(struct kref
@@ -5358,6 +5377,12 @@ static void ata_host_release(struct kref
kfree(ap->pmp_link);
kfree(ap->slave_link);
@ -98,7 +98,7 @@ Signed-off-by: Daniel Golle <daniel@makrotopia.org>
kfree(ap);
host->ports[i] = NULL;
}
@@ -5736,7 +5761,23 @@ int ata_host_register(struct ata_host *h
@@ -5764,7 +5789,23 @@ int ata_host_register(struct ata_host *h
host->ports[i]->print_id = atomic_inc_return(&ata_print_id);
host->ports[i]->local_port_no = i + 1;
}
@ -134,7 +134,7 @@ Signed-off-by: Daniel Golle <daniel@makrotopia.org>
/*
* Define if arch has non-standard setup. This is a _PCI_ standard
@@ -882,6 +885,12 @@ struct ata_port {
@@ -883,6 +886,12 @@ struct ata_port {
#ifdef CONFIG_ATA_ACPI
struct ata_acpi_gtm __acpi_init_gtm; /* use ata_acpi_init_gtm() */
#endif

View File

@ -185,7 +185,7 @@ Signed-off-by: Jonas Gorski <jogo@openwrt.org>
cfg->fc_flags |= RTF_REJECT;
if (rtm->rtm_type == RTN_LOCAL)
@@ -6028,6 +6059,8 @@ static int ip6_route_dev_notify(struct n
@@ -6029,6 +6060,8 @@ static int ip6_route_dev_notify(struct n
#ifdef CONFIG_IPV6_MULTIPLE_TABLES
net->ipv6.ip6_prohibit_entry->dst.dev = dev;
net->ipv6.ip6_prohibit_entry->rt6i_idev = in6_dev_get(dev);
@ -194,7 +194,7 @@ Signed-off-by: Jonas Gorski <jogo@openwrt.org>
net->ipv6.ip6_blk_hole_entry->dst.dev = dev;
net->ipv6.ip6_blk_hole_entry->rt6i_idev = in6_dev_get(dev);
#endif
@@ -6039,6 +6072,7 @@ static int ip6_route_dev_notify(struct n
@@ -6040,6 +6073,7 @@ static int ip6_route_dev_notify(struct n
in6_dev_put_clear(&net->ipv6.ip6_null_entry->rt6i_idev);
#ifdef CONFIG_IPV6_MULTIPLE_TABLES
in6_dev_put_clear(&net->ipv6.ip6_prohibit_entry->rt6i_idev);
@ -202,7 +202,7 @@ Signed-off-by: Jonas Gorski <jogo@openwrt.org>
in6_dev_put_clear(&net->ipv6.ip6_blk_hole_entry->rt6i_idev);
#endif
}
@@ -6231,6 +6265,8 @@ static int __net_init ip6_route_net_init
@@ -6232,6 +6266,8 @@ static int __net_init ip6_route_net_init
#ifdef CONFIG_IPV6_MULTIPLE_TABLES
net->ipv6.fib6_has_custom_rules = false;
@ -211,7 +211,7 @@ Signed-off-by: Jonas Gorski <jogo@openwrt.org>
net->ipv6.ip6_prohibit_entry = kmemdup(&ip6_prohibit_entry_template,
sizeof(*net->ipv6.ip6_prohibit_entry),
GFP_KERNEL);
@@ -6241,11 +6277,21 @@ static int __net_init ip6_route_net_init
@@ -6242,11 +6278,21 @@ static int __net_init ip6_route_net_init
ip6_template_metrics, true);
INIT_LIST_HEAD(&net->ipv6.ip6_prohibit_entry->rt6i_uncached);
@ -234,7 +234,7 @@ Signed-off-by: Jonas Gorski <jogo@openwrt.org>
net->ipv6.ip6_blk_hole_entry->dst.ops = &net->ipv6.ip6_dst_ops;
dst_init_metrics(&net->ipv6.ip6_blk_hole_entry->dst,
ip6_template_metrics, true);
@@ -6269,6 +6315,8 @@ out:
@@ -6270,6 +6316,8 @@ out:
return ret;
#ifdef CONFIG_IPV6_MULTIPLE_TABLES
@ -243,7 +243,7 @@ Signed-off-by: Jonas Gorski <jogo@openwrt.org>
out_ip6_prohibit_entry:
kfree(net->ipv6.ip6_prohibit_entry);
out_ip6_null_entry:
@@ -6288,6 +6336,7 @@ static void __net_exit ip6_route_net_exi
@@ -6289,6 +6337,7 @@ static void __net_exit ip6_route_net_exi
kfree(net->ipv6.ip6_null_entry);
#ifdef CONFIG_IPV6_MULTIPLE_TABLES
kfree(net->ipv6.ip6_prohibit_entry);
@ -251,7 +251,7 @@ Signed-off-by: Jonas Gorski <jogo@openwrt.org>
kfree(net->ipv6.ip6_blk_hole_entry);
#endif
dst_entries_destroy(&net->ipv6.ip6_dst_ops);
@@ -6365,6 +6414,9 @@ void __init ip6_route_init_special_entri
@@ -6366,6 +6415,9 @@ void __init ip6_route_init_special_entri
init_net.ipv6.ip6_prohibit_entry->rt6i_idev = in6_dev_get(init_net.loopback_dev);
init_net.ipv6.ip6_blk_hole_entry->dst.dev = init_net.loopback_dev;
init_net.ipv6.ip6_blk_hole_entry->rt6i_idev = in6_dev_get(init_net.loopback_dev);

View File

@ -1,102 +0,0 @@
From 6f8e5369ae054ec6c9265581d5a7e39738a5cd84 Mon Sep 17 00:00:00 2001
From: Ansuel Smith <ansuelsmth@gmail.com>
Date: Tue, 30 Mar 2021 13:16:38 +0200
Subject: [PATCH 1/2] NET: add mtd-mac-address support to of_get_mac_address()
Many embedded devices have information such as mac addresses stored inside mtd
devices. This patch allows us to add a property inside a node describing a
network interface. The new property points at a mtd partition with an offset
where the mac address can be found.
Signed-off-by: John Crispin <blogic@openwrt.org>
Signed-off-by: Felix Fietkau <nbd@nbd.name>
Signed-off-by: Ansuel Smith <ansuelsmth@gmail.com>
---
drivers/of/of_net.c | 75 ++++++++++++++++++++++++++++++++++++++++++++-
1 file changed, 74 insertions(+), 1 deletion(-)
--- a/drivers/of/of_net.c
+++ b/drivers/of/of_net.c
@@ -12,6 +12,7 @@
#include <linux/export.h>
#include <linux/device.h>
#include <linux/nvmem-consumer.h>
+#include <linux/mtd/mtd.h>
/**
* of_get_phy_mode - Get phy mode for given device_node
@@ -89,6 +90,52 @@ static int of_get_mac_addr_nvmem(struct
return 0;
}
+static int of_get_mac_address_mtd(struct device_node *np, u8 *addr)
+{
+#ifdef CONFIG_MTD
+ struct platform_device *pdev = of_find_device_by_node(np);
+ struct device_node *mtd_np = NULL;
+ size_t retlen;
+ int size, ret;
+ struct mtd_info *mtd;
+ const char *part;
+ const __be32 *list;
+ phandle phandle;
+ u8 mac[ETH_ALEN];
+
+ list = of_get_property(np, "mtd-mac-address", &size);
+ if (!list || (size != (2 * sizeof(*list))))
+ return -ENODEV;
+
+ phandle = be32_to_cpup(list++);
+ if (phandle)
+ mtd_np = of_find_node_by_phandle(phandle);
+
+ if (!mtd_np)
+ return -ENODEV;
+
+ part = of_get_property(mtd_np, "label", NULL);
+ if (!part)
+ part = mtd_np->name;
+
+ mtd = get_mtd_device_nm(part);
+ if (IS_ERR(mtd))
+ return -ENODEV;
+
+ ret = mtd_read(mtd, be32_to_cpup(list), 6, &retlen, mac);
+ put_mtd_device(mtd);
+
+ if (!is_valid_ether_addr(mac))
+ return -EINVAL;
+
+ memcpy(addr, mac, ETH_ALEN);
+
+ return 0;
+#endif
+ return -EINVAL;
+}
+
+
/**
* Search the device tree for the best MAC address to use. 'mac-address' is
* checked first, because that is supposed to contain to "most recent" MAC
@@ -109,6 +156,10 @@ static int of_get_mac_addr_nvmem(struct
* this case, the real MAC is in 'local-mac-address', and 'mac-address' exists
* but is all zeros.
*
+ *
+ * If a mtd-mac-address property exists, try to fetch the MAC address from the
+ * specified mtd device.
+ *
* Return: 0 on success and errno in case of error.
*/
int of_get_mac_address(struct device_node *np, u8 *addr)
@@ -130,6 +181,10 @@ int of_get_mac_address(struct device_nod
if (!ret)
return 0;
+ ret = of_get_mac_address_mtd(np, addr);
+ if (!ret)
+ return 0;
+
return of_get_mac_addr_nvmem(np, addr);
}
EXPORT_SYMBOL(of_get_mac_address);

View File

@ -20,9 +20,9 @@ Signed-off-by: Ansuel Smith <ansuelsmth@gmail.com>
--- a/drivers/of/of_net.c
+++ b/drivers/of/of_net.c
@@ -160,31 +160,56 @@ static int of_get_mac_address_mtd(struct
* If a mtd-mac-address property exists, try to fetch the MAC address from the
* specified mtd device.
@@ -109,27 +109,52 @@ static int of_get_mac_addr_nvmem(struct
* this case, the real MAC is in 'local-mac-address', and 'mac-address' exists
* but is all zeros.
*
+ * DT can tell the system to increment the mac-address after is extracted by
+ * using:
@ -63,11 +63,6 @@ Signed-off-by: Ansuel Smith <ansuelsmth@gmail.com>
ret = of_get_mac_addr(np, "address", addr);
if (!ret)
- return 0;
+ goto found;
ret = of_get_mac_address_mtd(np, addr);
if (!ret)
- return 0;
+ goto found;
+
+ ret = of_get_mac_addr_nvmem(np, addr);

View File

@ -1,7 +1,7 @@
--- a/drivers/of/of_net.c
+++ b/drivers/of/of_net.c
@@ -135,6 +135,26 @@ static int of_get_mac_address_mtd(struct
return -EINVAL;
@@ -89,6 +89,27 @@ static int of_get_mac_addr_nvmem(struct
return 0;
}
+static int of_add_mac_address(struct device_node *np, u8* addr)
@ -24,10 +24,11 @@
+ kfree(prop);
+ return -ENOMEM;
+}
+
/**
* Search the device tree for the best MAC address to use. 'mac-address' is
@@ -210,6 +230,7 @@ found:
* checked first, because that is supposed to contain to "most recent" MAC
@@ -155,6 +176,7 @@ found:
if (!of_property_read_u32(np, "mac-address-increment", &mac_inc))
addr[inc_idx] += mac_inc;

View File

@ -65,7 +65,7 @@ Signed-off-by: Daniel Golle <daniel@makrotopia.org>
/**
* ata_build_rw_tf - Build ATA taskfile for given read/write request
* @tf: Target ATA taskfile
@@ -5121,6 +5134,9 @@ struct ata_queued_cmd *ata_qc_new_init(s
@@ -5149,6 +5162,9 @@ struct ata_queued_cmd *ata_qc_new_init(s
if (tag < 0)
return NULL;
}
@ -75,7 +75,7 @@ Signed-off-by: Daniel Golle <daniel@makrotopia.org>
qc = __ata_qc_from_tag(ap, tag);
qc->tag = qc->hw_tag = tag;
@@ -6057,6 +6073,9 @@ struct ata_port *ata_port_alloc(struct a
@@ -6085,6 +6101,9 @@ struct ata_port *ata_port_alloc(struct a
ap->stats.unhandled_irq = 1;
ap->stats.idle_irq = 1;
#endif
@ -85,7 +85,7 @@ Signed-off-by: Daniel Golle <daniel@makrotopia.org>
ata_sff_port_init(ap);
return ap;
@@ -6092,6 +6111,12 @@ static void ata_host_release(struct kref
@@ -6120,6 +6139,12 @@ static void ata_host_release(struct kref
kfree(ap->pmp_link);
kfree(ap->slave_link);
@ -98,7 +98,7 @@ Signed-off-by: Daniel Golle <daniel@makrotopia.org>
kfree(ap);
host->ports[i] = NULL;
}
@@ -6555,7 +6580,23 @@ int ata_host_register(struct ata_host *h
@@ -6583,7 +6608,23 @@ int ata_host_register(struct ata_host *h
host->ports[i]->print_id = atomic_inc_return(&ata_print_id);
host->ports[i]->local_port_no = i + 1;
}
@ -134,7 +134,7 @@ Signed-off-by: Daniel Golle <daniel@makrotopia.org>
/*
* Define if arch has non-standard setup. This is a _PCI_ standard
@@ -881,6 +884,12 @@ struct ata_port {
@@ -882,6 +885,12 @@ struct ata_port {
#ifdef CONFIG_ATA_ACPI
struct ata_acpi_gtm __acpi_init_gtm; /* use ata_acpi_init_gtm() */
#endif

View File

@ -495,7 +495,7 @@ endef
TARGET_DEVICES += glinet_gl-ap1300
define Device/glinet_gl-b1300
$(call Device/FitImage)
$(call Device/FitzImage)
DEVICE_VENDOR := GL.iNet
DEVICE_MODEL := GL-B1300
BOARD_NAME := gl-b1300
@ -507,7 +507,7 @@ endef
TARGET_DEVICES += glinet_gl-b1300
define Device/glinet_gl-s1300
$(call Device/FitImage)
$(call Device/FitzImage)
DEVICE_VENDOR := GL.iNet
DEVICE_MODEL := GL-S1300
SOC := qcom-ipq4029

View File

@ -10,8 +10,7 @@ BOARDNAME:=Marvell Kirkwood
FEATURES:=usb nand squashfs ramdisk
CPU_TYPE:=xscale
KERNEL_PATCHVER:=5.4
KERNEL_TESTING_PATCHVER:=5.10
KERNEL_PATCHVER:=5.10
include $(INCLUDE_DIR)/target.mk

View File

@ -90,6 +90,7 @@ CONFIG_COMPAT_32BIT_TIME=y
CONFIG_COMPAT_BINFMT_ELF=y
CONFIG_COMPAT_NETLINK_MESSAGES=y
CONFIG_COMPAT_OLD_SIGACTION=y
CONFIG_CONFIGFS_FS=y
CONFIG_CONSOLE_LOGLEVEL_DEFAULT=15
# CONFIG_CPUFREQ_DT is not set
CONFIG_CPU_FREQ=y
@ -291,6 +292,7 @@ CONFIG_NVMEM=y
CONFIG_NVMEM_SYSFS=y
CONFIG_OF=y
CONFIG_OF_ADDRESS=y
CONFIG_OF_CONFIGFS=y
CONFIG_OF_EARLY_FLATTREE=y
CONFIG_OF_FLATTREE=y
CONFIG_OF_GPIO=y
@ -298,6 +300,7 @@ CONFIG_OF_IRQ=y
CONFIG_OF_KOBJ=y
CONFIG_OF_MDIO=y
CONFIG_OF_NET=y
CONFIG_OF_OVERLAY=y
CONFIG_OLD_SIGSUSPEND3=y
CONFIG_PADATA=y
CONFIG_PARTITION_PERCPU=y

View File

@ -446,6 +446,7 @@ CONFIG_NVMEM=y
CONFIG_NVMEM_SYSFS=y
CONFIG_OF=y
CONFIG_OF_ADDRESS=y
CONFIG_OF_CONFIGFS=y
CONFIG_OF_EARLY_FLATTREE=y
CONFIG_OF_FLATTREE=y
CONFIG_OF_GPIO=y
@ -454,6 +455,7 @@ CONFIG_OF_IRQ=y
CONFIG_OF_KOBJ=y
CONFIG_OF_MDIO=y
CONFIG_OF_NET=y
CONFIG_OF_OVERLAY=y
CONFIG_OLD_SIGACTION=y
CONFIG_OLD_SIGSUSPEND3=y
CONFIG_PADATA=y

View File

@ -235,48 +235,48 @@
reg = <0x64>;
led1_red: led@1 {
label = "led1:red";
label = "red:led1";
reg = <1>;
led-max-microamp = <20000>;
};
led1_green: led@2 {
label = "led1:green";
label = "green:led1";
reg = <2>;
};
led1_blue: led@3 {
label = "led1:blue";
label = "blue:led1";
reg = <3>;
};
led2_red: led@4 {
label = "led2:red";
label = "red:led2";
reg = <4>;
};
led2_green: led@5 {
label = "led2:green";
label = "green:led2";
reg = <5>;
};
led2_blue: led@6 {
label = "led2:blue";
label = "blue:led2";
reg = <6>;
};
led3_red: led@7 {
label = "led3:red";
label = "red:led3";
reg = <7>;
};
led3_green: led@8 {
label = "led3:green";
label = "green:led3";
reg = <8>;
};
led3_blue: led@9 {
label = "led3:blue";
label = "blue:led3";
reg = <9>;
};
};

View File

@ -7,8 +7,7 @@ SUBTARGETS:=ox810se ox820
FEATURES:=gpio ramdisk rtc squashfs
DEVICE_TYPE:=nas
KERNEL_PATCHVER:=5.4
KERNEL_TESTING_PATCHVER:=5.10
KERNEL_PATCHVER:=5.10
include $(INCLUDE_DIR)/target.mk

View File

@ -1,357 +0,0 @@
CONFIG_ALIGNMENT_TRAP=y
CONFIG_ARCH_32BIT_OFF_T=y
CONFIG_ARCH_CLOCKSOURCE_DATA=y
CONFIG_ARCH_HAS_BINFMT_FLAT=y
CONFIG_ARCH_HAS_DEBUG_VIRTUAL=y
CONFIG_ARCH_HAS_DMA_WRITE_COMBINE=y
CONFIG_ARCH_HAS_ELF_RANDOMIZE=y
CONFIG_ARCH_HAS_FORTIFY_SOURCE=y
CONFIG_ARCH_HAS_GCOV_PROFILE_ALL=y
CONFIG_ARCH_HAS_KCOV=y
CONFIG_ARCH_HAS_KEEPINITRD=y
CONFIG_ARCH_HAS_MEMBARRIER_SYNC_CORE=y
CONFIG_ARCH_HAS_PHYS_TO_DMA=y
CONFIG_ARCH_HAS_RESET_CONTROLLER=y
CONFIG_ARCH_HAS_SETUP_DMA_OPS=y
CONFIG_ARCH_HAS_SET_MEMORY=y
CONFIG_ARCH_HAS_STRICT_KERNEL_RWX=y
CONFIG_ARCH_HAS_STRICT_MODULE_RWX=y
CONFIG_ARCH_HAS_TEARDOWN_DMA_OPS=y
CONFIG_ARCH_HAVE_CUSTOM_GPIO_H=y
CONFIG_ARCH_HIBERNATION_POSSIBLE=y
CONFIG_ARCH_KEEP_MEMBLOCK=y
CONFIG_ARCH_MIGHT_HAVE_PC_PARPORT=y
CONFIG_ARCH_MULTIPLATFORM=y
CONFIG_ARCH_MULTI_CPU_AUTO=y
# CONFIG_ARCH_MULTI_V4 is not set
# CONFIG_ARCH_MULTI_V4T is not set
CONFIG_ARCH_MULTI_V4_V5=y
CONFIG_ARCH_MULTI_V5=y
CONFIG_ARCH_NR_GPIO=0
CONFIG_ARCH_OPTIONAL_KERNEL_RWX=y
CONFIG_ARCH_OXNAS=y
CONFIG_ARCH_SUPPORTS_ATOMIC_RMW=y
CONFIG_ARCH_SUPPORTS_UPROBES=y
CONFIG_ARCH_SUSPEND_POSSIBLE=y
CONFIG_ARCH_USE_BUILTIN_BSWAP=y
CONFIG_ARCH_USE_CMPXCHG_LOCKREF=y
CONFIG_ARCH_WANT_DEFAULT_TOPDOWN_MMAP_LAYOUT=y
CONFIG_ARCH_WANT_GENERAL_HUGETLB=y
CONFIG_ARCH_WANT_IPC_PARSE_VERSION=y
CONFIG_ARCH_WANT_LIBATA_LEDS=y
CONFIG_ARM=y
CONFIG_ARM_APPENDED_DTB=y
CONFIG_ARM_ATAG_DTB_COMPAT=y
# CONFIG_ARM_ATAG_DTB_COMPAT_CMDLINE_EXTEND is not set
# CONFIG_ARM_ATAG_DTB_COMPAT_CMDLINE_FROM_BOOTLOADER is not set
CONFIG_ARM_ATAG_DTB_COMPAT_CMDLINE_MANGLE=y
CONFIG_ARM_CPU_SUSPEND=y
CONFIG_ARM_HAS_SG_CHAIN=y
CONFIG_ARM_L1_CACHE_SHIFT=5
CONFIG_ARM_PATCH_PHYS_VIRT=y
CONFIG_ARM_PMU=y
# CONFIG_ARM_SMMU is not set
CONFIG_ARM_THUMB=y
CONFIG_ARM_UNWIND=y
CONFIG_ATAGS=y
CONFIG_AUTO_ZRELADDR=y
CONFIG_BINFMT_FLAT_ARGVP_ENVP_ON_STACK=y
CONFIG_BLK_CMDLINE_PARSER=y
CONFIG_BLK_DEBUG_FS=y
CONFIG_BLK_DEV_BSG=y
CONFIG_BLK_DEV_LOOP=y
CONFIG_BLK_DEV_RAM=y
CONFIG_BLK_DEV_RAM_COUNT=16
CONFIG_BLK_DEV_RAM_SIZE=65536
CONFIG_BLK_PM=y
CONFIG_BLK_SCSI_REQUEST=y
CONFIG_CC_HAS_KASAN_GENERIC=y
CONFIG_CLKDEV_LOOKUP=y
CONFIG_CLKSRC_MMIO=y
CONFIG_CLONE_BACKWARDS=y
CONFIG_CMA=y
CONFIG_CMA_ALIGNMENT=8
CONFIG_CMA_AREAS=7
# CONFIG_CMA_DEBUG is not set
# CONFIG_CMA_DEBUGFS is not set
CONFIG_CMA_SIZE_MBYTES=64
# CONFIG_CMA_SIZE_SEL_MAX is not set
CONFIG_CMA_SIZE_SEL_MBYTES=y
# CONFIG_CMA_SIZE_SEL_MIN is not set
# CONFIG_CMA_SIZE_SEL_PERCENTAGE is not set
CONFIG_CMDLINE_PARTITION=y
CONFIG_COMMON_CLK=y
CONFIG_COMMON_CLK_OXNAS=y
CONFIG_COMPAT_32BIT_TIME=y
CONFIG_CONTIG_ALLOC=y
CONFIG_COREDUMP=y
CONFIG_CORE_DUMP_DEFAULT_ELF_HEADERS=y
CONFIG_CPU_32v5=y
CONFIG_CPU_ABRT_EV5TJ=y
CONFIG_CPU_ARM926T=y
# CONFIG_CPU_CACHE_ROUND_ROBIN is not set
CONFIG_CPU_CACHE_VIVT=y
CONFIG_CPU_COPY_V4WB=y
CONFIG_CPU_CP15=y
CONFIG_CPU_CP15_MMU=y
# CONFIG_CPU_DCACHE_WRITETHROUGH is not set
# CONFIG_CPU_ICACHE_DISABLE is not set
CONFIG_CPU_PABRT_LEGACY=y
CONFIG_CPU_PM=y
CONFIG_CPU_THUMB_CAPABLE=y
CONFIG_CPU_TLB_V4WBI=y
CONFIG_CPU_USE_DOMAINS=y
CONFIG_CRASH_CORE=y
CONFIG_CRC16=y
# CONFIG_CRC32_SARWATE is not set
CONFIG_CRC32_SLICEBY8=y
CONFIG_CROSS_MEMORY_ATTACH=y
CONFIG_CRYPTO_RNG2=y
CONFIG_DEBUG_ALIGN_RODATA=y
CONFIG_DEBUG_BUGVERBOSE=y
CONFIG_DEBUG_LL_INCLUDE="mach/debug-macro.S"
# CONFIG_DEBUG_USER is not set
CONFIG_DECOMPRESS_BZIP2=y
CONFIG_DECOMPRESS_GZIP=y
CONFIG_DECOMPRESS_LZ4=y
CONFIG_DECOMPRESS_LZMA=y
CONFIG_DECOMPRESS_LZO=y
CONFIG_DECOMPRESS_XZ=y
CONFIG_DEVTMPFS=y
CONFIG_DEVTMPFS_MOUNT=y
CONFIG_DMA_CMA=y
CONFIG_DMA_REMAP=y
CONFIG_DNOTIFY=y
CONFIG_DTC=y
# CONFIG_DWMAC_DWC_QOS_ETH is not set
CONFIG_DWMAC_GENERIC=y
CONFIG_DWMAC_OXNAS=y
CONFIG_EDAC_ATOMIC_SCRUB=y
CONFIG_EDAC_SUPPORT=y
CONFIG_ELF_CORE=y
CONFIG_FAT_FS=y
CONFIG_FIXED_PHY=y
CONFIG_FIX_EARLYCON_MEM=y
CONFIG_FREEZER=y
CONFIG_FW_LOADER_PAGED_BUF=y
CONFIG_GENERIC_ALLOCATOR=y
CONFIG_GENERIC_ATOMIC64=y
CONFIG_GENERIC_BUG=y
CONFIG_GENERIC_CLOCKEVENTS=y
CONFIG_GENERIC_CPU_AUTOPROBE=y
CONFIG_GENERIC_EARLY_IOREMAP=y
CONFIG_GENERIC_IDLE_POLL_SETUP=y
CONFIG_GENERIC_IRQ_MULTI_HANDLER=y
CONFIG_GENERIC_IRQ_SHOW=y
CONFIG_GENERIC_IRQ_SHOW_LEVEL=y
CONFIG_GENERIC_PCI_IOMAP=y
CONFIG_GENERIC_PHY=y
CONFIG_GENERIC_PINCONF=y
CONFIG_GENERIC_SCHED_CLOCK=y
CONFIG_GENERIC_SMP_IDLE_THREAD=y
CONFIG_GENERIC_STRNCPY_FROM_USER=y
CONFIG_GENERIC_STRNLEN_USER=y
CONFIG_GPIOLIB=y
CONFIG_GPIOLIB_IRQCHIP=y
CONFIG_GPIO_GENERIC=y
CONFIG_GPIO_GENERIC_PLATFORM=y
CONFIG_HANDLE_DOMAIN_IRQ=y
CONFIG_HARDIRQS_SW_RESEND=y
CONFIG_HAS_DMA=y
CONFIG_HAS_IOMEM=y
CONFIG_HAS_IOPORT_MAP=y
CONFIG_HAVE_ARCH_AUDITSYSCALL=y
CONFIG_HAVE_ARCH_JUMP_LABEL=y
CONFIG_HAVE_ARCH_KGDB=y
CONFIG_HAVE_ARCH_PFN_VALID=y
CONFIG_HAVE_ARCH_SECCOMP_FILTER=y
CONFIG_HAVE_ARCH_THREAD_STRUCT_WHITELIST=y
CONFIG_HAVE_ARCH_TRACEHOOK=y
CONFIG_HAVE_CLK=y
CONFIG_HAVE_CLK_PREPARE=y
CONFIG_HAVE_CONTEXT_TRACKING=y
CONFIG_HAVE_COPY_THREAD_TLS=y
CONFIG_HAVE_C_RECORDMCOUNT=y
CONFIG_HAVE_DEBUG_KMEMLEAK=y
CONFIG_HAVE_DMA_CONTIGUOUS=y
CONFIG_HAVE_DYNAMIC_FTRACE=y
CONFIG_HAVE_DYNAMIC_FTRACE_WITH_REGS=y
CONFIG_HAVE_EBPF_JIT=y
CONFIG_HAVE_FTRACE_MCOUNT_RECORD=y
CONFIG_HAVE_FUNCTION_GRAPH_TRACER=y
CONFIG_HAVE_FUNCTION_TRACER=y
CONFIG_HAVE_IRQ_TIME_ACCOUNTING=y
CONFIG_HAVE_LD_DEAD_CODE_DATA_ELIMINATION=y
CONFIG_HAVE_MOD_ARCH_SPECIFIC=y
CONFIG_HAVE_NET_DSA=y
CONFIG_HAVE_OPROFILE=y
CONFIG_HAVE_OPTPROBES=y
CONFIG_HAVE_PCI=y
CONFIG_HAVE_PERF_EVENTS=y
CONFIG_HAVE_PERF_REGS=y
CONFIG_HAVE_PERF_USER_STACK_DUMP=y
CONFIG_HAVE_PROC_CPU=y
CONFIG_HAVE_REGS_AND_STACK_ACCESS_API=y
CONFIG_HAVE_RSEQ=y
CONFIG_HAVE_SYSCALL_TRACEPOINTS=y
CONFIG_HAVE_UID16=y
CONFIG_HAVE_VIRT_CPU_ACCOUNTING_GEN=y
CONFIG_HID=y
CONFIG_HID_GENERIC=y
CONFIG_HWMON=y
CONFIG_HZ_FIXED=0
CONFIG_ICPLUS_PHY=y
CONFIG_INET_DIAG=y
# CONFIG_INET_DIAG_DESTROY is not set
# CONFIG_INET_RAW_DIAG is not set
CONFIG_INET_TCP_DIAG=y
CONFIG_INITRAMFS_SOURCE=""
CONFIG_INPUT=y
# CONFIG_IOMMU_DEBUGFS is not set
# CONFIG_IOMMU_IO_PGTABLE_ARMV7S is not set
# CONFIG_IOMMU_IO_PGTABLE_LPAE is not set
CONFIG_IOMMU_SUPPORT=y
CONFIG_IRQCHIP=y
CONFIG_IRQ_DOMAIN=y
CONFIG_IRQ_FORCED_THREADING=y
CONFIG_IRQ_WORK=y
# CONFIG_ISDN is not set
# CONFIG_JFFS2_FS is not set
CONFIG_KALLSYMS=y
CONFIG_KERNEL_GZIP=y
# CONFIG_KERNEL_XZ is not set
CONFIG_KEXEC=y
CONFIG_KEXEC_CORE=y
# CONFIG_LEDS_BRIGHTNESS_HW_CHANGED is not set
CONFIG_LEDS_GPIO=y
CONFIG_LEDS_TRIGGER_CPU=y
CONFIG_LEDS_TRIGGER_GPIO=y
CONFIG_LEDS_TRIGGER_ONESHOT=y
CONFIG_LIBFDT=y
CONFIG_LOCALVERSION_AUTO=y
CONFIG_LOCK_DEBUGGING_SUPPORT=y
CONFIG_LZ4_DECOMPRESS=y
CONFIG_LZO_DECOMPRESS=y
# CONFIG_MACH_OX810SE is not set
CONFIG_MDIO_BUS=y
CONFIG_MDIO_DEVICE=y
CONFIG_MEMFD_CREATE=y
CONFIG_MEMORY_ISOLATION=y
CONFIG_MFD_SYSCON=y
CONFIG_MIGRATION=y
CONFIG_MODULES_TREE_LOOKUP=y
CONFIG_MODULES_USE_ELF_REL=y
CONFIG_NEED_DMA_MAP_STATE=y
CONFIG_NEED_KUSER_HELPERS=y
CONFIG_NEED_PER_CPU_KM=y
CONFIG_NET_PTP_CLASSIFY=y
CONFIG_NLS=y
CONFIG_NO_HZ=y
CONFIG_NO_HZ_COMMON=y
CONFIG_NO_HZ_IDLE=y
CONFIG_OF=y
CONFIG_OF_ADDRESS=y
CONFIG_OF_EARLY_FLATTREE=y
CONFIG_OF_FLATTREE=y
CONFIG_OF_GPIO=y
CONFIG_OF_IRQ=y
CONFIG_OF_KOBJ=y
CONFIG_OF_MDIO=y
CONFIG_OF_NET=y
CONFIG_OLD_SIGACTION=y
CONFIG_OLD_SIGSUSPEND3=y
CONFIG_OXNAS_RPS_TIMER=y
CONFIG_PAGE_OFFSET=0xC0000000
CONFIG_PAGE_POOL=y
# CONFIG_PANIC_ON_OOPS is not set
CONFIG_PANIC_ON_OOPS_VALUE=0
CONFIG_PANIC_TIMEOUT=0
CONFIG_PERF_USE_VMALLOC=y
CONFIG_PGTABLE_LEVELS=2
CONFIG_PHYLIB=y
CONFIG_PHYLINK=y
CONFIG_PHY_OXNAS=y
CONFIG_PINCTRL=y
CONFIG_PINCTRL_OXNAS=y
# CONFIG_PINCTRL_SINGLE is not set
CONFIG_PM=y
CONFIG_PM_CLK=y
# CONFIG_PM_DEBUG is not set
CONFIG_PM_SLEEP=y
CONFIG_POWER_RESET=y
CONFIG_POWER_RESET_OXNAS=y
CONFIG_PPS=y
CONFIG_PTP_1588_CLOCK=y
CONFIG_RAS=y
CONFIG_RATIONAL=y
CONFIG_RCU_TRACE=y
CONFIG_RD_BZIP2=y
CONFIG_RD_GZIP=y
CONFIG_RD_LZ4=y
CONFIG_RD_LZMA=y
CONFIG_RD_LZO=y
CONFIG_RD_XZ=y
CONFIG_REALTEK_PHY=y
CONFIG_REFCOUNT_FULL=y
CONFIG_REGMAP=y
CONFIG_REGMAP_MMIO=y
CONFIG_RESET_CONTROLLER=y
CONFIG_RESET_OXNAS=y
CONFIG_SCHED_DEBUG=y
CONFIG_SERIAL_8250_DEPRECATED_OPTIONS=y
CONFIG_SERIAL_8250_FSL=y
CONFIG_SERIAL_8250_NR_UARTS=4
CONFIG_SERIAL_8250_RUNTIME_UARTS=4
CONFIG_SERIAL_MCTRL_GPIO=y
CONFIG_SERIAL_OF_PLATFORM=y
CONFIG_SERIO=y
CONFIG_SERIO_LIBPS2=y
CONFIG_SERIO_SERPORT=y
CONFIG_SIMPLE_PM_BUS=y
CONFIG_SLUB_DEBUG=y
CONFIG_SOCK_DIAG=y
CONFIG_SPARSE_IRQ=y
CONFIG_SPLIT_PTLOCK_CPUS=999999
CONFIG_SRCU=y
CONFIG_STACKTRACE=y
CONFIG_STMMAC_ETH=y
CONFIG_STMMAC_PLATFORM=y
# CONFIG_STMMAC_SELFTESTS is not set
# CONFIG_STRIP_ASM_SYMS is not set
CONFIG_SUSPEND=y
CONFIG_SUSPEND_FREEZER=y
CONFIG_SWPHY=y
CONFIG_SYS_SUPPORTS_APM_EMULATION=y
CONFIG_THERMAL=y
CONFIG_THERMAL_DEFAULT_GOV_STEP_WISE=y
CONFIG_THERMAL_EMERGENCY_POWEROFF_DELAY_MS=0
CONFIG_THERMAL_GOV_STEP_WISE=y
CONFIG_THERMAL_HWMON=y
CONFIG_THERMAL_OF=y
CONFIG_TICK_CPU_ACCOUNTING=y
CONFIG_TIMER_OF=y
CONFIG_TIMER_PROBE=y
CONFIG_TINY_SRCU=y
CONFIG_TRACE_CLOCK=y
CONFIG_UEVENT_HELPER_PATH=""
CONFIG_UNCOMPRESS_INCLUDE="debug/uncompress.h"
CONFIG_UNWINDER_ARM=y
# CONFIG_UNWINDER_FRAME_POINTER is not set
CONFIG_USB_SUPPORT=y
CONFIG_USE_OF=y
CONFIG_VERSATILE_FPGA_IRQ=y
CONFIG_VERSATILE_FPGA_IRQ_NR=4
CONFIG_VFAT_FS=y
# CONFIG_VFP is not set
CONFIG_VM_EVENT_COUNTERS=y
# CONFIG_WATCHDOG is not set
# CONFIG_WQ_POWER_EFFICIENT_DEFAULT is not set
CONFIG_XZ_DEC_ARM=y
CONFIG_XZ_DEC_BCJ=y
CONFIG_XZ_DEC_IA64=y
CONFIG_XZ_DEC_POWERPC=y
CONFIG_XZ_DEC_SPARC=y
CONFIG_XZ_DEC_X86=y
CONFIG_ZBOOT_ROM_BSS=0
CONFIG_ZBOOT_ROM_TEXT=0
CONFIG_ZLIB_INFLATE=y

View File

@ -15,7 +15,7 @@
/* initialize internal qc */
qc = __ata_qc_from_tag(ap, ATA_TAG_INTERNAL);
@@ -4524,6 +4532,9 @@ struct ata_queued_cmd *ata_qc_new_init(s
@@ -4552,6 +4560,9 @@ struct ata_queued_cmd *ata_qc_new_init(s
if (unlikely(ap->pflags & ATA_PFLAG_FROZEN))
return NULL;
@ -25,7 +25,7 @@
/* libsas case */
if (ap->flags & ATA_FLAG_SAS_HOST) {
tag = ata_sas_allocate_tag(ap);
@@ -4569,6 +4580,8 @@ void ata_qc_free(struct ata_queued_cmd *
@@ -4597,6 +4608,8 @@ void ata_qc_free(struct ata_queued_cmd *
qc->tag = ATA_TAG_POISON;
if (ap->flags & ATA_FLAG_SAS_HOST)
ata_sas_free_tag(tag, ap);
@ -36,7 +36,7 @@
--- a/include/linux/libata.h
+++ b/include/linux/libata.h
@@ -911,6 +911,8 @@ struct ata_port_operations {
@@ -912,6 +912,8 @@ struct ata_port_operations {
enum ata_completion_errors (*qc_prep)(struct ata_queued_cmd *qc);
unsigned int (*qc_issue)(struct ata_queued_cmd *qc);
bool (*qc_fill_rtf)(struct ata_queued_cmd *qc);
@ -45,7 +45,7 @@
/*
* Configuration and exception handling
@@ -1001,6 +1003,9 @@ struct ata_port_operations {
@@ -1002,6 +1004,9 @@ struct ata_port_operations {
void (*phy_reset)(struct ata_port *ap);
void (*eng_timeout)(struct ata_port *ap);

View File

@ -1,82 +0,0 @@
- add compatible string
- add console to bootargs
- add led aliases
- adjust nand partition table
---
--- a/arch/arm/boot/dts/ox820-cloudengines-pogoplug-series-3.dts
+++ b/arch/arm/boot/dts/ox820-cloudengines-pogoplug-series-3.dts
@@ -11,10 +11,10 @@
/ {
model = "Cloud Engines PogoPlug Series 3";
- compatible = "cloudengines,pogoplugv3", "oxsemi,ox820";
+ compatible = "cloudengines,pogoplug-series-3", "cloudengines,pogoplugv3", "oxsemi,ox820";
chosen {
- bootargs = "earlyprintk";
+ bootargs = "earlyprintk console=ttyS0,115200";
stdout-path = "serial0:115200n8";
};
@@ -27,24 +27,28 @@
serial0 = &uart0;
gpio0 = &gpio0;
gpio1 = &gpio1;
+ led-boot = &led_status;
+ led-failsafe = &led_warn;
+ led-running = &led_act;
+ led-upgrade = &led_warn;
};
leds {
compatible = "gpio-leds";
- blue {
+ led_status: blue {
label = "pogoplug:blue";
gpios = <&gpio0 2 0>;
default-state = "keep";
};
- orange {
+ led_warn: orange {
label = "pogoplug:orange";
gpios = <&gpio1 16 1>;
default-state = "keep";
};
- green {
+ led_act: green {
label = "pogoplug:green";
gpios = <&gpio1 17 1>;
default-state = "keep";
@@ -73,11 +77,27 @@
nand-ecc-algo = "hamming";
partition@0 {
- label = "boot";
- reg = <0x00000000 0x00e00000>;
+ label = "stage1";
+ reg = <0x00000000 0x00040000>;
read-only;
};
+ partition@40000 {
+ label = "u-boot";
+ reg = <0x00040000 0x00380000>;
+ read-only;
+ };
+
+ partition@3c0000 {
+ label = "u-boot-env";
+ reg = <0x003c0000 0x00080000>;
+ };
+
+ partition@440000 {
+ label = "kernel";
+ reg = <0x00440000 0x009c0000>;
+ };
+
partition@e00000 {
label = "ubi";
reg = <0x00e00000 0x07200000>;

View File

@ -1,63 +0,0 @@
From 552ed4955c1fee1109bf5ba137dc35a411a1448c Mon Sep 17 00:00:00 2001
From: Daniel Golle <daniel@makrotopia.org>
Date: Fri, 1 Jun 2018 02:41:15 +0200
Subject: [PATCH] arm: ox820: remove left-overs
Signed-off-by: Daniel Golle <daniel@makrotopia.org>
---
drivers/clk/clk-oxnas.c | 2 --
include/dt-bindings/clock/oxsemi,ox820.h | 32 +++++++++++-------------
2 files changed, 14 insertions(+), 20 deletions(-)
--- a/drivers/clk/clk-oxnas.c
+++ b/drivers/clk/clk-oxnas.c
@@ -29,8 +29,6 @@ struct oxnas_stdclk_data {
struct clk_hw_onecell_data *onecell_data;
struct clk_oxnas_gate **gates;
unsigned int ngates;
- struct clk_oxnas_pll **plls;
- unsigned int nplls;
};
/* Regmap offsets */
--- a/include/dt-bindings/clock/oxsemi,ox820.h
+++ b/include/dt-bindings/clock/oxsemi,ox820.h
@@ -6,24 +6,20 @@
#ifndef DT_CLOCK_OXSEMI_OX820_H
#define DT_CLOCK_OXSEMI_OX820_H
-/* PLLs */
-#define CLK_820_PLLA 0
-#define CLK_820_PLLB 1
-
/* Gate Clocks */
-#define CLK_820_LEON 2
-#define CLK_820_DMA_SGDMA 3
-#define CLK_820_CIPHER 4
-#define CLK_820_SD 5
-#define CLK_820_SATA 6
-#define CLK_820_AUDIO 7
-#define CLK_820_USBMPH 8
-#define CLK_820_ETHA 9
-#define CLK_820_PCIEA 10
-#define CLK_820_NAND 11
-#define CLK_820_PCIEB 12
-#define CLK_820_ETHB 13
-#define CLK_820_REF600 14
-#define CLK_820_USBDEV 15
+#define CLK_820_LEON 0
+#define CLK_820_DMA_SGDMA 1
+#define CLK_820_CIPHER 2
+#define CLK_820_SD 3
+#define CLK_820_SATA 4
+#define CLK_820_AUDIO 5
+#define CLK_820_USBMPH 6
+#define CLK_820_ETHA 7
+#define CLK_820_PCIEA 8
+#define CLK_820_NAND 9
+#define CLK_820_PCIEB 10
+#define CLK_820_ETHB 11
+#define CLK_820_REF600 12
+#define CLK_820_USBDEV 13
#endif /* DT_CLOCK_OXSEMI_OX820_H */

View File

@ -1,273 +0,0 @@
--- a/drivers/clk/clk-oxnas.c
+++ b/drivers/clk/clk-oxnas.c
@@ -5,19 +5,42 @@
* Copyright (C) 2016 Neil Armstrong <narmstrong@baylibre.com>
*/
+#include <linux/clk.h>
+#include <linux/clkdev.h>
#include <linux/clk-provider.h>
#include <linux/kernel.h>
#include <linux/init.h>
+#include <linux/delay.h>
#include <linux/of.h>
#include <linux/of_device.h>
#include <linux/platform_device.h>
#include <linux/stringify.h>
#include <linux/regmap.h>
#include <linux/mfd/syscon.h>
+#include <linux/reset.h>
#include <dt-bindings/clock/oxsemi,ox810se.h>
#include <dt-bindings/clock/oxsemi,ox820.h>
+#define REF300_DIV_INT_SHIFT 8
+#define REF300_DIV_FRAC_SHIFT 0
+#define REF300_DIV_INT(val) ((val) << REF300_DIV_INT_SHIFT)
+#define REF300_DIV_FRAC(val) ((val) << REF300_DIV_FRAC_SHIFT)
+
+#define PLLB_BYPASS 1
+#define PLLB_ENSAT 3
+#define PLLB_OUTDIV 4
+#define PLLB_REFDIV 8
+#define PLLB_DIV_INT_SHIFT 8
+#define PLLB_DIV_FRAC_SHIFT 0
+#define PLLB_DIV_INT(val) ((val) << PLLB_DIV_INT_SHIFT)
+#define PLLB_DIV_FRAC(val) ((val) << PLLB_DIV_FRAC_SHIFT)
+
+#define PLLA_REFDIV_MASK 0x3F
+#define PLLA_REFDIV_SHIFT 8
+#define PLLA_OUTDIV_MASK 0x7
+#define PLLA_OUTDIV_SHIFT 4
+
/* Standard regmap gate clocks */
struct clk_oxnas_gate {
struct clk_hw hw;
@@ -36,6 +59,135 @@ struct oxnas_stdclk_data {
#define CLK_SET_REGOFFSET 0x2c
#define CLK_CLR_REGOFFSET 0x30
+#define PLLA_CTRL0_REGOFFSET 0x1f0
+#define PLLA_CTRL1_REGOFFSET 0x1f4
+#define PLLB_CTRL0_REGOFFSET 0x1001f0
+#define MHZ (1000 * 1000)
+
+struct clk_oxnas_pll {
+ struct clk_hw hw;
+ struct device_node *devnode;
+ struct reset_control *rstc;
+ struct regmap *syscon;
+};
+
+#define to_clk_oxnas_pll(_hw) container_of(_hw, struct clk_oxnas_pll, hw)
+
+static unsigned long plla_clk_recalc_rate(struct clk_hw *hw,
+ unsigned long parent_rate)
+{
+ struct clk_oxnas_pll *plla = to_clk_oxnas_pll(hw);
+ unsigned long fin = parent_rate;
+ unsigned long refdiv, outdiv;
+ unsigned int pll0, fbdiv;
+
+ BUG_ON(regmap_read(plla->syscon, PLLA_CTRL0_REGOFFSET, &pll0));
+
+ refdiv = (pll0 >> PLLA_REFDIV_SHIFT) & PLLA_REFDIV_MASK;
+ refdiv += 1;
+ outdiv = (pll0 >> PLLA_OUTDIV_SHIFT) & PLLA_OUTDIV_MASK;
+ outdiv += 1;
+
+ BUG_ON(regmap_read(plla->syscon, PLLA_CTRL1_REGOFFSET, &fbdiv));
+ /* seems we will not be here when pll is bypassed, so ignore this
+ * case */
+
+ return fin / MHZ * fbdiv / (refdiv * outdiv) / 32768 * MHZ;
+}
+
+static const char *pll_clk_parents[] = {
+ "oscillator",
+};
+
+static struct clk_ops plla_ops = {
+ .recalc_rate = plla_clk_recalc_rate,
+};
+
+static struct clk_init_data clk_plla_init = {
+ .name = "plla",
+ .ops = &plla_ops,
+ .parent_names = pll_clk_parents,
+ .num_parents = ARRAY_SIZE(pll_clk_parents),
+};
+
+static int pllb_clk_is_prepared(struct clk_hw *hw)
+{
+ struct clk_oxnas_pll *pllb = to_clk_oxnas_pll(hw);
+
+ return !!pllb->rstc;
+}
+
+static int pllb_clk_prepare(struct clk_hw *hw)
+{
+ struct clk_oxnas_pll *pllb = to_clk_oxnas_pll(hw);
+
+ pllb->rstc = of_reset_control_get(pllb->devnode, NULL);
+
+ return IS_ERR(pllb->rstc) ? PTR_ERR(pllb->rstc) : 0;
+}
+
+static void pllb_clk_unprepare(struct clk_hw *hw)
+{
+ struct clk_oxnas_pll *pllb = to_clk_oxnas_pll(hw);
+
+ BUG_ON(IS_ERR(pllb->rstc));
+
+ reset_control_put(pllb->rstc);
+ pllb->rstc = NULL;
+}
+
+static int pllb_clk_enable(struct clk_hw *hw)
+{
+ struct clk_oxnas_pll *pllb = to_clk_oxnas_pll(hw);
+
+ BUG_ON(IS_ERR(pllb->rstc));
+
+ /* put PLL into bypass */
+ regmap_update_bits(pllb->syscon, PLLB_CTRL0_REGOFFSET, BIT(PLLB_BYPASS), BIT(PLLB_BYPASS));
+ wmb();
+ udelay(10);
+ reset_control_assert(pllb->rstc);
+ udelay(10);
+ /* set PLL B control information */
+ regmap_write_bits(pllb->syscon, PLLB_CTRL0_REGOFFSET, 0xffff,
+ (1 << PLLB_ENSAT) | (1 << PLLB_OUTDIV) | (2 << PLLB_REFDIV));
+ reset_control_deassert(pllb->rstc);
+ udelay(100);
+ regmap_update_bits(pllb->syscon, PLLB_CTRL0_REGOFFSET, BIT(PLLB_BYPASS), 0);
+
+ return 0;
+}
+
+static void pllb_clk_disable(struct clk_hw *hw)
+{
+ struct clk_oxnas_pll *pllb = to_clk_oxnas_pll(hw);
+
+ BUG_ON(IS_ERR(pllb->rstc));
+
+ /* put PLL into bypass */
+ regmap_update_bits(pllb->syscon, PLLB_CTRL0_REGOFFSET, BIT(PLLB_BYPASS), BIT(PLLB_BYPASS));
+
+ wmb();
+ udelay(10);
+
+ reset_control_assert(pllb->rstc);
+}
+
+static struct clk_ops pllb_ops = {
+ .prepare = pllb_clk_prepare,
+ .unprepare = pllb_clk_unprepare,
+ .is_prepared = pllb_clk_is_prepared,
+ .enable = pllb_clk_enable,
+ .disable = pllb_clk_disable,
+};
+
+static struct clk_init_data clk_pllb_init = {
+ .name = "pllb",
+ .ops = &pllb_ops,
+ .parent_names = pll_clk_parents,
+ .num_parents = ARRAY_SIZE(pll_clk_parents),
+};
+
static inline struct clk_oxnas_gate *to_clk_oxnas_gate(struct clk_hw *hw)
{
return container_of(hw, struct clk_oxnas_gate, hw);
@@ -249,3 +401,42 @@ static struct platform_driver oxnas_stdc
},
};
builtin_platform_driver(oxnas_stdclk_driver);
+
+void __init oxnas_init_plla(struct device_node *np)
+{
+ struct clk *clk;
+ struct clk_oxnas_pll *plla;
+
+ plla = kmalloc(sizeof(*plla), GFP_KERNEL);
+ BUG_ON(!plla);
+
+ plla->syscon = syscon_node_to_regmap(of_get_parent(np));
+ plla->hw.init = &clk_plla_init;
+ plla->devnode = np;
+ plla->rstc = NULL;
+ clk = clk_register(NULL, &plla->hw);
+ BUG_ON(IS_ERR(clk));
+ /* mark it as enabled */
+ clk_prepare_enable(clk);
+ of_clk_add_provider(np, of_clk_src_simple_get, clk);
+}
+CLK_OF_DECLARE(oxnas_plla, "plxtech,nas782x-plla", oxnas_init_plla);
+
+void __init oxnas_init_pllb(struct device_node *np)
+{
+ struct clk *clk;
+ struct clk_oxnas_pll *pllb;
+
+ pllb = kmalloc(sizeof(*pllb), GFP_KERNEL);
+ BUG_ON(!pllb);
+
+ pllb->syscon = syscon_node_to_regmap(of_get_parent(np));
+ pllb->hw.init = &clk_pllb_init;
+ pllb->devnode = np;
+ pllb->rstc = NULL;
+
+ clk = clk_register(NULL, &pllb->hw);
+ BUG_ON(IS_ERR(clk));
+ of_clk_add_provider(np, of_clk_src_simple_get, clk);
+}
+CLK_OF_DECLARE(oxnas_pllb, "plxtech,nas782x-pllb", oxnas_init_pllb);
--- a/arch/arm/boot/dts/ox820.dtsi
+++ b/arch/arm/boot/dts/ox820.dtsi
@@ -61,12 +61,6 @@
clocks = <&osc>;
};
- plla: plla {
- compatible = "fixed-clock";
- #clock-cells = <0>;
- clock-frequency = <850000000>;
- };
-
armclk: armclk {
compatible = "fixed-factor-clock";
#clock-cells = <0>;
@@ -266,6 +260,19 @@
compatible = "oxsemi,ox820-stdclk", "oxsemi,ox810se-stdclk";
#clock-cells = <1>;
};
+
+ plla: plla {
+ compatible = "plxtech,nas782x-plla";
+ #clock-cells = <0>;
+ clocks = <&osc>;
+ };
+
+ pllb: pllb {
+ compatible = "plxtech,nas782x-pllb";
+ #clock-cells = <0>;
+ clocks = <&osc>;
+ resets = <&reset RESET_PLLB>;
+ };
};
};
@@ -287,6 +294,13 @@
clocks = <&armclk>;
};
+ watchdog@620 {
+ compatible = "mpcore_wdt";
+ reg = <0x620 0x20>;
+ interrupts = <GIC_PPI 14 (GIC_CPU_MASK_RAW(3)|IRQ_TYPE_LEVEL_HIGH)>;
+ clocks = <&armclk>;
+ };
+
gic: gic@1000 {
compatible = "arm,arm11mp-gic";
interrupt-controller;

View File

@ -1,25 +0,0 @@
--- a/drivers/power/reset/Kconfig
+++ b/drivers/power/reset/Kconfig
@@ -123,6 +123,12 @@ config POWER_RESET_OCELOT_RESET
help
This driver supports restart for Microsemi Ocelot SoC.
+config POWER_RESET_OXNAS
+ bool "OXNAS SoC restart driver"
+ depends on ARCH_OXNAS
+ help
+ Restart support for OXNAS boards.
+
config POWER_RESET_PIIX4_POWEROFF
tristate "Intel PIIX4 power-off driver"
depends on PCI
--- a/drivers/power/reset/Makefile
+++ b/drivers/power/reset/Makefile
@@ -11,6 +11,7 @@ obj-$(CONFIG_POWER_RESET_GPIO) += gpio-p
obj-$(CONFIG_POWER_RESET_GPIO_RESTART) += gpio-restart.o
obj-$(CONFIG_POWER_RESET_HISI) += hisi-reboot.o
obj-$(CONFIG_POWER_RESET_MSM) += msm-poweroff.o
+obj-$(CONFIG_POWER_RESET_OXNAS) += oxnas-restart.o
obj-$(CONFIG_POWER_RESET_QCOM_PON) += qcom-pon.o
obj-$(CONFIG_POWER_RESET_OCELOT_RESET) += ocelot-reset.o
obj-$(CONFIG_POWER_RESET_PIIX4_POWEROFF) += piix4-poweroff.o

View File

@ -1,44 +0,0 @@
--- a/arch/arm/boot/dts/ox820.dtsi
+++ b/arch/arm/boot/dts/ox820.dtsi
@@ -247,6 +247,15 @@
};
};
+ pcie_phy: pcie-phy@a00000 {
+ compatible = "oxsemi,ox820-pcie-phy";
+ reg = <0xa00000 0x10>;
+ #phy-cells = <0>;
+ resets = <&reset RESET_PCIEPHY>;
+ reset-names = "phy";
+ status = "disabled";
+ };
+
sys: sys-ctrl@e00000 {
compatible = "oxsemi,ox820-sys-ctrl", "syscon", "simple-mfd";
reg = <0xe00000 0x200000>;
--- a/drivers/phy/Kconfig
+++ b/drivers/phy/Kconfig
@@ -35,6 +35,13 @@ config PHY_LPC18XX_USB_OTG
This driver is need for USB0 support on LPC18xx/43xx and takes
care of enabling and clock setup.
+config PHY_OXNAS
+ tristate "Oxford Semi. OX820 PCI-E PHY support"
+ depends on HAS_IOMEM && OF && (ARM || COMPILE_TEST)
+ select GENERIC_PHY
+ help
+ This option enables support for OXNAS OX820 SoC PCIE PHY.
+
config PHY_PISTACHIO_USB
tristate "IMG Pistachio USB2.0 PHY driver"
depends on MACH_PISTACHIO
--- a/drivers/phy/Makefile
+++ b/drivers/phy/Makefile
@@ -6,6 +6,7 @@
obj-$(CONFIG_GENERIC_PHY) += phy-core.o
obj-$(CONFIG_GENERIC_PHY_MIPI_DPHY) += phy-core-mipi-dphy.o
obj-$(CONFIG_PHY_LPC18XX_USB_OTG) += phy-lpc18xx-usb-otg.o
+obj-$(CONFIG_PHY_OXNAS) += phy-oxnas-pcie.o
obj-$(CONFIG_PHY_XGENE) += phy-xgene.o
obj-$(CONFIG_PHY_PISTACHIO_USB) += phy-pistachio-usb.o
obj-$(CONFIG_ARCH_SUNXI) += allwinner/

View File

@ -1,122 +0,0 @@
--- a/drivers/pci/controller/Kconfig
+++ b/drivers/pci/controller/Kconfig
@@ -48,6 +48,11 @@ config PCIE_CADENCE_EP
endpoint mode. This PCIe controller may be embedded into many
different vendors SoCs.
+config PCIE_OXNAS
+ bool "PLX Oxnas PCIe controller"
+ depends on ARCH_OXNAS
+ select PCIEPORTBUS
+
endmenu
config PCIE_XILINX_NWL
--- a/drivers/pci/controller/Makefile
+++ b/drivers/pci/controller/Makefile
@@ -28,6 +28,7 @@ obj-$(CONFIG_PCIE_ROCKCHIP_EP) += pcie-r
obj-$(CONFIG_PCIE_ROCKCHIP_HOST) += pcie-rockchip-host.o
obj-$(CONFIG_PCIE_MEDIATEK) += pcie-mediatek.o
obj-$(CONFIG_PCIE_MOBIVEIL) += pcie-mobiveil.o
+obj-$(CONFIG_PCIE_OXNAS) += pcie-oxnas.o
obj-$(CONFIG_PCIE_TANGO_SMP8759) += pcie-tango.o
obj-$(CONFIG_VMD) += vmd.o
# pcie-hisi.o quirks are needed even without CONFIG_PCIE_DW
--- a/arch/arm/boot/dts/ox820.dtsi
+++ b/arch/arm/boot/dts/ox820.dtsi
@@ -289,7 +289,7 @@
#address-cells = <1>;
#size-cells = <1>;
compatible = "simple-bus";
- ranges = <0 0x47000000 0x1000000>;
+ ranges = <0 0x47000000 0x2000>;
scu: scu@0 {
compatible = "arm,arm11mp-scu";
@@ -318,5 +318,86 @@
<0x100 0x500>;
};
};
+
+ pcie0: pcie-controller@47c00000 {
+ compatible = "plxtech,nas782x-pcie";
+ device_type = "pci";
+ #address-cells = <3>;
+ #size-cells = <2>;
+
+ /* flag & space bus address host address size */
+ ranges = < 0x82000000 0 0x48000000 0x48000000 0 0x2000000
+ 0xC2000000 0 0x4A000000 0x4A000000 0 0x1E00000
+ 0x81000000 0 0x4BE00000 0x4BE00000 0 0x0100000
+ 0x80000000 0 0x4BF00000 0x4BF00000 0 0x0100000>;
+
+ bus-range = <0x00 0x7f>;
+
+ /* cfg inbound translator */
+ reg = <0x47c00000 0x1000>, <0x47d00000 0x100>;
+
+ phys = <&pcie_phy>;
+ phy-names = "pcie-phy";
+
+ #interrupt-cells = <1>;
+ /* wild card mask, match all bus address & interrupt specifier */
+ /* format: bus address mask, interrupt specifier mask */
+ /* each bit 1 means need match, 0 means ignored when match */
+ interrupt-map-mask = <0 0 0 0>;
+ /* format: a list of: bus address, interrupt specifier,
+ * parent interrupt controller & specifier */
+ interrupt-map = <0 0 0 0 &gic 0 19 0x304>;
+ gpios = <&gpio1 12 0>;
+ clocks = <&stdclk CLK_820_PCIEA>, <&pllb>;
+ clock-names = "pcie", "busclk";
+ resets = <&reset RESET_PCIEA>;
+ reset-names = "pcie";
+
+ plxtech,pcie-hcsl-bit = <2>;
+ plxtech,pcie-ctrl-offset = <0x120>;
+ plxtech,pcie-outbound-offset = <0x138>;
+ status = "disabled";
+ };
+
+ pcie1: pcie-controller@47e00000 {
+ compatible = "plxtech,nas782x-pcie";
+ device_type = "pci";
+ #address-cells = <3>;
+ #size-cells = <2>;
+
+ /* flag & space bus address host address size */
+ ranges = < 0x82000000 0 0x4C000000 0x4C000000 0 0x2000000
+ 0xC2000000 0 0x4E000000 0x4E000000 0 0x1E00000
+ 0x81000000 0 0x4FE00000 0x4FE00000 0 0x0100000
+ 0x80000000 0 0x4FF00000 0x4FF00000 0 0x0100000>;
+
+ bus-range = <0x80 0xff>;
+
+ /* cfg inbound translator */
+ reg = <0x47e00000 0x1000>, <0x47f00000 0x100>;
+
+ phys = <&pcie_phy>;
+ phy-names = "pcie-phy";
+
+ #interrupt-cells = <1>;
+ /* wild card mask, match all bus address & interrupt specifier */
+ /* format: bus address mask, interrupt specifier mask */
+ /* each bit 1 means need match, 0 means ignored when match */
+ interrupt-map-mask = <0 0 0 0>;
+ /* format: a list of: bus address, interrupt specifier,
+ * parent interrupt controller & specifier */
+ interrupt-map = <0 0 0 0 &gic 0 20 0x304>;
+
+ /* gpios = <&gpio1 12 0>; */
+ clocks = <&stdclk CLK_820_PCIEB>, <&pllb>;
+ clock-names = "pcie", "busclk";
+ resets = <&reset RESET_PCIEB>;
+ reset-names = "pcie";
+
+ plxtech,pcie-hcsl-bit = <3>;
+ plxtech,pcie-ctrl-offset = <0x124>;
+ plxtech,pcie-outbound-offset = <0x174>;
+ status = "disabled";
+ };
};
};

View File

@ -1,59 +0,0 @@
--- a/drivers/ata/Kconfig
+++ b/drivers/ata/Kconfig
@@ -508,6 +508,13 @@ config SATA_VITESSE
If unsure, say N.
+config SATA_OXNAS
+ tristate "PLXTECH NAS782X SATA support"
+ help
+ This option enables support for Nas782x Serial ATA controller.
+
+ If unsure, say N.
+
comment "PATA SFF controllers with BMDMA"
config PATA_ALI
--- a/drivers/ata/Makefile
+++ b/drivers/ata/Makefile
@@ -46,6 +46,7 @@ obj-$(CONFIG_SATA_SVW) += sata_svw.o
obj-$(CONFIG_SATA_ULI) += sata_uli.o
obj-$(CONFIG_SATA_VIA) += sata_via.o
obj-$(CONFIG_SATA_VITESSE) += sata_vsc.o
+obj-$(CONFIG_SATA_OXNAS) += sata_oxnas.o
# SFF PATA w/ BMDMA
obj-$(CONFIG_PATA_ALI) += pata_ali.o
--- a/arch/arm/boot/dts/ox820.dtsi
+++ b/arch/arm/boot/dts/ox820.dtsi
@@ -399,5 +399,20 @@
plxtech,pcie-outbound-offset = <0x174>;
status = "disabled";
};
+
+ sata: sata@45900000 {
+ compatible = "plxtech,nas782x-sata";
+ /* ports dmactl sgdma */
+ reg = <0x45900000 0x20000>, <0x459A0000 0x40>, <0x459B0000 0x20>,
+ /* core phy descriptors (optional) */
+ <0x459E0000 0x2000>, <0x44900000 0x0C>, <0x50000000 0x1000>;
+ interrupts = <GIC_SPI 18 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&stdclk CLK_820_SATA>;
+ resets = <&reset RESET_SATA>, <&reset RESET_SATA_LINK>, <&reset RESET_SATA_PHY>;
+ reset-names = "sata", "link", "phy";
+ nr-ports = <1>;
+ status = "disabled";
+ };
+
};
};
--- a/arch/arm/boot/dts/ox820-cloudengines-pogoplug-series-3.dts
+++ b/arch/arm/boot/dts/ox820-cloudengines-pogoplug-series-3.dts
@@ -111,3 +111,7 @@
pinctrl-names = "default";
pinctrl-0 = <&pinctrl_etha_mdio>;
};
+
+&sata {
+ status = "okay";
+};

View File

@ -1,10 +0,0 @@
--- a/arch/arm/mach-oxnas/Kconfig
+++ b/arch/arm/mach-oxnas/Kconfig
@@ -2,6 +2,7 @@
menuconfig ARCH_OXNAS
bool "Oxford Semiconductor OXNAS Family SoCs"
select ARCH_HAS_RESET_CONTROLLER
+ select ARCH_WANT_LIBATA_LEDS
select COMMON_CLK_OXNAS
select GPIOLIB
select MFD_SYSCON

View File

@ -1,73 +0,0 @@
--- a/drivers/usb/host/Kconfig
+++ b/drivers/usb/host/Kconfig
@@ -321,6 +321,13 @@ config USB_OCTEON_EHCI
USB 2.0 device support. All CN6XXX based chips with USB are
supported.
+config USB_EHCI_OXNAS
+ tristate "OXNAS EHCI Module"
+ depends on USB_EHCI_HCD && ARCH_OXNAS
+ select USB_EHCI_ROOT_HUB_TT
+ ---help---
+ Enable support for the OX820 SOC's on-chip EHCI controller.
+
endif # USB_EHCI_HCD
config USB_OXU210HP_HCD
--- a/drivers/usb/host/Makefile
+++ b/drivers/usb/host/Makefile
@@ -49,6 +49,7 @@ obj-$(CONFIG_USB_EHCI_HCD_STI) += ehci-s
obj-$(CONFIG_USB_EHCI_EXYNOS) += ehci-exynos.o
obj-$(CONFIG_USB_EHCI_HCD_AT91) += ehci-atmel.o
obj-$(CONFIG_USB_EHCI_TEGRA) += ehci-tegra.o
+obj-$(CONFIG_USB_EHCI_OXNAS) += ehci-oxnas.o
obj-$(CONFIG_USB_OXU210HP_HCD) += oxu210hp-hcd.o
obj-$(CONFIG_USB_ISP116X_HCD) += isp116x-hcd.o
--- a/arch/arm/boot/dts/ox820.dtsi
+++ b/arch/arm/boot/dts/ox820.dtsi
@@ -106,6 +106,31 @@
status = "disabled";
};
+ ehci: ehci@40200100 {
+ compatible = "plxtech,nas782x-ehci";
+ reg = <0x40200100 0xf00>;
+ interrupts = <GIC_SPI 7 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&stdclk CLK_820_USBMPH>, <&pllb>, <&stdclk CLK_820_REF600>;
+ clock-names = "usb", "refsrc", "phyref";
+ resets = <&reset RESET_USBHS>, <&reset RESET_USBPHYA>, <&reset RESET_USBPHYB>;
+ reset-names = "host", "phya", "phyb";
+ oxsemi,sys-ctrl = <&sys>;
+ /* Otherwise ref300 is used, which is derived from sata phy
+ * in that case, usb depends on sata initialization */
+ /* FIXME: how to make this dependency explicit ? */
+ oxsemi,ehci_use_pllb;
+ status = "disabled";
+
+ ehci_port1: port@1 {
+ reg = <1>;
+ #trigger-source-cells = <0>;
+ };
+ ehci_port2: port@2 {
+ reg = <2>;
+ #trigger-source-cells = <0>;
+ };
+ };
+
apb-bridge@44000000 {
#address-cells = <1>;
#size-cells = <1>;
--- a/arch/arm/boot/dts/ox820-cloudengines-pogoplug-series-3.dts
+++ b/arch/arm/boot/dts/ox820-cloudengines-pogoplug-series-3.dts
@@ -105,6 +105,10 @@
};
};
+&ehci {
+ status = "okay";
+};
+
&etha {
status = "okay";

View File

@ -1,189 +0,0 @@
From 71270226b14733a4b1f2cde58ea9265caa50b38d Mon Sep 17 00:00:00 2001
From: Adrian Panella <ianchi74@outlook.com>
Date: Thu, 9 Mar 2017 09:37:17 +0100
Subject: [PATCH 67/69] generic: Mangle bootloader's kernel arguments
The command-line arguments provided by the boot loader will be
appended to a new device tree property: bootloader-args.
If there is a property "append-rootblock" in DT under /chosen
and a root= option in bootloaders command line it will be parsed
and added to DT bootargs with the form: <append-rootblock>XX.
Only command line ATAG will be processed, the rest of the ATAGs
sent by bootloader will be ignored.
This is usefull in dual boot systems, to get the current root partition
without afecting the rest of the system.
Signed-off-by: Adrian Panella <ianchi74@outlook.com>
---
arch/arm/Kconfig | 11 +++++
arch/arm/boot/compressed/atags_to_fdt.c | 72 ++++++++++++++++++++++++++++++++-
init/main.c | 16 ++++++++
3 files changed, 98 insertions(+), 1 deletion(-)
--- a/arch/arm/Kconfig
+++ b/arch/arm/Kconfig
@@ -1827,6 +1827,17 @@ config ARM_ATAG_DTB_COMPAT_CMDLINE_EXTEN
The command-line arguments provided by the boot loader will be
appended to the the device tree bootargs property.
+config ARM_ATAG_DTB_COMPAT_CMDLINE_MANGLE
+ bool "Append rootblock parsing bootloader's kernel arguments"
+ help
+ The command-line arguments provided by the boot loader will be
+ appended to a new device tree property: bootloader-args.
+ If there is a property "append-rootblock" in DT under /chosen
+ and a root= option in bootloaders command line it will be parsed
+ and added to DT bootargs with the form: <append-rootblock>XX.
+ Only command line ATAG will be processed, the rest of the ATAGs
+ sent by bootloader will be ignored.
+
endchoice
config CMDLINE
--- a/arch/arm/boot/compressed/atags_to_fdt.c
+++ b/arch/arm/boot/compressed/atags_to_fdt.c
@@ -4,6 +4,8 @@
#if defined(CONFIG_ARM_ATAG_DTB_COMPAT_CMDLINE_EXTEND)
#define do_extend_cmdline 1
+#elif defined(CONFIG_ARM_ATAG_DTB_COMPAT_CMDLINE_MANGLE)
+#define do_extend_cmdline 1
#else
#define do_extend_cmdline 0
#endif
@@ -67,6 +69,59 @@ static uint32_t get_cell_size(const void
return cell_size;
}
+#if defined(CONFIG_ARM_ATAG_DTB_COMPAT_CMDLINE_MANGLE)
+
+static char *append_rootblock(char *dest, const char *str, int len, void *fdt)
+{
+ char *ptr, *end;
+ char *root="root=";
+ int i, l;
+ const char *rootblock;
+
+ //ARM doesn't have __HAVE_ARCH_STRSTR, so search manually
+ ptr = str - 1;
+
+ do {
+ //first find an 'r' at the begining or after a space
+ do {
+ ptr++;
+ ptr = strchr(ptr, 'r');
+ if(!ptr) return dest;
+
+ } while (ptr != str && *(ptr-1) != ' ');
+
+ //then check for the rest
+ for(i = 1; i <= 4; i++)
+ if(*(ptr+i) != *(root+i)) break;
+
+ } while (i != 5);
+
+ end = strchr(ptr, ' ');
+ end = end ? (end - 1) : (strchr(ptr, 0) - 1);
+
+ //find partition number (assumes format root=/dev/mtdXX | /dev/mtdblockXX | yy:XX )
+ for( i = 0; end >= ptr && *end >= '0' && *end <= '9'; end--, i++);
+ ptr = end + 1;
+
+ /* if append-rootblock property is set use it to append to command line */
+ rootblock = getprop(fdt, "/chosen", "append-rootblock", &l);
+ if(rootblock != NULL) {
+ if(*dest != ' ') {
+ *dest = ' ';
+ dest++;
+ len++;
+ }
+ if (len + l + i <= COMMAND_LINE_SIZE) {
+ memcpy(dest, rootblock, l);
+ dest += l - 1;
+ memcpy(dest, ptr, i);
+ dest += i;
+ }
+ }
+ return dest;
+}
+#endif
+
static void merge_fdt_bootargs(void *fdt, const char *fdt_cmdline)
{
char cmdline[COMMAND_LINE_SIZE];
@@ -86,12 +141,21 @@ static void merge_fdt_bootargs(void *fdt
/* and append the ATAG_CMDLINE */
if (fdt_cmdline) {
+
+#if defined(CONFIG_ARM_ATAG_DTB_COMPAT_CMDLINE_MANGLE)
+ //save original bootloader args
+ //and append ubi.mtd with root partition number to current cmdline
+ setprop_string(fdt, "/chosen", "bootloader-args", fdt_cmdline);
+ ptr = append_rootblock(ptr, fdt_cmdline, len, fdt);
+
+#else
len = strlen(fdt_cmdline);
if (ptr - cmdline + len + 2 < COMMAND_LINE_SIZE) {
*ptr++ = ' ';
memcpy(ptr, fdt_cmdline, len);
ptr += len;
}
+#endif
}
*ptr = '\0';
@@ -166,7 +230,9 @@ int atags_to_fdt(void *atag_list, void *
else
setprop_string(fdt, "/chosen", "bootargs",
atag->u.cmdline.cmdline);
- } else if (atag->hdr.tag == ATAG_MEM) {
+ }
+#ifndef CONFIG_ARM_ATAG_DTB_COMPAT_CMDLINE_MANGLE
+ else if (atag->hdr.tag == ATAG_MEM) {
if (memcount >= sizeof(mem_reg_property)/4)
continue;
if (!atag->u.mem.size)
@@ -210,6 +276,10 @@ int atags_to_fdt(void *atag_list, void *
setprop(fdt, "/memory", "reg", mem_reg_property,
4 * memcount * memsize);
}
+#else
+
+ }
+#endif
return fdt_pack(fdt);
}
--- a/init/main.c
+++ b/init/main.c
@@ -104,6 +104,10 @@
#define CREATE_TRACE_POINTS
#include <trace/events/initcall.h>
+#if defined(CONFIG_ARM_ATAG_DTB_COMPAT_CMDLINE_MANGLE)
+#include <linux/of.h>
+#endif
+
static int kernel_init(void *);
extern void init_IRQ(void);
@@ -631,6 +635,18 @@ asmlinkage __visible void __init start_k
page_alloc_init();
pr_notice("Kernel command line: %s\n", boot_command_line);
+
+#if defined(CONFIG_ARM_ATAG_DTB_COMPAT_CMDLINE_MANGLE)
+ //Show bootloader's original command line for reference
+ if(of_chosen) {
+ const char *prop = of_get_property(of_chosen, "bootloader-args", NULL);
+ if(prop)
+ pr_notice("Bootloader command line (ignored): %s\n", prop);
+ else
+ pr_notice("Bootloader command line not present\n");
+ }
+#endif
+
/* parameters may set static keys */
jump_label_init();
parse_early_param();

View File

@ -1,57 +0,0 @@
--- a/drivers/ata/libata-core.c
+++ b/drivers/ata/libata-core.c
@@ -1583,6 +1583,14 @@ unsigned ata_exec_internal_sg(struct ata
return AC_ERR_SYSTEM;
}
+ if (ap->ops->acquire_hw && !ap->ops->acquire_hw(ap, 0, 0)) {
+ spin_unlock_irqrestore(ap->lock, flags);
+ if (!ap->ops->acquire_hw(ap, 1, (2*HZ))) {
+ return AC_ERR_TIMEOUT;
+ }
+ spin_lock_irqsave(ap->lock, flags);
+ }
+
/* initialize internal qc */
qc = __ata_qc_from_tag(ap, ATA_TAG_INTERNAL);
@@ -5128,6 +5136,9 @@ struct ata_queued_cmd *ata_qc_new_init(s
if (unlikely(ap->pflags & ATA_PFLAG_FROZEN))
return NULL;
+ if (ap->ops->qc_new && ap->ops->qc_new(ap))
+ return NULL;
+
/* libsas case */
if (ap->flags & ATA_FLAG_SAS_HOST) {
tag = ata_sas_allocate_tag(ap);
@@ -5173,6 +5184,8 @@ void ata_qc_free(struct ata_queued_cmd *
qc->tag = ATA_TAG_POISON;
if (ap->flags & ATA_FLAG_SAS_HOST)
ata_sas_free_tag(tag, ap);
+ if (ap->ops->qc_free)
+ ap->ops->qc_free(qc);
}
}
--- a/include/linux/libata.h
+++ b/include/linux/libata.h
@@ -910,6 +910,8 @@ struct ata_port_operations {
enum ata_completion_errors (*qc_prep)(struct ata_queued_cmd *qc);
unsigned int (*qc_issue)(struct ata_queued_cmd *qc);
bool (*qc_fill_rtf)(struct ata_queued_cmd *qc);
+ int (*qc_new)(struct ata_port *ap);
+ void (*qc_free)(struct ata_queued_cmd *qc);
/*
* Configuration and exception handling
@@ -1000,6 +1002,9 @@ struct ata_port_operations {
void (*phy_reset)(struct ata_port *ap);
void (*eng_timeout)(struct ata_port *ap);
+ int (*acquire_hw)(struct ata_port *ap, int may_sleep,
+ int timeout_jiffies);
+
/*
* ->inherits must be the last field and all the preceding
* fields must be pointers.

View File

@ -1,3 +1,4 @@
CONFIG_AQUANTIA_PHY=y
CONFIG_ARCH_32BIT_OFF_T=y
CONFIG_ARCH_HIBERNATION_POSSIBLE=y
CONFIG_ARCH_MMAP_RND_BITS_MAX=15
@ -71,6 +72,7 @@ CONFIG_GPIOLIB_IRQCHIP=y
CONFIG_GPIO_GENERIC=y
CONFIG_GPIO_REALTEK_OTTO=y
CONFIG_GPIO_RTL8231=y
CONFIG_GPIO_RTL838X=y
CONFIG_GRO_CELLS=y
CONFIG_HANDLE_DOMAIN_IRQ=y
CONFIG_HARDWARE_WATCHPOINTS=y

View File

@ -214,6 +214,13 @@
#define RTL838X_GPIO_PAB_IMR (GPIO_CTRL_REG_BASE + 0x14)
#define RTL838X_GPIO_PC_IMR (GPIO_CTRL_REG_BASE + 0x18)
#define RTL930X_GPIO_CTRL_REG_BASE ((volatile void *) 0xb8003300)
#define RTL930X_GPIO_PABCD_DIR (RTL930X_GPIO_CTRL_REG_BASE + 0x8)
#define RTL930X_GPIO_PABCD_DAT (RTL930X_GPIO_CTRL_REG_BASE + 0xc)
#define RTL930X_GPIO_PABCD_ISR (RTL930X_GPIO_CTRL_REG_BASE + 0x10)
#define RTL930X_GPIO_PAB_IMR (RTL930X_GPIO_CTRL_REG_BASE + 0x14)
#define RTL930X_GPIO_PCD_IMR (RTL930X_GPIO_CTRL_REG_BASE + 0x18)
#define RTL838X_MODEL_NAME_INFO (0x00D4)
#define RTL839X_MODEL_NAME_INFO (0x0FF0)
#define RTL93XX_MODEL_NAME_INFO (0x0004)

View File

@ -0,0 +1,474 @@
// SPDX-License-Identifier: GPL-2.0-only
#include <linux/gpio/driver.h>
#include <linux/module.h>
#include <linux/platform_device.h>
#include <linux/delay.h>
#include <asm/mach-rtl838x/mach-rtl83xx.h>
/* RTL8231 registers for LED control */
#define RTL8231_LED_FUNC0 0x0000
#define RTL8231_GPIO_PIN_SEL(gpio) ((0x0002) + ((gpio) >> 4))
#define RTL8231_GPIO_DIR(gpio) ((0x0005) + ((gpio) >> 4))
#define RTL8231_GPIO_DATA(gpio) ((0x001C) + ((gpio) >> 4))
struct rtl838x_gpios {
struct gpio_chip gc;
u32 id;
struct device *dev;
int irq;
int num_leds;
int min_led;
int leds_per_port;
u32 led_mode;
int led_glb_ctrl;
int led_sw_ctrl;
int (*led_sw_p_ctrl)(int port);
int (*led_sw_p_en_ctrl)(int port);
int (*ext_gpio_dir)(int i);
int (*ext_gpio_data)(int i);
};
inline int rtl838x_ext_gpio_dir(int i)
{
return RTL838X_EXT_GPIO_DIR + ((i >>5) << 2);
}
inline int rtl839x_ext_gpio_dir(int i)
{
return RTL839X_EXT_GPIO_DIR + ((i >>5) << 2);
}
inline int rtl838x_ext_gpio_data(int i)
{
return RTL838X_EXT_GPIO_DATA + ((i >>5) << 2);
}
inline int rtl839x_ext_gpio_data(int i)
{
return RTL839X_EXT_GPIO_DATA + ((i >>5) << 2);
}
inline int rtl838x_led_sw_p_ctrl(int p)
{
return RTL838X_LED_SW_P_CTRL + (p << 2);
}
inline int rtl839x_led_sw_p_ctrl(int p)
{
return RTL839X_LED_SW_P_CTRL + (p << 2);
}
inline int rtl838x_led_sw_p_en_ctrl(int p)
{
return RTL838X_LED_SW_P_EN_CTRL + ((p / 10) << 2);
}
inline int rtl839x_led_sw_p_en_ctrl(int p)
{
return RTL839X_LED_SW_P_EN_CTRL + ((p / 10) << 2);
}
extern struct mutex smi_lock;
extern struct rtl83xx_soc_info soc_info;
void rtl838x_gpio_set(struct gpio_chip *gc, unsigned int offset, int value)
{
int bit;
struct rtl838x_gpios *gpios = gpiochip_get_data(gc);
pr_debug("rtl838x_set: %d, value: %d\n", offset, value);
/* Internal GPIO of the RTL8380 */
if (offset < 32) {
if (value)
rtl83xx_w32_mask(0, BIT(offset), RTL838X_GPIO_PABC_DATA);
else
rtl83xx_w32_mask(BIT(offset), 0, RTL838X_GPIO_PABC_DATA);
}
/* LED driver for PWR and SYS */
if (offset >= 32 && offset < 64) {
bit = offset - 32;
if (value)
sw_w32_mask(0, BIT(bit), gpios->led_glb_ctrl);
else
sw_w32_mask(BIT(bit), 0, gpios->led_glb_ctrl);
return;
}
bit = (offset - 64) % 32;
/* First Port-LED */
if (offset >= 64 && offset < 96
&& offset >= (64 + gpios->min_led)
&& offset < (64 + gpios->min_led + gpios->num_leds)) {
if (value)
sw_w32_mask(7, 5, gpios->led_sw_p_ctrl(bit));
else
sw_w32_mask(7, 0, gpios->led_sw_p_ctrl(bit));
}
if (offset >= 96 && offset < 128
&& offset >= (96 + gpios->min_led)
&& offset < (96 + gpios->min_led + gpios->num_leds)) {
if (value)
sw_w32_mask(7 << 3, 5 << 3, gpios->led_sw_p_ctrl(bit));
else
sw_w32_mask(7 << 3, 0, gpios->led_sw_p_ctrl(bit));
}
if (offset >= 128 && offset < 160
&& offset >= (128 + gpios->min_led)
&& offset < (128 + gpios->min_led + gpios->num_leds)) {
if (value)
sw_w32_mask(7 << 6, 5 << 6, gpios->led_sw_p_ctrl(bit));
else
sw_w32_mask(7 << 6, 0, gpios->led_sw_p_ctrl(bit));
}
__asm__ volatile ("sync");
}
void rtl930x_gpio_set(struct gpio_chip *gc, unsigned int offset, int value)
{
pr_debug("rtl838x_set: %d, value: %d\n", offset, value);
/* Internal GPIO of the RTL9300 */
if (value)
rtl83xx_w32_mask(0, BIT(offset), RTL930X_GPIO_PABCD_DAT);
else
rtl83xx_w32_mask(BIT(offset), 0, RTL930X_GPIO_PABCD_DAT);
}
static int rtl838x_direction_input(struct gpio_chip *gc, unsigned int offset)
{
pr_debug("%s: %d\n", __func__, offset);
if (offset < 32) {
rtl83xx_w32_mask(BIT(offset), 0, RTL838X_GPIO_PABC_DIR);
return 0;
}
/* Internal LED driver does not support input */
return -ENOTSUPP;
}
static int rtl930x_direction_input(struct gpio_chip *gc, unsigned int offset)
{
pr_debug("%s: %d\n", __func__, offset);
rtl83xx_w32_mask(BIT(offset), 0, RTL930X_GPIO_PABCD_DIR);
return 0;
}
static int rtl838x_direction_output(struct gpio_chip *gc, unsigned int offset, int value)
{
pr_debug("%s: %d\n", __func__, offset);
if (offset < 32)
rtl83xx_w32_mask(0, BIT(offset), RTL838X_GPIO_PABC_DIR);
rtl930x_gpio_set(gc, offset, value);
/* LED for PWR and SYS driver is direction output by default */
return 0;
}
static int rtl930x_direction_output(struct gpio_chip *gc, unsigned int offset, int value)
{
pr_debug("%s: %d\n", __func__, offset);
rtl83xx_w32_mask(0, BIT(offset), RTL930X_GPIO_PABCD_DIR);
rtl930x_gpio_set(gc, offset, value);
/* LED for PWR and SYS driver is direction output by default */
return 0;
}
static int rtl838x_get_direction(struct gpio_chip *gc, unsigned int offset)
{
u32 v = 0;
pr_debug("%s: %d\n", __func__, offset);
if (offset < 32) {
v = rtl83xx_r32(RTL838X_GPIO_PABC_DIR);
if (v & BIT(offset))
return 0;
return 1;
}
/* LED driver for PWR and SYS is direction output by default */
if (offset >= 32 && offset < 64)
return 0;
return 0;
}
static int rtl930x_get_direction(struct gpio_chip *gc, unsigned int offset)
{
u32 v = 0;
v = rtl83xx_r32(RTL930X_GPIO_PABCD_DIR);
if (v & BIT(offset))
return 0;
return 1;
}
static int rtl838x_gpio_get(struct gpio_chip *gc, unsigned int offset)
{
u32 v;
struct rtl838x_gpios *gpios = gpiochip_get_data(gc);
pr_debug("%s: %d\n", __func__, offset);
/* Internal GPIO of the RTL8380 */
if (offset < 32) {
v = rtl83xx_r32(RTL838X_GPIO_PABC_DATA);
if (v & BIT(offset))
return 1;
return 0;
}
/* LED driver for PWR and SYS */
if (offset >= 32 && offset < 64) {
v = sw_r32(gpios->led_glb_ctrl);
if (v & BIT(offset-32))
return 1;
return 0;
}
return 0;
}
static int rtl930x_gpio_get(struct gpio_chip *gc, unsigned int offset)
{
u32 v = rtl83xx_r32(RTL930X_GPIO_PABCD_DAT);
if (v & BIT(offset))
return 1;
return 0;
}
void rtl8380_led_test(struct rtl838x_gpios *gpios, u32 mask)
{
int i;
u32 led_gbl = sw_r32(gpios->led_glb_ctrl);
u32 mode_sel, led_p_en;
if (soc_info.family == RTL8380_FAMILY_ID) {
mode_sel = sw_r32(RTL838X_LED_MODE_SEL);
led_p_en = sw_r32(RTL838X_LED_P_EN_CTRL);
}
/* 2 Leds for ports 0-23 and 24-27, 3 would be 0x7 */
sw_w32_mask(0x3f, 0x3 | (0x3 << 3), gpios->led_glb_ctrl);
if(soc_info.family == RTL8380_FAMILY_ID) {
/* Enable all leds */
sw_w32(0xFFFFFFF, RTL838X_LED_P_EN_CTRL);
}
/* Enable software control of all leds */
sw_w32(0xFFFFFFF, gpios->led_sw_ctrl);
sw_w32(0xFFFFFFF, gpios->led_sw_p_en_ctrl(0));
sw_w32(0xFFFFFFF, gpios->led_sw_p_en_ctrl(10));
sw_w32(0x0000000, gpios->led_sw_p_en_ctrl(20));
for (i = 0; i < 28; i++) {
if (mask & BIT(i))
sw_w32(5 | (5 << 3) | (5 << 6), gpios->led_sw_p_ctrl(i));
}
msleep(3000);
if (soc_info.family == RTL8380_FAMILY_ID)
sw_w32(led_p_en, RTL838X_LED_P_EN_CTRL);
/* Disable software control of all leds */
sw_w32(0x0000000, gpios->led_sw_ctrl);
sw_w32(0x0000000, gpios->led_sw_p_en_ctrl(0));
sw_w32(0x0000000, gpios->led_sw_p_en_ctrl(10));
sw_w32(0x0000000, gpios->led_sw_p_en_ctrl(20));
sw_w32(led_gbl, gpios->led_glb_ctrl);
if (soc_info.family == RTL8380_FAMILY_ID)
sw_w32(mode_sel, RTL838X_LED_MODE_SEL);
}
void take_port_leds(struct rtl838x_gpios *gpios)
{
int leds_per_port = gpios->leds_per_port;
int mode = gpios->led_mode;
pr_info("%s, %d, %x\n", __func__, leds_per_port, mode);
pr_debug("Bootloader settings: %x %x %x\n",
sw_r32(gpios->led_sw_p_en_ctrl(0)),
sw_r32(gpios->led_sw_p_en_ctrl(10)),
sw_r32(gpios->led_sw_p_en_ctrl(20))
);
if (soc_info.family == RTL8380_FAMILY_ID) {
pr_debug("led glb: %x, sel %x\n",
sw_r32(gpios->led_glb_ctrl), sw_r32(RTL838X_LED_MODE_SEL));
pr_debug("RTL838X_LED_P_EN_CTRL: %x", sw_r32(RTL838X_LED_P_EN_CTRL));
pr_debug("RTL838X_LED_MODE_CTRL: %x", sw_r32(RTL838X_LED_MODE_CTRL));
sw_w32_mask(3, 0, RTL838X_LED_MODE_SEL);
sw_w32(mode, RTL838X_LED_MODE_CTRL);
}
/* Enable software control of all leds */
sw_w32(0xFFFFFFF, gpios->led_sw_ctrl);
if (soc_info.family == RTL8380_FAMILY_ID)
sw_w32(0xFFFFFFF, RTL838X_LED_P_EN_CTRL);
sw_w32(0x0000000, gpios->led_sw_p_en_ctrl(0));
sw_w32(0x0000000, gpios->led_sw_p_en_ctrl(10));
sw_w32(0x0000000, gpios->led_sw_p_en_ctrl(20));
sw_w32_mask(0x3f, 0, gpios->led_glb_ctrl);
switch (leds_per_port) {
case 3:
sw_w32_mask(0, 0x7 | (0x7 << 3), gpios->led_glb_ctrl);
sw_w32(0xFFFFFFF, gpios->led_sw_p_en_ctrl(20));
/* FALLTHRU */
case 2:
sw_w32_mask(0, 0x3 | (0x3 << 3), gpios->led_glb_ctrl);
sw_w32(0xFFFFFFF, gpios->led_sw_p_en_ctrl(10));
/* FALLTHRU */
case 1:
sw_w32_mask(0, 0x1 | (0x1 << 3), gpios->led_glb_ctrl);
sw_w32(0xFFFFFFF, gpios->led_sw_p_en_ctrl(0));
break;
default:
pr_err("No LEDS configured for software control\n");
}
}
static const struct of_device_id rtl838x_gpio_of_match[] = {
{ .compatible = "realtek,rtl838x-gpio" },
{},
};
MODULE_DEVICE_TABLE(of, rtl838x_gpio_of_match);
static int rtl838x_gpio_probe(struct platform_device *pdev)
{
struct device *dev = &pdev->dev;
struct device_node *np = dev->of_node;
struct rtl838x_gpios *gpios;
int err;
pr_info("Probing RTL838X GPIOs for %08x\n", soc_info.id);
if (!np) {
dev_err(&pdev->dev, "No DT found\n");
return -EINVAL;
}
gpios = devm_kzalloc(dev, sizeof(*gpios), GFP_KERNEL);
if (!gpios)
return -ENOMEM;
gpios->id = soc_info.id;
switch (gpios->id) {
case 0x8332:
pr_debug("Found RTL8332M GPIO\n");
break;
case 0x8380:
pr_debug("Found RTL8380M GPIO\n");
break;
case 0x8381:
pr_debug("Found RTL8381M GPIO\n");
break;
case 0x8382:
pr_debug("Found RTL8382M GPIO\n");
break;
case 0x8391:
pr_debug("Found RTL8391 GPIO\n");
break;
case 0x8393:
pr_debug("Found RTL8393 GPIO\n");
break;
case 0x9302:
pr_info("Found RTL9302 GPIO\n");
break;
default:
pr_err("Unknown GPIO chip id (%04x)\n", gpios->id);
return -ENODEV;
}
if (soc_info.family == RTL8380_FAMILY_ID) {
gpios->led_glb_ctrl = RTL838X_LED_GLB_CTRL;
gpios->led_sw_ctrl = RTL838X_LED_SW_CTRL;
gpios->led_sw_p_ctrl = rtl838x_led_sw_p_ctrl;
gpios->led_sw_p_en_ctrl = rtl838x_led_sw_p_en_ctrl;
gpios->ext_gpio_dir = rtl838x_ext_gpio_dir;
gpios->ext_gpio_data = rtl838x_ext_gpio_data;
gpios->irq = 31;
}
if (soc_info.family == RTL8390_FAMILY_ID) {
gpios->led_glb_ctrl = RTL839X_LED_GLB_CTRL;
gpios->led_sw_ctrl = RTL839X_LED_SW_CTRL;
gpios->led_sw_p_ctrl = rtl839x_led_sw_p_ctrl;
gpios->led_sw_p_en_ctrl = rtl839x_led_sw_p_en_ctrl;
gpios->ext_gpio_dir = rtl839x_ext_gpio_dir;
gpios->ext_gpio_data = rtl839x_ext_gpio_data;
gpios->irq = 31;
}
if (soc_info.family == RTL9300_FAMILY_ID) {
gpios->irq = 13;
}
gpios->gc.label = "rtl838x";
gpios->gc.parent = dev;
gpios->gc.owner = THIS_MODULE;
gpios->gc.can_sleep = true;
gpios->dev = dev;
gpios->gc.base = 0;
if (soc_info.family != RTL9300_FAMILY_ID) {
/* 0-31: internal
* 32-63, LED control register
* 64-95: PORT-LED 0
* 96-127: PORT-LED 1
* 128-159: PORT-LED 2
*/
gpios->gc.ngpio = 160;
gpios->gc.direction_input = rtl838x_direction_input;
gpios->gc.direction_output = rtl838x_direction_output;
gpios->gc.set = rtl838x_gpio_set;
gpios->gc.get = rtl838x_gpio_get;
gpios->gc.get_direction = rtl838x_get_direction;
} else {
gpios->gc.ngpio = 32;
gpios->gc.direction_input = rtl930x_direction_input;
gpios->gc.direction_output = rtl930x_direction_output;
gpios->gc.set = rtl930x_gpio_set;
gpios->gc.get = rtl930x_gpio_get;
gpios->gc.get_direction = rtl930x_get_direction;
}
if (of_property_read_bool(np, "take-port-leds")) {
pr_info("A1\n");
if (of_property_read_u32(np, "leds-per-port", &gpios->leds_per_port))
gpios->leds_per_port = 2;
if (of_property_read_u32(np, "led-mode", &gpios->led_mode))
gpios->led_mode = (0x1ea << 15) | 0x1ea;
if (of_property_read_u32(np, "num-leds", &gpios->num_leds))
gpios->num_leds = 32;
if (of_property_read_u32(np, "min-led", &gpios->min_led))
gpios->min_led = 0;
take_port_leds(gpios);
}
err = devm_gpiochip_add_data(dev, &gpios->gc, gpios);
return err;
}
static struct platform_driver rtl838x_gpio_driver = {
.driver = {
.name = "rtl838x-gpio",
.of_match_table = rtl838x_gpio_of_match,
},
.probe = rtl838x_gpio_probe,
};
module_platform_driver(rtl838x_gpio_driver);
MODULE_DESCRIPTION("Realtek RTL838X GPIO API support");
MODULE_LICENSE("GPL v2");

View File

@ -1,3 +1,3 @@
# SPDX-License-Identifier: GPL-2.0
obj-$(CONFIG_NET_DSA_RTL83XX) += common.o dsa.o \
rtl838x.o rtl839x.o rtl930x.o rtl931x.o debugfs.o qos.o
rtl838x.o rtl839x.o rtl930x.o rtl931x.o debugfs.o qos.o tc.o

View File

@ -40,7 +40,11 @@
#define RTL839X_MIR_RSPAN_TX_CTRL (0x69b0)
#define RTL839X_MIR_RSPAN_TX_TAG_RM_CTRL (0x2550)
#define RTL839X_MIR_RSPAN_TX_TAG_EN_CTRL (0x2554)
#define RTL839X_MIR_SAMPLE_RATE_CTRL (0x2558)
#define RTL839X_MIR_SAMPLE_RATE_CTRL (0x2558)
#define RTL838X_STAT_PRVTE_DROP_COUNTERS (0x6A00)
#define RTL839X_STAT_PRVTE_DROP_COUNTERS (0x3E00)
#define RTL930X_STAT_PRVTE_DROP_COUNTERS (0xB5B8)
int rtl83xx_port_get_stp_state(struct rtl838x_switch_priv *priv, int port);
void rtl83xx_port_stp_state_set(struct dsa_switch *ds, int port, u8 state);
@ -50,6 +54,58 @@ u32 rtl839x_get_egress_rate(struct rtl838x_switch_priv *priv, int port);
int rtl838x_set_egress_rate(struct rtl838x_switch_priv *priv, int port, u32 rate);
int rtl839x_set_egress_rate(struct rtl838x_switch_priv *priv, int port, u32 rate);
const char *rtl838x_drop_cntr[] = {
"ALE_TX_GOOD_PKTS", "MAC_RX_DROP", "ACL_FWD_DROP", "HW_ATTACK_PREVENTION_DROP",
"RMA_DROP", "VLAN_IGR_FLTR_DROP", "INNER_OUTER_CFI_EQUAL_1_DROP", "PORT_MOVE_DROP",
"NEW_SA_DROP", "MAC_LIMIT_SYS_DROP", "MAC_LIMIT_VLAN_DROP", "MAC_LIMIT_PORT_DROP",
"SWITCH_MAC_DROP", "ROUTING_EXCEPTION_DROP", "DA_LKMISS_DROP", "RSPAN_DROP",
"ACL_LKMISS_DROP", "ACL_DROP", "INBW_DROP", "IGR_METER_DROP",
"ACCEPT_FRAME_TYPE_DROP", "STP_IGR_DROP", "INVALID_SA_DROP", "SA_BLOCKING_DROP",
"DA_BLOCKING_DROP", "L2_INVALID_DPM_DROP", "MCST_INVALID_DPM_DROP", "RX_FLOW_CONTROL_DROP",
"STORM_SPPRS_DROP", "LALS_DROP", "VLAN_EGR_FILTER_DROP", "STP_EGR_DROP",
"SRC_PORT_FILTER_DROP", "PORT_ISOLATION_DROP", "ACL_FLTR_DROP", "MIRROR_FLTR_DROP",
"TX_MAX_DROP", "LINK_DOWN_DROP", "FLOW_CONTROL_DROP", "BRIDGE .1d discards"
};
const char *rtl839x_drop_cntr[] = {
"ALE_TX_GOOD_PKTS", "ERROR_PKTS", "EGR_ACL_DROP", "EGR_METER_DROP",
"OAM", "CFM" "VLAN_IGR_FLTR", "VLAN_ERR",
"INNER_OUTER_CFI_EQUAL_1", "VLAN_TAG_FORMAT", "SRC_PORT_SPENDING_TREE", "INBW",
"RMA", "HW_ATTACK_PREVENTION", "PROTO_STORM", "MCAST_SA",
"IGR_ACL_DROP", "IGR_METER_DROP", "DFLT_ACTION_FOR_MISS_ACL_AND_C2SC", "NEW_SA",
"PORT_MOVE", "SA_BLOCKING", "ROUTING_EXCEPTION", "SRC_PORT_SPENDING_TREE_NON_FWDING",
"MAC_LIMIT", "UNKNOW_STORM", "MISS_DROP", "CPU_MAC_DROP",
"DA_BLOCKING", "SRC_PORT_FILTER_BEFORE_EGR_ACL", "VLAN_EGR_FILTER", "SPANNING_TRE",
"PORT_ISOLATION", "OAM_EGRESS_DROP", "MIRROR_ISOLATION", "MAX_LEN_BEFORE_EGR_ACL",
"SRC_PORT_FILTER_BEFORE_MIRROR", "MAX_LEN_BEFORE_MIRROR", "SPECIAL_CONGEST_BEFORE_MIRROR",
"LINK_STATUS_BEFORE_MIRROR",
"WRED_BEFORE_MIRROR", "MAX_LEN_AFTER_MIRROR", "SPECIAL_CONGEST_AFTER_MIRROR",
"LINK_STATUS_AFTER_MIRROR",
"WRED_AFTER_MIRROR"
};
const char *rtl930x_drop_cntr[] = {
"OAM_PARSER", "UC_RPF", "DEI_CFI", "MAC_IP_SUBNET_BASED_VLAN", "VLAN_IGR_FILTER",
"L2_UC_MC", "IPV_IP6_MC_BRIDGE", "PTP", "USER_DEF_0_3", "RESERVED",
"RESERVED1", "RESERVED2", "BPDU_RMA", "LACP", "LLDP",
"EAPOL", "XX_RMA", "L3_IPUC_NON_IP", "IP4_IP6_HEADER_ERROR", "L3_BAD_IP",
"L3_DIP_DMAC_MISMATCH", "IP4_IP_OPTION", "IP_UC_MC_ROUTING_LOOK_UP_MISS", "L3_DST_NULL_INTF",
"L3_PBR_NULL_INTF",
"HOST_NULL_INTF", "ROUTE_NULL_INTF", "BRIDGING_ACTION", "ROUTING_ACTION", "IPMC_RPF",
"L2_NEXTHOP_AGE_OUT", "L3_UC_TTL_FAIL", "L3_MC_TTL_FAIL", "L3_UC_MTU_FAIL", "L3_MC_MTU_FAIL",
"L3_UC_ICMP_REDIR", "IP6_MLD_OTHER_ACT", "ND", "IP_MC_RESERVED", "IP6_HBH",
"INVALID_SA", "L2_HASH_FULL", "NEW_SA", "PORT_MOVE_FORBID", "STATIC_PORT_MOVING",
"DYNMIC_PORT_MOVING", "L3_CRC", "MAC_LIMIT", "ATTACK_PREVENT", "ACL_FWD_ACTION",
"OAMPDU", "OAM_MUX", "TRUNK_FILTER", "ACL_DROP", "IGR_BW",
"ACL_METER", "VLAN_ACCEPT_FRAME_TYPE", "MSTP_SRC_DROP_DISABLED_BLOCKING", "SA_BLOCK", "DA_BLOCK",
"STORM_CONTROL", "VLAN_EGR_FILTER", "MSTP_DESTINATION_DROP", "SRC_PORT_FILTER", "PORT_ISOLATION",
"TX_MAX_FRAME_SIZE", "EGR_LINK_STATUS", "MAC_TX_DISABLE", "MAC_PAUSE_FRAME", "MAC_RX_DROP",
"MIRROR_ISOLATE", "RX_FC", "EGR_QUEUE", "HSM_RUNOUT", "ROUTING_DISABLE", "INVALID_L2_NEXTHOP_ENTRY",
"L3_MC_SRC_FLT", "CPUTAG_FLT", "FWD_PMSK_NULL", "IPUC_ROUTING_LOOKUP_MISS", "MY_DEV_DROP",
"STACK_NONUC_BLOCKING_PMSK", "STACK_PORT_NOT_FOUND", "ACL_LOOPBACK_DROP", "IP6_ROUTING_EXT_HEADER"
};
static ssize_t rtl838x_common_read(char __user *buffer, size_t count,
loff_t *ppos, unsigned int value)
{
@ -134,6 +190,61 @@ static const struct file_operations stp_state_fops = {
.write = stp_state_write,
};
static ssize_t drop_counter_read(struct file *filp, char __user *buffer, size_t count,
loff_t *ppos)
{
struct rtl838x_switch_priv *priv = filp->private_data;
int i;
const char **d;
u32 v;
char *buf;
int n = 0, len, offset;
int num;
switch (priv->family_id) {
case RTL8380_FAMILY_ID:
d = rtl838x_drop_cntr;
offset = RTL838X_STAT_PRVTE_DROP_COUNTERS;
num = 40;
break;
case RTL8390_FAMILY_ID:
d = rtl839x_drop_cntr;
offset = RTL839X_STAT_PRVTE_DROP_COUNTERS;
num = 45;
break;
case RTL9300_FAMILY_ID:
d = rtl930x_drop_cntr;
offset = RTL930X_STAT_PRVTE_DROP_COUNTERS;
num = 85;
break;
}
buf = kmalloc(30 * num, GFP_KERNEL);
if (!buf)
return -ENOMEM;
for (i = 0; i < num; i++) {
v = sw_r32(offset + (i << 2)) & 0xffff;
n += sprintf(buf + n, "%s: %d\n", d[i], v);
}
if (count < strlen(buf)) {
kfree(buf);
return -ENOSPC;
}
len = simple_read_from_buffer(buffer, count, ppos, buf, strlen(buf));
kfree(buf);
return len;
}
static const struct file_operations drop_counter_fops = {
.owner = THIS_MODULE,
.open = simple_open,
.read = drop_counter_read,
};
static ssize_t age_out_read(struct file *filp, char __user *buffer, size_t count,
loff_t *ppos)
{
@ -470,7 +581,23 @@ void rtl838x_dbgfs_init(struct rtl838x_switch_priv *priv)
if (ret)
goto err;
debugfs_create_file("drop_counters", 0400, rtl838x_dir, priv, &drop_counter_fops);
return;
err:
rtl838x_dbgfs_cleanup(priv);
}
void rtl930x_dbgfs_init(struct rtl838x_switch_priv *priv)
{
struct dentry *dbg_dir;
pr_info("%s called\n", __func__);
dbg_dir = debugfs_lookup(RTL838X_DRIVER_NAME, NULL);
if (!dbg_dir)
dbg_dir = debugfs_create_dir(RTL838X_DRIVER_NAME, NULL);
priv->dbgfs_dir = dbg_dir;
debugfs_create_file("drop_counters", 0400, dbg_dir, priv, &drop_counter_fops);
}

View File

@ -184,10 +184,14 @@ static int rtl83xx_setup(struct dsa_switch *ds)
ds->configure_vlan_while_not_filtering = true;
priv->r->l2_learning_setup();
/* Enable MAC Polling PHY again */
rtl83xx_enable_phy_polling(priv);
pr_debug("Please wait until PHY is settled\n");
msleep(1000);
priv->r->pie_init(priv);
return 0;
}
@ -226,8 +230,12 @@ static int rtl930x_setup(struct dsa_switch *ds)
ds->configure_vlan_while_not_filtering = true;
priv->r->l2_learning_setup();
rtl83xx_enable_phy_polling(priv);
priv->r->pie_init(priv);
return 0;
}
@ -276,7 +284,7 @@ static void rtl83xx_phylink_validate(struct dsa_switch *ds, int port,
phylink_set(mask, 1000baseX_Full);
/* On the RTL839x family of SoCs, ports 48 to 51 are SFP ports */
if (port >=48 && port <= 51 && priv->family_id == RTL8390_FAMILY_ID)
if (port >= 48 && port <= 51 && priv->family_id == RTL8390_FAMILY_ID)
phylink_set(mask, 1000baseX_Full);
phylink_set(mask, 10baseT_Half);
@ -290,6 +298,67 @@ static void rtl83xx_phylink_validate(struct dsa_switch *ds, int port,
__ETHTOOL_LINK_MODE_MASK_NBITS);
}
static void rtl93xx_phylink_validate(struct dsa_switch *ds, int port,
unsigned long *supported,
struct phylink_link_state *state)
{
__ETHTOOL_DECLARE_LINK_MODE_MASK(mask) = { 0, };
pr_debug("In %s port %d, state is %d (%s)", __func__, port, state->interface,
phy_modes(state->interface));
if (!phy_interface_mode_is_rgmii(state->interface) &&
state->interface != PHY_INTERFACE_MODE_NA &&
state->interface != PHY_INTERFACE_MODE_1000BASEX &&
state->interface != PHY_INTERFACE_MODE_MII &&
state->interface != PHY_INTERFACE_MODE_REVMII &&
state->interface != PHY_INTERFACE_MODE_GMII &&
state->interface != PHY_INTERFACE_MODE_QSGMII &&
state->interface != PHY_INTERFACE_MODE_XGMII &&
state->interface != PHY_INTERFACE_MODE_HSGMII &&
state->interface != PHY_INTERFACE_MODE_10GKR &&
state->interface != PHY_INTERFACE_MODE_USXGMII &&
state->interface != PHY_INTERFACE_MODE_INTERNAL &&
state->interface != PHY_INTERFACE_MODE_SGMII) {
bitmap_zero(supported, __ETHTOOL_LINK_MODE_MASK_NBITS);
dev_err(ds->dev,
"Unsupported interface: %d for port %d\n",
state->interface, port);
return;
}
/* Allow all the expected bits */
phylink_set(mask, Autoneg);
phylink_set_port_modes(mask);
phylink_set(mask, Pause);
phylink_set(mask, Asym_Pause);
/* With the exclusion of MII and Reverse MII, we support Gigabit,
* including Half duplex
*/
if (state->interface != PHY_INTERFACE_MODE_MII &&
state->interface != PHY_INTERFACE_MODE_REVMII) {
phylink_set(mask, 1000baseT_Full);
phylink_set(mask, 1000baseT_Half);
}
/* On the RTL9300 family of SoCs, ports 26 to 27 may be SFP ports TODO: take out of .dts */
if (port >= 26 && port <= 27)
phylink_set(mask, 1000baseX_Full);
if (port >= 26 && port <= 27)
phylink_set(mask, 10000baseKR_Full);
phylink_set(mask, 10baseT_Half);
phylink_set(mask, 10baseT_Full);
phylink_set(mask, 100baseT_Half);
phylink_set(mask, 100baseT_Full);
bitmap_and(supported, supported, mask,
__ETHTOOL_LINK_MODE_MASK_NBITS);
bitmap_and(state->advertising, state->advertising, mask,
__ETHTOOL_LINK_MODE_MASK_NBITS);
}
static int rtl83xx_phylink_mac_link_state(struct dsa_switch *ds, int port,
struct phylink_link_state *state)
{
@ -300,15 +369,8 @@ static int rtl83xx_phylink_mac_link_state(struct dsa_switch *ds, int port,
if (port < 0 || port > priv->cpu_port)
return -EINVAL;
/*
* On the RTL9300 for at least the RTL8226B PHY, the MAC-side link
* state needs to be read twice in order to read a correct result.
* This would not be necessary for ports connected e.g. to RTL8218D
* PHYs.
*/
state->link = 0;
link = priv->r->get_port_reg_le(priv->r->mac_link_sts);
link = priv->r->get_port_reg_le(priv->r->mac_link_sts);
if (link & BIT_ULL(port))
state->link = 1;
pr_debug("%s: link state port %d: %llx\n", __func__, port, link & BIT_ULL(port));
@ -345,6 +407,70 @@ static int rtl83xx_phylink_mac_link_state(struct dsa_switch *ds, int port,
return 1;
}
static int rtl93xx_phylink_mac_link_state(struct dsa_switch *ds, int port,
struct phylink_link_state *state)
{
struct rtl838x_switch_priv *priv = ds->priv;
u64 speed;
u64 link;
if (port < 0 || port > priv->cpu_port)
return -EINVAL;
/*
* On the RTL9300 for at least the RTL8226B PHY, the MAC-side link
* state needs to be read twice in order to read a correct result.
* This would not be necessary for ports connected e.g. to RTL8218D
* PHYs.
*/
state->link = 0;
link = priv->r->get_port_reg_le(priv->r->mac_link_sts);
link = priv->r->get_port_reg_le(priv->r->mac_link_sts);
if (link & BIT_ULL(port))
state->link = 1;
pr_debug("%s: link state port %d: %llx, media %08x\n", __func__, port,
link & BIT_ULL(port), sw_r32(RTL930X_MAC_LINK_MEDIA_STS));
state->duplex = 0;
if (priv->r->get_port_reg_le(priv->r->mac_link_dup_sts) & BIT_ULL(port))
state->duplex = 1;
speed = priv->r->get_port_reg_le(priv->r->mac_link_spd_sts(port));
speed >>= (port % 8) << 2;
switch (speed & 0xf) {
case 0:
state->speed = SPEED_10;
break;
case 1:
state->speed = SPEED_100;
break;
case 2:
case 7:
state->speed = SPEED_1000;
break;
case 4:
state->speed = SPEED_10000;
break;
case 5:
case 8:
state->speed = SPEED_2500;
break;
case 6:
state->speed = SPEED_5000;
break;
default:
pr_err("%s: unknown speed: %d\n", __func__, (u32)speed & 0xf);
}
pr_debug("%s: speed is: %d %d\n", __func__, (u32)speed & 0xf, state->speed);
state->pause &= (MLO_PAUSE_RX | MLO_PAUSE_TX);
if (priv->r->get_port_reg_le(priv->r->mac_rx_pause_sts) & BIT_ULL(port))
state->pause |= MLO_PAUSE_RX;
if (priv->r->get_port_reg_le(priv->r->mac_tx_pause_sts) & BIT_ULL(port))
state->pause |= MLO_PAUSE_TX;
return 1;
}
static void rtl83xx_config_interface(int port, phy_interface_t interface)
{
u32 old, int_shift, sds_shift;
@ -392,10 +518,6 @@ static void rtl83xx_phylink_mac_config(struct dsa_switch *ds, int port,
pr_debug("%s port %d, mode %x\n", __func__, port, mode);
// BUG: Make this work on RTL93XX
if (priv->family_id >= RTL9300_FAMILY_ID)
return;
if (port == priv->cpu_port) {
/* Set Speed, duplex, flow control
* FORCE_EN | LINK_EN | NWAY_EN | DUP_SEL
@ -464,6 +586,81 @@ static void rtl83xx_phylink_mac_config(struct dsa_switch *ds, int port,
sw_w32(reg, priv->r->mac_force_mode_ctrl(port));
}
static void rtl93xx_phylink_mac_config(struct dsa_switch *ds, int port,
unsigned int mode,
const struct phylink_link_state *state)
{
struct rtl838x_switch_priv *priv = ds->priv;
int sds_num, sds_mode;
u32 reg;
pr_debug("%s port %d, mode %x, phy-mode: %s, speed %d, link %d\n", __func__,
port, mode, phy_modes(state->interface), state->speed, state->link);
// Nothing to be done for the CPU-port
if (port == priv->cpu_port)
return;
reg = sw_r32(priv->r->mac_force_mode_ctrl(port));
reg &= ~(0xf << 3);
// On the RTL930X, ports 24 to 27 are using an internal SerDes
if (port >=24 && port <= 27) {
sds_num = port - 18; // Port 24 mapped to SerDes 6, 25 to 7 ...
switch (state->interface) {
case PHY_INTERFACE_MODE_HSGMII:
sds_mode = 0x12;
break;
case PHY_INTERFACE_MODE_1000BASEX:
sds_mode = 0x1b; // 10G 1000X Auto
break;
case PHY_INTERFACE_MODE_XGMII:
sds_mode = 0x10;
break;
case PHY_INTERFACE_MODE_10GKR:
sds_mode = 0x1a;
// We need to use media sel for fibre media:
reg |= BIT(16);
break;
case PHY_INTERFACE_MODE_USXGMII:
sds_mode = 0x0d;
break;
default:
pr_err("%s: unknown serdes mode: %s\n",
__func__, phy_modes(state->interface));
return;
}
rtl9300_sds_rst(sds_num, sds_mode);
}
switch (state->speed) {
case SPEED_10000:
reg |= 4 << 3;
break;
case SPEED_5000:
reg |= 6 << 3;
break;
case SPEED_2500:
reg |= 5 << 3;
break;
case SPEED_1000:
reg |= 2 << 3;
break;
default:
reg |= 2 << 3;
break;
}
if (state->link)
reg |= FORCE_LINK_EN;
if (state->duplex == DUPLEX_FULL)
reg |= BIT(2);
reg |= 1; // Force Link up
sw_w32(reg, priv->r->mac_force_mode_ctrl(port));
}
static void rtl83xx_phylink_mac_link_down(struct dsa_switch *ds, int port,
unsigned int mode,
phy_interface_t interface)
@ -473,6 +670,18 @@ static void rtl83xx_phylink_mac_link_down(struct dsa_switch *ds, int port,
sw_w32_mask(0x3, 0, priv->r->mac_port_ctrl(port));
}
static void rtl93xx_phylink_mac_link_down(struct dsa_switch *ds, int port,
unsigned int mode,
phy_interface_t interface)
{
struct rtl838x_switch_priv *priv = ds->priv;
/* Stop TX/RX to port */
sw_w32_mask(0x3, 0, priv->r->mac_port_ctrl(port));
// No longer force link
sw_w32_mask(3, 0, priv->r->mac_force_mode_ctrl(port));
}
static void rtl83xx_phylink_mac_link_up(struct dsa_switch *ds, int port,
unsigned int mode,
phy_interface_t interface,
@ -483,6 +692,21 @@ static void rtl83xx_phylink_mac_link_up(struct dsa_switch *ds, int port,
struct rtl838x_switch_priv *priv = ds->priv;
/* Restart TX/RX to port */
sw_w32_mask(0, 0x3, priv->r->mac_port_ctrl(port));
// TODO: Set speed/duplex/pauses
}
static void rtl93xx_phylink_mac_link_up(struct dsa_switch *ds, int port,
unsigned int mode,
phy_interface_t interface,
struct phy_device *phydev,
int speed, int duplex,
bool tx_pause, bool rx_pause)
{
struct rtl838x_switch_priv *priv = ds->priv;
/* Restart TX/RX to port */
sw_w32_mask(0, 0x3, priv->r->mac_port_ctrl(port));
// TODO: Set speed/duplex/pauses
}
static void rtl83xx_get_strings(struct dsa_switch *ds,
@ -847,14 +1071,14 @@ static int rtl83xx_vlan_filtering(struct dsa_switch *ds, int port,
*/
if (port != priv->cpu_port)
sw_w32_mask(0b10 << ((port % 16) << 1), 0b01 << ((port % 16) << 1),
priv->r->vlan_port_igr_filter + ((port >> 5) << 2));
sw_w32_mask(0, BIT(port % 32), priv->r->vlan_port_egr_filter + ((port >> 4) << 2));
priv->r->vlan_port_igr_filter + ((port >> 4) << 2));
sw_w32_mask(0, BIT(port % 32), priv->r->vlan_port_egr_filter + ((port >> 5) << 2));
} else {
/* Disable ingress and egress filtering */
if (port != priv->cpu_port)
sw_w32_mask(0b11 << ((port % 16) << 1), 0,
priv->r->vlan_port_igr_filter + ((port >> 5) << 2));
sw_w32_mask(BIT(port % 32), 0, priv->r->vlan_port_egr_filter + ((port >> 4) << 2));
priv->r->vlan_port_igr_filter + ((port >> 4) << 2));
sw_w32_mask(BIT(port % 32), 0, priv->r->vlan_port_egr_filter + ((port >> 5) << 2));
}
/* Do we need to do something to the CPU-Port, too? */
@ -1179,7 +1403,10 @@ static int rtl83xx_port_fdb_dump(struct dsa_switch *ds, int port,
if (!e.valid)
continue;
if (e.port == port) {
if (e.port == port || e.port == RTL930X_PORT_IGNORE) {
u64 seed;
u32 key;
fid = ((i >> 2) & 0x3ff) | (e.rvid & ~0x3ff);
mac = ether_addr_to_u64(&e.mac[0]);
pkey = priv->r->l2_hash_key(priv, priv->r->l2_hash_seed(mac, fid));
@ -1187,13 +1414,14 @@ static int rtl83xx_port_fdb_dump(struct dsa_switch *ds, int port,
pr_info("-> index %d, key %x, bucket %d, dmac %016llx, fid: %x rvid: %x\n",
i, i >> 2, i & 0x3, mac, fid, e.rvid);
dump_l2_entry(&e);
u64 seed = priv->r->l2_hash_seed(mac, e.rvid);
u32 key = priv->r->l2_hash_key(priv, seed);
seed = priv->r->l2_hash_seed(mac, e.rvid);
key = priv->r->l2_hash_key(priv, seed);
pr_info("seed: %016llx, key based on rvid: %08x\n", seed, key);
cb(e.mac, e.vid, e.is_static, data);
}
if (e.type == L2_MULTICAST) {
u64 portmask = priv->r->read_mcast_pmask(e.mc_portmask_index);
if (portmask & BIT_ULL(port)) {
dump_l2_entry(&e);
pr_info(" PM: %016llx\n", portmask);
@ -1554,11 +1782,11 @@ const struct dsa_switch_ops rtl930x_switch_ops = {
.phy_read = dsa_phy_read,
.phy_write = dsa_phy_write,
.phylink_validate = rtl83xx_phylink_validate,
.phylink_mac_link_state = rtl83xx_phylink_mac_link_state,
.phylink_mac_config = rtl83xx_phylink_mac_config,
.phylink_mac_link_down = rtl83xx_phylink_mac_link_down,
.phylink_mac_link_up = rtl83xx_phylink_mac_link_up,
.phylink_validate = rtl93xx_phylink_validate,
.phylink_mac_link_state = rtl93xx_phylink_mac_link_state,
.phylink_mac_config = rtl93xx_phylink_mac_config,
.phylink_mac_link_down = rtl93xx_phylink_mac_link_down,
.phylink_mac_link_up = rtl93xx_phylink_mac_link_up,
.get_strings = rtl83xx_get_strings,
.get_ethtool_stats = rtl83xx_get_ethtool_stats,

View File

@ -66,29 +66,28 @@
#define RTL838X_VLAN_PROFILE(idx) (0x3A88 + ((idx) << 2))
#define RTL838X_VLAN_PORT_EGR_FLTR (0x3A84)
#define RTL838X_VLAN_PORT_PB_VLAN (0x3C00)
#define RTL838X_VLAN_PORT_IGR_FLTR(port) (0x3A7C + (((port >> 4) << 2)))
#define RTL838X_VLAN_PORT_IGR_FLTR_0 (0x3A7C)
#define RTL838X_VLAN_PORT_IGR_FLTR_1 (0x3A7C + 4)
#define RTL838X_VLAN_PORT_IGR_FLTR (0x3A7C)
#define RTL838X_VLAN_PORT_TAG_STS_CTRL (0xA530)
#define RTL839X_VLAN_PROFILE(idx) (0x25C0 + (((idx) << 3)))
#define RTL839X_VLAN_CTRL (0x26D4)
#define RTL839X_VLAN_PORT_PB_VLAN (0x26D8)
#define RTL839X_VLAN_PORT_IGR_FLTR(port) (0x27B4 + (((port >> 4) << 2)))
#define RTL839X_VLAN_PORT_EGR_FLTR(port) (0x27C4 + (((port >> 5) << 2)))
#define RTL839X_VLAN_PORT_IGR_FLTR (0x27B4)
#define RTL839X_VLAN_PORT_EGR_FLTR (0x27C4)
#define RTL839X_VLAN_PORT_TAG_STS_CTRL (0x6828)
#define RTL839X_VLAN_PORT_TAG_STS_CTRL (0x6828)
#define RTL930X_VLAN_PROFILE_SET(idx) (0x9c60 + (((idx) * 20)))
#define RTL930X_VLAN_CTRL (0x82D4)
#define RTL930X_VLAN_PORT_PB_VLAN (0x82D8)
#define RTL930X_VLAN_PORT_IGR_FLTR(port) (0x83C0 + (((port >> 4) << 2)))
#define RTL930X_VLAN_PORT_IGR_FLTR (0x83C0)
#define RTL930X_VLAN_PORT_EGR_FLTR (0x83C8)
#define RTL930X_VLAN_PORT_TAG_STS_CTRL (0xCE24)
#define RTL931X_VLAN_PROFILE_SET(idx) (0x9800 + (((idx) * 28)))
#define RTL931X_VLAN_CTRL (0x94E4)
#define RTL931X_VLAN_PORT_IGR_FLTR(port) (0x96B4 + (((port >> 4) << 2)))
#define RTL931X_VLAN_PORT_EGR_FLTR(port) (0x96C4 + (((port >> 5) << 2)))
#define RTL931X_VLAN_PORT_IGR_FLTR (0x96B4)
#define RTL931X_VLAN_PORT_EGR_FLTR (0x96C4)
#define RTL931X_VLAN_PORT_TAG_CTRL (0x4860)
/* Table access registers */
@ -145,6 +144,7 @@
#define RTL839X_MAC_RX_PAUSE_STS (0x03c0)
#define RTL930X_MAC_RX_PAUSE_STS (0xCB30)
#define RTL931X_MAC_RX_PAUSE_STS (0x0F00)
#define RTL930X_MAC_LINK_MEDIA_STS (0xCB14)
/* MAC link state bits */
#define FORCE_EN (1 << 0)
@ -197,6 +197,15 @@
#define RTL930X_L2_TBL_FLUSH_CTRL (0x9404)
#define RTL931X_L2_TBL_FLUSH_CTRL (0xCD9C)
#define RTL838X_L2_LRN_CONSTRT (0x329C)
#define RTL839X_L2_LRN_CONSTRT (0x3910)
#define RTL930X_L2_LRN_CONSTRT_CTRL (0x909c)
#define RTL838X_L2_FLD_PMSK (0x3288)
#define RTL839X_L2_FLD_PMSK (0x38EC)
#define RTL930X_L2_BC_FLD_PMSK (0x9068)
#define RTL930X_L2_UNKN_UC_FLD_PMSK (0x9064)
#define RTL838X_L2_LRN_CONSTRT_EN (0x3368)
#define RTL838X_L2_PORT_NEW_SALRN(p) (0x328c + (((p >> 4) << 2)))
#define RTL839X_L2_PORT_NEW_SALRN(p) (0x38F0 + (((p >> 4) << 2)))
#define RTL930X_L2_PORT_SALRN(p) (0x8FEC + (((p >> 4) << 2)))
@ -302,6 +311,8 @@
/* 802.1X */
#define RTL838X_SPCL_TRAP_EAPOL_CTRL (0x6988)
#define RTL839X_SPCL_TRAP_EAPOL_CTRL (0x105C)
#define RTL838X_SPCL_TRAP_ARP_CTRL (0x698C)
#define RTL839X_SPCL_TRAP_ARP_CTRL (0x1060)
/* QoS */
#define RTL838X_QM_INTPRI2QID_CTRL (0x5F00)
@ -338,12 +349,82 @@
/* Debug features */
#define RTL930X_STAT_PRVTE_DROP_COUNTER0 (0xB5B8)
/* Packet Inspection Engine */
#define RTL838X_METER_GLB_CTRL (0x4B08)
#define RTL839X_METER_GLB_CTRL (0x1300)
#define RTL930X_METER_GLB_CTRL (0xa0a0)
#define RTL839X_ACL_CTRL (0x1288)
#define RTL838X_ACL_BLK_LOOKUP_CTRL (0x6100)
#define RTL839X_ACL_BLK_LOOKUP_CTRL (0x1280)
#define RTL930X_PIE_BLK_LOOKUP_CTRL (0xa5a0)
#define RTL838X_ACL_BLK_PWR_CTRL (0x6104)
#define RTL839X_PS_ACL_PWR_CTRL (0x049c)
#define RTL838X_ACL_BLK_TMPLTE_CTRL(block) (0x6108 + ((block) << 2))
#define RTL839X_ACL_BLK_TMPLTE_CTRL(block) (0x128c + ((block) << 2))
#define RTL930X_PIE_BLK_TMPLTE_CTRL(block) (0xa624 + ((block) << 2))
#define RTL838X_ACL_BLK_GROUP_CTRL (0x615C)
#define RTL839X_ACL_BLK_GROUP_CTRL (0x12ec)
#define RTL838X_ACL_CLR_CTRL (0x6168)
#define RTL839X_ACL_CLR_CTRL (0x12fc)
#define RTL930X_PIE_CLR_CTRL (0xa66c)
#define RTL838X_DMY_REG27 (0x3378)
#define RTL838X_ACL_PORT_LOOKUP_CTRL(p) (0x616C + (((p) << 2)))
#define RTL930X_ACL_PORT_LOOKUP_CTRL(p) (0xA784 + (((p) << 2)))
#define RTL930X_PIE_BLK_PHASE_CTRL (0xA5A4)
// PIE actions
#define PIE_ACT_COPY_TO_PORT 2
#define PIE_ACT_REDIRECT_TO_PORT 4
#define PIE_ACT_ROUTE_UC 6
#define PIE_ACT_VID_ASSIGN 0
// L3 actions
#define L3_FORWARD 0
#define L3_DROP 1
#define L3_TRAP2CPU 2
#define L3_COPY2CPU 3
#define L3_TRAP2MASTERCPU 4
#define L3_COPY2MASTERCPU 5
#define L3_HARDDROP 6
// Route actions
#define ROUTE_ACT_FORWARD 0
#define ROUTE_ACT_TRAP2CPU 1
#define ROUTE_ACT_COPY2CPU 2
#define ROUTE_ACT_DROP 3
/* L3 Routing */
#define RTL839X_ROUTING_SA_CTRL 0x6afc
#define RTL930X_L3_HOST_TBL_CTRL (0xAB48)
#define RTL930X_L3_IPUC_ROUTE_CTRL (0xAB4C)
#define RTL930X_L3_IP6UC_ROUTE_CTRL (0xAB50)
#define RTL930X_L3_IPMC_ROUTE_CTRL (0xAB54)
#define RTL930X_L3_IP6MC_ROUTE_CTRL (0xAB58)
#define RTL930X_L3_IP_MTU_CTRL(i) (0xAB5C + ((i >> 1) << 2))
#define RTL930X_L3_IP6_MTU_CTRL(i) (0xAB6C + ((i >> 1) << 2))
#define RTL930X_L3_HW_LU_KEY_CTRL (0xAC9C)
#define RTL930X_L3_HW_LU_KEY_IP_CTRL (0xACA0)
#define RTL930X_L3_HW_LU_CTRL (0xACC0)
#define RTL930X_L3_IP_ROUTE_CTRL 0xab44
#define MAX_VLANS 4096
#define MAX_LAGS 16
#define MAX_PRIOS 8
#define RTL930X_PORT_IGNORE 0x3f
#define MAX_MC_GROUPS 512
#define UNKNOWN_MC_PMASK (MAX_MC_GROUPS - 1)
#define PIE_BLOCK_SIZE 128
#define MAX_PIE_ENTRIES (18 * PIE_BLOCK_SIZE)
#define N_FIXED_FIELDS 12
#define MAX_COUNTERS 2048
#define MAX_ROUTES 512
#define MAX_HOST_ROUTES 1536
#define MAX_INTF_MTUS 8
#define DEFAULT_MTU 1536
#define MAX_INTERFACES 100
#define MAX_ROUTER_MACS 64
#define L3_EGRESS_DMACS 2048
#define MAX_SMACS 64
enum phy_type {
PHY_NONE = 0,
@ -409,21 +490,251 @@ struct rtl838x_l2_entry {
bool nh_vlan_target; // Only RTL83xx: VLAN used for next hop
};
struct rtl838x_nexthop {
u16 id; // ID in HW Nexthop table
u32 ip; // IP Addres of nexthop
enum fwd_rule_action {
FWD_RULE_ACTION_NONE = 0,
FWD_RULE_ACTION_FWD = 1,
};
enum pie_phase {
PHASE_VACL = 0,
PHASE_IACL = 1,
};
/* Intermediate representation of a Packet Inspection Engine Rule
* as suggested by the Kernel's tc flower offload subsystem
* Field meaning is universal across SoC families, but data content is specific
* to SoC family (e.g. because of different port ranges) */
struct pie_rule {
int id;
enum pie_phase phase; // Phase in which this template is applied
int packet_cntr; // ID of a packet counter assigned to this rule
int octet_cntr; // ID of a byte counter assigned to this rule
u32 last_packet_cnt;
u64 last_octet_cnt;
// The following are requirements for the pie template
bool is_egress;
bool is_ipv6; // This is a rule with IPv6 fields
// Fixed fields that are always matched against on RTL8380
u8 spmmask_fix;
u8 spn; // Source port number
bool stacking_port; // Source port is stacking port
bool mgnt_vlan; // Packet arrived on management VLAN
bool dmac_hit_sw; // The packet's destination MAC matches one of the device's
bool content_too_deep; // The content of the packet cannot be parsed: too many layers
bool not_first_frag; // Not the first IP fragment
u8 frame_type_l4; // 0: UDP, 1: TCP, 2: ICMP/ICMPv6, 3: IGMP
u8 frame_type; // 0: ARP, 1: L2 only, 2: IPv4, 3: IPv6
bool otag_fmt; // 0: outer tag packet, 1: outer priority tag or untagged
bool itag_fmt; // 0: inner tag packet, 1: inner priority tag or untagged
bool otag_exist; // packet with outer tag
bool itag_exist; // packet with inner tag
bool frame_type_l2; // 0: Ethernet, 1: LLC_SNAP, 2: LLC_Other, 3: Reserved
bool igr_normal_port; // Ingress port is not cpu or stacking port
u8 tid; // The template ID defining the what the templated fields mean
// Masks for the fields that are always matched against on RTL8380
u8 spmmask_fix_m;
u8 spn_m;
bool stacking_port_m;
bool mgnt_vlan_m;
bool dmac_hit_sw_m;
bool content_too_deep_m;
bool not_first_frag_m;
u8 frame_type_l4_m;
u8 frame_type_m;
bool otag_fmt_m;
bool itag_fmt_m;
bool otag_exist_m;
bool itag_exist_m;
bool frame_type_l2_m;
bool igr_normal_port_m;
u8 tid_m;
// Logical operations between rules, special rules for rule numbers apply
bool valid;
bool cond_not; // Matches when conditions not match
bool cond_and1; // And this rule 2n with the next rule 2n+1 in same block
bool cond_and2; // And this rule m in block 2n with rule m in block 2n+1
bool ivalid;
// Actions to be performed
bool drop; // Drop the packet
bool fwd_sel; // Forward packet: to port, portmask, dest route, next rule, drop
bool ovid_sel; // So something to outer vlan-id: shift, re-assign
bool ivid_sel; // Do something to inner vlan-id: shift, re-assign
bool flt_sel; // Filter the packet when sending to certain ports
bool log_sel; // Log the packet in one of the LOG-table counters
bool rmk_sel; // Re-mark the packet, i.e. change the priority-tag
bool meter_sel; // Meter the packet, i.e. limit rate of this type of packet
bool tagst_sel; // Change the ergress tag
bool mir_sel; // Mirror the packet to a Link Aggregation Group
bool nopri_sel; // Change the normal priority
bool cpupri_sel; // Change the CPU priority
bool otpid_sel; // Change Outer Tag Protocol Identifier (802.1q)
bool itpid_sel; // Change Inner Tag Protocol Identifier (802.1q)
bool shaper_sel; // Apply traffic shaper
bool mpls_sel; // MPLS actions
bool bypass_sel; // Bypass actions
bool fwd_sa_lrn; // Learn the source address when forwarding
bool fwd_mod_to_cpu; // Forward the modified VLAN tag format to CPU-port
// Fields used in predefined templates 0-2 on RTL8380 / 90 / 9300
u64 spm; // Source Port Matrix
u16 otag; // Outer VLAN-ID
u8 smac[ETH_ALEN]; // Source MAC address
u8 dmac[ETH_ALEN]; // Destination MAC address
u16 ethertype; // Ethernet frame type field in ethernet header
u16 itag; // Inner VLAN-ID
u16 field_range_check;
u32 sip; // Source IP
struct in6_addr sip6; // IPv6 Source IP
u32 dip; // Destination IP
struct in6_addr dip6; // IPv6 Destination IP
u16 tos_proto; // IPv4: TOS + Protocol fields, IPv6: Traffic class + next header
u16 sport; // TCP/UDP source port
u16 dport; // TCP/UDP destination port
u16 icmp_igmp;
u16 tcp_info;
u16 dsap_ssap; // Destination / Source Service Access Point bytes (802.3)
u64 spm_m;
u16 otag_m;
u8 smac_m[ETH_ALEN];
u8 dmac_m[ETH_ALEN];
u8 ethertype_m;
u16 itag_m;
u16 field_range_check_m;
u32 sip_m;
struct in6_addr sip6_m; // IPv6 Source IP mask
u32 dip_m;
struct in6_addr dip6_m; // IPv6 Destination IP mask
u16 tos_proto_m;
u16 sport_m;
u16 dport_m;
u16 icmp_igmp_m;
u16 tcp_info_m;
u16 dsap_ssap_m;
// Data associated with actions
u8 fwd_act; // Type of forwarding action
// 0: permit, 1: drop, 2: copy to port id, 4: copy to portmask
// 4: redirect to portid, 5: redirect to portmask
// 6: route, 7: vlan leaky (only 8380)
u16 fwd_data; // Additional data for forwarding action, e.g. destination port
u8 ovid_act;
u16 ovid_data; // Outer VLAN ID
u8 ivid_act;
u16 ivid_data; // Inner VLAN ID
u16 flt_data; // Filtering data
u16 log_data; // ID of packet or octet counter in LOG table, on RTL93xx
// unnecessary since PIE-Rule-ID == LOG-counter-ID
bool log_octets;
u8 mpls_act; // MPLS action type
u16 mpls_lib_idx; // MPLS action data
u16 rmk_data; // Data for remarking
u16 meter_data; // ID of meter for bandwidth control
u16 tagst_data;
u16 mir_data;
u16 nopri_data;
u16 cpupri_data;
u16 otpid_data;
u16 itpid_data;
u16 shaper_data;
// Bypass actions, ignored on RTL8380
bool bypass_all; // Not clear
bool bypass_igr_stp; // Bypass Ingress STP state
bool bypass_ibc_sc; // Bypass Ingress Bandwidth Control and Storm Control
};
struct rtl838x_l3_intf {
u16 vid;
u8 smac_idx;
u8 ip4_mtu_id;
u8 ip6_mtu_id;
u16 ip4_mtu;
u16 ip6_mtu;
u8 ttl_scope;
u8 hl_scope;
u8 ip4_icmp_redirect;
u8 ip6_icmp_redirect;
u8 ip4_pbr_icmp_redirect;
u8 ip6_pbr_icmp_redirect;
};
/*
* An entry in the RTL93XX SoC's ROUTER_MAC tables setting up a termination point
* for the L3 routing system. Packets arriving and matching an entry in this table
* will be considered for routing.
* Mask fields state whether the corresponding data fields matter for matching
*/
struct rtl93xx_rt_mac {
bool valid; // Valid or not
bool p_type; // Individual (0) or trunk (1) port
bool p_mask; // Whether the port type is used
u8 p_id;
u8 p_id_mask; // Mask for the port
u8 action; // Routing action performed: 0: FORWARD, 1: DROP, 2: TRAP2CPU
// 3: COPY2CPU, 4: TRAP2MASTERCPU, 5: COPY2MASTERCPU, 6: HARDDROP
u16 vid;
u16 vid_mask;
u64 mac; // MAC address used as source MAC in the routed packet
u64 mac_mask;
};
struct rtl83xx_nexthop {
u16 id; // ID: L3_NEXT_HOP table-index or route-index set in L2_NEXT_HOP
u32 dev_id;
u16 port;
u16 vid;
u16 fid;
u64 mac;
u16 vid; // VLAN-ID for L2 table entry (saved from L2-UC entry)
u16 rvid; // Relay VID/FID for the L2 table entry
u64 mac; // The MAC address of the entry in the L2_NEXT_HOP table
u16 mac_id;
u16 l2_id; // Index of this next hop forwarding entry in L2 FIB table
u16 if_id;
u64 gw; // The gateway MAC address packets are forwarded to
int if_id; // Interface (into L3_EGR_INTF_IDX)
};
struct rtl838x_switch_priv;
struct rtl83xx_flow {
unsigned long cookie;
struct rhash_head node;
struct rcu_head rcu_head;
struct rtl838x_switch_priv *priv;
struct pie_rule rule;
u32 flags;
};
struct rtl93xx_route_attr {
bool valid;
bool hit;
bool ttl_dec;
bool ttl_check;
bool dst_null;
bool qos_as;
u8 qos_prio;
u8 type;
u8 action;
};
struct rtl83xx_route {
u32 gw_ip; // IP of the route's gateway
u32 dst_ip; // IP of the destination net
struct in6_addr dst_ip6;
int prefix_len; // Network prefix len of the destination net
bool is_host_route;
int id; // ID number of this route
struct rhlist_head linkage;
u16 switch_mac_id; // Index into switch's own MACs, RTL839X only
struct rtl83xx_nexthop nh;
struct pie_rule pr;
struct rtl93xx_route_attr attr;
};
struct rtl838x_reg {
void (*mask_port_reg_be)(u64 clear, u64 set, int reg);
void (*set_port_reg_be)(u64 set, int reg);
@ -491,6 +802,27 @@ struct rtl838x_reg {
u64 (*read_mcast_pmask)(int idx);
void (*write_mcast_pmask)(int idx, u64 portmask);
void (*vlan_fwd_on_inner)(int port, bool is_set);
void (*pie_init)(struct rtl838x_switch_priv *priv);
int (*pie_rule_read)(struct rtl838x_switch_priv *priv, int idx, struct pie_rule *pr);
int (*pie_rule_write)(struct rtl838x_switch_priv *priv, int idx, struct pie_rule *pr);
int (*pie_rule_add)(struct rtl838x_switch_priv *priv, struct pie_rule *rule);
void (*pie_rule_rm)(struct rtl838x_switch_priv *priv, struct pie_rule *rule);
void (*l2_learning_setup)(void);
u32 (*packet_cntr_read)(int counter);
void (*packet_cntr_clear)(int counter);
void (*route_read)(int idx, struct rtl83xx_route *rt);
void (*route_write)(int idx, struct rtl83xx_route *rt);
void (*host_route_write)(int idx, struct rtl83xx_route *rt);
int (*l3_setup)(struct rtl838x_switch_priv *priv);
void (*set_l3_nexthop)(int idx, u16 dmac_id, u16 interface);
void (*get_l3_nexthop)(int idx, u16 *dmac_id, u16 *interface);
u64 (*get_l3_egress_mac)(u32 idx);
void (*set_l3_egress_mac)(u32 idx, u64 mac);
int (*find_l3_slot)(struct rtl83xx_route *rt, bool must_exist);
int (*route_lookup_hw)(struct rtl83xx_route *rt);
void (*get_l3_router_mac)(u32 idx, struct rtl93xx_rt_mac *m);
void (*set_l3_router_mac)(u32 idx, struct rtl93xx_rt_mac *m);
void (*set_l3_egress_intf)(int idx, struct rtl838x_l3_intf *intf);
};
struct rtl838x_switch_priv {
@ -501,7 +833,8 @@ struct rtl838x_switch_priv {
u16 family_id;
char version;
struct rtl838x_port ports[57];
struct mutex reg_mutex;
struct mutex reg_mutex; // Mutex for individual register manipulations
struct mutex pie_mutex; // Mutex for Packet Inspection Engine
int link_state_irq;
int mirror_group_ports[4];
struct mii_bus *mii_bus;
@ -509,6 +842,7 @@ struct rtl838x_switch_priv {
u8 cpu_port;
u8 port_mask;
u8 port_width;
u8 port_ignore;
u64 irq_mask;
u32 fib_entries;
int l2_bucket_size;
@ -516,11 +850,26 @@ struct rtl838x_switch_priv {
int n_lags;
u64 lags_port_members[MAX_LAGS];
struct net_device *lag_devs[MAX_LAGS];
struct notifier_block nb;
struct notifier_block nb; // TODO: change to different name
struct notifier_block ne_nb;
struct notifier_block fib_nb;
bool eee_enabled;
unsigned long int mc_group_bm[MAX_MC_GROUPS >> 5];
int n_pie_blocks;
struct rhashtable tc_ht;
unsigned long int pie_use_bm[MAX_PIE_ENTRIES >> 5];
int n_counters;
unsigned long int octet_cntr_use_bm[MAX_COUNTERS >> 5];
unsigned long int packet_cntr_use_bm[MAX_COUNTERS >> 4];
struct rhltable routes;
unsigned long int route_use_bm[MAX_ROUTES >> 5];
unsigned long int host_route_use_bm[MAX_HOST_ROUTES >> 5];
struct rtl838x_l3_intf *interfaces[MAX_INTERFACES];
u16 intf_mtus[MAX_INTF_MTUS];
int intf_mtu_count[MAX_INTF_MTUS];
};
void rtl838x_dbgfs_init(struct rtl838x_switch_priv *priv);
void rtl930x_dbgfs_init(struct rtl838x_switch_priv *priv);
#endif /* _RTL838X_H */

View File

@ -74,6 +74,11 @@ inline u32 rtl_table_data_r(struct table_reg *r, int i);
inline void rtl_table_data_w(struct table_reg *r, u32 v, int i);
void __init rtl83xx_setup_qos(struct rtl838x_switch_priv *priv);
int rtl83xx_packet_cntr_alloc(struct rtl838x_switch_priv *priv);
int rtl83xx_port_is_under(const struct net_device * dev, struct rtl838x_switch_priv *priv);
int read_phy(u32 port, u32 page, u32 reg, u32 *val);
int write_phy(u32 port, u32 page, u32 reg, u32 val);

View File

@ -384,8 +384,8 @@ const struct rtl838x_reg rtl931x_reg = {
.mac_tx_pause_sts = RTL931X_MAC_TX_PAUSE_STS,
.read_l2_entry_using_hash = rtl931x_read_l2_entry_using_hash,
.read_cam = rtl931x_read_cam,
.vlan_port_egr_filter = RTL931X_VLAN_PORT_EGR_FLTR(0),
.vlan_port_igr_filter = RTL931X_VLAN_PORT_IGR_FLTR(0),
.vlan_port_egr_filter = RTL931X_VLAN_PORT_EGR_FLTR,
.vlan_port_igr_filter = RTL931X_VLAN_PORT_IGR_FLTR,
// .vlan_port_pb = does not exist
.vlan_port_tag_sts_ctrl = RTL931X_VLAN_PORT_TAG_CTRL,
.trk_mbr_ctr = rtl931x_trk_mbr_ctr,

View File

@ -0,0 +1,409 @@
// SPDX-License-Identifier: GPL-2.0-only
#include <net/dsa.h>
#include <linux/delay.h>
#include <linux/netdevice.h>
#include <net/flow_offload.h>
#include <linux/rhashtable.h>
#include <asm/mach-rtl838x/mach-rtl83xx.h>
#include "rtl83xx.h"
#include "rtl838x.h"
/*
* Parse the flow rule for the matching conditions
*/
static int rtl83xx_parse_flow_rule(struct rtl838x_switch_priv *priv,
struct flow_rule *rule, struct rtl83xx_flow *flow)
{
struct flow_dissector *dissector = rule->match.dissector;
pr_debug("In %s\n", __func__);
/* KEY_CONTROL and KEY_BASIC are needed for forming a meaningful key */
if ((dissector->used_keys & BIT(FLOW_DISSECTOR_KEY_CONTROL)) == 0 ||
(dissector->used_keys & BIT(FLOW_DISSECTOR_KEY_BASIC)) == 0) {
pr_err("Cannot form TC key: used_keys = 0x%x\n", dissector->used_keys);
return -EOPNOTSUPP;
}
if (flow_rule_match_key(rule, FLOW_DISSECTOR_KEY_BASIC)) {
struct flow_match_basic match;
pr_debug("%s: BASIC\n", __func__);
flow_rule_match_basic(rule, &match);
if (match.key->n_proto == htons(ETH_P_ARP))
flow->rule.frame_type = 0;
if (match.key->n_proto == htons(ETH_P_IP))
flow->rule.frame_type = 2;
if (match.key->n_proto == htons(ETH_P_IPV6))
flow->rule.frame_type = 3;
if ((match.key->n_proto == htons(ETH_P_ARP)) || flow->rule.frame_type)
flow->rule.frame_type_m = 3;
if (flow->rule.frame_type >= 2) {
if (match.key->ip_proto == IPPROTO_UDP)
flow->rule.frame_type_l4 = 0;
if (match.key->ip_proto == IPPROTO_TCP)
flow->rule.frame_type_l4 = 1;
if (match.key->ip_proto == IPPROTO_ICMP
|| match.key->ip_proto ==IPPROTO_ICMPV6)
flow->rule.frame_type_l4 = 2;
if (match.key->ip_proto == IPPROTO_TCP)
flow->rule.frame_type_l4 = 3;
if ((match.key->ip_proto == IPPROTO_UDP) || flow->rule.frame_type_l4)
flow->rule.frame_type_l4_m = 7;
}
}
if (flow_rule_match_key(rule, FLOW_DISSECTOR_KEY_ETH_ADDRS)) {
struct flow_match_eth_addrs match;
pr_debug("%s: ETH_ADDR\n", __func__);
flow_rule_match_eth_addrs(rule, &match);
ether_addr_copy(flow->rule.dmac, match.key->dst);
ether_addr_copy(flow->rule.dmac_m, match.mask->dst);
ether_addr_copy(flow->rule.smac, match.key->src);
ether_addr_copy(flow->rule.smac_m, match.mask->src);
}
if (flow_rule_match_key(rule, FLOW_DISSECTOR_KEY_VLAN)) {
struct flow_match_vlan match;
pr_debug("%s: VLAN\n", __func__);
flow_rule_match_vlan(rule, &match);
flow->rule.itag = match.key->vlan_id;
flow->rule.itag_m = match.mask->vlan_id;
// TODO: What about match.key->vlan_priority ?
}
if (flow_rule_match_key(rule, FLOW_DISSECTOR_KEY_IPV4_ADDRS)) {
struct flow_match_ipv4_addrs match;
pr_debug("%s: IPV4\n", __func__);
flow_rule_match_ipv4_addrs(rule, &match);
flow->rule.is_ipv6 = false;
flow->rule.dip = match.key->dst;
flow->rule.dip_m = match.mask->dst;
flow->rule.sip = match.key->src;
flow->rule.sip_m = match.mask->src;
} else if (flow_rule_match_key(rule, FLOW_DISSECTOR_KEY_IPV6_ADDRS)) {
struct flow_match_ipv6_addrs match;
pr_debug("%s: IPV6\n", __func__);
flow->rule.is_ipv6 = true;
flow_rule_match_ipv6_addrs(rule, &match);
flow->rule.dip6 = match.key->dst;
flow->rule.dip6_m = match.mask->dst;
flow->rule.sip6 = match.key->src;
flow->rule.sip6_m = match.mask->src;
}
if (flow_rule_match_key(rule, FLOW_DISSECTOR_KEY_PORTS)) {
struct flow_match_ports match;
pr_debug("%s: PORTS\n", __func__);
flow_rule_match_ports(rule, &match);
flow->rule.dport = match.key->dst;
flow->rule.dport_m = match.mask->dst;
flow->rule.sport = match.key->src;
flow->rule.sport_m = match.mask->src;
}
// TODO: ICMP
return 0;
}
static void rtl83xx_flow_bypass_all(struct rtl83xx_flow *flow)
{
flow->rule.bypass_sel = true;
flow->rule.bypass_all = true;
flow->rule.bypass_igr_stp = true;
flow->rule.bypass_ibc_sc = true;
}
static int rtl83xx_parse_fwd(struct rtl838x_switch_priv *priv,
const struct flow_action_entry *act, struct rtl83xx_flow *flow)
{
struct net_device *dev = act->dev;
int port;
port = rtl83xx_port_is_under(dev, priv);
if (port < 0) {
netdev_info(dev, "%s: not a DSA device.\n", __func__);
return -EINVAL;
}
flow->rule.fwd_sel = true;
flow->rule.fwd_data = port;
pr_debug("Using port index: %d\n", port);
rtl83xx_flow_bypass_all(flow);
return 0;
}
static int rtl83xx_add_flow(struct rtl838x_switch_priv *priv, struct flow_cls_offload *f,
struct rtl83xx_flow *flow)
{
struct flow_rule *rule = flow_cls_offload_flow_rule(f);
const struct flow_action_entry *act;
int i, err;
pr_debug("%s\n", __func__);
rtl83xx_parse_flow_rule(priv, rule, flow);
flow_action_for_each(i, act, &rule->action) {
switch (act->id) {
case FLOW_ACTION_DROP:
pr_debug("%s: DROP\n", __func__);
flow->rule.drop = true;
rtl83xx_flow_bypass_all(flow);
return 0;
case FLOW_ACTION_TRAP:
pr_debug("%s: TRAP\n", __func__);
flow->rule.fwd_data = priv->cpu_port;
flow->rule.fwd_act = PIE_ACT_REDIRECT_TO_PORT;
rtl83xx_flow_bypass_all(flow);
break;
case FLOW_ACTION_MANGLE:
pr_err("%s: FLOW_ACTION_MANGLE not supported\n", __func__);
return -EOPNOTSUPP;
case FLOW_ACTION_ADD:
pr_err("%s: FLOW_ACTION_ADD not supported\n", __func__);
return -EOPNOTSUPP;
case FLOW_ACTION_VLAN_PUSH:
pr_debug("%s: VLAN_PUSH\n", __func__);
// TODO: act->vlan.proto
flow->rule.ivid_act = PIE_ACT_VID_ASSIGN;
flow->rule.ivid_sel = true;
flow->rule.ivid_data = htons(act->vlan.vid);
flow->rule.ovid_act = PIE_ACT_VID_ASSIGN;
flow->rule.ovid_sel = true;
flow->rule.ovid_data = htons(act->vlan.vid);
flow->rule.fwd_mod_to_cpu = true;
break;
case FLOW_ACTION_VLAN_POP:
pr_debug("%s: VLAN_POP\n", __func__);
flow->rule.ivid_act = PIE_ACT_VID_ASSIGN;
flow->rule.ivid_data = 0;
flow->rule.ivid_sel = true;
flow->rule.ovid_act = PIE_ACT_VID_ASSIGN;
flow->rule.ovid_data = 0;
flow->rule.ovid_sel = true;
flow->rule.fwd_mod_to_cpu = true;
break;
case FLOW_ACTION_CSUM:
pr_err("%s: FLOW_ACTION_CSUM not supported\n", __func__);
return -EOPNOTSUPP;
case FLOW_ACTION_REDIRECT:
pr_debug("%s: REDIRECT\n", __func__);
err = rtl83xx_parse_fwd(priv, act, flow);
if (err)
return err;
flow->rule.fwd_act = PIE_ACT_REDIRECT_TO_PORT;
break;
case FLOW_ACTION_MIRRED:
pr_debug("%s: MIRRED\n", __func__);
err = rtl83xx_parse_fwd(priv, act, flow);
if (err)
return err;
flow->rule.fwd_act = PIE_ACT_COPY_TO_PORT;
break;
default:
pr_err("%s: Flow action not supported: %d\n", __func__, act->id);
return -EOPNOTSUPP;
}
}
return 0;
}
static const struct rhashtable_params tc_ht_params = {
.head_offset = offsetof(struct rtl83xx_flow, node),
.key_offset = offsetof(struct rtl83xx_flow, cookie),
.key_len = sizeof(((struct rtl83xx_flow *)0)->cookie),
.automatic_shrinking = true,
};
static int rtl83xx_configure_flower(struct rtl838x_switch_priv *priv,
struct flow_cls_offload *f)
{
struct rtl83xx_flow *flow;
int err = 0;
pr_debug("In %s\n", __func__);
rcu_read_lock();
pr_debug("Cookie %08lx\n", f->cookie);
flow = rhashtable_lookup(&priv->tc_ht, &f->cookie, tc_ht_params);
if (flow) {
pr_info("%s: Got flow\n", __func__);
err = -EEXIST;
goto rcu_unlock;
}
rcu_unlock:
rcu_read_unlock();
if (flow)
goto out;
pr_debug("%s: New flow\n", __func__);
flow = kzalloc(sizeof(*flow), GFP_KERNEL);
if (!flow) {
err = -ENOMEM;
goto out;
}
flow->cookie = f->cookie;
flow->priv = priv;
err = rhashtable_insert_fast(&priv->tc_ht, &flow->node, tc_ht_params);
if (err) {
pr_err("Could not insert add new rule\n");
goto out_free;
}
rtl83xx_add_flow(priv, f, flow); // TODO: check error
// Add log action to flow
flow->rule.packet_cntr = rtl83xx_packet_cntr_alloc(priv);
if (flow->rule.packet_cntr >= 0) {
pr_debug("Using packet counter %d\n", flow->rule.packet_cntr);
flow->rule.log_sel = true;
flow->rule.log_data = flow->rule.packet_cntr;
}
err = priv->r->pie_rule_add(priv, &flow->rule);
return err;
out_free:
kfree(flow);
out:
pr_err("%s: error %d\n", __func__, err);
return err;
}
static int rtl83xx_delete_flower(struct rtl838x_switch_priv *priv,
struct flow_cls_offload * cls_flower)
{
struct rtl83xx_flow *flow;
pr_debug("In %s\n", __func__);
rcu_read_lock();
flow = rhashtable_lookup_fast(&priv->tc_ht, &cls_flower->cookie, tc_ht_params);
if (!flow) {
rcu_read_unlock();
return -EINVAL;
}
priv->r->pie_rule_rm(priv, &flow->rule);
rhashtable_remove_fast(&priv->tc_ht, &flow->node, tc_ht_params);
kfree_rcu(flow, rcu_head);
rcu_read_unlock();
return 0;
}
static int rtl83xx_stats_flower(struct rtl838x_switch_priv *priv,
struct flow_cls_offload * cls_flower)
{
struct rtl83xx_flow *flow;
unsigned long lastused = 0;
int total_packets, new_packets;
pr_debug("%s: \n", __func__);
flow = rhashtable_lookup_fast(&priv->tc_ht, &cls_flower->cookie, tc_ht_params);
if (!flow)
return -1;
if (flow->rule.packet_cntr >= 0) {
total_packets = priv->r->packet_cntr_read(flow->rule.packet_cntr);
pr_debug("Total packets: %d\n", total_packets);
new_packets = total_packets - flow->rule.last_packet_cnt;
flow->rule.last_packet_cnt = total_packets;
}
// TODO: We need a second PIE rule to count the bytes
flow_stats_update(&cls_flower->stats, 100 * new_packets, new_packets, 0, lastused,
FLOW_ACTION_HW_STATS_IMMEDIATE);
return 0;
}
static int rtl83xx_setup_tc_cls_flower(struct rtl838x_switch_priv *priv,
struct flow_cls_offload *cls_flower)
{
pr_debug("%s: %d\n", __func__, cls_flower->command);
switch (cls_flower->command) {
case FLOW_CLS_REPLACE:
return rtl83xx_configure_flower(priv, cls_flower);
case FLOW_CLS_DESTROY:
return rtl83xx_delete_flower(priv, cls_flower);
case FLOW_CLS_STATS:
return rtl83xx_stats_flower(priv, cls_flower);
default:
return -EOPNOTSUPP;
}
}
static int rtl83xx_setup_tc_block_cb(enum tc_setup_type type, void *type_data,
void *cb_priv)
{
struct rtl838x_switch_priv *priv = cb_priv;
switch (type) {
case TC_SETUP_CLSFLOWER:
pr_debug("%s: TC_SETUP_CLSFLOWER\n", __func__);
return rtl83xx_setup_tc_cls_flower(priv, type_data);
default:
return -EOPNOTSUPP;
}
}
static LIST_HEAD(rtl83xx_block_cb_list);
int rtl83xx_setup_tc(struct net_device *dev, enum tc_setup_type type, void *type_data)
{
struct rtl838x_switch_priv *priv;
struct flow_block_offload *f = type_data;
static bool first_time = true;
int err;
pr_debug("%s: %d\n", __func__, type);
if(!netdev_uses_dsa(dev)) {
pr_err("%s: no DSA\n", __func__);
return 0;
}
priv = dev->dsa_ptr->ds->priv;
switch (type) {
case TC_SETUP_BLOCK:
if (first_time) {
first_time = false;
err = rhashtable_init(&priv->tc_ht, &tc_ht_params);
if (err)
pr_err("%s: Could not initialize hash table\n", __func__);
}
f->unlocked_driver_cb = true;
return flow_block_cb_setup_simple(type_data,
&rtl83xx_block_cb_list,
rtl83xx_setup_tc_block_cb,
priv, priv, true);
default:
return -EOPNOTSUPP;
}
return 0;
}

View File

@ -30,15 +30,15 @@ extern struct rtl83xx_soc_info soc_info;
* Maximum number of RX rings is 8 on RTL83XX and 32 on the 93XX
* The ring is assigned by switch based on packet/port priortity
* Maximum number of TX rings is 2, Ring 2 being the high priority
* ring on the RTL93xx SoCs. MAX_RING_SIZE * RING_BUFFER gives
* the memory used for the ring buffer.
* ring on the RTL93xx SoCs. MAX_RXLEN gives the maximum length
* for an RX ring, MAX_ENTRIES the maximum number of entries
* available in total for all queues.
*/
#define MAX_RXRINGS 32
#define MAX_RXLEN 100
#define MAX_RXLEN 200
#define MAX_ENTRIES (200 * 8)
#define TXRINGS 2
// BUG: TXRINGLEN can be 160
#define TXRINGLEN 16
#define TXRINGLEN 160
#define NOTIFY_EVENTS 10
#define NOTIFY_BLOCKS 10
#define TX_EN 0x8
@ -47,14 +47,11 @@ extern struct rtl83xx_soc_info soc_info;
#define RX_EN_93XX 0x10
#define TX_DO 0x2
#define WRAP 0x2
#define MAX_PORTS 57
#define MAX_SMI_BUSSES 4
#define RING_BUFFER 1600
#define RTL838X_STORM_CTRL_PORT_BC_EXCEED (0x470C)
#define RTL838X_STORM_CTRL_PORT_MC_EXCEED (0x4710)
#define RTL838X_STORM_CTRL_PORT_UC_EXCEED (0x4714)
#define RTL838X_ATK_PRVNT_STS (0x5B1C)
struct p_hdr {
uint8_t *buf;
uint16_t reserved;
@ -95,14 +92,14 @@ struct notify_b {
u32 reserved2[8];
};
void rtl838x_create_tx_header(struct p_hdr *h, int dest_port, int prio)
static void rtl838x_create_tx_header(struct p_hdr *h, int dest_port, int prio)
{
prio &= 0x7;
if (dest_port > 0) {
// cpu_tag[0] is reserved on the RTL83XX SoCs
h->cpu_tag[1] = 0x0400;
h->cpu_tag[2] = 0x0200;
h->cpu_tag[1] = 0x0401; // BIT 10: RTL8380_CPU_TAG, BIT0: L2LEARNING on
h->cpu_tag[2] = 0x0200; // Set only AS_DPM, to enable DPM settings below
h->cpu_tag[3] = 0x0000;
h->cpu_tag[4] = BIT(dest_port) >> 16;
h->cpu_tag[5] = BIT(dest_port) & 0xffff;
@ -112,14 +109,15 @@ void rtl838x_create_tx_header(struct p_hdr *h, int dest_port, int prio)
}
}
void rtl839x_create_tx_header(struct p_hdr *h, int dest_port, int prio)
static void rtl839x_create_tx_header(struct p_hdr *h, int dest_port, int prio)
{
prio &= 0x7;
if (dest_port > 0) {
// cpu_tag[0] is reserved on the RTL83XX SoCs
h->cpu_tag[1] = 0x0100;
h->cpu_tag[1] = 0x0100; // RTL8390_CPU_TAG marker
h->cpu_tag[2] = h->cpu_tag[3] = h->cpu_tag[4] = h->cpu_tag[5] = 0;
// h->cpu_tag[1] |= BIT(1) | BIT(0); // Bypass filter 1/2
if (dest_port >= 32) {
dest_port -= 32;
h->cpu_tag[2] = BIT(dest_port) >> 16;
@ -128,35 +126,43 @@ void rtl839x_create_tx_header(struct p_hdr *h, int dest_port, int prio)
h->cpu_tag[4] = BIT(dest_port) >> 16;
h->cpu_tag[5] = BIT(dest_port) & 0xffff;
}
h->cpu_tag[6] |= BIT(21); // Enable destination port mask use
h->cpu_tag[2] |= BIT(20); // Enable destination port mask use
h->cpu_tag[2] |= BIT(23); // Enable L2 Learning
// Set internal priority and AS_PRIO
if (prio >= 0)
h->cpu_tag[1] |= prio | BIT(3);
}
}
void rtl930x_create_tx_header(struct p_hdr *h, int dest_port, int prio)
static void rtl930x_create_tx_header(struct p_hdr *h, int dest_port, int prio)
{
h->cpu_tag[0] = 0x8000;
h->cpu_tag[1] = 0; // TODO: Fill port and prio
h->cpu_tag[2] = 0;
h->cpu_tag[0] = 0x8000; // CPU tag marker
h->cpu_tag[1] = h->cpu_tag[2] = 0;
if (prio >= 0)
h->cpu_tag[2] = BIT(13) | prio << 8; // Enable and set Priority Queue
h->cpu_tag[3] = 0;
h->cpu_tag[4] = 0;
h->cpu_tag[5] = 0;
h->cpu_tag[6] = 0;
h->cpu_tag[7] = 0xffff;
h->cpu_tag[6] = BIT(dest_port) >> 16;
h->cpu_tag[7] = BIT(dest_port) & 0xffff;
}
void rtl931x_create_tx_header(struct p_hdr *h, int dest_port, int prio)
static void rtl931x_create_tx_header(struct p_hdr *h, int dest_port, int prio)
{
h->cpu_tag[0] = 0x8000;
h->cpu_tag[1] = 0; // TODO: Fill port and prio
h->cpu_tag[2] = 0;
h->cpu_tag[0] = 0x8000; // CPU tag marker
h->cpu_tag[1] = h->cpu_tag[2] = 0;
if (prio >= 0)
h->cpu_tag[2] = BIT(13) | prio << 8; // Enable and set Priority Queue
h->cpu_tag[3] = 0;
h->cpu_tag[4] = 0;
h->cpu_tag[5] = 0;
h->cpu_tag[6] = 0;
h->cpu_tag[7] = 0xffff;
h->cpu_tag[4] = h->cpu_tag[5] = h->cpu_tag[6] = h->cpu_tag[7] = 0;
if (dest_port >= 32) {
dest_port -= 32;
h->cpu_tag[4] = BIT(dest_port) >> 16;
h->cpu_tag[5] = BIT(dest_port) & 0xffff;
} else {
h->cpu_tag[6] = BIT(dest_port) >> 16;
h->cpu_tag[7] = BIT(dest_port) & 0xffff;
}
}
struct rtl838x_rx_q {
@ -181,6 +187,10 @@ struct rtl838x_eth_priv {
u32 lastEvent;
u16 rxrings;
u16 rxringlen;
u8 smi_bus[MAX_PORTS];
u8 smi_addr[MAX_PORTS];
bool smi_bus_isc45[MAX_SMI_BUSSES];
bool phy_is_internal[MAX_PORTS];
};
extern int rtl838x_phy_init(struct rtl838x_eth_priv *priv);
@ -408,29 +418,9 @@ static irqreturn_t rtl83xx_net_irq(int irq, void *dev_id)
struct net_device *dev = dev_id;
struct rtl838x_eth_priv *priv = netdev_priv(dev);
u32 status = sw_r32(priv->r->dma_if_intr_sts);
bool triggered = false;
u32 atk = sw_r32(RTL838X_ATK_PRVNT_STS);
int i;
u32 storm_uc = sw_r32(RTL838X_STORM_CTRL_PORT_UC_EXCEED);
u32 storm_mc = sw_r32(RTL838X_STORM_CTRL_PORT_MC_EXCEED);
u32 storm_bc = sw_r32(RTL838X_STORM_CTRL_PORT_BC_EXCEED);
pr_debug("IRQ: %08x\n", status);
if (storm_uc || storm_mc || storm_bc) {
pr_warn("Storm control UC: %08x, MC: %08x, BC: %08x\n",
storm_uc, storm_mc, storm_bc);
sw_w32(storm_uc, RTL838X_STORM_CTRL_PORT_UC_EXCEED);
sw_w32(storm_mc, RTL838X_STORM_CTRL_PORT_MC_EXCEED);
sw_w32(storm_bc, RTL838X_STORM_CTRL_PORT_BC_EXCEED);
triggered = true;
}
if (atk) {
pr_debug("Attack prevention triggered: %08x\n", atk);
sw_w32(atk, RTL838X_ATK_PRVNT_STS);
}
spin_lock(&priv->lock);
/* Ignore TX interrupt */
@ -454,7 +444,7 @@ static irqreturn_t rtl83xx_net_irq(int irq, void *dev_id)
/* RX buffer overrun */
if (status & 0x000ff) {
pr_info("RX buffer overrun: status %x, mask: %x\n",
pr_debug("RX buffer overrun: status %x, mask: %x\n",
status, sw_r32(priv->r->dma_if_intr_msk));
sw_w32(status, priv->r->dma_if_intr_sts);
rtl838x_rb_cleanup(priv, status & 0xff);
@ -1743,52 +1733,56 @@ static int rtl930x_mdio_reset(struct mii_bus *bus)
{
int i;
int pos;
struct rtl838x_eth_priv *priv = bus->priv;
u32 c45_mask = 0;
u32 poll_sel[2];
u32 poll_ctrl = 0;
pr_info("RTL930X_SMI_PORT0_15_POLLING_SEL %08x 16-27: %08x\n",
sw_r32(RTL930X_SMI_PORT0_15_POLLING_SEL),
sw_r32(RTL930X_SMI_PORT16_27_POLLING_SEL));
pr_info("%s: Enable SMI polling on SMI bus 0, SMI1, SMI2, disable on SMI3\n", __func__);
sw_w32_mask(BIT(20) | BIT(21) | BIT(22), BIT(23), RTL930X_SMI_GLB_CTRL);
pr_info("RTL9300 Powering on SerDes ports\n");
rtl9300_sds_power(24, 1);
rtl9300_sds_power(25, 1);
rtl9300_sds_power(26, 1);
rtl9300_sds_power(27, 1);
mdelay(200);
// RTL930X_SMI_PORT0_15_POLLING_SEL 55550000 16-27: 00f9aaaa
// i.e SMI=0 for all ports
for (i = 0; i < 5; i++)
pr_info("port phy: %08x\n", sw_r32(RTL930X_SMI_PORT0_5_ADDR + i *4));
// 1-to-1 mapping of port to phy-address
for (i = 0; i < 24; i++) {
// Mapping of port to phy-addresses on an SMI bus
poll_sel[0] = poll_sel[1] = 0;
for (i = 0; i < 28; i++) {
pos = (i % 6) * 5;
sw_w32_mask(0x1f << pos, i << pos, RTL930X_SMI_PORT0_5_ADDR + (i / 6) * 4);
sw_w32_mask(0x1f << pos, priv->smi_addr[i] << pos,
RTL930X_SMI_PORT0_5_ADDR + (i / 6) * 4);
pos = (i * 2) % 32;
poll_sel[i / 16] |= priv->smi_bus[i] << pos;
poll_ctrl |= BIT(20 + priv->smi_bus[i]);
}
// ports 24 and 25 have PHY addresses 8 and 9, ports 26/27 PHY 26/27
sw_w32(8 | 9 << 5 | 26 << 10 | 27 << 15, RTL930X_SMI_PORT0_5_ADDR + 4 * 4);
// Configure which SMI bus is behind which port number
sw_w32(poll_sel[0], RTL930X_SMI_PORT0_15_POLLING_SEL);
sw_w32(poll_sel[1], RTL930X_SMI_PORT16_27_POLLING_SEL);
// Ports 24 and 25 live on SMI bus 1 and 2
sw_w32_mask(0x3 << 16, 0x1 << 16, RTL930X_SMI_PORT16_27_POLLING_SEL);
sw_w32_mask(0x3 << 18, 0x2 << 18, RTL930X_SMI_PORT16_27_POLLING_SEL);
// Enable polling on the respective SMI busses
sw_w32_mask(0, poll_ctrl, RTL930X_SMI_GLB_CTRL);
// SMI bus 1 and 2 speak Clause 45 TODO: Configure from .dts
sw_w32_mask(0, BIT(17) | BIT(18), RTL930X_SMI_GLB_CTRL);
// Configure which SMI busses are polled in c45 based on a c45 PHY being on that bus
for (i = 0; i < 4; i++)
if (priv->smi_bus_isc45[i])
c45_mask |= BIT(i + 16);
// Ports 24 and 25 are 2.5 Gig, set this type (1)
sw_w32_mask(0x7 << 12, 1 << 12, RTL930X_SMI_MAC_TYPE_CTRL);
sw_w32_mask(0x7 << 15, 1 << 15, RTL930X_SMI_MAC_TYPE_CTRL);
pr_info("c45_mask: %08x\n", c45_mask);
sw_w32_mask(0, c45_mask, RTL930X_SMI_GLB_CTRL);
// Ports 24 to 27 are 2.5 or 10Gig, set this type (1) or (0) for internal SerDes
for (i = 24; i < 28; i++) {
pos = (i - 24) * 3 + 12;
if (priv->phy_is_internal[i])
sw_w32_mask(0x7 << pos, 0 << pos, RTL930X_SMI_MAC_TYPE_CTRL);
else
sw_w32_mask(0x7 << pos, 1 << pos, RTL930X_SMI_MAC_TYPE_CTRL);
}
// TODO: Set up RTL9300_SMI_10GPHY_POLLING_SEL_0 for Aquantia PHYs on e.g. XGS 1250
return 0;
}
static int rtl838x_mdio_init(struct rtl838x_eth_priv *priv)
{
struct device_node *mii_np;
struct device_node *mii_np, *dn;
u32 pn;
int ret;
pr_debug("%s called\n", __func__);
@ -1841,6 +1835,33 @@ static int rtl838x_mdio_init(struct rtl838x_eth_priv *priv)
priv->mii_bus->priv = priv;
priv->mii_bus->parent = &priv->pdev->dev;
for_each_node_by_name(dn, "ethernet-phy") {
u32 smi_addr[2];
if (of_property_read_u32(dn, "reg", &pn))
continue;
if (of_property_read_u32_array(dn, "rtl9300,smi-address", &smi_addr[0], 2)) {
smi_addr[0] = 0;
smi_addr[1] = pn;
}
if (pn < MAX_PORTS) {
priv->smi_bus[pn] = smi_addr[0];
priv->smi_addr[pn] = smi_addr[1];
} else {
pr_err("%s: illegal port number %d\n", __func__, pn);
}
if (of_device_is_compatible(dn, "ethernet-phy-ieee802.3-c45"))
priv->smi_bus_isc45[smi_addr[0]] = true;
if (of_property_read_bool(dn, "phy-is-integrated")) {
priv->phy_is_internal[pn] = true;
}
}
snprintf(priv->mii_bus->id, MII_BUS_ID_SIZE, "%pOFn", mii_np);
ret = of_mdiobus_register(priv->mii_bus, mii_np);
@ -1906,6 +1927,7 @@ static const struct net_device_ops rtl838x_eth_netdev_ops = {
.ndo_tx_timeout = rtl838x_eth_tx_timeout,
.ndo_set_features = rtl83xx_set_features,
.ndo_fix_features = rtl838x_fix_features,
.ndo_setup_tc = rtl83xx_setup_tc,
};
static const struct net_device_ops rtl839x_eth_netdev_ops = {
@ -1919,6 +1941,7 @@ static const struct net_device_ops rtl839x_eth_netdev_ops = {
.ndo_tx_timeout = rtl838x_eth_tx_timeout,
.ndo_set_features = rtl83xx_set_features,
.ndo_fix_features = rtl838x_fix_features,
.ndo_setup_tc = rtl83xx_setup_tc,
};
static const struct net_device_ops rtl930x_eth_netdev_ops = {
@ -1932,6 +1955,7 @@ static const struct net_device_ops rtl930x_eth_netdev_ops = {
.ndo_tx_timeout = rtl838x_eth_tx_timeout,
.ndo_set_features = rtl93xx_set_features,
.ndo_fix_features = rtl838x_fix_features,
.ndo_setup_tc = rtl83xx_setup_tc,
};
static const struct net_device_ops rtl931x_eth_netdev_ops = {

View File

@ -424,6 +424,6 @@ int rtl930x_write_phy(u32 port, u32 page, u32 reg, u32 val);
int rtl930x_read_phy(u32 port, u32 page, u32 reg, u32 *val);
int rtl931x_write_phy(u32 port, u32 page, u32 reg, u32 val);
int rtl931x_read_phy(u32 port, u32 page, u32 reg, u32 *val);
void rtl9300_sds_power(int sds_num, int val);
int rtl83xx_setup_tc(struct net_device *dev, enum tc_setup_type type, void *type_data);
#endif /* _RTL838X_ETH_H */

View File

@ -211,7 +211,7 @@ void rtl9300_sds_rst(int sds_num, u32 mode)
0x02A4, 0x02A4, 0x0198, 0x0198 };
u8 lsb[] = { 0, 6, 12, 18, 0, 6, 12, 18, 0, 6, 0, 6};
pr_info("SerDes: %s %d\n", __func__, mode);
pr_info("%s %d\n", __func__, mode);
if (sds_num < 0 || sds_num > 11) {
pr_err("Wrong SerDes number: %d\n", sds_num);
return;
@ -223,7 +223,7 @@ void rtl9300_sds_rst(int sds_num, u32 mode)
sw_w32_mask(0x1f << lsb[sds_num], mode << lsb[sds_num], regs[sds_num]);
mdelay(10);
pr_info("SDS: 194:%08x 198:%08x 2a0:%08x 2a4:%08x\n",
pr_debug("%s: 194:%08x 198:%08x 2a0:%08x 2a4:%08x\n", __func__,
sw_r32(0x194), sw_r32(0x198), sw_r32(0x2a0), sw_r32(0x2a4));
}
@ -276,7 +276,7 @@ int rtl930x_read_sds_phy(int phy_addr, int page, int phy_reg)
int i;
u32 cmd = phy_addr << 2 | page << 7 | phy_reg << 13 | 1;
pr_info("%s: phy_addr %d, phy_reg: %d\n", __func__, phy_addr, phy_reg);
pr_debug("%s: phy_addr %d, phy_reg: %d\n", __func__, phy_addr, phy_reg);
sw_w32(cmd, RTL930X_SDS_INDACS_CMD);
for (i = 0; i < 100; i++) {
@ -288,7 +288,7 @@ int rtl930x_read_sds_phy(int phy_addr, int page, int phy_reg)
if (i >= 100)
return -EIO;
pr_info("%s: returning %04x\n", __func__, sw_r32(RTL930X_SDS_INDACS_DATA) & 0xffff);
pr_debug("%s: returning %04x\n", __func__, sw_r32(RTL930X_SDS_INDACS_DATA) & 0xffff);
return sw_r32(RTL930X_SDS_INDACS_DATA) & 0xffff;
}
@ -508,7 +508,7 @@ static int rtl8226_config_aneg(struct phy_device *phydev)
u32 v;
int port = phydev->mdio.addr;
pr_info("In %s\n", __func__);
pr_debug("In %s\n", __func__);
if (phydev->autoneg == AUTONEG_ENABLE) {
ret = rtl8226_advertise_aneg(phydev);
if (ret)
@ -532,11 +532,9 @@ static int rtl8226_config_aneg(struct phy_device *phydev)
ret = write_mmd_phy(port, MMD_VEND2, 0xA400, v);
}
pr_info("%s: Ret is already: %d\n", __func__, ret);
// TODO: ret = __genphy_config_aneg(phydev, ret);
out:
pr_info("%s: And ret is now: %d\n", __func__, ret);
return ret;
}
@ -1727,7 +1725,7 @@ static int rtl8218d_phy_probe(struct phy_device *phydev)
struct rtl838x_phy_priv *priv;
int addr = phydev->mdio.addr;
pr_info("%s: id: %d\n", __func__, addr);
pr_debug("%s: id: %d\n", __func__, addr);
priv = devm_kzalloc(dev, sizeof(*priv), GFP_KERNEL);
if (!priv)
return -ENOMEM;

View File

@ -0,0 +1,25 @@
--- a/drivers/gpio/Kconfig
+++ b/drivers/gpio/Kconfig
@@ -514,6 +514,12 @@ config GPIO_RTL8231
help
Say yes here to support Realtek RTL8231 GPIO expansion chips.
+config GPIO_RTL838X
+ tristate "RTL838X GPIO"
+ depends on RTL838X
+ help
+ Say yes here to support RTL838X GPIO on RTL93xx SoCs.
+
config GPIO_SAMA5D2_PIOBU
tristate "SAMA5D2 PIOBU GPIO support"
depends on MFD_SYSCON
--- a/drivers/gpio/Makefile
+++ b/drivers/gpio/Makefile
@@ -127,6 +127,7 @@ obj-$(CONFIG_GPIO_RDC321X) += gpio-rdc3
obj-$(CONFIG_GPIO_REALTEK_OTTO) += gpio-realtek-otto.o
obj-$(CONFIG_GPIO_REG) += gpio-reg.o
obj-$(CONFIG_GPIO_RTL8231) += gpio-rtl8231.o
+obj-$(CONFIG_GPIO_RTL838X) += gpio-rtl838x.o
obj-$(CONFIG_ARCH_SA1100) += gpio-sa1100.o
obj-$(CONFIG_GPIO_SAMA5D2_PIOBU) += gpio-sama5d2-piobu.o
obj-$(CONFIG_GPIO_SCH311X) += gpio-sch311x.o

View File

@ -0,0 +1,19 @@
--- a/include/linux/phy.h
+++ b/include/linux/phy.h
@@ -133,6 +133,7 @@ typedef enum {
PHY_INTERFACE_MODE_XGMII,
PHY_INTERFACE_MODE_XLGMII,
PHY_INTERFACE_MODE_MOCA,
+ PHY_INTERFACE_MODE_HSGMII,
PHY_INTERFACE_MODE_QSGMII,
PHY_INTERFACE_MODE_TRGMII,
PHY_INTERFACE_MODE_1000BASEX,
@@ -199,6 +200,8 @@ static inline const char *phy_modes(phy_
return "xlgmii";
case PHY_INTERFACE_MODE_MOCA:
return "moca";
+ case PHY_INTERFACE_MODE_HSGMII:
+ return "hsgmii";
case PHY_INTERFACE_MODE_QSGMII:
return "qsgmii";
case PHY_INTERFACE_MODE_TRGMII:

View File

@ -1,6 +1,6 @@
--- a/include/linux/phy.h
+++ b/include/linux/phy.h
@@ -226,7 +226,7 @@ static inline const char *phy_modes(phy_
@@ -229,7 +229,7 @@ static inline const char *phy_modes(phy_
#define PHY_INIT_TIMEOUT 100000
#define PHY_FORCE_TIMEOUT 10

View File

@ -7,8 +7,7 @@ BOARDNAME:=Rockchip
FEATURES:=ext4 audio usb usbgadget display gpio fpu pci pcie rootfs-part boot-part squashfs
SUBTARGETS:=armv8
KERNEL_PATCHVER=5.4
KERNEL_TESTING_PATCHVER=5.10
KERNEL_PATCHVER=5.10
define Target/Description
Build firmware image for Rockchip SoC devices.

View File

@ -1,19 +0,0 @@
// SPDX-License-Identifier: (GPL-2.0+ OR MIT)
/*
* Copyright (c) 2019 Akash Gajjar <Akash_Gajjar@mentor.com>
* Copyright (c) 2019 Pragnesh Patel <Pragnesh_Patel@mentor.com>
*/
/* TODO
* Delete this file and migrate RockPi 4 to RockPi 4A after
* removing Kernel 5.4.
*/
/dts-v1/;
#include "rk3399-rock-pi-4.dtsi"
/ {
model = "Radxa ROCK Pi 4";
compatible = "radxa,rockpi4", "rockchip,rk3399";
};

View File

@ -42,16 +42,16 @@ define Device/pine64_rockpro64
endef
TARGET_DEVICES += pine64_rockpro64
define Device/radxa_rock-pi-4
define Device/radxa_rock-pi-4a
DEVICE_VENDOR := Radxa
DEVICE_MODEL := ROCK Pi 4
DEVICE_MODEL := ROCK Pi 4A
SOC := rk3399
SUPPORTED_DEVICES := radxa,rockpi4
SUPPORTED_DEVICES := radxa,rockpi4a radxa,rockpi4
UBOOT_DEVICE_NAME := rock-pi-4-rk3399
IMAGE/sysupgrade.img.gz := boot-common | boot-script | pine64-img | gzip | append-metadata
DEVICE_PACKAGES := brcmfmac-firmware-43456-sdio brcmfmac-nvram-43456-sdio kmod-brcmfmac -urngd
endef
TARGET_DEVICES += radxa_rock-pi-4
TARGET_DEVICES += radxa_rock-pi-4a
define Device/xunlong_orangepi-r1-plus
DEVICE_VENDOR := Xunlong

View File

@ -1,10 +0,0 @@
--- a/arch/arm64/boot/dts/rockchip/Makefile
+++ b/arch/arm64/boot/dts/rockchip/Makefile
@@ -36,6 +36,7 @@ dtb-$(CONFIG_ARCH_ROCKCHIP) += rk3399-pi
dtb-$(CONFIG_ARCH_ROCKCHIP) += rk3399-puma-haikou.dtb
dtb-$(CONFIG_ARCH_ROCKCHIP) += rk3399-roc-pc.dtb
dtb-$(CONFIG_ARCH_ROCKCHIP) += rk3399-roc-pc-mezzanine.dtb
+dtb-$(CONFIG_ARCH_ROCKCHIP) += rk3399-rock-pi-4.dtb
dtb-$(CONFIG_ARCH_ROCKCHIP) += rk3399-rock-pi-4a.dtb
dtb-$(CONFIG_ARCH_ROCKCHIP) += rk3399-rock-pi-4b.dtb
dtb-$(CONFIG_ARCH_ROCKCHIP) += rk3399-rock-pi-4c.dtb

View File

@ -7,6 +7,10 @@
board_config_update
case "$(board_name)" in
cisco-mx100-hw)
ucidef_set_led_usbport "usb" "USB" "mx100:green:usb" "1-1-port2"
ucidef_set_led_default "diag" "DIAG" "mx100:green:ha" "1"
;;
pc-engines-apu1|pc-engines-apu2|pc-engines-apu3)
ucidef_set_led_netdev "wan" "WAN" "apu:green:3" "eth0"
ucidef_set_led_netdev "lan" "LAN" "apu:green:2" "br-lan"

View File

@ -8,6 +8,9 @@
board_config_update
case "$(board_name)" in
cisco-mx100-hw)
ucidef_set_interfaces_lan_wan "eth0 eth1 eth2 eth3 eth4 eth5 eth7 eth8 eth9 eth10 eth11" "eth6"
;;
pc-engines-apu1|pc-engines-apu2|pc-engines-apu3)
ucidef_set_interfaces_lan_wan "eth1 eth2" "eth0"
;;

View File

@ -65,6 +65,16 @@ platform_do_bootloader_upgrade() {
"/dev/$diskdev" \
&& touch /tmp/boot/boot/grub/upgraded
case "$(board_name)" in
cisco-mx100-hw)
# If the MX100 is booted UEFI AND the SATA HDD exists, we need to change
# grub's root= to hd1 for it to boot correctly, otherwise we can keep it hd0.
if [ -d /sys/firmware/efi ] && [ "$(ls -a /dev/sd[a-z] | wc -w)" -gt 1 ] ; then
sed -i "s|hd0,${parttable}1|hd1,${parttable}1|g" /tmp/boot/boot/grub/grub.cfg
fi
;;
esac
umount /tmp/boot
fi
}

View File

@ -82,3 +82,23 @@ define KernelPackage/pcengines-apuv2/description
endef
$(eval $(call KernelPackage,pcengines-apuv2))
define KernelPackage/meraki-mx100
SUBMENU:=$(OTHER_MENU)
TITLE:=Cisco Meraki MX100 Platform Driver
DEPENDS:=@TARGET_x86 @!LINUX_5_4 +kmod-tg3 +kmod-gpio-button-hotplug +kmod-leds-gpio \
+kmod-usb-ledtrig-usbport +kmod-itco-wdt
KCONFIG:=CONFIG_MERAKI_MX100
FILES:=$(LINUX_DIR)/drivers/platform/x86/meraki-mx100.ko
AUTOLOAD:=$(call AutoLoad,60,meraki-mx100,1)
endef
define KernelPackage/meraki-mx100/description
This driver provides support for the front button and LEDs on
the Cisco Meraki MX100 (Tinkerbell) 1U appliance. Note this also
selects the gpio-cdev nu801 userspace driver to support the Status
LED, as well as other required platform drivers.
endef
$(eval $(call KernelPackage,meraki-mx100))

View File

@ -0,0 +1,32 @@
From ef0eea5b151aefe1efea78e2fa7c507ff3c56bf0 Mon Sep 17 00:00:00 2001
From: Chris Blake <chrisrblake93@gmail.com>
Date: Mon, 7 Jun 2021 18:35:35 -0500
Subject: mfd: lpc_ich: Enable GPIO driver for DH89xxCC
Based on the Intel Datasheet for the DH89xxCC PCH, the GPIO driver
is the same as ICH_v5_GPIO, minus the fact the DH89xxCC also has
blink support. However, blink support isn't supported by the GPIO
driver so we should use ICH_v5_GPIO. Tested and working on a Meraki
MX100-HW.
Signed-off-by: Chris Blake <chrisrblake93@gmail.com>
Co-developed-by: Christian Lamparter <chunkeey@gmail.com>
Signed-off-by: Lee Jones <lee.jones@linaro.org>
---
drivers/mfd/lpc_ich.c | 1 +
1 file changed, 1 insertion(+)
diff --git a/drivers/mfd/lpc_ich.c b/drivers/mfd/lpc_ich.c
index 3bbb29a7e7a57..f10e53187f67a 100644
--- a/drivers/mfd/lpc_ich.c
+++ b/drivers/mfd/lpc_ich.c
@@ -489,6 +489,7 @@ static struct lpc_ich_info lpc_chipset_info[] = {
[LPC_DH89XXCC] = {
.name = "DH89xxCC",
.iTCO_version = 2,
+ .gpio_version = ICH_V5_GPIO,
},
[LPC_PPT] = {
.name = "Panther Point",
--
cgit 1.2.3-1.el7

View File

@ -0,0 +1,300 @@
From 636a1e697555e73c28cdd6952a409edbfdd16475 Mon Sep 17 00:00:00 2001
From: Chris Blake <chrisrblake93@gmail.com>
Date: Mon, 9 Aug 2021 19:40:21 -0500
Subject: platform/x86: add meraki-mx100 platform driver
This adds platform support for the Cisco Meraki MX100 (Tinkerbell)
network appliance. This sets up the network LEDs and Reset
button.
Depends-on: ef0eea5b151ae ("mfd: lpc_ich: Enable GPIO driver for DH89xxCC")
Co-developed-by: Christian Lamparter <chunkeey@gmail.com>
Signed-off-by: Christian Lamparter <chunkeey@gmail.com>
Signed-off-by: Chris Blake <chrisrblake93@gmail.com>
Reviewed-by: Andy Shevchenko <andy.shevchenko@gmail.com>
Link: https://lore.kernel.org/r/20210810004021.2538308-1-chrisrblake93@gmail.com
Reviewed-by: Hans de Goede <hdegoede@redhat.com>
Signed-off-by: Hans de Goede <hdegoede@redhat.com>
---
drivers/platform/x86/Kconfig | 13 ++
drivers/platform/x86/Makefile | 3 +
drivers/platform/x86/meraki-mx100.c | 230 ++++++++++++++++++++++++++++++++++++
3 files changed, 246 insertions(+)
create mode 100644 drivers/platform/x86/meraki-mx100.c
diff --git a/drivers/platform/x86/Kconfig b/drivers/platform/x86/Kconfig
index 6ad35158ae4ef..432d72170b003 100644
--- a/drivers/platform/x86/Kconfig
+++ b/drivers/platform/x86/Kconfig
@@ -302,6 +302,19 @@ config ASUS_NB_WMI
If you have an ACPI-WMI compatible Asus Notebook, say Y or M
here.
+config MERAKI_MX100
+ tristate "Cisco Meraki MX100 Platform Driver"
+ depends on GPIOLIB
+ depends on GPIO_ICH
+ depends on LEDS_CLASS
+ select LEDS_GPIO
+ help
+ This driver provides support for the front button and LEDs on
+ the Cisco Meraki MX100 (Tinkerbell) 1U appliance.
+
+ To compile this driver as a module, choose M here: the module
+ will be called meraki-mx100.
+
config EEEPC_LAPTOP
tristate "Eee PC Hotkey Driver"
depends on ACPI
diff --git a/drivers/platform/x86/Makefile b/drivers/platform/x86/Makefile
index 5edfdc2ea7f29..9bb3c3f773864 100644
--- a/drivers/platform/x86/Makefile
+++ b/drivers/platform/x86/Makefile
@@ -39,6 +39,9 @@ obj-$(CONFIG_ASUS_NB_WMI) += asus-nb-wmi.o
obj-$(CONFIG_EEEPC_LAPTOP) += eeepc-laptop.o
obj-$(CONFIG_EEEPC_WMI) += eeepc-wmi.o
+# Cisco/Meraki
+obj-$(CONFIG_MERAKI_MX100) += meraki-mx100.o
+
# Dell
obj-$(CONFIG_X86_PLATFORM_DRIVERS_DELL) += dell/
diff --git a/drivers/platform/x86/meraki-mx100.c b/drivers/platform/x86/meraki-mx100.c
new file mode 100644
index 0000000000000..3751ed36a980a
--- /dev/null
+++ b/drivers/platform/x86/meraki-mx100.c
@@ -0,0 +1,230 @@
+// SPDX-License-Identifier: GPL-2.0+
+
+/*
+ * Cisco Meraki MX100 (Tinkerbell) board platform driver
+ *
+ * Based off of arch/x86/platform/meraki/tink.c from the
+ * Meraki GPL release meraki-firmware-sources-r23-20150601
+ *
+ * Format inspired by platform/x86/pcengines-apuv2.c
+ *
+ * Copyright (C) 2021 Chris Blake <chrisrblake93@gmail.com>
+ */
+
+#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
+
+#include <linux/dmi.h>
+#include <linux/err.h>
+#include <linux/gpio_keys.h>
+#include <linux/gpio/machine.h>
+#include <linux/input.h>
+#include <linux/io.h>
+#include <linux/kernel.h>
+#include <linux/leds.h>
+#include <linux/module.h>
+#include <linux/platform_device.h>
+
+#define TINK_GPIO_DRIVER_NAME "gpio_ich"
+
+/* LEDs */
+static const struct gpio_led tink_leds[] = {
+ {
+ .name = "mx100:green:internet",
+ .default_trigger = "default-on",
+ },
+ {
+ .name = "mx100:green:lan2",
+ },
+ {
+ .name = "mx100:green:lan3",
+ },
+ {
+ .name = "mx100:green:lan4",
+ },
+ {
+ .name = "mx100:green:lan5",
+ },
+ {
+ .name = "mx100:green:lan6",
+ },
+ {
+ .name = "mx100:green:lan7",
+ },
+ {
+ .name = "mx100:green:lan8",
+ },
+ {
+ .name = "mx100:green:lan9",
+ },
+ {
+ .name = "mx100:green:lan10",
+ },
+ {
+ .name = "mx100:green:lan11",
+ },
+ {
+ .name = "mx100:green:ha",
+ },
+ {
+ .name = "mx100:orange:ha",
+ },
+ {
+ .name = "mx100:green:usb",
+ },
+ {
+ .name = "mx100:orange:usb",
+ },
+};
+
+static const struct gpio_led_platform_data tink_leds_pdata = {
+ .num_leds = ARRAY_SIZE(tink_leds),
+ .leds = tink_leds,
+};
+
+static struct gpiod_lookup_table tink_leds_table = {
+ .dev_id = "leds-gpio",
+ .table = {
+ GPIO_LOOKUP_IDX(TINK_GPIO_DRIVER_NAME, 11,
+ NULL, 0, GPIO_ACTIVE_LOW),
+ GPIO_LOOKUP_IDX(TINK_GPIO_DRIVER_NAME, 18,
+ NULL, 1, GPIO_ACTIVE_HIGH),
+ GPIO_LOOKUP_IDX(TINK_GPIO_DRIVER_NAME, 20,
+ NULL, 2, GPIO_ACTIVE_HIGH),
+ GPIO_LOOKUP_IDX(TINK_GPIO_DRIVER_NAME, 22,
+ NULL, 3, GPIO_ACTIVE_HIGH),
+ GPIO_LOOKUP_IDX(TINK_GPIO_DRIVER_NAME, 23,
+ NULL, 4, GPIO_ACTIVE_HIGH),
+ GPIO_LOOKUP_IDX(TINK_GPIO_DRIVER_NAME, 32,
+ NULL, 5, GPIO_ACTIVE_HIGH),
+ GPIO_LOOKUP_IDX(TINK_GPIO_DRIVER_NAME, 34,
+ NULL, 6, GPIO_ACTIVE_HIGH),
+ GPIO_LOOKUP_IDX(TINK_GPIO_DRIVER_NAME, 35,
+ NULL, 7, GPIO_ACTIVE_HIGH),
+ GPIO_LOOKUP_IDX(TINK_GPIO_DRIVER_NAME, 36,
+ NULL, 8, GPIO_ACTIVE_HIGH),
+ GPIO_LOOKUP_IDX(TINK_GPIO_DRIVER_NAME, 37,
+ NULL, 9, GPIO_ACTIVE_HIGH),
+ GPIO_LOOKUP_IDX(TINK_GPIO_DRIVER_NAME, 48,
+ NULL, 10, GPIO_ACTIVE_HIGH),
+ GPIO_LOOKUP_IDX(TINK_GPIO_DRIVER_NAME, 16,
+ NULL, 11, GPIO_ACTIVE_LOW),
+ GPIO_LOOKUP_IDX(TINK_GPIO_DRIVER_NAME, 7,
+ NULL, 12, GPIO_ACTIVE_LOW),
+ GPIO_LOOKUP_IDX(TINK_GPIO_DRIVER_NAME, 21,
+ NULL, 13, GPIO_ACTIVE_LOW),
+ GPIO_LOOKUP_IDX(TINK_GPIO_DRIVER_NAME, 19,
+ NULL, 14, GPIO_ACTIVE_LOW),
+ {} /* Terminating entry */
+ }
+};
+
+/* Reset Button */
+static struct gpio_keys_button tink_buttons[] = {
+ {
+ .desc = "Reset",
+ .type = EV_KEY,
+ .code = KEY_RESTART,
+ .active_low = 1,
+ .debounce_interval = 100,
+ },
+};
+
+static const struct gpio_keys_platform_data tink_buttons_pdata = {
+ .buttons = tink_buttons,
+ .nbuttons = ARRAY_SIZE(tink_buttons),
+ .poll_interval = 20,
+ .rep = 0,
+ .name = "mx100-keys",
+};
+
+static struct gpiod_lookup_table tink_keys_table = {
+ .dev_id = "gpio-keys-polled",
+ .table = {
+ GPIO_LOOKUP_IDX(TINK_GPIO_DRIVER_NAME, 60,
+ NULL, 0, GPIO_ACTIVE_LOW),
+ {} /* Terminating entry */
+ }
+};
+
+/* Board setup */
+static const struct dmi_system_id tink_systems[] __initconst = {
+ {
+ .matches = {
+ DMI_EXACT_MATCH(DMI_SYS_VENDOR, "Cisco"),
+ DMI_EXACT_MATCH(DMI_PRODUCT_NAME, "MX100-HW"),
+ },
+ },
+ {} /* Terminating entry */
+};
+MODULE_DEVICE_TABLE(dmi, tink_systems);
+
+static struct platform_device *tink_leds_pdev;
+static struct platform_device *tink_keys_pdev;
+
+static struct platform_device * __init tink_create_dev(
+ const char *name, const void *pdata, size_t sz)
+{
+ struct platform_device *pdev;
+
+ pdev = platform_device_register_data(NULL,
+ name, PLATFORM_DEVID_NONE, pdata, sz);
+ if (IS_ERR(pdev))
+ pr_err("failed registering %s: %ld\n", name, PTR_ERR(pdev));
+
+ return pdev;
+}
+
+static int __init tink_board_init(void)
+{
+ int ret;
+
+ if (!dmi_first_match(tink_systems))
+ return -ENODEV;
+
+ /*
+ * We need to make sure that GPIO60 isn't set to native mode as is default since it's our
+ * Reset Button. To do this, write to GPIO_USE_SEL2 to have GPIO60 set to GPIO mode.
+ * This is documented on page 1609 of the PCH datasheet, order number 327879-005US
+ */
+ outl(inl(0x530) | BIT(28), 0x530);
+
+ gpiod_add_lookup_table(&tink_leds_table);
+ gpiod_add_lookup_table(&tink_keys_table);
+
+ tink_leds_pdev = tink_create_dev("leds-gpio",
+ &tink_leds_pdata, sizeof(tink_leds_pdata));
+ if (IS_ERR(tink_leds_pdev)) {
+ ret = PTR_ERR(tink_leds_pdev);
+ goto err;
+ }
+
+ tink_keys_pdev = tink_create_dev("gpio-keys-polled",
+ &tink_buttons_pdata, sizeof(tink_buttons_pdata));
+ if (IS_ERR(tink_keys_pdev)) {
+ ret = PTR_ERR(tink_keys_pdev);
+ platform_device_unregister(tink_leds_pdev);
+ goto err;
+ }
+
+ return 0;
+
+err:
+ gpiod_remove_lookup_table(&tink_keys_table);
+ gpiod_remove_lookup_table(&tink_leds_table);
+ return ret;
+}
+module_init(tink_board_init);
+
+static void __exit tink_board_exit(void)
+{
+ platform_device_unregister(tink_keys_pdev);
+ platform_device_unregister(tink_leds_pdev);
+ gpiod_remove_lookup_table(&tink_keys_table);
+ gpiod_remove_lookup_table(&tink_leds_table);
+}
+module_exit(tink_board_exit);
+
+MODULE_AUTHOR("Chris Blake <chrisrblake93@gmail.com>");
+MODULE_DESCRIPTION("Cisco Meraki MX100 Platform Driver");
+MODULE_LICENSE("GPL");
+MODULE_ALIAS("platform:meraki-mx100");
--
cgit 1.2.3-1.el7

View File

@ -1,6 +1,7 @@
config MAKE_TOOLCHAIN
bool "Package the OpenWrt-based Toolchain"
depends on !EXTERNAL_TOOLCHAIN
default BUILDBOT
help
Package the created toolchain as a tarball under the bin/ directory as
OpenWrt-Toolchain-$(BOARD)-for-$(ARCH)$(ARCH_SUFFIX)-gcc-$(GCCV)$(DIR_SUFFIX).

View File

@ -8,11 +8,11 @@ include $(TOPDIR)/rules.mk
include $(INCLUDE_DIR)/target.mk
PKG_NAME:=ccache
PKG_VERSION:=4.3
PKG_VERSION:=4.4.2
PKG_SOURCE:=$(PKG_NAME)-$(PKG_VERSION).tar.xz
PKG_SOURCE_URL:=https://github.com/ccache/ccache/releases/download/v$(PKG_VERSION)
PKG_HASH:=504a0f2184465c306826f035b4bc00bae7500308d6af4abbfb50e33a694989b4
PKG_HASH:=9200cafbaa5fd62c2600fccb40a18214e57747825e6cdcd76688b4b61c2dcba0
include $(INCLUDE_DIR)/host-build.mk
include $(INCLUDE_DIR)/cmake.mk
@ -22,6 +22,7 @@ CMAKE_HOST_OPTIONS += \
-DCMAKE_CXX_COMPILER_LAUNCHER="" \
-DCMAKE_SKIP_RPATH=FALSE \
-DCMAKE_INSTALL_RPATH="${STAGING_DIR_HOST}/lib" \
-DREDIS_STORAGE_BACKEND=OFF
ifneq (docs-$(CONFIG_BUILD_DOCUMENTATION),docs-y)
CMAKE_HOST_OPTIONS += -DENABLE_DOCUMENTATION=OFF

Some files were not shown because too many files have changed in this diff Show More