mirror of
				https://github.com/Telecominfraproject/wlan-ap.git
				synced 2025-11-02 19:37:51 +00:00 
			
		
		
		
	Compare commits
	
		
			92 Commits
		
	
	
		
			v4.0.0-rc1
			...
			WIFI-14697
		
	
	| Author | SHA1 | Date | |
|---|---|---|---|
| 
						 | 
					cd8294eca0 | ||
| 
						 | 
					e12ecf831e | ||
| 
						 | 
					1213182012 | ||
| 
						 | 
					d5df71619a | ||
| 
						 | 
					a177884893 | ||
| 
						 | 
					1f7d8a7bb7 | ||
| 
						 | 
					dc02d2722a | ||
| 
						 | 
					13ac9166ef | ||
| 
						 | 
					3d6f360cb6 | ||
| 
						 | 
					6659e77bd0 | ||
| 
						 | 
					b061cc55ce | ||
| 
						 | 
					b17db16c15 | ||
| 
						 | 
					d36866301f | ||
| 
						 | 
					ffccb65d1b | ||
| 
						 | 
					af165342ed | ||
| 
						 | 
					ed62236d31 | ||
| 
						 | 
					346bdd9c16 | ||
| 
						 | 
					dc41a0fd0c | ||
| 
						 | 
					2b26a4e68a | ||
| 
						 | 
					fa96b2b24d | ||
| 
						 | 
					36f00adc7a | ||
| 
						 | 
					5314a752bd | ||
| 
						 | 
					0f6683f31e | ||
| 
						 | 
					8ee96c36c9 | ||
| 
						 | 
					89789900f5 | ||
| 
						 | 
					6add44ae27 | ||
| 
						 | 
					14a0c2d272 | ||
| 
						 | 
					9e769c85cb | ||
| 
						 | 
					d6e1008c7a | ||
| 
						 | 
					0a4c10d6cc | ||
| 
						 | 
					edfd2883f5 | ||
| 
						 | 
					f6ac6f791e | ||
| 
						 | 
					88fe15a985 | ||
| 
						 | 
					a9f47c9e1e | ||
| 
						 | 
					f17314a2d3 | ||
| 
						 | 
					29739ebd13 | ||
| 
						 | 
					3caba52dba | ||
| 
						 | 
					44bcc50815 | ||
| 
						 | 
					942d7c15b4 | ||
| 
						 | 
					25be7aef1a | ||
| 
						 | 
					a2e1ffe089 | ||
| 
						 | 
					911f8eaa4c | ||
| 
						 | 
					590ee6d514 | ||
| 
						 | 
					5054a71062 | ||
| 
						 | 
					d69c1c3176 | ||
| 
						 | 
					8d0da5a086 | ||
| 
						 | 
					eb66feb5c5 | ||
| 
						 | 
					89b6ebd518 | ||
| 
						 | 
					e3dfe5ea74 | ||
| 
						 | 
					f39339564a | ||
| 
						 | 
					adac3818a4 | ||
| 
						 | 
					a516b035ab | ||
| 
						 | 
					29b088ef21 | ||
| 
						 | 
					10b875d42c | ||
| 
						 | 
					1f0a24a941 | ||
| 
						 | 
					ea3afcda56 | ||
| 
						 | 
					b5987cc2a7 | ||
| 
						 | 
					fc700364d1 | ||
| 
						 | 
					f2fec9dd87 | ||
| 
						 | 
					2de57bf167 | ||
| 
						 | 
					7d31bebdb0 | ||
| 
						 | 
					fcb5a972cf | ||
| 
						 | 
					082d04025c | ||
| 
						 | 
					9ef7d2c227 | ||
| 
						 | 
					e0d61cb0fb | ||
| 
						 | 
					ed2795b30b | ||
| 
						 | 
					4b31e481ec | ||
| 
						 | 
					ba10a88ab3 | ||
| 
						 | 
					b85bc5db9c | ||
| 
						 | 
					e998711444 | ||
| 
						 | 
					2d6bea18df | ||
| 
						 | 
					1bf9e40987 | ||
| 
						 | 
					a20b96eb31 | ||
| 
						 | 
					c83ac67492 | ||
| 
						 | 
					2b0c600fb3 | ||
| 
						 | 
					c5793bae3a | ||
| 
						 | 
					6afbb92dec | ||
| 
						 | 
					89cb9d63bd | ||
| 
						 | 
					16963c997f | ||
| 
						 | 
					f7a9ad770d | ||
| 
						 | 
					dcdccc7ba0 | ||
| 
						 | 
					b67f97f213 | ||
| 
						 | 
					e9dcf3d953 | ||
| 
						 | 
					cc5edd4446 | ||
| 
						 | 
					79adece623 | ||
| 
						 | 
					49b64ec93f | ||
| 
						 | 
					b1e3686124 | ||
| 
						 | 
					e5bcda17e7 | ||
| 
						 | 
					7c04ed76bd | ||
| 
						 | 
					04a5cc67e0 | ||
| 
						 | 
					80b2c6d080 | ||
| 
						 | 
					c683f19b7c | 
							
								
								
									
										2
									
								
								.github/workflows/build-dev.yml
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										2
									
								
								.github/workflows/build-dev.yml
									
									
									
									
										vendored
									
									
								
							@@ -21,7 +21,7 @@ jobs:
 | 
			
		||||
    strategy:
 | 
			
		||||
      fail-fast: false
 | 
			
		||||
      matrix:
 | 
			
		||||
        target: [ 'cig_wf186h', 'cig_wf186w', 'cig_wf188n', 'cig_wf189', 'cig_wf196', 'cig_wf196', 'cybertan_eww631-a1', 'cybertan_eww631-b1', 'sonicfi_rap630w-312g', 'sonicfi_rap63xc-211g', 'sonicfi_rap630c-311g', 'sonicfi_rap630w-311g', 'sonicfi_rap630w-211g', 'sonicfi_rap7110c-341x', 'edgecore_eap101', 'edgecore_eap102', 'edgecore_eap104', 'edgecore_eap105', 'edgecore_eap111', 'edgecore_eap112', 'edgecore_oap101', 'edgecore_oap101-6e', 'edgecore_oap101e', 'edgecore_oap101e-6e', 'edgecore_oap103', 'hfcl_ion4xe', 'hfcl_ion4xi', 'hfcl_ion4x', 'hfcl_ion4x_2', 'hfcl_ion4x_3', 'hfcl_ion4xi_w', 'hfcl_ion4x_w', 'indio_um-305ax', 'senao_iap4300m', 'senao_iap2300m', 'senao_jeap6500', 'udaya_a6-id2', 'udaya_a6-od2', 'yuncore_ax820', 'yuncore_ax840', 'yuncore_fap640', 'yuncore_fap650', 'yuncore_fap655' ]
 | 
			
		||||
        target: [ 'cig_wf189h', 'cig_wf189w', 'cig_wf660a', 'cig_wf672', 'cig_wf186h', 'cig_wf186w', 'cig_wf188n', 'cig_wf189', 'cig_wf196', 'cig_wf196', 'cybertan_eww631-a1', 'cybertan_eww631-b1', 'sonicfi_rap630w-312g', 'sonicfi_rap63xc-211g', 'sonicfi_rap630c-311g', 'sonicfi_rap630w-311g', 'sonicfi_rap630w-211g', 'sonicfi_rap650c', 'sonicfi_rap7110c-341x', 'sonicfi_rap750e-h', 'sonicfi_rap750e-s', 'sonicfi_rap750w-311a', 'edgecore_eap101', 'edgecore_eap102', 'edgecore_eap104', 'edgecore_eap105', 'edgecore_eap111', 'edgecore_eap112', 'edgecore_oap101', 'edgecore_oap101-6e', 'edgecore_oap101e', 'edgecore_oap101e-6e', 'edgecore_oap103', 'hfcl_ion4xe', 'hfcl_ion4xi', 'hfcl_ion4x', 'hfcl_ion4x_2', 'hfcl_ion4x_3', 'hfcl_ion4xi_w', 'hfcl_ion4x_w', 'indio_um-305ax', 'senao_iap4300m', 'senao_iap2300m', 'senao_jeap6500', 'udaya_a6-id2', 'udaya_a6-od2', 'yuncore_ax820', 'yuncore_ax840', 'yuncore_fap640', 'yuncore_fap650', 'yuncore_fap655', 'emplus_wap588m', 'zyxel_nwa130be', 'sercomm_ap72tip-v4' ]
 | 
			
		||||
    steps:
 | 
			
		||||
    - uses: actions/checkout@v3
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
@@ -117,8 +117,6 @@ hostapd_common_add_device_config() {
 | 
			
		||||
	config_add_boolean legacy_rates
 | 
			
		||||
	config_add_int cell_density
 | 
			
		||||
	config_add_int rts_threshold
 | 
			
		||||
	config_add_int rssi_reject_assoc_rssi
 | 
			
		||||
	config_add_int rssi_ignore_probe_request
 | 
			
		||||
	config_add_int maxassoc
 | 
			
		||||
	config_add_boolean maxassoc_ignore_probe
 | 
			
		||||
 | 
			
		||||
@@ -162,7 +160,7 @@ hostapd_prepare_device_config() {
 | 
			
		||||
 | 
			
		||||
	json_get_vars country country3 country_ie beacon_int:100 dtim_period:2 doth require_mode legacy_rates \
 | 
			
		||||
		acs_chan_bias local_pwr_constraint spectrum_mgmt_required airtime_mode cell_density \
 | 
			
		||||
		rts_threshold beacon_rate rssi_reject_assoc_rssi rssi_ignore_probe_request maxassoc \
 | 
			
		||||
		rts_threshold beacon_rate maxassoc \
 | 
			
		||||
		multiple_bssid he_co_locate rnr_beacon ema acs_exclude_dfs \
 | 
			
		||||
		maxassoc_ignore_probe band
 | 
			
		||||
 | 
			
		||||
@@ -261,8 +259,6 @@ hostapd_prepare_device_config() {
 | 
			
		||||
		hostapd_add_rate brlist "$br"
 | 
			
		||||
	done
 | 
			
		||||
 | 
			
		||||
	[ -n "$rssi_reject_assoc_rssi" ] && append base_cfg "rssi_reject_assoc_rssi=$rssi_reject_assoc_rssi" "$N"
 | 
			
		||||
	[ -n "$rssi_ignore_probe_request" ] && append base_cfg "rssi_ignore_probe_request=$rssi_ignore_probe_request" "$N"
 | 
			
		||||
	[ -n "$beacon_rate" ] && append base_cfg "beacon_rate=$beacon_rate" "$N"
 | 
			
		||||
	[ -n "$rlist" ] && append base_cfg "supported_rates=$rlist" "$N"
 | 
			
		||||
	[ -n "$brlist" ] && append base_cfg "basic_rates=$brlist" "$N"
 | 
			
		||||
@@ -471,6 +467,9 @@ hostapd_common_add_bss_config() {
 | 
			
		||||
	config_add_string uci_section
 | 
			
		||||
 | 
			
		||||
	config_add_boolean dynamic_probe_resp
 | 
			
		||||
 | 
			
		||||
	config_add_int rssi_reject_assoc_rssi
 | 
			
		||||
	config_add_int rssi_ignore_probe_request
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
hostapd_set_vlan_file() {
 | 
			
		||||
@@ -724,7 +723,8 @@ hostapd_set_bss_options() {
 | 
			
		||||
		airtime_bss_weight airtime_bss_limit airtime_sta_weight \
 | 
			
		||||
		multicast_to_unicast_all proxy_arp per_sta_vif \
 | 
			
		||||
		eap_server eap_user_file ca_cert server_cert private_key private_key_passwd server_id \
 | 
			
		||||
		vendor_elements fils uci_section dynamic_probe_resp
 | 
			
		||||
		vendor_elements fils uci_section dynamic_probe_resp \
 | 
			
		||||
		rssi_reject_assoc_rssi rssi_ignore_probe_request 
 | 
			
		||||
 | 
			
		||||
	set_default fils 0
 | 
			
		||||
	set_default isolate 0
 | 
			
		||||
@@ -778,6 +778,8 @@ hostapd_set_bss_options() {
 | 
			
		||||
	append bss_conf "uapsd_advertisement_enabled=$uapsd" "$N"
 | 
			
		||||
	append bss_conf "utf8_ssid=$utf8_ssid" "$N"
 | 
			
		||||
	append bss_conf "multi_ap=$multi_ap" "$N"
 | 
			
		||||
	[ -n "$rssi_reject_assoc_rssi" ] && append bss_conf "rssi_reject_assoc_rssi=$rssi_reject_assoc_rssi" "$N"
 | 
			
		||||
	[ -n "$rssi_ignore_probe_request" ] && append bss_conf "rssi_ignore_probe_request=$rssi_ignore_probe_request" "$N"
 | 
			
		||||
	[ -n "$vendor_elements" ] && append bss_conf "vendor_elements=$vendor_elements" "$N"
 | 
			
		||||
 | 
			
		||||
	[ "$tdls_prohibit" -gt 0 ] && append bss_conf "tdls_prohibit=$tdls_prohibit" "$N"
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										14
									
								
								feeds/hostapd/hostapd/patches/zzz-ignore-probe-event.patch
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										14
									
								
								feeds/hostapd/hostapd/patches/zzz-ignore-probe-event.patch
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,14 @@
 | 
			
		||||
--- a/src/ap/beacon.c
 | 
			
		||||
+++ b/src/ap/beacon.c
 | 
			
		||||
@@ -934,8 +934,10 @@ void handle_probe_req(struct hostapd_dat
 | 
			
		||||
 	int ubus_response;
 | 
			
		||||
 
 | 
			
		||||
 	if (hapd->iconf->rssi_ignore_probe_request && ssi_signal &&
 | 
			
		||||
-	    ssi_signal < hapd->iconf->rssi_ignore_probe_request)
 | 
			
		||||
+	    ssi_signal < hapd->iconf->rssi_ignore_probe_request) {
 | 
			
		||||
+		hostapd_ubus_notify_rssi(hapd, "rssi-ignore-probe", mgmt->sa, ssi_signal);
 | 
			
		||||
 		return;
 | 
			
		||||
+	}
 | 
			
		||||
 
 | 
			
		||||
 	if (len < IEEE80211_HDRLEN)
 | 
			
		||||
 		return;
 | 
			
		||||
@@ -0,0 +1,46 @@
 | 
			
		||||
Index: hostapd-2023-09-08-e5ccbfc6/src/ap/wpa_auth_ft.c
 | 
			
		||||
===================================================================
 | 
			
		||||
--- hostapd-2023-09-08-e5ccbfc6.orig/src/ap/wpa_auth_ft.c
 | 
			
		||||
+++ hostapd-2023-09-08-e5ccbfc6/src/ap/wpa_auth_ft.c
 | 
			
		||||
@@ -3293,6 +3297,8 @@ static int wpa_ft_process_auth_req(struc
 | 
			
		||||
 	size_t identity_len = 0, radius_cui_len = 0;
 | 
			
		||||
 	size_t pmk_r1_len, kdk_len, len;
 | 
			
		||||
 	int retval = WLAN_STATUS_UNSPECIFIED_FAILURE;
 | 
			
		||||
+	struct os_reltime now;
 | 
			
		||||
+	struct rsn_ftie *ftie;
 | 
			
		||||
 
 | 
			
		||||
 	*resp_ies = NULL;
 | 
			
		||||
 	*resp_ies_len = 0;
 | 
			
		||||
@@ -3324,6 +3330,9 @@ static int wpa_ft_process_auth_req(struc
 | 
			
		||||
 		goto out;
 | 
			
		||||
 	}
 | 
			
		||||
 
 | 
			
		||||
+	ftie = (struct rsn_ftie *) parse.ftie;
 | 
			
		||||
+	os_memcpy(sm->SNonce, ftie->snonce, WPA_NONCE_LEN);
 | 
			
		||||
+
 | 
			
		||||
 	if (parse.r0kh_id == NULL) {
 | 
			
		||||
 		wpa_printf(MSG_DEBUG, "FT: Invalid FTIE - no R0KH-ID");
 | 
			
		||||
 		retval = WLAN_STATUS_INVALID_FTIE;
 | 
			
		||||
@@ -3424,10 +3433,18 @@ pmk_r1_derived:
 | 
			
		||||
 	os_memcpy(sm->pmk_r1, pmk_r1, pmk_r1_len);
 | 
			
		||||
 	sm->pmk_r1_len = pmk_r1_len;
 | 
			
		||||
 
 | 
			
		||||
-	if (random_get_bytes(sm->ANonce, WPA_NONCE_LEN)) {
 | 
			
		||||
-		wpa_printf(MSG_DEBUG, "FT: Failed to get random data for "
 | 
			
		||||
-			   "ANonce");
 | 
			
		||||
-		goto out;
 | 
			
		||||
+	if (os_get_reltime(&now) < 0 ||
 | 
			
		||||
+	    os_reltime_expired(&now, &sm->ANonce_time, 1)) {
 | 
			
		||||
+		if (random_get_bytes(sm->ANonce, WPA_NONCE_LEN)) {
 | 
			
		||||
+			wpa_printf(MSG_DEBUG, "FT: Failed to get random data for "
 | 
			
		||||
+				   "ANonce");
 | 
			
		||||
+			return WLAN_STATUS_UNSPECIFIED_FAILURE;
 | 
			
		||||
+		}
 | 
			
		||||
+		sm->ANonce_time.sec = now.sec;
 | 
			
		||||
+		sm->ANonce_time.usec = now.usec;
 | 
			
		||||
+		wpa_printf(MSG_INFO, "FT: ANonce was randomized");
 | 
			
		||||
+	} else {
 | 
			
		||||
+		wpa_printf(MSG_INFO, "FT: ANonce has not expired");
 | 
			
		||||
 	}
 | 
			
		||||
 
 | 
			
		||||
 	/* Now that we know the correct PMK-R1 length and as such, the length
 | 
			
		||||
@@ -1944,6 +1944,21 @@ void hostapd_ubus_notify(struct hostapd_data *hapd, const char *type, const u8 *
 | 
			
		||||
	ubus_notify(ctx, &hapd->ubus.obj, type, b.head, -1);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void hostapd_ubus_notify_rssi(struct hostapd_data *hapd, const char *type, const u8 *addr, int rssi)
 | 
			
		||||
{
 | 
			
		||||
	if (!hapd->ubus.obj.has_subscribers)
 | 
			
		||||
		return;
 | 
			
		||||
 | 
			
		||||
	if (!addr)
 | 
			
		||||
		return;
 | 
			
		||||
 | 
			
		||||
	blob_buf_init(&b, 0);
 | 
			
		||||
	blobmsg_add_macaddr(&b, "address", addr);
 | 
			
		||||
	blobmsg_add_u32(&b, "rssi", rssi);
 | 
			
		||||
 | 
			
		||||
	ubus_notify(ctx, &hapd->ubus.obj, type, b.head, -1);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void hostapd_ubus_notify_csa(struct hostapd_data *hapd, int freq)
 | 
			
		||||
{
 | 
			
		||||
	if (!hapd->ubus.obj.has_subscribers)
 | 
			
		||||
 
 | 
			
		||||
@@ -56,6 +56,7 @@ void hostapd_ubus_notify_beacon_report(struct hostapd_data *hapd,
 | 
			
		||||
				       size_t len);
 | 
			
		||||
void hostapd_ubus_notify_radar_detected(struct hostapd_iface *iface, int frequency,
 | 
			
		||||
					int chan_width, int cf1, int cf2);
 | 
			
		||||
void hostapd_ubus_notify_rssi(struct hostapd_data *hapd, const char *type, const u8 *addr, int rssi);
 | 
			
		||||
 | 
			
		||||
void hostapd_ubus_notify_bss_transition_response(
 | 
			
		||||
	struct hostapd_data *hapd, const u8 *addr, u8 dialog_token, u8 status_code,
 | 
			
		||||
 
 | 
			
		||||
@@ -41,6 +41,8 @@ ALLWIFIBOARDS:= \
 | 
			
		||||
	edgecore-oap102 \
 | 
			
		||||
	edgecore-oap103 \
 | 
			
		||||
	edgecore-eap104 \
 | 
			
		||||
	emplus-wap385c \
 | 
			
		||||
	emplus-wap386v2 \
 | 
			
		||||
	liteon-wpx8324 \
 | 
			
		||||
	indio-um-310ax-v1 \
 | 
			
		||||
	indio-um-510axp-v1 \
 | 
			
		||||
@@ -53,6 +55,7 @@ ALLWIFIBOARDS:= \
 | 
			
		||||
	sonicfi-rap630c-311g \
 | 
			
		||||
	sonicfi-rap630w-311g \
 | 
			
		||||
	sonicfi-rap630w-312g \
 | 
			
		||||
	sonicfi-rap650c \
 | 
			
		||||
	tplink-ex227 \
 | 
			
		||||
	tplink-ex447 \
 | 
			
		||||
	yuncore-ax840 \
 | 
			
		||||
@@ -403,6 +406,8 @@ $(eval $(call generate-ath11k-wifi-package,edgecore-eap102,Edgecore EAP102))
 | 
			
		||||
$(eval $(call generate-ath11k-wifi-package,edgecore-oap102,Edgecore OAP102))
 | 
			
		||||
$(eval $(call generate-ath11k-wifi-package,edgecore-oap103,Edgecore OAP103))
 | 
			
		||||
$(eval $(call generate-ath11k-wifi-package,edgecore-eap104,Edgecore EAP104))
 | 
			
		||||
$(eval $(call generate-ath11k-wifi-package,emplus-wap385c,Emplus WAP385C))
 | 
			
		||||
$(eval $(call generate-ath11k-wifi-package,emplus-wap386v2,Emplus WAP386 V2))
 | 
			
		||||
$(eval $(call generate-ath11k-wifi-package,liteon-wpx8324,Liteon WPX8324))
 | 
			
		||||
$(eval $(call generate-ath11k-wifi-package,indio-um-310ax-v1,Indio UM-310AX V1))
 | 
			
		||||
$(eval $(call generate-ath11k-wifi-package,indio-um-510axp-v1,Indio UM-510AXP V1))
 | 
			
		||||
@@ -410,6 +415,7 @@ $(eval $(call generate-ath11k-wifi-package,indio-um-510axm-v1,Indio UM-510AXM V1
 | 
			
		||||
$(eval $(call generate-ath11k-wifi-package,sonicfi-rap630c-311g,Sonicfi RAP630C 311G))
 | 
			
		||||
$(eval $(call generate-ath11k-wifi-package,sonicfi-rap630w-311g,Sonicfi RAP630W 311G))
 | 
			
		||||
$(eval $(call generate-ath11k-wifi-package,sonicfi-rap630w-312g,Sonicfi RAP630W 312G))
 | 
			
		||||
$(eval $(call generate-ath11k-wifi-package,sonicfi-rap650c,SonicFi RAP650C))
 | 
			
		||||
$(eval $(call generate-ath11k-wifi-package,tplink-ex227,TP-Link EX227))
 | 
			
		||||
$(eval $(call generate-ath11k-wifi-package,tplink-ex447,TP-Link EX447))
 | 
			
		||||
$(eval $(call generate-ath11k-wifi-package,yuncore-ax840,YunCore AX840))
 | 
			
		||||
 
 | 
			
		||||
										
											Binary file not shown.
										
									
								
							
										
											Binary file not shown.
										
									
								
							
							
								
								
									
										
											BIN
										
									
								
								feeds/ipq807x_v5.4/ath11k-wifi/board-emplus-wap385c.bin.IPQ5018
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										
											BIN
										
									
								
								feeds/ipq807x_v5.4/ath11k-wifi/board-emplus-wap385c.bin.IPQ5018
									
									
									
									
									
										Normal file
									
								
							
										
											Binary file not shown.
										
									
								
							
							
								
								
									
										
											BIN
										
									
								
								feeds/ipq807x_v5.4/ath11k-wifi/board-emplus-wap385c.bin.QCN6122
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										
											BIN
										
									
								
								feeds/ipq807x_v5.4/ath11k-wifi/board-emplus-wap385c.bin.QCN6122
									
									
									
									
									
										Normal file
									
								
							
										
											Binary file not shown.
										
									
								
							
							
								
								
									
										
											BIN
										
									
								
								feeds/ipq807x_v5.4/ath11k-wifi/board-sonicfi-rap650c.bin.IPQ8074
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										
											BIN
										
									
								
								feeds/ipq807x_v5.4/ath11k-wifi/board-sonicfi-rap650c.bin.IPQ8074
									
									
									
									
									
										Normal file
									
								
							
										
											Binary file not shown.
										
									
								
							@@ -18,9 +18,11 @@ start() {
 | 
			
		||||
	[ "$enabled" -gt 0 ] || return 1
 | 
			
		||||
 | 
			
		||||
	case "$board" in
 | 
			
		||||
	sonicfi,rap630c-311g|\
 | 
			
		||||
	sonicfi,rap630w-311g)
 | 
			
		||||
        service_start /usr/sbin/cooling
 | 
			
		||||
		sonicfi,rap630c-311g)
 | 
			
		||||
		service_start /usr/sbin/cooling -c /etc/cooling/sonicfi-rap630c-311g-cooling.conf
 | 
			
		||||
		;;
 | 
			
		||||
		sonicfi,rap630w-311g)
 | 
			
		||||
		service_start /usr/sbin/cooling -c /etc/cooling/sonicfi-rap630w-311g-cooling.conf
 | 
			
		||||
		;;
 | 
			
		||||
	esac
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
@@ -28,143 +28,270 @@
 | 
			
		||||
 | 
			
		||||
#define CUR_STATE_PATH "/sys/devices/virtual/thermal/cooling_device%i/cur_state"
 | 
			
		||||
#define TEMPER_PATH "/sys/devices/virtual/thermal/thermal_zone%i/temp"
 | 
			
		||||
#define CPU_FREQ_PATH "/sys/devices/system/cpu/cpu0/cpufreq/%s"
 | 
			
		||||
 | 
			
		||||
#define PATH_MAX 256
 | 
			
		||||
#define BUF_MAX 8
 | 
			
		||||
#define THERSHOLD_MAX 20
 | 
			
		||||
#define BUF_MAX 32
 | 
			
		||||
#define PHY0 0
 | 
			
		||||
#define PHY1 1
 | 
			
		||||
#define NUM_VALUES 4
 | 
			
		||||
 | 
			
		||||
int load_config_file=0;
 | 
			
		||||
 | 
			
		||||
//#define ULOG_INFO(fmt, ...) ulog(LOG_INFO, fmt, ## __VA_ARGS__)
 | 
			
		||||
 | 
			
		||||
typedef unsigned char	u8;
 | 
			
		||||
typedef unsigned long	u32;
 | 
			
		||||
 | 
			
		||||
u8 w2g_threshold_level=0;
 | 
			
		||||
u8 w5g_threshold_level=0;
 | 
			
		||||
u8 w2g_cur_temper=0;
 | 
			
		||||
u8 w5g_cur_temper=0;
 | 
			
		||||
u32 level_cpu_freq=1008000;
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
/* default value of wifi thresholds*/
 | 
			
		||||
#ifdef PLATFORM_RAP630C_311G
 | 
			
		||||
u8 level_2g_lo[4]={0, 105, 110, 115};
 | 
			
		||||
u8 level_2g_hi[4]={105, 110, 115, 120};
 | 
			
		||||
u8 level_2g_limit[4]={0, 35, 50, 70};
 | 
			
		||||
u8 level_5g_lo[4]={0, 105, 110, 115};
 | 
			
		||||
u8 level_5g_hi[4]={105, 110, 115, 120};
 | 
			
		||||
u8 level_5g_limit[4]={0, 20, 30, 50};
 | 
			
		||||
u8 level_2g_high[4]={105, 110, 115, 120};
 | 
			
		||||
u8 level_2g_low[4]={0, 105, 110, 115};
 | 
			
		||||
u8 level_2g_mitigation[4]={0, 35, 50, 70};
 | 
			
		||||
u8 level_5g_high[4]={105, 110, 115, 120};
 | 
			
		||||
u8 level_5g_low[4]={0, 105, 110, 115};
 | 
			
		||||
u8 level_5g_mitigation[4]={0, 20, 30, 50};
 | 
			
		||||
u32 level_cpu_frequency[4]={1008000, 800000, 800000, 800000};
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
#ifdef PLATFORM_RAP630W_311G
 | 
			
		||||
u8 level_2g_lo[4]={0, 105, 110, 115};
 | 
			
		||||
u8 level_2g_hi[4]={105, 110, 115, 120};
 | 
			
		||||
u8 level_2g_limit[4]={0, 20, 50, 70};
 | 
			
		||||
u8 level_5g_lo[4]={0, 105, 110, 115};
 | 
			
		||||
u8 level_5g_hi[4]={105, 110, 115, 120};
 | 
			
		||||
u8 level_5g_limit[4]={0, 20, 50, 70};
 | 
			
		||||
u8 level_2g_high[4]={105, 110, 115, 120};
 | 
			
		||||
u8 level_2g_low[4]={0, 105, 110, 115};
 | 
			
		||||
u8 level_2g_mitigation[4]={0, 20, 50, 70};
 | 
			
		||||
u8 level_5g_high[4]={105, 110, 115, 120};
 | 
			
		||||
u8 level_5g_low[4]={0, 105, 110, 115};
 | 
			
		||||
u8 level_5g_mitigation[4]={0, 20, 50, 70};
 | 
			
		||||
u32 level_cpu_frequency[4]={1008000, 800000, 800000, 800000};
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
static char *config_file = NULL;
 | 
			
		||||
char temp[4][BUF_MAX];
 | 
			
		||||
 | 
			
		||||
#define ULOG_DBG(fmt, ...) ulog(LOG_DEBUG, fmt, ## __VA_ARGS__)
 | 
			
		||||
typedef struct {
 | 
			
		||||
    int thresholds_high[NUM_VALUES];
 | 
			
		||||
    int thresholds_low[NUM_VALUES];
 | 
			
		||||
    int mitigation[NUM_VALUES];
 | 
			
		||||
    int cpu_freq[NUM_VALUES];
 | 
			
		||||
} WifiConfig;
 | 
			
		||||
 | 
			
		||||
static void write_cur_state (char *filename, int state) {
 | 
			
		||||
WifiConfig wifi2g = {0}, wifi5g = {0};
 | 
			
		||||
 | 
			
		||||
static void set_cpu_freq (int freq) {
 | 
			
		||||
	FILE * fp;
 | 
			
		||||
	char filename[PATH_MAX];
 | 
			
		||||
 | 
			
		||||
	snprintf(filename, PATH_MAX, CPU_FREQ_PATH, "scaling_governor");
 | 
			
		||||
 | 
			
		||||
	fp = fopen(filename, "w");
 | 
			
		||||
	if (!fp) {
 | 
			
		||||
		ULOG_ERR("open scaling_governor error\n");
 | 
			
		||||
	}
 | 
			
		||||
	fprintf(fp, "%s", "userspace");
 | 
			
		||||
	fclose(fp);
 | 
			
		||||
 | 
			
		||||
	snprintf(filename, PATH_MAX, CPU_FREQ_PATH, "scaling_setspeed");
 | 
			
		||||
 | 
			
		||||
	fp = fopen(filename, "w");
 | 
			
		||||
	if (!fp) {
 | 
			
		||||
		ULOG_ERR("open scaling_setspeed error\n");
 | 
			
		||||
	}
 | 
			
		||||
	fprintf(fp, "%d", freq);
 | 
			
		||||
	fclose(fp);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void parse_line(const char* line, const char* key, int* array) {
 | 
			
		||||
	char label[64];
 | 
			
		||||
	int values[NUM_VALUES];
 | 
			
		||||
	int i;
 | 
			
		||||
 | 
			
		||||
	if (sscanf(line, "%s %d %d %d %d %d", label, &values[0], &values[1], &values[2], &values[3], &values[4]) == 5) {
 | 
			
		||||
		for (i = 0; i < NUM_VALUES; ++i) {
 | 
			
		||||
			array[i] = values[i];
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
int load_config() {
 | 
			
		||||
	FILE * fp = fopen(config_file, "r");
 | 
			
		||||
	if (!fp) {
 | 
			
		||||
		ULOG_ERR("open config file error\n");
 | 
			
		||||
		return 1;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	WifiConfig* current_config = NULL;
 | 
			
		||||
	char line[256];
 | 
			
		||||
 | 
			
		||||
	while (fgets(line, sizeof(line), fp)) {
 | 
			
		||||
		if (strstr(line, "[wifi2g]")) {
 | 
			
		||||
			current_config = &wifi2g;
 | 
			
		||||
		} else if (strstr(line, "[wifi5g]")) {
 | 
			
		||||
			current_config = &wifi5g;
 | 
			
		||||
		} else if (current_config) {
 | 
			
		||||
			if (strstr(line, "thresholds_high")) {
 | 
			
		||||
				parse_line(line, "thresholds_high", current_config->thresholds_high);
 | 
			
		||||
			} else if (strstr(line, "thresholds_low")) {
 | 
			
		||||
				parse_line(line, "thresholds_low", current_config->thresholds_low);
 | 
			
		||||
			} else if (strstr(line, "mitigation")) {
 | 
			
		||||
				parse_line(line, "mitigation", current_config->mitigation);
 | 
			
		||||
			} else if (strstr(line, "CPU_freq")) {
 | 
			
		||||
				parse_line(line, "CPU_freq", current_config->cpu_freq);
 | 
			
		||||
			}
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	fclose(fp);
 | 
			
		||||
	set_cpu_freq(wifi5g.cpu_freq[0]);
 | 
			
		||||
 | 
			
		||||
	return 0;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
int load_default_config(){
 | 
			
		||||
	int i=0;
 | 
			
		||||
 | 
			
		||||
	set_cpu_freq(1008000);
 | 
			
		||||
	for (i = 0; i < NUM_VALUES; i++) {
 | 
			
		||||
		wifi2g.thresholds_high[i]=level_2g_high[i];
 | 
			
		||||
		wifi2g.thresholds_low[i]=level_2g_low[i];
 | 
			
		||||
		wifi2g.mitigation[i]=level_2g_mitigation[i];
 | 
			
		||||
		wifi2g.cpu_freq[i]=level_cpu_frequency[i];
 | 
			
		||||
		wifi5g.thresholds_high[i]=level_5g_high[i];
 | 
			
		||||
		wifi5g.thresholds_low[i]=level_5g_low[i];
 | 
			
		||||
		wifi5g.mitigation[i]=level_5g_mitigation[i];
 | 
			
		||||
		wifi5g.cpu_freq[i]=level_cpu_frequency[i];
 | 
			
		||||
	}
 | 
			
		||||
	return 0;
 | 
			
		||||
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void write_cur_state (const char *filename, int state) {
 | 
			
		||||
	FILE * fp;
 | 
			
		||||
 | 
			
		||||
	ULOG_DBG("write_cur_state filename=[%s] [%d]\n", filename, state);
 | 
			
		||||
	fp = fopen(filename, "w");
 | 
			
		||||
	if (!fp){
 | 
			
		||||
		ULOG_ERR("some kind of error write cur_state\n");
 | 
			
		||||
		ULOG_ERR("open %s file error\n",filename);
 | 
			
		||||
	}
 | 
			
		||||
	fprintf(fp, "%d", state);
 | 
			
		||||
	fclose(fp);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void read_cur_state (char *filename, char *buffer) {
 | 
			
		||||
	FILE * fp;
 | 
			
		||||
int read_cur_state(const char *filename, char *buf, size_t buffer) {
 | 
			
		||||
	FILE *fp;
 | 
			
		||||
	
 | 
			
		||||
	fp = fopen(filename, "r");
 | 
			
		||||
	if (!fp){
 | 
			
		||||
		ULOG_ERR("some kind of error write cur_state\n");
 | 
			
		||||
	if (!fp) {
 | 
			
		||||
		ULOG_ERR("open %s file error\n",filename);
 | 
			
		||||
		return -1;
 | 
			
		||||
	}
 | 
			
		||||
	if (0 == fread(buffer, sizeof(char), 3, fp)) {
 | 
			
		||||
		ULOG_ERR("some kind of error read value\n");
 | 
			
		||||
	if (!fgets(buf, buffer, fp)) {
 | 
			
		||||
		ULOG_ERR("Failed to read %s file\n", filename);
 | 
			
		||||
		fclose(fp);
 | 
			
		||||
		return -1;
 | 
			
		||||
	}
 | 
			
		||||
	fclose(fp);
 | 
			
		||||
	return 0;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
static void wifi_get_temperature() {
 | 
			
		||||
	char filename[PATH_MAX];
 | 
			
		||||
	FILE * fp;
 | 
			
		||||
	int i = 0;
 | 
			
		||||
	char buffer[BUF_MAX];
 | 
			
		||||
	int i = 0;
 | 
			
		||||
 | 
			
		||||
//	ULOG_INFO("=================================\n");
 | 
			
		||||
 | 
			
		||||
	/* read cpuinfo_cur_freq*/
 | 
			
		||||
	snprintf(filename, PATH_MAX, CPU_FREQ_PATH, "cpuinfo_cur_freq");
 | 
			
		||||
 | 
			
		||||
	memset(buffer, 0, BUF_MAX);
 | 
			
		||||
	read_cur_state(filename, buffer, sizeof(buffer));
 | 
			
		||||
//	ULOG_INFO("CPU current frequency: %s\n", buffer);
 | 
			
		||||
 | 
			
		||||
	/* get current phy cooling state*/
 | 
			
		||||
	for (i=0 ; i <= 1; i++ ) {
 | 
			
		||||
	for (i=0; i <= 1; i++) {
 | 
			
		||||
		memset(buffer, 0, BUF_MAX);
 | 
			
		||||
		snprintf(filename, PATH_MAX, CUR_STATE_PATH, i);
 | 
			
		||||
		read_cur_state(filename, buffer);
 | 
			
		||||
		ULOG_DBG("read from Phy%i cur_state is %s\n", i, buffer);
 | 
			
		||||
		read_cur_state(filename, buffer, sizeof(buffer));
 | 
			
		||||
//		ULOG_INFO("Phy%i cur_state is: %s\n", i, buffer);
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	for (i=0 ; i <= 3; i++ ) {
 | 
			
		||||
	for (i=0; i <= 3; i++) {
 | 
			
		||||
		memset(buffer, 0, BUF_MAX);
 | 
			
		||||
		snprintf(filename, PATH_MAX, TEMPER_PATH, i);
 | 
			
		||||
		fp = fopen(filename, "r");
 | 
			
		||||
		if (!fp) {
 | 
			
		||||
			ULOG_ERR("some kind of error open value\n");
 | 
			
		||||
		}
 | 
			
		||||
		memset(temp[i], 0, BUF_MAX);
 | 
			
		||||
		if (0 == fread(temp[i], sizeof(char), 3, fp)) {
 | 
			
		||||
			ULOG_ERR("some kind of error read value\n");
 | 
			
		||||
		}
 | 
			
		||||
		fclose(fp);
 | 
			
		||||
		ULOG_DBG("thermal_zone%i cur_temp is %s\n", i, temp[i]);
 | 
			
		||||
		read_cur_state(filename, buffer, sizeof(buffer));
 | 
			
		||||
//		ULOG_INFO("thermal_zone%i cur_temp is: %s\n", i, buffer);
 | 
			
		||||
 | 
			
		||||
		if (i == 0)
 | 
			
		||||
			w2g_cur_temper=atoi(buffer);
 | 
			
		||||
		else if (i == 3)
 | 
			
		||||
			w5g_cur_temper=atoi(buffer);
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	w2g_cur_temper=atoi(temp[0]);
 | 
			
		||||
	w5g_cur_temper=atoi(temp[3]);
 | 
			
		||||
	if (w5g_cur_temper >= 120)
 | 
			
		||||
	{
 | 
			
		||||
		ULOG_ERR("!! Temperature is over %d degree, system will reboot\n", w5g_cur_temper);
 | 
			
		||||
		sync();
 | 
			
		||||
		if ( -1 != system("reboot &") ){
 | 
			
		||||
			printf("sysyem reboot...\n");
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void wifi_set_cooling() {
 | 
			
		||||
	char filename[PATH_MAX];
 | 
			
		||||
	int level;
 | 
			
		||||
 | 
			
		||||
	for (level=0 ; level<=3 ; level++) {
 | 
			
		||||
		if (w2g_cur_temper >= level_2g_lo[level] && w2g_cur_temper < level_2g_hi[level]) {
 | 
			
		||||
			ULOG_DBG("2G at level %d , %d degree\n" ,level, w2g_cur_temper);
 | 
			
		||||
	for (level = 0; level <= 3; level++) {
 | 
			
		||||
		if (w2g_cur_temper >= wifi2g.thresholds_low[level] && w2g_cur_temper < wifi2g.thresholds_high[level]) {
 | 
			
		||||
//			ULOG_INFO("2G at level %d , %d degree\n" ,level, w2g_cur_temper);
 | 
			
		||||
			if (w2g_threshold_level != level) {
 | 
			
		||||
				ULOG_DBG("setting 2G reduce %d percent\n" ,level_2g_limit[level]);
 | 
			
		||||
//				ULOG_INFO("setting 2G reduce %d percent\n" ,wifi2g.mitigation[level]);
 | 
			
		||||
				snprintf(filename, PATH_MAX, CUR_STATE_PATH, PHY0);
 | 
			
		||||
				write_cur_state(filename, level_2g_limit[level]);
 | 
			
		||||
				write_cur_state(filename, wifi2g.mitigation[level]);
 | 
			
		||||
				w2g_threshold_level = level;
 | 
			
		||||
			}
 | 
			
		||||
		}
 | 
			
		||||
		if (w5g_cur_temper >= level_5g_lo[level] && w5g_cur_temper < level_5g_hi[level]) {
 | 
			
		||||
			ULOG_DBG("5G at level %d , %d degree\n" ,level, w5g_cur_temper);
 | 
			
		||||
		if (w5g_cur_temper >= wifi5g.thresholds_low[level] && w5g_cur_temper < wifi5g.thresholds_high[level]) {
 | 
			
		||||
//			ULOG_INFO("5G at level %d , %d degree\n" ,level, w5g_cur_temper);
 | 
			
		||||
			if (w5g_threshold_level != level) {
 | 
			
		||||
				ULOG_DBG("setting 5G reduce %d percent\n" ,level_5g_limit[level]);
 | 
			
		||||
//				ULOG_INFO("setting 5G reduce %d percent\n" ,wifi5g.mitigation[level]);
 | 
			
		||||
				snprintf(filename, PATH_MAX, CUR_STATE_PATH, PHY1);
 | 
			
		||||
				write_cur_state(filename, level_5g_limit[level]);
 | 
			
		||||
				write_cur_state(filename, wifi5g.mitigation[level]);
 | 
			
		||||
				w5g_threshold_level = level;
 | 
			
		||||
				set_cpu_freq(wifi5g.cpu_freq[level]);
 | 
			
		||||
			}
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
static void cooling_init() {
 | 
			
		||||
	char filename[256];
 | 
			
		||||
	int i;
 | 
			
		||||
	char filename[PATH_MAX];
 | 
			
		||||
	int i,result=0;
 | 
			
		||||
 | 
			
		||||
	for (i=0 ; i <= 1; i++) {
 | 
			
		||||
		snprintf(filename, PATH_MAX, CUR_STATE_PATH, i);
 | 
			
		||||
		write_cur_state(filename, 0);
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	if(load_config_file)
 | 
			
		||||
		result = load_config();
 | 
			
		||||
 | 
			
		||||
	if (result == 1 || load_config_file == 0)
 | 
			
		||||
		load_default_config();
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void print_usage(void)
 | 
			
		||||
{
 | 
			
		||||
	printf("\nWifi-cooling daemon usage\n");
 | 
			
		||||
	printf("Optional arguments:\n");
 | 
			
		||||
	printf("  -c <file>        config file\n");
 | 
			
		||||
	printf("  -d               debug output\n");
 | 
			
		||||
	printf("  -c <file>        setting with config file\n");
 | 
			
		||||
	printf("  -d               default setting\n");
 | 
			
		||||
	printf("  -h               this usage screen\n");
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
@@ -185,17 +312,18 @@ int main(int argc, char *argv[])
 | 
			
		||||
	setpriority(PRIO_PROCESS, getpid(), -20);
 | 
			
		||||
 | 
			
		||||
	ulog_open(ULOG_STDIO | ULOG_SYSLOG, LOG_DAEMON, "cooling");
 | 
			
		||||
	ulog_threshold(LOG_INFO);
 | 
			
		||||
	ulog_threshold(LOG_ERR);
 | 
			
		||||
//	ulog_threshold(LOG_INFO);
 | 
			
		||||
 | 
			
		||||
	while ((ch = getopt(argc, argv, "c:dh")) != -1) {
 | 
			
		||||
 	while ((ch = getopt(argc, argv, "c:dh")) != -1) {
 | 
			
		||||
		switch (ch) {
 | 
			
		||||
		case 'c':
 | 
			
		||||
			printf("wifi-cooling load configuration file %s\n", optarg);
 | 
			
		||||
			config_file = optarg;
 | 
			
		||||
			load_config_file=1;
 | 
			
		||||
			break;
 | 
			
		||||
		case 'd':
 | 
			
		||||
			printf("wifi-cooling ulog_threshold set to debug level\n");
 | 
			
		||||
			ulog_threshold(LOG_DEBUG);
 | 
			
		||||
			printf("wifi-cooling set to default value\n");
 | 
			
		||||
			break;
 | 
			
		||||
		case 'h':
 | 
			
		||||
		default:
 | 
			
		||||
 
 | 
			
		||||
@@ -1,15 +1,11 @@
 | 
			
		||||
sampling 5000
 | 
			
		||||
[wifi2g]
 | 
			
		||||
thresholds_high     105         110         115         120
 | 
			
		||||
thresholds_low      0           105         110         115
 | 
			
		||||
mitigation          0           35          50          70
 | 
			
		||||
CPU_freq            1008000     800000      800000      800000
 | 
			
		||||
 | 
			
		||||
[tsens_tz_sensor1]
 | 
			
		||||
sampling 	5000
 | 
			
		||||
thresholds 			105			110			115			119			120
 | 
			
		||||
thresholds_clr 		0			100			105			110			115
 | 
			
		||||
actions 			cooling		cooling	 	cooling		cooling		shutdown
 | 
			
		||||
action_info 		0			35	 		50			70			800000
 | 
			
		||||
 | 
			
		||||
[tsens_tz_sensor4]
 | 
			
		||||
sampling 	5000
 | 
			
		||||
thresholds 			105			110			115			119			120
 | 
			
		||||
thresholds_clr 		0			100			105			110			115
 | 
			
		||||
actions 			cooling		cooling		cooling		cooling		shutdown
 | 
			
		||||
action_info 		0			20			30	 		50			800000
 | 
			
		||||
[wifi5g]
 | 
			
		||||
thresholds_high     105         110         115         120
 | 
			
		||||
thresholds_low      0           105         110         115
 | 
			
		||||
mitigation          0           20          30          50
 | 
			
		||||
CPU_freq            1008000     800000      800000      800000
 | 
			
		||||
 
 | 
			
		||||
@@ -1,15 +1,11 @@
 | 
			
		||||
sampling 5000
 | 
			
		||||
[wifi2g]
 | 
			
		||||
thresholds_high     105         110         115         120
 | 
			
		||||
thresholds_low      0           105         110         115
 | 
			
		||||
mitigation          0           20          50          70
 | 
			
		||||
CPU_freq            1008000     800000      800000      800000
 | 
			
		||||
 | 
			
		||||
[tsens_tz_sensor1]
 | 
			
		||||
sampling 	5000
 | 
			
		||||
thresholds 			105			115			119			125
 | 
			
		||||
thresholds_clr 		0			105			110			120
 | 
			
		||||
actions 			cooling		cooling	 	cooling		cooling
 | 
			
		||||
action_info 		0			20	 		50			70
 | 
			
		||||
 | 
			
		||||
[tsens_tz_sensor4]
 | 
			
		||||
sampling 	5000
 | 
			
		||||
thresholds 			105			115			119			125
 | 
			
		||||
thresholds_clr 		0			105			110			120
 | 
			
		||||
actions 			cooling		cooling		cooling		cooling
 | 
			
		||||
action_info 		0			20			50	 		70
 | 
			
		||||
[wifi5g]
 | 
			
		||||
thresholds_high     105         110         115         120
 | 
			
		||||
thresholds_low      0           105         110         115
 | 
			
		||||
mitigation          0           20          50          70
 | 
			
		||||
CPU_freq            1008000     800000      800000      800000
 | 
			
		||||
 
 | 
			
		||||
@@ -117,8 +117,6 @@ hostapd_common_add_device_config() {
 | 
			
		||||
	config_add_boolean legacy_rates
 | 
			
		||||
	config_add_int cell_density
 | 
			
		||||
	config_add_int rts_threshold
 | 
			
		||||
	config_add_int rssi_reject_assoc_rssi
 | 
			
		||||
	config_add_int rssi_ignore_probe_request
 | 
			
		||||
	config_add_int maxassoc
 | 
			
		||||
	config_add_boolean maxassoc_ignore_probe
 | 
			
		||||
 | 
			
		||||
@@ -162,7 +160,7 @@ hostapd_prepare_device_config() {
 | 
			
		||||
 | 
			
		||||
	json_get_vars country country3 country_ie beacon_int:100 dtim_period:2 doth require_mode legacy_rates \
 | 
			
		||||
		acs_chan_bias local_pwr_constraint spectrum_mgmt_required airtime_mode cell_density \
 | 
			
		||||
		rts_threshold beacon_rate rssi_reject_assoc_rssi rssi_ignore_probe_request maxassoc \
 | 
			
		||||
		rts_threshold beacon_rate maxassoc \
 | 
			
		||||
		multiple_bssid he_co_locate rnr_beacon ema acs_exclude_dfs \
 | 
			
		||||
		maxassoc_ignore_probe band
 | 
			
		||||
 | 
			
		||||
@@ -261,8 +259,6 @@ hostapd_prepare_device_config() {
 | 
			
		||||
		hostapd_add_rate brlist "$br"
 | 
			
		||||
	done
 | 
			
		||||
 | 
			
		||||
	[ -n "$rssi_reject_assoc_rssi" ] && append base_cfg "rssi_reject_assoc_rssi=$rssi_reject_assoc_rssi" "$N"
 | 
			
		||||
	[ -n "$rssi_ignore_probe_request" ] && append base_cfg "rssi_ignore_probe_request=$rssi_ignore_probe_request" "$N"
 | 
			
		||||
	[ -n "$beacon_rate" ] && append base_cfg "beacon_rate=$beacon_rate" "$N"
 | 
			
		||||
	[ -n "$rlist" ] && append base_cfg "supported_rates=$rlist" "$N"
 | 
			
		||||
	[ -n "$brlist" ] && append base_cfg "basic_rates=$brlist" "$N"
 | 
			
		||||
@@ -472,6 +468,9 @@ hostapd_common_add_bss_config() {
 | 
			
		||||
	config_add_string uci_section
 | 
			
		||||
 | 
			
		||||
	config_add_boolean dynamic_probe_resp
 | 
			
		||||
 | 
			
		||||
	config_add_int rssi_reject_assoc_rssi
 | 
			
		||||
	config_add_int rssi_ignore_probe_request
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
hostapd_set_vlan_file() {
 | 
			
		||||
@@ -725,7 +724,8 @@ hostapd_set_bss_options() {
 | 
			
		||||
		airtime_bss_weight airtime_bss_limit airtime_sta_weight \
 | 
			
		||||
		multicast_to_unicast_all proxy_arp per_sta_vif \
 | 
			
		||||
		eap_server eap_user_file ca_cert server_cert private_key private_key_passwd server_id \
 | 
			
		||||
		vendor_elements fils uci_section dynamic_probe_resp multi_psk
 | 
			
		||||
		vendor_elements fils uci_section dynamic_probe_resp multi_psk \
 | 
			
		||||
		rssi_reject_assoc_rssi rssi_ignore_probe_request
 | 
			
		||||
 | 
			
		||||
	set_default fils 0
 | 
			
		||||
	set_default isolate 0
 | 
			
		||||
@@ -780,6 +780,8 @@ hostapd_set_bss_options() {
 | 
			
		||||
	append bss_conf "uapsd_advertisement_enabled=$uapsd" "$N"
 | 
			
		||||
	append bss_conf "utf8_ssid=$utf8_ssid" "$N"
 | 
			
		||||
	append bss_conf "multi_ap=$multi_ap" "$N"
 | 
			
		||||
	[ -n "$rssi_reject_assoc_rssi" ] && append bss_conf "rssi_reject_assoc_rssi=$rssi_reject_assoc_rssi" "$N"
 | 
			
		||||
	[ -n "$rssi_ignore_probe_request" ] && append bss_conf "rssi_ignore_probe_request=$rssi_ignore_probe_request" "$N"
 | 
			
		||||
	[ -n "$vendor_elements" ] && append bss_conf "vendor_elements=$vendor_elements" "$N"
 | 
			
		||||
 | 
			
		||||
	[ "$tdls_prohibit" -gt 0 ] && append bss_conf "tdls_prohibit=$tdls_prohibit" "$N"
 | 
			
		||||
 
 | 
			
		||||
@@ -144,7 +144,7 @@ function netifd_reload() {
 | 
			
		||||
 | 
			
		||||
			push(ssid.interfaces, iface.ifname);
 | 
			
		||||
			ssid.bands[band] = iface.ifname;
 | 
			
		||||
			ssid.mpsk = config.multi_psk;
 | 
			
		||||
			ssid.mpsk = ssid?.mpsk ? true : config.multi_psk;
 | 
			
		||||
			for (let sta in iface.stations) {
 | 
			
		||||
				let stacfg = sta.config;
 | 
			
		||||
 | 
			
		||||
@@ -308,18 +308,18 @@ function sta_auth_cache(ifname, addr, idx, phrase) {
 | 
			
		||||
function auth_cb(msg) {
 | 
			
		||||
	let data = msg.data;
 | 
			
		||||
 | 
			
		||||
	if (!is_ssid_mpsk(data.iface))
 | 
			
		||||
		return;
 | 
			
		||||
 | 
			
		||||
	printf(`Event ${msg.type}: ${msg.data}\n`);
 | 
			
		||||
	switch (msg.type) {
 | 
			
		||||
	case 'sta_auth':
 | 
			
		||||
		if (!is_ssid_mpsk(data.iface))
 | 
			
		||||
			return;
 | 
			
		||||
 | 
			
		||||
		return {
 | 
			
		||||
			psk: sta_auth_psk(data.iface, data.sta),
 | 
			
		||||
			force_psk: true,
 | 
			
		||||
		};
 | 
			
		||||
	case 'sta_connected':
 | 
			
		||||
		if (data.psk_idx == null)
 | 
			
		||||
		if (data.psk_idx == null || !is_ssid_mpsk(data.iface))
 | 
			
		||||
			return;
 | 
			
		||||
		return sta_auth_cache(data.iface, data.sta, data.psk_idx, data.psk);
 | 
			
		||||
	case 'reload':
 | 
			
		||||
 
 | 
			
		||||
@@ -0,0 +1,27 @@
 | 
			
		||||
--- a/src/ap/hostapd.c
 | 
			
		||||
+++ b/src/ap/hostapd.c
 | 
			
		||||
@@ -1527,19 +1527,15 @@ int hostapd_setup_bss(struct hostapd_dat
 | 
			
		||||
 		if (x_snoop_init(hapd)) {
 | 
			
		||||
 			wpa_printf(MSG_ERROR,
 | 
			
		||||
 				   "Generic snooping infrastructure initialization failed");
 | 
			
		||||
-			return -1;
 | 
			
		||||
-		}
 | 
			
		||||
-
 | 
			
		||||
-		if (dhcp_snoop_init(hapd)) {
 | 
			
		||||
+			conf->proxy_arp = 0;
 | 
			
		||||
+		} else if (dhcp_snoop_init(hapd)) {
 | 
			
		||||
 			wpa_printf(MSG_ERROR,
 | 
			
		||||
 				   "DHCP snooping initialization failed");
 | 
			
		||||
-			return -1;
 | 
			
		||||
-		}
 | 
			
		||||
-
 | 
			
		||||
-		if (ndisc_snoop_init(hapd)) {
 | 
			
		||||
+			conf->proxy_arp = 0;
 | 
			
		||||
+		} else if (ndisc_snoop_init(hapd)) {
 | 
			
		||||
 			wpa_printf(MSG_ERROR,
 | 
			
		||||
 				   "Neighbor Discovery snooping initialization failed");
 | 
			
		||||
-			return -1;
 | 
			
		||||
+			conf->proxy_arp = 0;
 | 
			
		||||
 		}
 | 
			
		||||
 	}
 | 
			
		||||
 
 | 
			
		||||
@@ -0,0 +1,411 @@
 | 
			
		||||
From: Jouni Malinen <quic_jouni@quicinc.com>
 | 
			
		||||
Date: Tue, 14 Feb 2023 11:29:30 +0200
 | 
			
		||||
Subject: [PATCH] FT: Store PMK-R0/PMK-R1 after EAPOL-Key msg 2/4 MIC
 | 
			
		||||
 validation
 | 
			
		||||
 | 
			
		||||
hostapd was previously storing the derived PMK-R0 and PMK-R1 as soon as
 | 
			
		||||
these keys were derived. While that is fine for most purposes, it is
 | 
			
		||||
unnecessary to do that so quickly and if anything were to fail before
 | 
			
		||||
the supplicant is able to return a valid EAPOL-Key msg 2/4, there would
 | 
			
		||||
not really be any real use for the derived keys.
 | 
			
		||||
 | 
			
		||||
For the special case of FT-PSK and VLAN determination based on the
 | 
			
		||||
wpa_psk file, the VLAN information is set in the per-STA data structures
 | 
			
		||||
only after the EAPOL-Key msg 2/4 MIC has been verified. This ended up
 | 
			
		||||
storing the PMK-R0/PMK-R1 entries without correct VLAN assignment and as
 | 
			
		||||
such, any use of the FT protocol would not be able to transfer the VLAN
 | 
			
		||||
information through RRB.
 | 
			
		||||
 | 
			
		||||
Split local storing of the FT key hierarchy for the cases using the FT
 | 
			
		||||
4-way handshake so that PMK-R0 and PMK-R1 are first derived and then
 | 
			
		||||
stored as a separate step after having verified the MIC in the EAPOL-Key
 | 
			
		||||
msg 2/4 (i.e., after having confirmed the per-STA passphrase/PSK was
 | 
			
		||||
selected) and VLAN update. This fixes VLAN information for the
 | 
			
		||||
wpa_psk_file cases with FT-PSK.
 | 
			
		||||
 | 
			
		||||
Signed-off-by: Jouni Malinen <quic_jouni@quicinc.com>
 | 
			
		||||
---
 | 
			
		||||
 | 
			
		||||
--- a/src/ap/wpa_auth.c
 | 
			
		||||
+++ b/src/ap/wpa_auth.c
 | 
			
		||||
@@ -58,7 +58,9 @@ static int wpa_group_config_group_keys(s
 | 
			
		||||
 				       struct wpa_group *group);
 | 
			
		||||
 static int wpa_derive_ptk(struct wpa_state_machine *sm, const u8 *snonce,
 | 
			
		||||
 			  const u8 *pmk, unsigned int pmk_len,
 | 
			
		||||
-			  struct wpa_ptk *ptk, int force_sha256);
 | 
			
		||||
+			  struct wpa_ptk *ptk, int force_sha256,
 | 
			
		||||
+			  u8 *pmk_r0, u8 *pmk_r1, u8 *pmk_r0_name,
 | 
			
		||||
+			  size_t *key_len);
 | 
			
		||||
 static void wpa_group_free(struct wpa_authenticator *wpa_auth,
 | 
			
		||||
 			   struct wpa_group *group);
 | 
			
		||||
 static void wpa_group_get(struct wpa_authenticator *wpa_auth,
 | 
			
		||||
@@ -940,6 +942,10 @@ static int wpa_try_alt_snonce(struct wpa
 | 
			
		||||
 	const u8 *pmk = NULL;
 | 
			
		||||
 	size_t pmk_len;
 | 
			
		||||
 	int vlan_id = 0;
 | 
			
		||||
+	u8 pmk_r0[PMK_LEN_MAX], pmk_r0_name[WPA_PMK_NAME_LEN];
 | 
			
		||||
+	u8 pmk_r1[PMK_LEN_MAX];
 | 
			
		||||
+	size_t key_len;
 | 
			
		||||
+	int ret = -1;
 | 
			
		||||
 
 | 
			
		||||
 	os_memset(&PTK, 0, sizeof(PTK));
 | 
			
		||||
 	for (;;) {
 | 
			
		||||
@@ -961,8 +967,8 @@ static int wpa_try_alt_snonce(struct wpa
 | 
			
		||||
 			pmk_len = sm->pmk_len;
 | 
			
		||||
 		}
 | 
			
		||||
 
 | 
			
		||||
-		if (wpa_derive_ptk(sm, sm->alt_SNonce, pmk, pmk_len, &PTK, 0) <
 | 
			
		||||
-		    0)
 | 
			
		||||
+		if (wpa_derive_ptk(sm, sm->alt_SNonce, pmk, pmk_len, &PTK, 0,
 | 
			
		||||
+				   pmk_r0, pmk_r1, pmk_r0_name, &key_len) < 0)
 | 
			
		||||
 			break;
 | 
			
		||||
 
 | 
			
		||||
 		if (wpa_verify_key_mic(sm->wpa_key_mgmt, pmk_len, &PTK,
 | 
			
		||||
@@ -983,7 +989,7 @@ static int wpa_try_alt_snonce(struct wpa
 | 
			
		||||
 	if (!ok) {
 | 
			
		||||
 		wpa_printf(MSG_DEBUG,
 | 
			
		||||
 			   "WPA: Earlier SNonce did not result in matching MIC");
 | 
			
		||||
-		return -1;
 | 
			
		||||
+		goto fail;
 | 
			
		||||
 	}
 | 
			
		||||
 
 | 
			
		||||
 	wpa_printf(MSG_DEBUG,
 | 
			
		||||
@@ -992,14 +998,26 @@ static int wpa_try_alt_snonce(struct wpa
 | 
			
		||||
 
 | 
			
		||||
 	if (vlan_id && wpa_key_mgmt_wpa_psk(sm->wpa_key_mgmt) &&
 | 
			
		||||
 	    wpa_auth_update_vlan(sm->wpa_auth, sm->addr, vlan_id) < 0)
 | 
			
		||||
-		return -1;
 | 
			
		||||
+		goto fail;
 | 
			
		||||
+
 | 
			
		||||
+#ifdef CONFIG_IEEE80211R_AP
 | 
			
		||||
+	if (wpa_key_mgmt_ft(sm->wpa_key_mgmt) && !sm->ft_completed) {
 | 
			
		||||
+		wpa_printf(MSG_DEBUG, "FT: Store PMK-R0/PMK-R1");
 | 
			
		||||
+		wpa_auth_ft_store_keys(sm, pmk_r0, pmk_r1, pmk_r0_name,
 | 
			
		||||
+				       key_len);
 | 
			
		||||
+	}
 | 
			
		||||
+#endif /* CONFIG_IEEE80211R_AP */
 | 
			
		||||
 
 | 
			
		||||
 	os_memcpy(sm->SNonce, sm->alt_SNonce, WPA_NONCE_LEN);
 | 
			
		||||
 	os_memcpy(&sm->PTK, &PTK, sizeof(PTK));
 | 
			
		||||
 	forced_memzero(&PTK, sizeof(PTK));
 | 
			
		||||
 	sm->PTK_valid = true;
 | 
			
		||||
 
 | 
			
		||||
-	return 0;
 | 
			
		||||
+	ret = 0;
 | 
			
		||||
+fail:
 | 
			
		||||
+	forced_memzero(pmk_r0, sizeof(pmk_r0));
 | 
			
		||||
+	forced_memzero(pmk_r1, sizeof(pmk_r1));
 | 
			
		||||
+	return ret;
 | 
			
		||||
 }
 | 
			
		||||
 
 | 
			
		||||
 
 | 
			
		||||
@@ -2283,7 +2301,9 @@ SM_STATE(WPA_PTK, PTKSTART)
 | 
			
		||||
 
 | 
			
		||||
 static int wpa_derive_ptk(struct wpa_state_machine *sm, const u8 *snonce,
 | 
			
		||||
 			  const u8 *pmk, unsigned int pmk_len,
 | 
			
		||||
-			  struct wpa_ptk *ptk, int force_sha256)
 | 
			
		||||
+			  struct wpa_ptk *ptk, int force_sha256,
 | 
			
		||||
+			  u8 *pmk_r0, u8 *pmk_r1, u8 *pmk_r0_name,
 | 
			
		||||
+			  size_t *key_len)
 | 
			
		||||
 {
 | 
			
		||||
 	const u8 *z = NULL;
 | 
			
		||||
 	size_t z_len = 0, kdk_len;
 | 
			
		||||
@@ -2311,7 +2331,8 @@ static int wpa_derive_ptk(struct wpa_sta
 | 
			
		||||
 						 sm->pairwise,
 | 
			
		||||
 						 kdk_len);
 | 
			
		||||
 		}
 | 
			
		||||
-		return wpa_auth_derive_ptk_ft(sm, ptk);
 | 
			
		||||
+		return wpa_auth_derive_ptk_ft(sm, ptk, pmk_r0, pmk_r1,
 | 
			
		||||
+					      pmk_r0_name, key_len);
 | 
			
		||||
 	}
 | 
			
		||||
 #endif /* CONFIG_IEEE80211R_AP */
 | 
			
		||||
 
 | 
			
		||||
@@ -2934,6 +2955,9 @@ SM_STATE(WPA_PTK, PTKCALCNEGOTIATING)
 | 
			
		||||
 	struct wpa_eapol_ie_parse kde;
 | 
			
		||||
 	int vlan_id = 0;
 | 
			
		||||
 	int owe_ptk_workaround = !!wpa_auth->conf.owe_ptk_workaround;
 | 
			
		||||
+	u8 pmk_r0[PMK_LEN_MAX], pmk_r0_name[WPA_PMK_NAME_LEN];
 | 
			
		||||
+	u8 pmk_r1[PMK_LEN_MAX];
 | 
			
		||||
+	size_t key_len;
 | 
			
		||||
 
 | 
			
		||||
 	SM_ENTRY_MA(WPA_PTK, PTKCALCNEGOTIATING, wpa_ptk);
 | 
			
		||||
 	sm->EAPOLKeyReceived = false;
 | 
			
		||||
@@ -2972,7 +2996,8 @@ SM_STATE(WPA_PTK, PTKCALCNEGOTIATING)
 | 
			
		||||
 		}
 | 
			
		||||
 
 | 
			
		||||
 		if (wpa_derive_ptk(sm, sm->SNonce, pmk, pmk_len, &PTK,
 | 
			
		||||
-				   owe_ptk_workaround == 2) < 0)
 | 
			
		||||
+				   owe_ptk_workaround == 2, pmk_r0, pmk_r1,
 | 
			
		||||
+				   pmk_r0_name, &key_len) < 0)
 | 
			
		||||
 			break;
 | 
			
		||||
 
 | 
			
		||||
 		if (mic_len &&
 | 
			
		||||
@@ -3021,7 +3046,7 @@ SM_STATE(WPA_PTK, PTKCALCNEGOTIATING)
 | 
			
		||||
 						 sm->last_rx_eapol_key,
 | 
			
		||||
 						 sm->last_rx_eapol_key_len);
 | 
			
		||||
 		sm->waiting_radius_psk = 1;
 | 
			
		||||
-		return;
 | 
			
		||||
+		goto out;
 | 
			
		||||
 	}
 | 
			
		||||
 
 | 
			
		||||
 	if (!ok) {
 | 
			
		||||
@@ -3029,7 +3054,7 @@ SM_STATE(WPA_PTK, PTKCALCNEGOTIATING)
 | 
			
		||||
 				"invalid MIC in msg 2/4 of 4-Way Handshake");
 | 
			
		||||
 		if (psk_found)
 | 
			
		||||
 			wpa_auth_psk_failure_report(sm->wpa_auth, sm->addr);
 | 
			
		||||
-		return;
 | 
			
		||||
+		goto out;
 | 
			
		||||
 	}
 | 
			
		||||
 
 | 
			
		||||
 	/*
 | 
			
		||||
@@ -3043,12 +3068,12 @@ SM_STATE(WPA_PTK, PTKCALCNEGOTIATING)
 | 
			
		||||
 	key_data_length = WPA_GET_BE16(mic + mic_len);
 | 
			
		||||
 	if (key_data_length > sm->last_rx_eapol_key_len - sizeof(*hdr) -
 | 
			
		||||
 	    sizeof(*key) - mic_len - 2)
 | 
			
		||||
-		return;
 | 
			
		||||
+		goto out;
 | 
			
		||||
 
 | 
			
		||||
 	if (wpa_parse_kde_ies(key_data, key_data_length, &kde) < 0) {
 | 
			
		||||
 		wpa_auth_vlogger(wpa_auth, sm->addr, LOGGER_INFO,
 | 
			
		||||
 				 "received EAPOL-Key msg 2/4 with invalid Key Data contents");
 | 
			
		||||
-		return;
 | 
			
		||||
+		goto out;
 | 
			
		||||
 	}
 | 
			
		||||
 	if (kde.rsn_ie) {
 | 
			
		||||
 		eapol_key_ie = kde.rsn_ie;
 | 
			
		||||
@@ -3075,7 +3100,7 @@ SM_STATE(WPA_PTK, PTKCALCNEGOTIATING)
 | 
			
		||||
 		/* MLME-DEAUTHENTICATE.request */
 | 
			
		||||
 		wpa_sta_disconnect(wpa_auth, sm->addr,
 | 
			
		||||
 				   WLAN_REASON_PREV_AUTH_NOT_VALID);
 | 
			
		||||
-		return;
 | 
			
		||||
+		goto out;
 | 
			
		||||
 	}
 | 
			
		||||
 	if ((!sm->rsnxe && kde.rsnxe) ||
 | 
			
		||||
 	    (sm->rsnxe && !kde.rsnxe) ||
 | 
			
		||||
@@ -3091,7 +3116,7 @@ SM_STATE(WPA_PTK, PTKCALCNEGOTIATING)
 | 
			
		||||
 		/* MLME-DEAUTHENTICATE.request */
 | 
			
		||||
 		wpa_sta_disconnect(wpa_auth, sm->addr,
 | 
			
		||||
 				   WLAN_REASON_PREV_AUTH_NOT_VALID);
 | 
			
		||||
-		return;
 | 
			
		||||
+		goto out;
 | 
			
		||||
 	}
 | 
			
		||||
 #ifdef CONFIG_OCV
 | 
			
		||||
 	if (wpa_auth_uses_ocv(sm)) {
 | 
			
		||||
@@ -3103,14 +3128,14 @@ SM_STATE(WPA_PTK, PTKCALCNEGOTIATING)
 | 
			
		||||
 		if (wpa_channel_info(wpa_auth, &ci) != 0) {
 | 
			
		||||
 			wpa_auth_logger(wpa_auth, sm->addr, LOGGER_INFO,
 | 
			
		||||
 					"Failed to get channel info to validate received OCI in EAPOL-Key 2/4");
 | 
			
		||||
-			return;
 | 
			
		||||
+			goto out;
 | 
			
		||||
 		}
 | 
			
		||||
 
 | 
			
		||||
 		if (get_sta_tx_parameters(sm,
 | 
			
		||||
 					  channel_width_to_int(ci.chanwidth),
 | 
			
		||||
 					  ci.seg1_idx, &tx_chanwidth,
 | 
			
		||||
 					  &tx_seg1_idx) < 0)
 | 
			
		||||
-			return;
 | 
			
		||||
+			goto out;
 | 
			
		||||
 
 | 
			
		||||
 		res = ocv_verify_tx_params(kde.oci, kde.oci_len, &ci,
 | 
			
		||||
 					   tx_chanwidth, tx_seg1_idx);
 | 
			
		||||
@@ -3127,7 +3152,7 @@ SM_STATE(WPA_PTK, PTKCALCNEGOTIATING)
 | 
			
		||||
 					OCV_FAILURE "addr=" MACSTR
 | 
			
		||||
 					" frame=eapol-key-m2 error=%s",
 | 
			
		||||
 					MAC2STR(sm->addr), ocv_errorstr);
 | 
			
		||||
-			return;
 | 
			
		||||
+			goto out;
 | 
			
		||||
 		}
 | 
			
		||||
 	}
 | 
			
		||||
 #endif /* CONFIG_OCV */
 | 
			
		||||
@@ -3135,7 +3160,7 @@ SM_STATE(WPA_PTK, PTKCALCNEGOTIATING)
 | 
			
		||||
 	if (ft && ft_check_msg_2_of_4(wpa_auth, sm, &kde) < 0) {
 | 
			
		||||
 		wpa_sta_disconnect(wpa_auth, sm->addr,
 | 
			
		||||
 				   WLAN_REASON_PREV_AUTH_NOT_VALID);
 | 
			
		||||
-		return;
 | 
			
		||||
+		goto out;
 | 
			
		||||
 	}
 | 
			
		||||
 #endif /* CONFIG_IEEE80211R_AP */
 | 
			
		||||
 #ifdef CONFIG_P2P
 | 
			
		||||
@@ -3171,7 +3196,7 @@ SM_STATE(WPA_PTK, PTKCALCNEGOTIATING)
 | 
			
		||||
 				   "DPP: Peer indicated it supports PFS and local configuration allows this, but PFS was not negotiated for the association");
 | 
			
		||||
 			wpa_sta_disconnect(wpa_auth, sm->addr,
 | 
			
		||||
 					   WLAN_REASON_PREV_AUTH_NOT_VALID);
 | 
			
		||||
-			return;
 | 
			
		||||
+			goto out;
 | 
			
		||||
 		}
 | 
			
		||||
 	}
 | 
			
		||||
 #endif /* CONFIG_DPP2 */
 | 
			
		||||
@@ -3191,7 +3216,7 @@ SM_STATE(WPA_PTK, PTKCALCNEGOTIATING)
 | 
			
		||||
 				    sm->sup_pmk_r1_name, WPA_PMK_NAME_LEN);
 | 
			
		||||
 			wpa_hexdump(MSG_DEBUG, "FT: Derived PMKR1Name",
 | 
			
		||||
 				    sm->pmk_r1_name, WPA_PMK_NAME_LEN);
 | 
			
		||||
-			return;
 | 
			
		||||
+			goto out;
 | 
			
		||||
 		}
 | 
			
		||||
 	}
 | 
			
		||||
 #endif /* CONFIG_IEEE80211R_AP */
 | 
			
		||||
@@ -3200,7 +3225,7 @@ SM_STATE(WPA_PTK, PTKCALCNEGOTIATING)
 | 
			
		||||
 	    wpa_auth_update_vlan(wpa_auth, sm->addr, vlan_id) < 0) {
 | 
			
		||||
 		wpa_sta_disconnect(wpa_auth, sm->addr,
 | 
			
		||||
 				   WLAN_REASON_PREV_AUTH_NOT_VALID);
 | 
			
		||||
-		return;
 | 
			
		||||
+		goto out;
 | 
			
		||||
 	}
 | 
			
		||||
 
 | 
			
		||||
 	sm->pending_1_of_4_timeout = 0;
 | 
			
		||||
@@ -3216,9 +3241,20 @@ SM_STATE(WPA_PTK, PTKCALCNEGOTIATING)
 | 
			
		||||
 
 | 
			
		||||
 	sm->MICVerified = true;
 | 
			
		||||
 
 | 
			
		||||
+#ifdef CONFIG_IEEE80211R_AP
 | 
			
		||||
+	if (wpa_key_mgmt_ft(sm->wpa_key_mgmt) && !sm->ft_completed) {
 | 
			
		||||
+		wpa_printf(MSG_DEBUG, "FT: Store PMK-R0/PMK-R1");
 | 
			
		||||
+		wpa_auth_ft_store_keys(sm, pmk_r0, pmk_r1, pmk_r0_name,
 | 
			
		||||
+				       key_len);
 | 
			
		||||
+	}
 | 
			
		||||
+#endif /* CONFIG_IEEE80211R_AP */
 | 
			
		||||
+
 | 
			
		||||
 	os_memcpy(&sm->PTK, &PTK, sizeof(PTK));
 | 
			
		||||
 	forced_memzero(&PTK, sizeof(PTK));
 | 
			
		||||
 	sm->PTK_valid = true;
 | 
			
		||||
+out:
 | 
			
		||||
+	forced_memzero(pmk_r0, sizeof(pmk_r0));
 | 
			
		||||
+	forced_memzero(pmk_r1, sizeof(pmk_r1));
 | 
			
		||||
 }
 | 
			
		||||
 
 | 
			
		||||
 
 | 
			
		||||
--- a/src/ap/wpa_auth_ft.c
 | 
			
		||||
+++ b/src/ap/wpa_auth_ft.c
 | 
			
		||||
@@ -2175,13 +2175,13 @@ int wpa_ft_store_pmk_fils(struct wpa_sta
 | 
			
		||||
 }
 | 
			
		||||
 
 | 
			
		||||
 
 | 
			
		||||
-int wpa_auth_derive_ptk_ft(struct wpa_state_machine *sm, struct wpa_ptk *ptk)
 | 
			
		||||
+int wpa_auth_derive_ptk_ft(struct wpa_state_machine *sm, struct wpa_ptk *ptk,
 | 
			
		||||
+			   u8 *pmk_r0, u8 *pmk_r1, u8 *pmk_r0_name,
 | 
			
		||||
+			   size_t *key_len)
 | 
			
		||||
 {
 | 
			
		||||
-	u8 pmk_r0[PMK_LEN_MAX], pmk_r0_name[WPA_PMK_NAME_LEN];
 | 
			
		||||
 	size_t pmk_r0_len = wpa_key_mgmt_sha384(sm->wpa_key_mgmt) ?
 | 
			
		||||
 		SHA384_MAC_LEN : PMK_LEN;
 | 
			
		||||
 	size_t pmk_r1_len = pmk_r0_len;
 | 
			
		||||
-	u8 pmk_r1[PMK_LEN_MAX];
 | 
			
		||||
 	u8 ptk_name[WPA_PMK_NAME_LEN];
 | 
			
		||||
 	const u8 *mdid = sm->wpa_auth->conf.mobility_domain;
 | 
			
		||||
 	const u8 *r0kh = sm->wpa_auth->conf.r0_key_holder;
 | 
			
		||||
@@ -2189,13 +2189,6 @@ int wpa_auth_derive_ptk_ft(struct wpa_st
 | 
			
		||||
 	const u8 *r1kh = sm->wpa_auth->conf.r1_key_holder;
 | 
			
		||||
 	const u8 *ssid = sm->wpa_auth->conf.ssid;
 | 
			
		||||
 	size_t ssid_len = sm->wpa_auth->conf.ssid_len;
 | 
			
		||||
-	int psk_local = sm->wpa_auth->conf.ft_psk_generate_local;
 | 
			
		||||
-	int expires_in = sm->wpa_auth->conf.r0_key_lifetime;
 | 
			
		||||
-	struct vlan_description vlan;
 | 
			
		||||
-	struct rate_description rate;
 | 
			
		||||
-	const u8 *identity, *radius_cui;
 | 
			
		||||
-	size_t identity_len, radius_cui_len;
 | 
			
		||||
-	int session_timeout;
 | 
			
		||||
 	const u8 *mpmk;
 | 
			
		||||
 	size_t mpmk_len;
 | 
			
		||||
 
 | 
			
		||||
@@ -2211,10 +2204,41 @@ int wpa_auth_derive_ptk_ft(struct wpa_st
 | 
			
		||||
 		return -1;
 | 
			
		||||
 	}
 | 
			
		||||
 
 | 
			
		||||
+	*key_len = pmk_r0_len;
 | 
			
		||||
+	if (wpa_derive_pmk_r0(mpmk, mpmk_len, ssid, ssid_len, mdid,
 | 
			
		||||
+			      r0kh, r0kh_len, sm->addr,
 | 
			
		||||
+			      pmk_r0, pmk_r0_name,
 | 
			
		||||
+			      pmk_r0_len == SHA384_MAC_LEN) < 0 ||
 | 
			
		||||
+	    wpa_derive_pmk_r1(pmk_r0, pmk_r0_len, pmk_r0_name, r1kh, sm->addr,
 | 
			
		||||
+			      pmk_r1, sm->pmk_r1_name) < 0)
 | 
			
		||||
+		return -1;
 | 
			
		||||
+
 | 
			
		||||
+	return wpa_pmk_r1_to_ptk(pmk_r1, pmk_r1_len, sm->SNonce, sm->ANonce,
 | 
			
		||||
+				 sm->addr, sm->wpa_auth->addr, sm->pmk_r1_name,
 | 
			
		||||
+				 ptk, ptk_name, sm->wpa_key_mgmt, sm->pairwise,
 | 
			
		||||
+				 0);
 | 
			
		||||
+}
 | 
			
		||||
+
 | 
			
		||||
+
 | 
			
		||||
+void wpa_auth_ft_store_keys(struct wpa_state_machine *sm, const u8 *pmk_r0,
 | 
			
		||||
+			    const u8 *pmk_r1, const u8 *pmk_r0_name,
 | 
			
		||||
+			    size_t key_len)
 | 
			
		||||
+{
 | 
			
		||||
+	int psk_local = sm->wpa_auth->conf.ft_psk_generate_local;
 | 
			
		||||
+	int expires_in = sm->wpa_auth->conf.r0_key_lifetime;
 | 
			
		||||
+	struct vlan_description vlan;
 | 
			
		||||
+	struct rate_description rate;
 | 
			
		||||
+	const u8 *identity, *radius_cui;
 | 
			
		||||
+	size_t identity_len, radius_cui_len;
 | 
			
		||||
+	int session_timeout;
 | 
			
		||||
+
 | 
			
		||||
+	if (psk_local && wpa_key_mgmt_ft_psk(sm->wpa_key_mgmt))
 | 
			
		||||
+		return;
 | 
			
		||||
+
 | 
			
		||||
 	if (wpa_ft_get_vlan(sm->wpa_auth, sm->addr, &vlan) < 0) {
 | 
			
		||||
 		wpa_printf(MSG_DEBUG, "FT: vlan not available for STA " MACSTR,
 | 
			
		||||
 			   MAC2STR(sm->addr));
 | 
			
		||||
-		return -1;
 | 
			
		||||
+		return;
 | 
			
		||||
 	}
 | 
			
		||||
 
 | 
			
		||||
 	wpa_ft_get_rate_limit(sm->wpa_auth, sm->addr, &rate);
 | 
			
		||||
@@ -2224,32 +2248,16 @@ int wpa_auth_derive_ptk_ft(struct wpa_st
 | 
			
		||||
 					       &radius_cui);
 | 
			
		||||
 	session_timeout = wpa_ft_get_session_timeout(sm->wpa_auth, sm->addr);
 | 
			
		||||
 
 | 
			
		||||
-	if (wpa_derive_pmk_r0(mpmk, mpmk_len, ssid, ssid_len, mdid,
 | 
			
		||||
-			      r0kh, r0kh_len, sm->addr,
 | 
			
		||||
-			      pmk_r0, pmk_r0_name,
 | 
			
		||||
-			      wpa_key_mgmt_sha384(sm->wpa_key_mgmt)) < 0)
 | 
			
		||||
-		return -1;
 | 
			
		||||
-	if (!psk_local || !wpa_key_mgmt_ft_psk(sm->wpa_key_mgmt))
 | 
			
		||||
-		wpa_ft_store_pmk_r0(sm->wpa_auth, sm->addr, pmk_r0, pmk_r0_len,
 | 
			
		||||
-				    pmk_r0_name,
 | 
			
		||||
-				    sm->pairwise, &vlan, expires_in,
 | 
			
		||||
-				    session_timeout, identity, identity_len,
 | 
			
		||||
-				    radius_cui, radius_cui_len, &rate);
 | 
			
		||||
-
 | 
			
		||||
-	if (wpa_derive_pmk_r1(pmk_r0, pmk_r0_len, pmk_r0_name, r1kh, sm->addr,
 | 
			
		||||
-			      pmk_r1, sm->pmk_r1_name) < 0)
 | 
			
		||||
-		return -1;
 | 
			
		||||
-	if (!psk_local || !wpa_key_mgmt_ft_psk(sm->wpa_key_mgmt))
 | 
			
		||||
-		wpa_ft_store_pmk_r1(sm->wpa_auth, sm->addr, pmk_r1, pmk_r1_len,
 | 
			
		||||
-				    sm->pmk_r1_name, sm->pairwise, &vlan,
 | 
			
		||||
-				    expires_in, session_timeout, identity,
 | 
			
		||||
-				    identity_len, radius_cui, radius_cui_len,
 | 
			
		||||
-				    &rate);
 | 
			
		||||
-
 | 
			
		||||
-	return wpa_pmk_r1_to_ptk(pmk_r1, pmk_r1_len, sm->SNonce, sm->ANonce,
 | 
			
		||||
-				 sm->addr, sm->wpa_auth->addr, sm->pmk_r1_name,
 | 
			
		||||
-				 ptk, ptk_name, sm->wpa_key_mgmt, sm->pairwise,
 | 
			
		||||
-				 0);
 | 
			
		||||
+	wpa_ft_store_pmk_r0(sm->wpa_auth, sm->addr, pmk_r0, key_len,
 | 
			
		||||
+			    pmk_r0_name,
 | 
			
		||||
+			    sm->pairwise, &vlan, expires_in,
 | 
			
		||||
+			    session_timeout, identity, identity_len,
 | 
			
		||||
+			    radius_cui, radius_cui_len, &rate);
 | 
			
		||||
+
 | 
			
		||||
+	wpa_ft_store_pmk_r1(sm->wpa_auth, sm->addr, pmk_r1, key_len,
 | 
			
		||||
+			    sm->pmk_r1_name, sm->pairwise, &vlan,
 | 
			
		||||
+			    expires_in, session_timeout, identity,
 | 
			
		||||
+			    identity_len, radius_cui, radius_cui_len, &rate);
 | 
			
		||||
 }
 | 
			
		||||
 
 | 
			
		||||
 
 | 
			
		||||
--- a/src/ap/wpa_auth_i.h
 | 
			
		||||
+++ b/src/ap/wpa_auth_i.h
 | 
			
		||||
@@ -302,7 +302,12 @@ int wpa_write_ftie(struct wpa_auth_confi
 | 
			
		||||
 		   const u8 *anonce, const u8 *snonce,
 | 
			
		||||
 		   u8 *buf, size_t len, const u8 *subelem,
 | 
			
		||||
 		   size_t subelem_len, int rsnxe_used);
 | 
			
		||||
-int wpa_auth_derive_ptk_ft(struct wpa_state_machine *sm, struct wpa_ptk *ptk);
 | 
			
		||||
+int wpa_auth_derive_ptk_ft(struct wpa_state_machine *sm, struct wpa_ptk *ptk,
 | 
			
		||||
+			   u8 *pmk_r0, u8 *pmk_r1, u8 *pmk_r0_name,
 | 
			
		||||
+			   size_t *key_len);
 | 
			
		||||
+void wpa_auth_ft_store_keys(struct wpa_state_machine *sm, const u8 *pmk_r0,
 | 
			
		||||
+			    const u8 *pmk_r1, const u8 *pmk_r0_name,
 | 
			
		||||
+			    size_t key_len);
 | 
			
		||||
 struct wpa_ft_pmk_cache * wpa_ft_pmk_cache_init(void);
 | 
			
		||||
 void wpa_ft_pmk_cache_deinit(struct wpa_ft_pmk_cache *cache);
 | 
			
		||||
 void wpa_ft_install_ptk(struct wpa_state_machine *sm, int retry);
 | 
			
		||||
@@ -0,0 +1,14 @@
 | 
			
		||||
--- a/src/ap/beacon.c
 | 
			
		||||
+++ b/src/ap/beacon.c
 | 
			
		||||
@@ -934,8 +934,10 @@ void handle_probe_req(struct hostapd_dat
 | 
			
		||||
 	int ubus_response;
 | 
			
		||||
 
 | 
			
		||||
 	if (hapd->iconf->rssi_ignore_probe_request && ssi_signal &&
 | 
			
		||||
-	    ssi_signal < hapd->iconf->rssi_ignore_probe_request)
 | 
			
		||||
+	    ssi_signal < hapd->iconf->rssi_ignore_probe_request) {
 | 
			
		||||
+		hostapd_ubus_notify_rssi(hapd, "rssi-ignore-probe", mgmt->sa, ssi_signal);
 | 
			
		||||
 		return;
 | 
			
		||||
+	}
 | 
			
		||||
 
 | 
			
		||||
 	if (len < IEEE80211_HDRLEN)
 | 
			
		||||
 		return;
 | 
			
		||||
@@ -1944,6 +1944,21 @@ void hostapd_ubus_notify(struct hostapd_data *hapd, const char *type, const u8 *
 | 
			
		||||
	ubus_notify(ctx, &hapd->ubus.obj, type, b.head, -1);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void hostapd_ubus_notify_rssi(struct hostapd_data *hapd, const char *type, const u8 *addr, int rssi)
 | 
			
		||||
{
 | 
			
		||||
	if (!hapd->ubus.obj.has_subscribers)
 | 
			
		||||
		return;
 | 
			
		||||
 | 
			
		||||
	if (!addr)
 | 
			
		||||
		return;
 | 
			
		||||
 | 
			
		||||
	blob_buf_init(&b, 0);
 | 
			
		||||
	blobmsg_add_macaddr(&b, "address", addr);
 | 
			
		||||
	blobmsg_add_u32(&b, "rssi", rssi);
 | 
			
		||||
 | 
			
		||||
	ubus_notify(ctx, &hapd->ubus.obj, type, b.head, -1);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void hostapd_ubus_notify_csa(struct hostapd_data *hapd, int freq)
 | 
			
		||||
{
 | 
			
		||||
	if (!hapd->ubus.obj.has_subscribers)
 | 
			
		||||
 
 | 
			
		||||
@@ -56,6 +56,7 @@ void hostapd_ubus_notify_beacon_report(struct hostapd_data *hapd,
 | 
			
		||||
				       size_t len);
 | 
			
		||||
void hostapd_ubus_notify_radar_detected(struct hostapd_iface *iface, int frequency,
 | 
			
		||||
					int chan_width, int cf1, int cf2);
 | 
			
		||||
void hostapd_ubus_notify_rssi(struct hostapd_data *hapd, const char *type, const u8 *addr, int rssi);
 | 
			
		||||
 | 
			
		||||
void hostapd_ubus_notify_bss_transition_response(
 | 
			
		||||
	struct hostapd_data *hapd, const u8 *addr, u8 dialog_token, u8 status_code,
 | 
			
		||||
 
 | 
			
		||||
@@ -40,6 +40,11 @@ edgecore,oap101e-6e)
 | 
			
		||||
	ucidef_set_led_netdev "wan" "wan" "red:ethernet" "eth1"
 | 
			
		||||
        ucidef_set_led_default "power" "POWER" "blue:management" "on"
 | 
			
		||||
	;;
 | 
			
		||||
emplus,wap385c)
 | 
			
		||||
	ucidef_set_led_default "ledr" "LEDR" "sys:red" "on"
 | 
			
		||||
	ucidef_set_led_default "ledg" "LEDG" "sys:green" "on"
 | 
			
		||||
	ucidef_set_led_default "ledb" "LEDB" "sys:blue" "on"
 | 
			
		||||
	;;
 | 
			
		||||
hfcl,ion4x_w|\
 | 
			
		||||
hfcl,ion4xi_w)
 | 
			
		||||
	ucidef_set_led_wlan "wlan5g" "WLAN5G" "blue:wifi5" "phy0tpt"
 | 
			
		||||
 
 | 
			
		||||
@@ -13,10 +13,10 @@ qcom_setup_interfaces()
 | 
			
		||||
 | 
			
		||||
	case $board in
 | 
			
		||||
	cig,wf186w)
 | 
			
		||||
		ucidef_add_switch "switch0" "4:wan" "0:lan" "1:lan" "2:lan" "3:lan" "6@eth0"
 | 
			
		||||
		ucidef_add_switch "switch0" "4:wan" "0:lan" "1:lan" "2:lan" "3:lan" "6u@eth0"
 | 
			
		||||
		;;
 | 
			
		||||
	cig,wf186h)
 | 
			
		||||
		ucidef_add_switch "switch0" "4:wan" "1:lan" "2:lan" "6@eth0"
 | 
			
		||||
		ucidef_add_switch "switch0" "4:wan" "1:lan" "2:lan" "6u@eth0"
 | 
			
		||||
		;;
 | 
			
		||||
	sonicfi,rap630c-311g|\
 | 
			
		||||
	cybertan,eww631-a1)
 | 
			
		||||
@@ -25,7 +25,7 @@ qcom_setup_interfaces()
 | 
			
		||||
		;;
 | 
			
		||||
	sonicfi,rap630w-311g|\
 | 
			
		||||
	cybertan,eww631-b1)
 | 
			
		||||
		ucidef_add_switch "switch1" "5:wan" "2:lan" "3:lan" "4:lan" "6@eth0"
 | 
			
		||||
		ucidef_add_switch "switch1" "5:wan" "2:lan" "3:lan" "4:lan" "6u@eth0"
 | 
			
		||||
		;;
 | 
			
		||||
	udaya,a6-id2)
 | 
			
		||||
		ucidef_set_interface_wan "eth1"
 | 
			
		||||
@@ -46,8 +46,9 @@ qcom_setup_interfaces()
 | 
			
		||||
	edgecore,eap104)
 | 
			
		||||
		ucidef_set_interface_wan "eth0"
 | 
			
		||||
		ucidef_add_switch "switch1" \
 | 
			
		||||
			"6@eth1" "1:lan" "2:lan" "3:lan" "4:lan"
 | 
			
		||||
			"6u@eth1" "1:lan" "2:lan" "3:lan" "4:lan"
 | 
			
		||||
		;;
 | 
			
		||||
	emplus,wap385c|\
 | 
			
		||||
	hfcl,ion4x_w|\
 | 
			
		||||
	hfcl,ion4xi_w)
 | 
			
		||||
		ucidef_set_interface_wan "eth0"
 | 
			
		||||
@@ -62,10 +63,10 @@ qcom_setup_interfaces()
 | 
			
		||||
	sonicfi,rap630w-312g|\
 | 
			
		||||
	yuncore,fap655)
 | 
			
		||||
		ucidef_add_switch "switch1" \
 | 
			
		||||
			"6@eth0" "1:lan" "2:lan" "3:lan" "4:lan" "5:wan"
 | 
			
		||||
			"6u@eth0" "1:lan" "2:lan" "3:lan" "4:lan" "5:wan"
 | 
			
		||||
		;;
 | 
			
		||||
	glinet,b3000)
 | 
			
		||||
		ucidef_add_switch "switch1" "6@eth1" "1:wan" "2:lan" "3:lan"
 | 
			
		||||
		ucidef_add_switch "switch1" "6u@eth1" "1:wan" "2:lan" "3:lan"
 | 
			
		||||
		;;
 | 
			
		||||
	esac
 | 
			
		||||
}
 | 
			
		||||
 
 | 
			
		||||
@@ -129,6 +129,7 @@ ath11k/IPQ5018/hw1.0/caldata.bin)
 | 
			
		||||
	edgecore,oap101-6e|\
 | 
			
		||||
	edgecore,oap101e|\
 | 
			
		||||
	edgecore,oap101e-6e|\
 | 
			
		||||
	emplus,wap385c|\
 | 
			
		||||
	hfcl,ion4x_w|\
 | 
			
		||||
	hfcl,ion4xi_w|\
 | 
			
		||||
	optimcloud,d60|\
 | 
			
		||||
@@ -157,6 +158,7 @@ ath11k/qcn6122/hw1.0/caldata_1.bin)
 | 
			
		||||
	edgecore,oap101-6e|\
 | 
			
		||||
	edgecore,oap101e|\
 | 
			
		||||
	edgecore,oap101e-6e|\
 | 
			
		||||
	emplus,wap385c|\
 | 
			
		||||
	udaya,a6-id2|\
 | 
			
		||||
	udaya,a6-od2|\
 | 
			
		||||
	hfcl,ion4xi_w|\
 | 
			
		||||
 
 | 
			
		||||
@@ -76,6 +76,7 @@ platform_check_image() {
 | 
			
		||||
	cybertan,eww631-a1|\
 | 
			
		||||
	cybertan,eww631-b1|\
 | 
			
		||||
	edgecore,eap104|\
 | 
			
		||||
	emplus,wap385c|\
 | 
			
		||||
	wallys,dr5018|\
 | 
			
		||||
	hfcl,ion4x_w|\
 | 
			
		||||
	hfcl,ion4xi_w|\
 | 
			
		||||
@@ -129,6 +130,7 @@ platform_do_upgrade() {
 | 
			
		||||
                ;;
 | 
			
		||||
	cig,wf186w|\
 | 
			
		||||
	cig,wf186h|\
 | 
			
		||||
	emplus,wap385c|\
 | 
			
		||||
	udaya,a6-id2|\
 | 
			
		||||
	udaya,a6-od2|\
 | 
			
		||||
	wallys,dr5018|\
 | 
			
		||||
 
 | 
			
		||||
@@ -0,0 +1,760 @@
 | 
			
		||||
/dts-v1/;
 | 
			
		||||
/* Copyright (c) 2018-2021, The Linux Foundation. All rights reserved.
 | 
			
		||||
 *
 | 
			
		||||
 * Copyright (c) 2021 Qualcomm Innovation Center, Inc. All rights reserved.
 | 
			
		||||
 *
 | 
			
		||||
 * Permission to use, copy, modify, and/or distribute this software for any
 | 
			
		||||
 * purpose with or without fee is hereby granted, provided that the above
 | 
			
		||||
 * copyright notice and this permission notice appear in all copies.
 | 
			
		||||
 *
 | 
			
		||||
 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
 | 
			
		||||
 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
 | 
			
		||||
 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
 | 
			
		||||
 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
 | 
			
		||||
 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
 | 
			
		||||
 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
 | 
			
		||||
 * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
#include "ipq5018.dtsi"
 | 
			
		||||
#include <dt-bindings/input/input.h>
 | 
			
		||||
 | 
			
		||||
/ {
 | 
			
		||||
	#address-cells = <0x2>;
 | 
			
		||||
	#size-cells = <0x2>;
 | 
			
		||||
	model = "Emplus WAP385C";
 | 
			
		||||
	compatible = "emplus,wap385c", "qcom,ipq5018-mp03.3", "qcom,ipq5018";
 | 
			
		||||
	interrupt-parent = <&intc>;
 | 
			
		||||
 | 
			
		||||
	aliases {
 | 
			
		||||
		sdhc1 = &sdhc_1; /* SDC1 eMMC slot */
 | 
			
		||||
		serial0 = &blsp1_uart1;
 | 
			
		||||
		serial1 = &blsp1_uart2;
 | 
			
		||||
		ethernet1 = "/soc/dp1";
 | 
			
		||||
 | 
			
		||||
		led-boot = &led_power;
 | 
			
		||||
		led-failsafe = &led_power;
 | 
			
		||||
		led-running = &led_power;
 | 
			
		||||
		led-upgrade = &led_power;
 | 
			
		||||
	};
 | 
			
		||||
 | 
			
		||||
	chosen {
 | 
			
		||||
		bootargs = "console=ttyMSM0,115200,n8 rw init=/init";
 | 
			
		||||
		bootargs-append = " swiotlb=1 coherent_pool=2M";
 | 
			
		||||
		stdout-path = "serial0";
 | 
			
		||||
	};
 | 
			
		||||
 | 
			
		||||
	reserved-memory {
 | 
			
		||||
	#ifdef __IPQ_MEM_PROFILE_256_MB__
 | 
			
		||||
	/*		   256 MB Profile
 | 
			
		||||
	 * +==========+==============+=========================+
 | 
			
		||||
	 * |	  |	      |			 |
 | 
			
		||||
	 * |  Region  | Start Offset |	  Size	   |
 | 
			
		||||
	 * |	  |	      |			 |
 | 
			
		||||
	 * +----------+--------------+-------------------------+
 | 
			
		||||
	 * |    NSS   |  0x40000000  |	   8MB	   |
 | 
			
		||||
	 * +----------+--------------+-------------------------+
 | 
			
		||||
	 * |   Linux  |  0x40800000  | Depends on total memory |
 | 
			
		||||
	 * +----------+--------------+-------------------------+
 | 
			
		||||
	 * |   uboot  |  0x4A600000  |	   4MB	   |
 | 
			
		||||
	 * +----------+--------------+-------------------------+
 | 
			
		||||
	 * |    SBL   |  0x4AA00000  |	   1MB	   |
 | 
			
		||||
	 * +----------+--------------+-------------------------+
 | 
			
		||||
	 * |   smem   |  0x4AB00000  |	   1MB	   |
 | 
			
		||||
	 * +----------+--------------+-------------------------+
 | 
			
		||||
	 * |    TZ    |  0x4AC00000  |	   4MB	   |
 | 
			
		||||
	 * +----------+--------------+-------------------------+
 | 
			
		||||
	 * |    Q6    |	      |			 |
 | 
			
		||||
	 * |   code/  |  0x4B000000  |	  20MB	   |
 | 
			
		||||
	 * |   data   |	      |			 |
 | 
			
		||||
	 * +----------+--------------+-------------------------+
 | 
			
		||||
	 * |  IPQ5018 |	      |			 |
 | 
			
		||||
	 * |   data   |  0x4C400000  |	  13MB	   |
 | 
			
		||||
	 * +----------+--------------+-------------------------+
 | 
			
		||||
	 * |  IPQ5018 |	      |			 |
 | 
			
		||||
	 * |  M3 Dump |  0x4D100000  |	   1MB	   |
 | 
			
		||||
	 * +----------+--------------+-------------------------+
 | 
			
		||||
	 * |  IPQ5018 |	      |			 |
 | 
			
		||||
	 * |   QDSS   |  0x4D200000  |	   1MB	   |
 | 
			
		||||
	 * +----------+--------------+-------------------------+
 | 
			
		||||
	 * | QCN6122_1|	      |			 |
 | 
			
		||||
	 * |   data   |  0x4D300000  |	  13MB	   |
 | 
			
		||||
	 * +----------+--------------+-------------------------+
 | 
			
		||||
	 * | QCN6122_1|	      |			 |
 | 
			
		||||
	 * |  M3 Dump |  0x4E000000  |	   1MB	   |
 | 
			
		||||
	 * +----------+--------------+-------------------------+
 | 
			
		||||
	 * | QCN6122_1|	      |			 |
 | 
			
		||||
	 * |   QDSS   |  0x4E100000  |	   1MB	   |
 | 
			
		||||
	 * +----------+--------------+-------------------------+
 | 
			
		||||
	 * | QCN6122_2|	      |			 |
 | 
			
		||||
	 * |   data   |  0x4E200000  |	  13MB	   |
 | 
			
		||||
	 * +----------+--------------+-------------------------+
 | 
			
		||||
	 * | QCN6122_2|	      |			 |
 | 
			
		||||
	 * |  M3 Dump |  0x4EF00000  |	   1MB	   |
 | 
			
		||||
	 * +----------+--------------+-------------------------+
 | 
			
		||||
	 * | QCN6122_2|	      |			 |
 | 
			
		||||
	 * |   QDSS   |  0x4F000000  |	   1MB	   |
 | 
			
		||||
	 * +----------+--------------+-------------------------+
 | 
			
		||||
	 * |						   |
 | 
			
		||||
	 * |	    Rest of the memory for Linux	   |
 | 
			
		||||
	 * |						   |
 | 
			
		||||
	 * +===================================================+
 | 
			
		||||
	 */
 | 
			
		||||
		q6_mem_regions: q6_mem_regions@4B000000 {
 | 
			
		||||
			no-map;
 | 
			
		||||
			reg = <0x0 0x4B000000 0x0 0x4100000>;
 | 
			
		||||
		};
 | 
			
		||||
 | 
			
		||||
		q6_code_data: q6_code_data@4B000000 {
 | 
			
		||||
			no-map;
 | 
			
		||||
			reg = <0x0 0x4B000000 0x0 0x1400000>;
 | 
			
		||||
		};
 | 
			
		||||
 | 
			
		||||
		q6_ipq5018_data: q6_ipq5018_data@4C400000 {
 | 
			
		||||
			no-map;
 | 
			
		||||
			reg = <0x0 0x4C400000 0x0 0xD00000>;
 | 
			
		||||
		};
 | 
			
		||||
 | 
			
		||||
		m3_dump: m3_dump@4D100000 {
 | 
			
		||||
			no-map;
 | 
			
		||||
			reg = <0x0 0x4D100000 0x0 0x100000>;
 | 
			
		||||
		};
 | 
			
		||||
 | 
			
		||||
		q6_etr_region: q6_etr_dump@4D200000 {
 | 
			
		||||
			no-map;
 | 
			
		||||
			reg = <0x0 0x4D200000 0x0 0x100000>;
 | 
			
		||||
		};
 | 
			
		||||
 | 
			
		||||
		q6_qcn6122_data1: q6_qcn6122_data1@4D300000 {
 | 
			
		||||
			no-map;
 | 
			
		||||
			reg = <0x0 0x4D300000 0x0 0xD00000>;
 | 
			
		||||
		};
 | 
			
		||||
 | 
			
		||||
		m3_dump_qcn6122_1: m3_dump_qcn6122_1@4E000000 {
 | 
			
		||||
			no-map;
 | 
			
		||||
			reg = <0x0 0x4E000000 0x0 0x100000>;
 | 
			
		||||
		};
 | 
			
		||||
 | 
			
		||||
		q6_qcn6122_etr_1: q6_qcn6122_etr_1@4E100000 {
 | 
			
		||||
			no-map;
 | 
			
		||||
			reg = <0x0 0x4E100000 0x0 0x100000>;
 | 
			
		||||
		};
 | 
			
		||||
 | 
			
		||||
		q6_qcn6122_data2: q6_qcn6122_data2@4E200000 {
 | 
			
		||||
			no-map;
 | 
			
		||||
			reg = <0x0 0x4E200000 0x0 0xD00000>;
 | 
			
		||||
		};
 | 
			
		||||
 | 
			
		||||
		m3_dump_qcn6122_2: m3_dump_qcn6122_2@4EF00000 {
 | 
			
		||||
			no-map;
 | 
			
		||||
			reg = <0x0 0x4EF00000 0x0 0x100000>;
 | 
			
		||||
		};
 | 
			
		||||
 | 
			
		||||
		q6_qcn6122_etr_2: q6_qcn6122_etr_2@4F000000 {
 | 
			
		||||
			no-map;
 | 
			
		||||
			reg = <0x0 0x4F000000 0x0 0x100000>;
 | 
			
		||||
		};
 | 
			
		||||
	#else
 | 
			
		||||
	/*		 512MB/1GB Profiles
 | 
			
		||||
	 * +==========+==============+=========================+
 | 
			
		||||
	 * |	  |	      |			 |
 | 
			
		||||
	 * |  Region  | Start Offset |	  Size	   |
 | 
			
		||||
	 * |	  |	      |			 |
 | 
			
		||||
	 * +----------+--------------+-------------------------+
 | 
			
		||||
	 * |    NSS   |  0x40000000  |	  16MB	   |
 | 
			
		||||
	 * +----------+--------------+-------------------------+
 | 
			
		||||
	 * |   Linux  |  0x41000000  | Depends on total memory |
 | 
			
		||||
	 * +----------+--------------+-------------------------+
 | 
			
		||||
	 * |   uboot  |  0x4A600000  |	   4MB	   |
 | 
			
		||||
	 * +----------+--------------+-------------------------+
 | 
			
		||||
	 * |    SBL   |  0x4AA00000  |	   1MB	   |
 | 
			
		||||
	 * +----------+--------------+-------------------------+
 | 
			
		||||
	 * |   smem   |  0x4AB00000  |	   1MB	   |
 | 
			
		||||
	 * +----------+--------------+-------------------------+
 | 
			
		||||
	 * |    TZ    |  0x4AC00000  |	   4MB	   |
 | 
			
		||||
	 * +----------+--------------+-------------------------+
 | 
			
		||||
	 * |    Q6    |	      |			 |
 | 
			
		||||
	 * |   code/  |  0x4B000000  |	  20MB	   |
 | 
			
		||||
	 * |   data   |	      |			 |
 | 
			
		||||
	 * +----------+--------------+-------------------------+
 | 
			
		||||
	 * |  IPQ5018 |	      |			 |
 | 
			
		||||
	 * |   data   |  0x4C400000  |	  13MB	   |
 | 
			
		||||
	 * +----------+--------------+-------------------------+
 | 
			
		||||
	 * |  IPQ5018 |	      |			 |
 | 
			
		||||
	 * |  M3 Dump |  0x4D100000  |	   1MB	   |
 | 
			
		||||
	 * +----------+--------------+-------------------------+
 | 
			
		||||
	 * |  IPQ5018 |	      |			 |
 | 
			
		||||
	 * |   QDSS   |  0x4D200000  |	   1MB	   |
 | 
			
		||||
	 * +----------+--------------+-------------------------+
 | 
			
		||||
	 * |  IPQ5018 |	      |			 |
 | 
			
		||||
	 * |  Caldb   |  0x4D300000  |	   2MB	   |
 | 
			
		||||
	 * +----------+--------------+-------------------------+
 | 
			
		||||
	 * | QCN6122_1|	      |			 |
 | 
			
		||||
	 * |   data   |  0x4D500000  |	  13MB	   |
 | 
			
		||||
	 * +----------+--------------+-------------------------+
 | 
			
		||||
	 * | QCN6122_1|	      |			 |
 | 
			
		||||
	 * |  M3 Dump |  0x4E200000  |	   1MB	   |
 | 
			
		||||
	 * +----------+--------------+-------------------------+
 | 
			
		||||
	 * | QCN6122_1|	      |			 |
 | 
			
		||||
	 * |   QDSS   |  0x4E300000  |	   1MB	   |
 | 
			
		||||
	 * +----------+--------------+-------------------------+
 | 
			
		||||
	 * | QCN6122_1|	      |			 |
 | 
			
		||||
	 * |  Caldb   |  0x4E400000  |	   5MB	   |
 | 
			
		||||
	 * +----------+--------------+-------------------------+
 | 
			
		||||
	 * | QCN6122_2|	      |			 |
 | 
			
		||||
	 * |   data   |  0x4E900000  |	  13MB	   |
 | 
			
		||||
	 * +----------+--------------+-------------------------+
 | 
			
		||||
	 * | QCN6122_2|	      |			 |
 | 
			
		||||
	 * |  M3 Dump |  0x4F600000  |	   1MB	   |
 | 
			
		||||
	 * +----------+--------------+-------------------------+
 | 
			
		||||
	 * | QCN6122_2|	      |			 |
 | 
			
		||||
	 * |   QDSS   |  0x4F700000  |	   1MB	   |
 | 
			
		||||
	 * +----------+--------------+-------------------------+
 | 
			
		||||
	 * | QCN6122_2|	      |			 |
 | 
			
		||||
	 * |  Caldb   |  0x4F800000  |	   5MB	   |
 | 
			
		||||
	 * +----------+--------------+-------------------------+
 | 
			
		||||
	 * |						   |
 | 
			
		||||
	 * |	    Rest of the memory for Linux	   |
 | 
			
		||||
	 * |						   |
 | 
			
		||||
	 * +===================================================+
 | 
			
		||||
	 */
 | 
			
		||||
		q6_mem_regions: q6_mem_regions@4B000000 {
 | 
			
		||||
			no-map;
 | 
			
		||||
			reg = <0x0 0x4B000000 0x0 0x4D00000>;
 | 
			
		||||
		};
 | 
			
		||||
 | 
			
		||||
		q6_code_data: q6_code_data@4B000000 {
 | 
			
		||||
			no-map;
 | 
			
		||||
			reg = <0x0 0x4B000000 0x0 01400000>;
 | 
			
		||||
		};
 | 
			
		||||
 | 
			
		||||
		q6_ipq5018_data: q6_ipq5018_data@4C400000 {
 | 
			
		||||
			no-map;
 | 
			
		||||
			reg = <0x0 0x4C400000 0x0 0xD00000>;
 | 
			
		||||
		};
 | 
			
		||||
 | 
			
		||||
		m3_dump: m3_dump@4D100000 {
 | 
			
		||||
			no-map;
 | 
			
		||||
			reg = <0x0 0x4D100000 0x0 0x100000>;
 | 
			
		||||
		};
 | 
			
		||||
 | 
			
		||||
		q6_etr_region: q6_etr_dump@4D200000 {
 | 
			
		||||
			no-map;
 | 
			
		||||
			reg = <0x0 0x4D200000 0x0 0x100000>;
 | 
			
		||||
		};
 | 
			
		||||
 | 
			
		||||
		q6_caldb_region: q6_caldb_region@4D300000 {
 | 
			
		||||
			no-map;
 | 
			
		||||
			reg = <0x0 0x4D300000 0x0 0x200000>;
 | 
			
		||||
		};
 | 
			
		||||
 | 
			
		||||
		q6_qcn6122_data1: q6_qcn6122_data1@4D500000 {
 | 
			
		||||
			no-map;
 | 
			
		||||
			reg = <0x0 0x4D500000 0x0 0xD00000>;
 | 
			
		||||
		};
 | 
			
		||||
 | 
			
		||||
		m3_dump_qcn6122_1: m3_dump_qcn6122_1@4E200000 {
 | 
			
		||||
			no-map;
 | 
			
		||||
			reg = <0x0 0x4E200000 0x0 0x100000>;
 | 
			
		||||
		};
 | 
			
		||||
 | 
			
		||||
		q6_qcn6122_etr_1: q6_qcn6122_etr_1@4E300000 {
 | 
			
		||||
			no-map;
 | 
			
		||||
			reg = <0x0 0x4E300000 0x0 0x100000>;
 | 
			
		||||
		};
 | 
			
		||||
 | 
			
		||||
		q6_qcn6122_caldb_1: q6_qcn6122_caldb_1@4E400000 {
 | 
			
		||||
			no-map;
 | 
			
		||||
			reg = <0x0 0x4E400000 0x0 0x500000>;
 | 
			
		||||
		};
 | 
			
		||||
	#endif
 | 
			
		||||
	};
 | 
			
		||||
 | 
			
		||||
	soc {
 | 
			
		||||
		serial@78af000 {
 | 
			
		||||
			status = "ok";
 | 
			
		||||
		};
 | 
			
		||||
 | 
			
		||||
		qpic_bam: dma@7984000{
 | 
			
		||||
			status = "ok";
 | 
			
		||||
		};
 | 
			
		||||
 | 
			
		||||
		nand: qpic-nand@79b0000 {
 | 
			
		||||
			pinctrl-0 = <&qspi_nand_pins>;
 | 
			
		||||
			pinctrl-names = "default";
 | 
			
		||||
			status = "ok";
 | 
			
		||||
		};
 | 
			
		||||
 | 
			
		||||
		spi_0: spi@78b5000 { /* BLSP1 QUP0 */
 | 
			
		||||
			pinctrl-0 = <&blsp0_spi_pins>;
 | 
			
		||||
			pinctrl-names = "default";
 | 
			
		||||
			cs-select = <0>;
 | 
			
		||||
			status = "ok";
 | 
			
		||||
 | 
			
		||||
			m25p80@0 {
 | 
			
		||||
				#address-cells = <1>;
 | 
			
		||||
				#size-cells = <1>;
 | 
			
		||||
				reg = <0>;
 | 
			
		||||
				compatible = "n25q128a11";
 | 
			
		||||
				linux,modalias = "m25p80", "n25q128a11";
 | 
			
		||||
				spi-max-frequency = <50000000>;
 | 
			
		||||
				use-default-sizes;
 | 
			
		||||
			};
 | 
			
		||||
		};
 | 
			
		||||
 | 
			
		||||
		mdio0: mdio@88000 {
 | 
			
		||||
			status = "ok";
 | 
			
		||||
 | 
			
		||||
			ethernet-phy@0 {
 | 
			
		||||
				reg = <7>;
 | 
			
		||||
			};
 | 
			
		||||
		};
 | 
			
		||||
 | 
			
		||||
		mdio1: mdio@90000 {
 | 
			
		||||
			status = "ok";
 | 
			
		||||
			pinctrl-0 = <&mdio1_pins>;
 | 
			
		||||
			pinctrl-names = "default";
 | 
			
		||||
			phy-reset-gpio = <&tlmm 23 0>;
 | 
			
		||||
 | 
			
		||||
			ethernet-phy@0 {
 | 
			
		||||
				reg = <24>;
 | 
			
		||||
			};
 | 
			
		||||
		};
 | 
			
		||||
 | 
			
		||||
		ess-instance {
 | 
			
		||||
			num_devices = <0x1>;
 | 
			
		||||
			ess-switch@0x39c00000 {
 | 
			
		||||
				switch_mac_mode = <0xf>; /* mac mode for uniphy instance*/
 | 
			
		||||
				cmnblk_clk = "internal_96MHz"; /* cmnblk clk*/
 | 
			
		||||
				qcom,port_phyinfo {
 | 
			
		||||
					port@0 {
 | 
			
		||||
						port_id = <1>;
 | 
			
		||||
						phy_address = <7>;
 | 
			
		||||
						mdiobus = <&mdio0>;
 | 
			
		||||
					};
 | 
			
		||||
					port@1 {
 | 
			
		||||
						port_id = <2>;
 | 
			
		||||
						phy_address = <0x18>;
 | 
			
		||||
						mdiobus = <&mdio1>;
 | 
			
		||||
						port_mac_sel = "QGMAC_PORT";
 | 
			
		||||
					};
 | 
			
		||||
				};
 | 
			
		||||
				led_source@0 {
 | 
			
		||||
					source = <0>;
 | 
			
		||||
					mode = "normal";
 | 
			
		||||
					speed = "all";
 | 
			
		||||
					blink_en = "enable";
 | 
			
		||||
					active = "high";
 | 
			
		||||
				};
 | 
			
		||||
			};
 | 
			
		||||
		};
 | 
			
		||||
 | 
			
		||||
		wifi0: wifi@c000000 {
 | 
			
		||||
			status = "ok";
 | 
			
		||||
		};
 | 
			
		||||
 | 
			
		||||
		dp1 {
 | 
			
		||||
			device_type = "network";
 | 
			
		||||
			compatible = "qcom,nss-dp";
 | 
			
		||||
			clocks = <&gcc GCC_SNOC_GMAC0_AXI_CLK>;
 | 
			
		||||
			clock-names = "nss-snoc-gmac-axi-clk";
 | 
			
		||||
			qcom,id = <1>;
 | 
			
		||||
			reg = <0x39C00000 0x10000>;
 | 
			
		||||
			interrupts = <GIC_SPI 101 IRQ_TYPE_LEVEL_HIGH>;
 | 
			
		||||
			qcom,mactype = <2>;
 | 
			
		||||
			qcom,link-poll = <1>;
 | 
			
		||||
			qcom,phy-mdio-addr = <7>;
 | 
			
		||||
			mdio-bus = <&mdio0>;
 | 
			
		||||
			local-mac-address = [000000000000];
 | 
			
		||||
			phy-mode = "sgmii";
 | 
			
		||||
		};
 | 
			
		||||
 | 
			
		||||
		nss-macsec1 {
 | 
			
		||||
			compatible = "qcom,nss-macsec";
 | 
			
		||||
			phy_addr = <0x18>;
 | 
			
		||||
			mdiobus = <&mdio1>;
 | 
			
		||||
		};
 | 
			
		||||
 | 
			
		||||
		lpass: lpass@0xA000000{
 | 
			
		||||
			status = "disabled";
 | 
			
		||||
		};
 | 
			
		||||
 | 
			
		||||
		pcm_lb: pcm_lb@0 {
 | 
			
		||||
			status = "disabled";
 | 
			
		||||
		};
 | 
			
		||||
	};
 | 
			
		||||
 | 
			
		||||
	qcom,test@0 {
 | 
			
		||||
		status = "ok";
 | 
			
		||||
	};
 | 
			
		||||
 | 
			
		||||
	thermal-zones {
 | 
			
		||||
		status = "ok";
 | 
			
		||||
	};
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
&tlmm {
 | 
			
		||||
	pinctrl-0 = <&blsp0_uart_pins>;
 | 
			
		||||
	pinctrl-names = "default";
 | 
			
		||||
 | 
			
		||||
	blsp0_uart_pins: uart_pins {
 | 
			
		||||
		blsp0_uart_rx_tx {
 | 
			
		||||
			pins = "gpio20", "gpio21";
 | 
			
		||||
			function = "blsp0_uart0";
 | 
			
		||||
			bias-disable;
 | 
			
		||||
		};
 | 
			
		||||
	};
 | 
			
		||||
 | 
			
		||||
	blsp0_spi_pins: blsp0_spi_pins {
 | 
			
		||||
		mux {
 | 
			
		||||
			pins = "gpio10", "gpio11", "gpio12", "gpio13";
 | 
			
		||||
			function = "blsp0_spi";
 | 
			
		||||
			drive-strength = <2>;
 | 
			
		||||
			bias-disable;
 | 
			
		||||
		};
 | 
			
		||||
	};
 | 
			
		||||
 | 
			
		||||
	qspi_nand_pins: qspi_nand_pins {
 | 
			
		||||
		qspi_clock {
 | 
			
		||||
			pins = "gpio9";
 | 
			
		||||
			function = "qspi_clk";
 | 
			
		||||
			drive-strength = <8>;
 | 
			
		||||
			bias-disable;
 | 
			
		||||
		};
 | 
			
		||||
 | 
			
		||||
		qspi_cs {
 | 
			
		||||
			pins = "gpio8";
 | 
			
		||||
			function = "qspi_cs";
 | 
			
		||||
			drive-strength = <8>;
 | 
			
		||||
			bias-disable;
 | 
			
		||||
		};
 | 
			
		||||
 | 
			
		||||
		qspi_data {
 | 
			
		||||
			pins = "gpio4", "gpio5", "gpio6", "gpio7";
 | 
			
		||||
			function = "qspi_data";
 | 
			
		||||
			drive-strength = <8>;
 | 
			
		||||
			bias-disable;
 | 
			
		||||
		};
 | 
			
		||||
	};
 | 
			
		||||
 | 
			
		||||
	mdio1_pins: mdio_pinmux {
 | 
			
		||||
		mux_0 {
 | 
			
		||||
			pins = "gpio36";
 | 
			
		||||
			function = "mdc";
 | 
			
		||||
			drive-strength = <8>;
 | 
			
		||||
			bias-pull-up;
 | 
			
		||||
		};
 | 
			
		||||
 | 
			
		||||
		mux_1 {
 | 
			
		||||
			pins = "gpio37";
 | 
			
		||||
			function = "mdio";
 | 
			
		||||
			drive-strength = <8>;
 | 
			
		||||
			bias-pull-up;
 | 
			
		||||
		};
 | 
			
		||||
	};
 | 
			
		||||
 | 
			
		||||
	poe_dc_pins: poe_dc_pins {
 | 
			
		||||
		T2P_DET {
 | 
			
		||||
			pins = "gpio31";
 | 
			
		||||
			function = "gpio";
 | 
			
		||||
			drive-strength = <8>;
 | 
			
		||||
			bias-disable;
 | 
			
		||||
		};
 | 
			
		||||
 | 
			
		||||
		12V_DET {
 | 
			
		||||
			pins = "gpio32";
 | 
			
		||||
			function = "gpio";
 | 
			
		||||
			drive-strength = <8>;
 | 
			
		||||
			bias-disable;
 | 
			
		||||
		};
 | 
			
		||||
	};
 | 
			
		||||
 | 
			
		||||
	button_pins: button_pins {
 | 
			
		||||
		reset_button {
 | 
			
		||||
			pins = "gpio27";
 | 
			
		||||
			function = "gpio";
 | 
			
		||||
			drive-strength = <8>;
 | 
			
		||||
			bias-pull-up;
 | 
			
		||||
		};
 | 
			
		||||
	};
 | 
			
		||||
 | 
			
		||||
	leds_pins: leds_pinmux {
 | 
			
		||||
		linux,phandle = <0x4d>;
 | 
			
		||||
		phandle = <0x4d>;
 | 
			
		||||
 | 
			
		||||
		led_G {
 | 
			
		||||
			pins = "gpio24";
 | 
			
		||||
			function = "gpio";
 | 
			
		||||
			bias-pull-down;
 | 
			
		||||
			drive-strength = <0x08>;
 | 
			
		||||
		};
 | 
			
		||||
 | 
			
		||||
		led_B {
 | 
			
		||||
			pins = "gpio28";
 | 
			
		||||
			function = "gpio";
 | 
			
		||||
			bias-pull-down;
 | 
			
		||||
			drive-strength = <0x08>;
 | 
			
		||||
		};
 | 
			
		||||
 | 
			
		||||
		led_R {
 | 
			
		||||
			pins = "gpio38";
 | 
			
		||||
			function = "gpio";
 | 
			
		||||
			bias-pull-down;
 | 
			
		||||
			drive-strength = <0x08>;
 | 
			
		||||
		};
 | 
			
		||||
	};
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
&soc {
 | 
			
		||||
	gpio_keys {
 | 
			
		||||
		compatible = "gpio-keys";
 | 
			
		||||
		pinctrl-0 = <&button_pins>;
 | 
			
		||||
		pinctrl-names = "default";
 | 
			
		||||
 | 
			
		||||
		button@1 {
 | 
			
		||||
			label = "reset";
 | 
			
		||||
			linux,code = <KEY_RESTART>;
 | 
			
		||||
			gpios = <&tlmm 27 GPIO_ACTIVE_LOW>;
 | 
			
		||||
			linux,input-type = <1>;
 | 
			
		||||
			debounce-interval = <60>;
 | 
			
		||||
		};
 | 
			
		||||
	};
 | 
			
		||||
 | 
			
		||||
	leds {
 | 
			
		||||
		compatible = "gpio-leds";
 | 
			
		||||
		pinctrl-0 = <&leds_pins>;
 | 
			
		||||
		pinctrl-names = "default";
 | 
			
		||||
 | 
			
		||||
		led@24 {
 | 
			
		||||
			label = "sys:green";
 | 
			
		||||
			gpios = <&tlmm 24 GPIO_ACTIVE_HIGH>;
 | 
			
		||||
			default-state = "on";
 | 
			
		||||
		};
 | 
			
		||||
 | 
			
		||||
		led@28 {
 | 
			
		||||
			label = "sys:blue";
 | 
			
		||||
			gpios = <&tlmm 28 GPIO_ACTIVE_HIGH>;
 | 
			
		||||
			default-state = "on";
 | 
			
		||||
		};
 | 
			
		||||
 | 
			
		||||
		led_power: led@38 {
 | 
			
		||||
			label = "sys:red";
 | 
			
		||||
			gpios = <&tlmm 38 GPIO_ACTIVE_HIGH>;
 | 
			
		||||
			linux,default-trigger = "wap385c:sys:red";
 | 
			
		||||
			default-state = "on";
 | 
			
		||||
		};
 | 
			
		||||
	};
 | 
			
		||||
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
&q6v5_wcss {
 | 
			
		||||
	compatible = "qcom,ipq5018-q6-mpd";
 | 
			
		||||
	#address-cells = <1>;
 | 
			
		||||
	#size-cells = <1>;
 | 
			
		||||
	ranges;
 | 
			
		||||
	firmware = "IPQ5018/q6_fw.mdt";
 | 
			
		||||
	reg = <0x0cd00000 0x4040>,
 | 
			
		||||
		<0x1938000 0x8>,
 | 
			
		||||
		<0x193d204 0x4>;
 | 
			
		||||
	reg-names = "qdsp6",
 | 
			
		||||
			"tcsr-msip",
 | 
			
		||||
			"tcsr-q6";
 | 
			
		||||
	resets = <&gcc GCC_WCSSAON_RESET>,
 | 
			
		||||
			<&gcc GCC_WCSS_Q6_BCR>;
 | 
			
		||||
 | 
			
		||||
	reset-names = "wcss_aon_reset",
 | 
			
		||||
			"wcss_q6_reset";
 | 
			
		||||
 | 
			
		||||
	clocks = <&gcc GCC_Q6_AXIS_CLK>,
 | 
			
		||||
		<&gcc GCC_WCSS_ECAHB_CLK>,
 | 
			
		||||
		<&gcc GCC_Q6_AXIM_CLK>,
 | 
			
		||||
		<&gcc GCC_Q6_AXIM2_CLK>,
 | 
			
		||||
		<&gcc GCC_Q6_AHB_CLK>,
 | 
			
		||||
		<&gcc GCC_Q6_AHB_S_CLK>,
 | 
			
		||||
		<&gcc GCC_WCSS_AXI_S_CLK>;
 | 
			
		||||
	clock-names = "gcc_q6_axis_clk",
 | 
			
		||||
		"gcc_wcss_ecahb_clk",
 | 
			
		||||
		"gcc_q6_axim_clk",
 | 
			
		||||
		"gcc_q6_axim2_clk",
 | 
			
		||||
		"gcc_q6_ahb_clk",
 | 
			
		||||
		"gcc_q6_ahb_s_clk",
 | 
			
		||||
		"gcc_wcss_axi_s_clk";
 | 
			
		||||
 | 
			
		||||
	#ifdef __IPQ_MEM_PROFILE_256_MB__
 | 
			
		||||
		memory-region = <&q6_mem_regions>, <&q6_etr_region>;
 | 
			
		||||
	#else
 | 
			
		||||
		memory-region = <&q6_mem_regions>, <&q6_etr_region>,
 | 
			
		||||
				<&q6_caldb_region>;
 | 
			
		||||
	#endif
 | 
			
		||||
 | 
			
		||||
	qcom,rproc = <&q6v5_wcss>;
 | 
			
		||||
	qcom,bootargs_smem = <507>;
 | 
			
		||||
	boot-args = <0x1 0x4 0x3 0x0F 0x0 0x0>,
 | 
			
		||||
			<0x2 0x4 0x2 0x12 0x0 0x0>;
 | 
			
		||||
	status = "ok";
 | 
			
		||||
 | 
			
		||||
	q6_wcss_pd1: remoteproc_pd1@4ab000 {
 | 
			
		||||
		compatible = "qcom,ipq5018-wcss-ahb-mpd";
 | 
			
		||||
		reg = <0x4ab000 0x20>;
 | 
			
		||||
		reg-names = "rmb";
 | 
			
		||||
		firmware = "IPQ5018/q6_fw.mdt";
 | 
			
		||||
		m3_firmware = "IPQ5018/m3_fw.mdt";
 | 
			
		||||
		interrupts-extended = <&wcss_smp2p_in 8 0>,
 | 
			
		||||
			<&wcss_smp2p_in 9 0>,
 | 
			
		||||
			<&wcss_smp2p_in 12 0>,
 | 
			
		||||
			<&wcss_smp2p_in 11 0>;
 | 
			
		||||
		interrupt-names = "fatal",
 | 
			
		||||
			"ready",
 | 
			
		||||
			"spawn-ack",
 | 
			
		||||
			"stop-ack";
 | 
			
		||||
 | 
			
		||||
		resets = <&gcc GCC_WCSSAON_RESET>,
 | 
			
		||||
				<&gcc GCC_WCSS_BCR>,
 | 
			
		||||
				<&gcc GCC_CE_BCR>;
 | 
			
		||||
		reset-names = "wcss_aon_reset",
 | 
			
		||||
				"wcss_reset",
 | 
			
		||||
				"ce_reset";
 | 
			
		||||
 | 
			
		||||
		clocks = <&gcc GCC_WCSS_AHB_S_CLK>,
 | 
			
		||||
				<&gcc GCC_WCSS_ACMT_CLK>,
 | 
			
		||||
				<&gcc GCC_WCSS_AXI_M_CLK>;
 | 
			
		||||
		clock-names = "gcc_wcss_ahb_s_clk",
 | 
			
		||||
			"gcc_wcss_acmt_clk",
 | 
			
		||||
			"gcc_wcss_axi_m_clk";
 | 
			
		||||
 | 
			
		||||
		qcom,halt-regs = <&tcsr_q6_block 0xa000 0xd000 0x0>;
 | 
			
		||||
 | 
			
		||||
		qcom,smem-states = <&wcss_smp2p_out 8>,
 | 
			
		||||
			<&wcss_smp2p_out 9>,
 | 
			
		||||
			<&wcss_smp2p_out 10>;
 | 
			
		||||
		qcom,smem-state-names = "shutdown",
 | 
			
		||||
			"stop",
 | 
			
		||||
			"spawn";
 | 
			
		||||
 | 
			
		||||
	#ifdef __IPQ_MEM_PROFILE_256_MB__
 | 
			
		||||
		memory-region = <&q6_ipq5018_data>, <&m3_dump>,
 | 
			
		||||
				<&q6_etr_region>;
 | 
			
		||||
	#else
 | 
			
		||||
		memory-region = <&q6_ipq5018_data>, <&m3_dump>,
 | 
			
		||||
				<&q6_etr_region>, <&q6_caldb_region>;
 | 
			
		||||
	#endif
 | 
			
		||||
	};
 | 
			
		||||
 | 
			
		||||
	q6_wcss_pd2: remoteproc_pd2 {
 | 
			
		||||
		compatible = "qcom,ipq5018-wcss-pcie-mpd";
 | 
			
		||||
		firmware = "IPQ5018/q6_fw.mdt";
 | 
			
		||||
		m3_firmware = "qcn6122/m3_fw.mdt";
 | 
			
		||||
		interrupts-extended = <&wcss_smp2p_in 16 0>,
 | 
			
		||||
			<&wcss_smp2p_in 17 0>,
 | 
			
		||||
			<&wcss_smp2p_in 20 0>,
 | 
			
		||||
			<&wcss_smp2p_in 19 0>;
 | 
			
		||||
		interrupt-names = "fatal",
 | 
			
		||||
			"ready",
 | 
			
		||||
			"spawn-ack",
 | 
			
		||||
			"stop-ack";
 | 
			
		||||
		qcom,smem-states = <&wcss_smp2p_out 16>,
 | 
			
		||||
			<&wcss_smp2p_out 17>,
 | 
			
		||||
			<&wcss_smp2p_out 18>;
 | 
			
		||||
		qcom,smem-state-names = "shutdown",
 | 
			
		||||
			"stop",
 | 
			
		||||
			"spawn";
 | 
			
		||||
	#ifdef __IPQ_MEM_PROFILE_256_MB__
 | 
			
		||||
		memory-region = <&q6_qcn6122_data1>, <&m3_dump_qcn6122_1>,
 | 
			
		||||
				<&q6_qcn6122_etr_1>;
 | 
			
		||||
	#else
 | 
			
		||||
		memory-region = <&q6_qcn6122_data1>, <&m3_dump_qcn6122_1>,
 | 
			
		||||
				<&q6_qcn6122_etr_1>, <&q6_qcn6122_caldb_1>;
 | 
			
		||||
	#endif
 | 
			
		||||
 | 
			
		||||
	};
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
&wifi0 {
 | 
			
		||||
	/* IPQ5018 */
 | 
			
		||||
	qcom,multipd_arch;
 | 
			
		||||
	qcom,rproc = <&q6_wcss_pd1>;
 | 
			
		||||
	qcom,userpd-subsys-name = "q6v5_wcss_userpd1";
 | 
			
		||||
#ifdef __IPQ_MEM_PROFILE_256_MB__
 | 
			
		||||
	qcom,tgt-mem-mode = <2>;
 | 
			
		||||
#else
 | 
			
		||||
	qcom,tgt-mem-mode = <1>;
 | 
			
		||||
#endif
 | 
			
		||||
	qcom,board_id = <0x24>;
 | 
			
		||||
#ifdef __CNSS2__
 | 
			
		||||
	qcom,bdf-addr = <0x4C400000 0x4C400000 0x4C400000 0x0 0x0>;
 | 
			
		||||
	qcom,caldb-addr = <0x4D300000 0x4D300000 0 0 0>;
 | 
			
		||||
	qcom,caldb-size = <0x200000>;
 | 
			
		||||
	mem-region = <&q6_ipq5018_data>;
 | 
			
		||||
#else
 | 
			
		||||
	memory-region = <&q6_ipq5018_data>;
 | 
			
		||||
#endif
 | 
			
		||||
	status = "ok";
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
&wifi1 {
 | 
			
		||||
	/* QCN6122 5G */
 | 
			
		||||
	qcom,multipd_arch;
 | 
			
		||||
	qcom,userpd-subsys-name = "q6v5_wcss_userpd2";
 | 
			
		||||
	qcom,rproc = <&q6_wcss_pd2>;
 | 
			
		||||
#ifdef __IPQ_MEM_PROFILE_256_MB__
 | 
			
		||||
	qcom,tgt-mem-mode = <2>;
 | 
			
		||||
#else
 | 
			
		||||
	qcom,tgt-mem-mode = <1>;
 | 
			
		||||
#endif
 | 
			
		||||
	qcom,board_id = <0x60>;
 | 
			
		||||
#ifdef __CNSS2__
 | 
			
		||||
	qcom,bdf-addr = <0x4D500000 0x4D500000 0x4D300000 0x0 0x0>;
 | 
			
		||||
	qcom,caldb-addr = <0x4E400000 0x4E400000 0 0 0>;
 | 
			
		||||
	qcom,caldb-size = <0x500000>;
 | 
			
		||||
	mem-region = <&q6_qcn6122_data1>;
 | 
			
		||||
#else
 | 
			
		||||
	memory-region = <&q6_qcn6122_data1>;
 | 
			
		||||
#endif
 | 
			
		||||
	status = "ok";
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
&dwc_0 {
 | 
			
		||||
	/delete-property/ #phy-cells;
 | 
			
		||||
	/delete-property/ phys;
 | 
			
		||||
	/delete-property/ phy-names;
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
&hs_m31phy_0 {
 | 
			
		||||
	status = "ok";
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
&eud {
 | 
			
		||||
	status = "ok";
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
&pcie_x1 {
 | 
			
		||||
	perst-gpio = <&tlmm 18 GPIO_ACTIVE_LOW>;
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
&pcie_x2 {
 | 
			
		||||
	perst-gpio = <&tlmm 15 GPIO_ACTIVE_LOW>;
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
&pcie_x1_rp {
 | 
			
		||||
	status = "disabled";
 | 
			
		||||
 | 
			
		||||
	mhi_0: qcom,mhi@0 {
 | 
			
		||||
		reg = <0 0 0 0 0 >;
 | 
			
		||||
	};
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
&pcie_x2_rp {
 | 
			
		||||
	status = "disabled";
 | 
			
		||||
 | 
			
		||||
	mhi_1: qcom,mhi@1 {
 | 
			
		||||
		reg = <0 0 0 0 0 >;
 | 
			
		||||
	};
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
&qfprom {
 | 
			
		||||
	status = "ok";
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
&tsens {
 | 
			
		||||
	status = "ok";
 | 
			
		||||
};
 | 
			
		||||
@@ -154,6 +154,15 @@ define Device/edgecore_oap101e_6e
 | 
			
		||||
endef
 | 
			
		||||
TARGET_DEVICES += edgecore_oap101e_6e
 | 
			
		||||
 | 
			
		||||
define Device/emplus_wap385c
 | 
			
		||||
  DEVICE_TITLE := Emplus WAP385C
 | 
			
		||||
  DEVICE_DTS := qcom-ipq5018-emplus-wap385c
 | 
			
		||||
  SUPPORTED_DEVICES := emplus,wap385c
 | 
			
		||||
  DEVICE_PACKAGES := ath11k-wifi-emplus-wap385c ath11k-firmware-ipq50xx-map-spruce
 | 
			
		||||
  DEVICE_DTS_CONFIG := config@mp03.3
 | 
			
		||||
endef
 | 
			
		||||
TARGET_DEVICES += emplus_wap385c
 | 
			
		||||
 | 
			
		||||
define Device/hfcl_ion4x_w
 | 
			
		||||
  DEVICE_TITLE := HFCL ION4x_w
 | 
			
		||||
  DEVICE_DTS := qcom-ipq5018-hfcl-ion4x_w
 | 
			
		||||
 
 | 
			
		||||
@@ -26,6 +26,12 @@ edgecore,eap101)
 | 
			
		||||
	ucidef_set_led_netdev "poe" "poe" "green:wan" "eth0"
 | 
			
		||||
        ucidef_set_led_default "power" "POWER" "green:led_pwr" "on"
 | 
			
		||||
	;;
 | 
			
		||||
emplus,wap386v2)
 | 
			
		||||
	ucidef_set_led_default "power" "POWER" "red:power" "on"
 | 
			
		||||
	ucidef_set_led_netdev "wan" "WAN" "blue:wan" "eth0" "tx rx link"
 | 
			
		||||
	ucidef_set_led_wlan "wlan2g" "WLAN2G" "blue:wifi2" "phy1tpt"
 | 
			
		||||
	ucidef_set_led_wlan "wlan5g" "WLAN5G" "blue:wifi5" "phy0tpt"
 | 
			
		||||
	;;
 | 
			
		||||
hfcl,ion4xi|\
 | 
			
		||||
hfcl,ion4x|\
 | 
			
		||||
hfcl,ion4x_2|\
 | 
			
		||||
 
 | 
			
		||||
@@ -34,10 +34,10 @@ qcom_setup_interfaces()
 | 
			
		||||
		ucidef_set_interface_lan "eth1"
 | 
			
		||||
		ucidef_set_interface_wan "eth0"
 | 
			
		||||
		;;
 | 
			
		||||
       cig,wf660a)
 | 
			
		||||
	cig,wf660a|\
 | 
			
		||||
	emplus,wap386v2)
 | 
			
		||||
		ucidef_set_interface_wan "eth0"		
 | 
			
		||||
		;;
 | 
			
		||||
 | 
			
		||||
	yuncore,fap650)
 | 
			
		||||
		ucidef_set_interface_lan "eth3 eth2 eth1 eth0"
 | 
			
		||||
		ucidef_set_interface_wan "eth4"
 | 
			
		||||
@@ -76,6 +76,9 @@ qcom_setup_macs()
 | 
			
		||||
		ucidef_set_network_device_mac eth0 $wan_mac
 | 
			
		||||
		ip link set eth0 address $wan_mac
 | 
			
		||||
		;;
 | 
			
		||||
	emplus,wap386v2)
 | 
			
		||||
		wan_mac=$(cat /sys/class/net/eth0/address)
 | 
			
		||||
		;;
 | 
			
		||||
	yuncore,ax840)
 | 
			
		||||
		wan_mac=$(cat /sys/class/net/eth1/address)
 | 
			
		||||
		lan_mac=$(macaddr_add "$wan_mac" 1)
 | 
			
		||||
 
 | 
			
		||||
@@ -76,6 +76,7 @@ case "$FIRMWARE" in
 | 
			
		||||
	cig,wf188n|\
 | 
			
		||||
	cig,wf660a|\
 | 
			
		||||
	edgecore,eap101|\
 | 
			
		||||
	emplus,wap386v2|\
 | 
			
		||||
	hfcl,ion4xi|\
 | 
			
		||||
	hfcl,ion4x|\
 | 
			
		||||
	hfcl,ion4x_2|\
 | 
			
		||||
@@ -109,7 +110,8 @@ ath11k-macs)
 | 
			
		||||
	edgecore,eap101)
 | 
			
		||||
		ath11k_generate_macs_eap101
 | 
			
		||||
		;;
 | 
			
		||||
	cig,wf188n)
 | 
			
		||||
	cig,wf188n|\
 | 
			
		||||
	emplus,wap386v2)
 | 
			
		||||
		ath11k_generate_macs
 | 
			
		||||
		;;
 | 
			
		||||
	cig,wf660a)
 | 
			
		||||
 
 | 
			
		||||
@@ -122,6 +122,7 @@ platform_check_image() {
 | 
			
		||||
	wallys,dr6018|\
 | 
			
		||||
	wallys,dr6018-v4|\
 | 
			
		||||
	edgecore,eap101|\
 | 
			
		||||
	emplus,wap386v2|\
 | 
			
		||||
	hfcl,ion4xi|\
 | 
			
		||||
	hfcl,ion4x|\
 | 
			
		||||
	hfcl,ion4x_2|\
 | 
			
		||||
@@ -145,7 +146,8 @@ platform_do_upgrade() {
 | 
			
		||||
	cig,wf660a)
 | 
			
		||||
		spi_nor_emmc_do_upgrade_bootconfig $1
 | 
			
		||||
		;;
 | 
			
		||||
	cig,wf188n)
 | 
			
		||||
	cig,wf188n|\
 | 
			
		||||
	emplus,wap386v2)
 | 
			
		||||
		[ -f /proc/boot_info/rootfs/upgradepartition ] && {
 | 
			
		||||
			CI_UBIPART="$(cat /proc/boot_info/rootfs/upgradepartition)"
 | 
			
		||||
			CI_BOOTCFG=1
 | 
			
		||||
 
 | 
			
		||||
@@ -0,0 +1,356 @@
 | 
			
		||||
/*
 | 
			
		||||
 * Copyright (c) 2019-2021, The Linux Foundation. All rights reserved.
 | 
			
		||||
 *
 | 
			
		||||
 * Permission to use, copy, modify, and/or distribute this software for any
 | 
			
		||||
 * purpose with or without fee is hereby granted, provided that the above
 | 
			
		||||
 * copyright notice and this permission notice appear in all copies.
 | 
			
		||||
 *
 | 
			
		||||
 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
 | 
			
		||||
 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
 | 
			
		||||
 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
 | 
			
		||||
 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
 | 
			
		||||
 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
 | 
			
		||||
 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
 | 
			
		||||
 * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
/dts-v1/;
 | 
			
		||||
 | 
			
		||||
#include "ipq6018.dtsi"
 | 
			
		||||
#include "ipq6018-cpr-regulator.dtsi"
 | 
			
		||||
#include <dt-bindings/input/input.h>
 | 
			
		||||
 | 
			
		||||
/ {
 | 
			
		||||
	model = "Emplus WAP386 v2";
 | 
			
		||||
	compatible = "emplus,wap386v2", "qcom,ipq6018-cp03", "qcom,ipq6018";
 | 
			
		||||
 | 
			
		||||
	aliases {
 | 
			
		||||
		/*
 | 
			
		||||
		 * Aliases as required by u-boot
 | 
			
		||||
		 * to patch MAC addresses
 | 
			
		||||
		 */
 | 
			
		||||
		ethernet0 = "/soc/dp1";
 | 
			
		||||
 | 
			
		||||
		led-boot = &led_power;
 | 
			
		||||
		led-failsafe = &led_power;
 | 
			
		||||
		led-running = &led_power;
 | 
			
		||||
		led-upgrade = &led_power;
 | 
			
		||||
	};
 | 
			
		||||
 | 
			
		||||
	chosen {
 | 
			
		||||
		stdout-path = "serial0:115200n8";
 | 
			
		||||
		bootargs-append = " swiotlb=1 coherent_pool=2M";
 | 
			
		||||
	};
 | 
			
		||||
 | 
			
		||||
	/*
 | 
			
		||||
	 * +=========+==============+========================+
 | 
			
		||||
	 * |        |              |                         |
 | 
			
		||||
	 * | Region | Start Offset |          Size           |
 | 
			
		||||
	 * |        |              |                         |
 | 
			
		||||
	 * +--------+--------------+-------------------------+
 | 
			
		||||
	 * |        |              |                         |
 | 
			
		||||
	 * |        |              |                         |
 | 
			
		||||
	 * |        |              |                         |
 | 
			
		||||
	 * |        |              |                         |
 | 
			
		||||
	 * | Linux  |  0x41000000  |         139MB           |
 | 
			
		||||
	 * |        |              |                         |
 | 
			
		||||
	 * |        |              |                         |
 | 
			
		||||
	 * |        |              |                         |
 | 
			
		||||
	 * +--------+--------------+-------------------------+
 | 
			
		||||
	 * | TZ App |  0x49B00000  |           6MB           |
 | 
			
		||||
	 * +--------+--------------+-------------------------+
 | 
			
		||||
	 *
 | 
			
		||||
	 * From the available 145 MB for Linux in the first 256 MB,
 | 
			
		||||
	 * we are reserving 6 MB for TZAPP.
 | 
			
		||||
	 *
 | 
			
		||||
	 * Refer arch/arm64/boot/dts/qcom/qcom-ipq6018-memory.dtsi
 | 
			
		||||
	 * for memory layout.
 | 
			
		||||
	 */
 | 
			
		||||
 | 
			
		||||
/* TZAPP is enabled only in default memory profile */
 | 
			
		||||
#if !defined(__IPQ_MEM_PROFILE_256_MB__) && !defined(__IPQ_MEM_PROFILE_512_MB__)
 | 
			
		||||
	reserved-memory {
 | 
			
		||||
		tzapp:tzapp@49B00000 {	/* TZAPPS */
 | 
			
		||||
			no-map;
 | 
			
		||||
			reg = <0x0 0x49B00000 0x0 0x00600000>;
 | 
			
		||||
		};
 | 
			
		||||
	};
 | 
			
		||||
#endif
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
&tlmm {
 | 
			
		||||
	gpio-reserved-ranges = <20 1>;
 | 
			
		||||
 | 
			
		||||
	uart_pins: uart_pins {
 | 
			
		||||
		mux {
 | 
			
		||||
			pins = "gpio44", "gpio45";
 | 
			
		||||
			function = "blsp2_uart";
 | 
			
		||||
			drive-strength = <8>;
 | 
			
		||||
			bias-pull-down;
 | 
			
		||||
		};
 | 
			
		||||
	};
 | 
			
		||||
 | 
			
		||||
	spi_0_pins: spi_0_pins {
 | 
			
		||||
		mux {
 | 
			
		||||
			pins = "gpio38", "gpio39", "gpio40", "gpio41";
 | 
			
		||||
			function = "blsp0_spi";
 | 
			
		||||
			drive-strength = <8>;
 | 
			
		||||
			bias-pull-down;
 | 
			
		||||
		};
 | 
			
		||||
	};
 | 
			
		||||
 | 
			
		||||
	button_pins: button_pins {
 | 
			
		||||
		reset_button {
 | 
			
		||||
			pins = "gpio9";
 | 
			
		||||
			function = "gpio";
 | 
			
		||||
			drive-strength = <8>;
 | 
			
		||||
			bias-pull-down;
 | 
			
		||||
		};
 | 
			
		||||
	};
 | 
			
		||||
 | 
			
		||||
	mdio_pins: mdio_pinmux {
 | 
			
		||||
		mux_0 {
 | 
			
		||||
			pins = "gpio64";
 | 
			
		||||
			function = "mdc";
 | 
			
		||||
			drive-strength = <8>;
 | 
			
		||||
			bias-pull-up;
 | 
			
		||||
		};
 | 
			
		||||
		mux_1 {
 | 
			
		||||
			pins = "gpio65";
 | 
			
		||||
			function = "mdio";
 | 
			
		||||
			drive-strength = <8>;
 | 
			
		||||
			bias-pull-up;
 | 
			
		||||
		};
 | 
			
		||||
		mux_2 {
 | 
			
		||||
			pins = "gpio75";
 | 
			
		||||
			function = "gpio";
 | 
			
		||||
			bias-pull-up;
 | 
			
		||||
		};
 | 
			
		||||
	};
 | 
			
		||||
 | 
			
		||||
	leds_pins: leds_pins {
 | 
			
		||||
		led_5g {
 | 
			
		||||
			pins = "gpio31";
 | 
			
		||||
			function = "gpio";
 | 
			
		||||
			drive-strength = <8>;
 | 
			
		||||
			bias-pull-down;
 | 
			
		||||
		};
 | 
			
		||||
		led_2g {
 | 
			
		||||
			pins = "gpio30";
 | 
			
		||||
			function = "gpio";
 | 
			
		||||
			drive-strength = <8>;
 | 
			
		||||
			bias-pull-down;
 | 
			
		||||
		};
 | 
			
		||||
	};
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
&soc {
 | 
			
		||||
	mdio@90000 {
 | 
			
		||||
		pinctrl-0 = <&mdio_pins>;
 | 
			
		||||
		pinctrl-names = "default";
 | 
			
		||||
		phy-reset-gpio = <&tlmm 75 0>;
 | 
			
		||||
		status = "ok";
 | 
			
		||||
		phy0: ethernet-phy@0 {
 | 
			
		||||
			reg = <3>;
 | 
			
		||||
		};
 | 
			
		||||
		phy1: ethernet-phy@1 {
 | 
			
		||||
			reg = <4>;
 | 
			
		||||
		};
 | 
			
		||||
	};
 | 
			
		||||
 | 
			
		||||
	ess-switch@3a000000 {
 | 
			
		||||
		switch_cpu_bmp = <0x1>;  /* cpu port bitmap */
 | 
			
		||||
		switch_lan_bmp = <0x08>; /* lan port bitmap */
 | 
			
		||||
		switch_wan_bmp = <0x10>; /* wan port bitmap */
 | 
			
		||||
		switch_inner_bmp = <0xc0>; /*inner port bitmap*/
 | 
			
		||||
		switch_mac_mode = <0x0>; /* mac mode for uniphy instance0*/
 | 
			
		||||
		switch_mac_mode1 = <0xff>; /* mac mode for uniphy instance1*/
 | 
			
		||||
		switch_mac_mode2 = <0xff>; /* mac mode for uniphy instance2*/
 | 
			
		||||
		qcom,port_phyinfo {
 | 
			
		||||
			port@0 {
 | 
			
		||||
				port_id = <2>;
 | 
			
		||||
				phy_address = <3>;
 | 
			
		||||
			};
 | 
			
		||||
			port@1 {
 | 
			
		||||
				port_id = <3>;
 | 
			
		||||
				phy_address = <4>;
 | 
			
		||||
			};
 | 
			
		||||
		};
 | 
			
		||||
	};
 | 
			
		||||
 | 
			
		||||
	dp1 {
 | 
			
		||||
		device_type = "network";
 | 
			
		||||
		compatible = "qcom,nss-dp";
 | 
			
		||||
		qcom,id = <3>;
 | 
			
		||||
		reg = <0x3a001400 0x200>;
 | 
			
		||||
		qcom,mactype = <0>;
 | 
			
		||||
		local-mac-address = [000000000000];
 | 
			
		||||
		qcom,link-poll = <1>;
 | 
			
		||||
		qcom,phy-mdio-addr = <4>;
 | 
			
		||||
		phy-mode = "sgmii";
 | 
			
		||||
	};
 | 
			
		||||
 | 
			
		||||
	gpio_keys {
 | 
			
		||||
		compatible = "gpio-keys";
 | 
			
		||||
		pinctrl-0 = <&button_pins>;
 | 
			
		||||
		pinctrl-names = "default";
 | 
			
		||||
 | 
			
		||||
		button@9 {
 | 
			
		||||
			label = "reset";
 | 
			
		||||
			linux,code = <KEY_RESTART>;
 | 
			
		||||
			gpios = <&tlmm 9 GPIO_ACTIVE_LOW>;
 | 
			
		||||
			linux,input-type = <1>;
 | 
			
		||||
			debounce-interval = <60>;
 | 
			
		||||
		};
 | 
			
		||||
	};
 | 
			
		||||
 | 
			
		||||
	leds {
 | 
			
		||||
		compatible = "gpio-leds";
 | 
			
		||||
		pinctrl-0 = <&leds_pins>;
 | 
			
		||||
		pinctrl-names = "default";
 | 
			
		||||
 | 
			
		||||
		led_power: led@28 {
 | 
			
		||||
			label = "red:power";
 | 
			
		||||
			gpios = <&tlmm 28 GPIO_ACTIVE_HIGH>;
 | 
			
		||||
			linux,default-trigger = "wap386v2:red:power";
 | 
			
		||||
			default-state = "on";
 | 
			
		||||
		};
 | 
			
		||||
		led@29 {
 | 
			
		||||
			label = "blue:wan";
 | 
			
		||||
			gpios = <&tlmm 29 GPIO_ACTIVE_HIGH>;
 | 
			
		||||
			linux,default-trigger = "wap386v2:blue:eth";
 | 
			
		||||
			default-state = "on";
 | 
			
		||||
		};
 | 
			
		||||
		led@30 {
 | 
			
		||||
			label = "blue:wifi2";
 | 
			
		||||
			gpios = <&tlmm 30 GPIO_ACTIVE_HIGH>;
 | 
			
		||||
			linux,default-trigger = "wap386v2:blue:2g";
 | 
			
		||||
			default-state = "on";
 | 
			
		||||
		};
 | 
			
		||||
		led@31 {
 | 
			
		||||
			label = "blue:wifi5";
 | 
			
		||||
			gpios = <&tlmm 31 GPIO_ACTIVE_HIGH>;
 | 
			
		||||
			linux,default-trigger = "wap386v2:blue:5g";
 | 
			
		||||
			default-state = "on";
 | 
			
		||||
		};
 | 
			
		||||
	};
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
&blsp1_uart3 {
 | 
			
		||||
	pinctrl-0 = <&uart_pins>;
 | 
			
		||||
	pinctrl-names = "default";
 | 
			
		||||
	status = "ok";
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
&spi_0 {
 | 
			
		||||
	pinctrl-0 = <&spi_0_pins>;
 | 
			
		||||
	pinctrl-names = "default";
 | 
			
		||||
	cs-select = <0>;
 | 
			
		||||
	status = "ok";
 | 
			
		||||
 | 
			
		||||
	m25p80@0 {
 | 
			
		||||
		#address-cells = <1>;
 | 
			
		||||
		#size-cells = <1>;
 | 
			
		||||
		reg = <0>;
 | 
			
		||||
		compatible = "n25q128a11";
 | 
			
		||||
		linux,modalias = "m25p80", "n25q128a11";
 | 
			
		||||
		spi-max-frequency = <50000000>;
 | 
			
		||||
		use-default-sizes;
 | 
			
		||||
	};
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
&wifi0 {
 | 
			
		||||
	qcom,board_id = <0x30>;
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
&pcie_phy {
 | 
			
		||||
	status = "ok";
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
&pcie0 {
 | 
			
		||||
#if defined(__CNSS2__)
 | 
			
		||||
	status = "ok";
 | 
			
		||||
#endif
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
&qpic_bam {
 | 
			
		||||
	status = "ok";
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
&qpic_nand {
 | 
			
		||||
	status = "ok";
 | 
			
		||||
 | 
			
		||||
	nand@0 {
 | 
			
		||||
		reg = <0>;
 | 
			
		||||
		#address-cells = <1>;
 | 
			
		||||
		#size-cells = <1>;
 | 
			
		||||
 | 
			
		||||
		nand-ecc-strength = <4>;
 | 
			
		||||
		nand-ecc-step-size = <512>;
 | 
			
		||||
		nand-bus-width = <8>;
 | 
			
		||||
	};
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
&ssphy_0 {
 | 
			
		||||
	status = "ok";
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
&nss_crypto {
 | 
			
		||||
	status = "ok";
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
&CPU0 {
 | 
			
		||||
	operating-points = <
 | 
			
		||||
		/* kHz   uV (fixed) */
 | 
			
		||||
		864000   1100000
 | 
			
		||||
		1056000  1100000
 | 
			
		||||
		1320000  1100000
 | 
			
		||||
		1440000  1100000
 | 
			
		||||
		1608000  1100000
 | 
			
		||||
		1800000  1100000
 | 
			
		||||
	>;
 | 
			
		||||
	clock-latency = <200000>;
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
&CPU1 {
 | 
			
		||||
	operating-points = <
 | 
			
		||||
		/* kHz   uV (fixed) */
 | 
			
		||||
		864000   1100000
 | 
			
		||||
		1056000  1100000
 | 
			
		||||
		1320000  1100000
 | 
			
		||||
		1440000  1100000
 | 
			
		||||
		1608000  1100000
 | 
			
		||||
		1800000  1100000
 | 
			
		||||
	>;
 | 
			
		||||
	clock-latency = <200000>;
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
&CPU2 {
 | 
			
		||||
	operating-points = <
 | 
			
		||||
		/* kHz   uV (fixed) */
 | 
			
		||||
		864000   1100000
 | 
			
		||||
		1056000  1100000
 | 
			
		||||
		1320000  1100000
 | 
			
		||||
		1440000  1100000
 | 
			
		||||
		1608000  1100000
 | 
			
		||||
		1800000  1100000
 | 
			
		||||
	>;
 | 
			
		||||
	clock-latency = <200000>;
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
&CPU3 {
 | 
			
		||||
	operating-points = <
 | 
			
		||||
		/* kHz   uV (fixed) */
 | 
			
		||||
		864000   1100000
 | 
			
		||||
		1056000  1100000
 | 
			
		||||
		1320000  1100000
 | 
			
		||||
		1440000  1100000
 | 
			
		||||
		1608000  1100000
 | 
			
		||||
		1800000  1100000
 | 
			
		||||
	>;
 | 
			
		||||
	clock-latency = <200000>;
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
&rpm_glink {
 | 
			
		||||
	status = "disabled";
 | 
			
		||||
};
 | 
			
		||||
@@ -76,6 +76,15 @@ define Device/edgecore_eap101
 | 
			
		||||
endef
 | 
			
		||||
TARGET_DEVICES += edgecore_eap101
 | 
			
		||||
 | 
			
		||||
define Device/emplus_wap386v2
 | 
			
		||||
  DEVICE_TITLE := Emplus WAP386v2
 | 
			
		||||
  DEVICE_DTS := qcom-ipq6018-emplus-wap386v2
 | 
			
		||||
  DEVICE_DTS_CONFIG := config@cp03-c1
 | 
			
		||||
  SUPPORTED_DEVICES := emplus,wap386v2
 | 
			
		||||
  DEVICE_PACKAGES := ath11k-wifi-qcom-ipq6018 uboot-env
 | 
			
		||||
endef
 | 
			
		||||
TARGET_DEVICES += emplus_wap386v2
 | 
			
		||||
 | 
			
		||||
define Device/indio_um-310ax-v1
 | 
			
		||||
  DEVICE_TITLE := Indio UM-310AX V1
 | 
			
		||||
  DEVICE_DTS := qcom-ipq6018-indio-um-310ax-v1
 | 
			
		||||
 
 | 
			
		||||
@@ -21,6 +21,7 @@ edgecore,oap103)
 | 
			
		||||
        ucidef_set_led_wlan "power" "POWER" "green:power" "default-on"
 | 
			
		||||
	;;
 | 
			
		||||
sonicfi,rap630w-311g|\
 | 
			
		||||
sonicfi,rap650c|\
 | 
			
		||||
cybertan,eww631-b1)
 | 
			
		||||
	ucidef_set_led_default "power" "POWER" "sys:blue" "on"
 | 
			
		||||
	;;
 | 
			
		||||
 
 | 
			
		||||
@@ -24,6 +24,7 @@ qcom_setup_interfaces()
 | 
			
		||||
	edgecore,eap102|\
 | 
			
		||||
	edgecore,oap102|\
 | 
			
		||||
	edgecore,oap103|\
 | 
			
		||||
	sonicfi,rap650c|\
 | 
			
		||||
	cig,wf196)
 | 
			
		||||
		ucidef_set_interface_lan "eth1"
 | 
			
		||||
		ucidef_set_interface_wan "eth0"
 | 
			
		||||
@@ -50,6 +51,16 @@ qcom_setup_macs()
 | 
			
		||||
		ip link set eth1 address $lan_mac
 | 
			
		||||
		ucidef_set_label_macaddr $wan_mac
 | 
			
		||||
		;;
 | 
			
		||||
	sonicfi,rap650c)
 | 
			
		||||
		mac=$(fw_printenv -n BaseMacAddress)
 | 
			
		||||
		[ -z "$mac" ] && return;
 | 
			
		||||
		wan_mac=$(macaddr_canonicalize $mac)
 | 
			
		||||
		lan_mac=$(macaddr_add "$wan_mac" 1)
 | 
			
		||||
		ucidef_set_network_device_mac eth0 $wan_mac
 | 
			
		||||
		ucidef_set_network_device_mac eth1 $lan_mac
 | 
			
		||||
		ip link set eth0 address $wan_mac
 | 
			
		||||
		ip link set eth1 address $lan_mac
 | 
			
		||||
		;;
 | 
			
		||||
	*)
 | 
			
		||||
		wan_mac=$(cat /sys/class/net/eth0/address)
 | 
			
		||||
		lan_mac=$(macaddr_add "$wan_mac" 1)
 | 
			
		||||
 
 | 
			
		||||
@@ -16,6 +16,20 @@ ath11k_generate_macs() {
 | 
			
		||||
	echo -ne \\x${mac3//:/\\x} >> /lib/firmware/ath11k-macs
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
ath11k_generate_macs_rap650c() {
 | 
			
		||||
	mac=$(fw_printenv -n BaseMacAddress)
 | 
			
		||||
	[ -z "$mac" ] && return;
 | 
			
		||||
 | 
			
		||||
	touch /lib/firmware/ath11k-macs
 | 
			
		||||
	eth=$(macaddr_canonicalize $mac)
 | 
			
		||||
	mac1=$(macaddr_add $eth 3)
 | 
			
		||||
	mac2=$(macaddr_add $eth 2)
 | 
			
		||||
	mac3=$(macaddr_add $eth 4)
 | 
			
		||||
	echo -ne \\x${mac1//:/\\x} >> /lib/firmware/ath11k-macs
 | 
			
		||||
	echo -ne \\x${mac2//:/\\x} >> /lib/firmware/ath11k-macs
 | 
			
		||||
	echo -ne \\x${mac3//:/\\x} >> /lib/firmware/ath11k-macs
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
ath11k_generate_macs_wf196() {
 | 
			
		||||
	touch /lib/firmware/ath11k-macs
 | 
			
		||||
	mac=$(grep BaseMacAddress= /dev/mtd18 | cut -dx -f2)
 | 
			
		||||
@@ -63,6 +77,7 @@ case "$FIRMWARE" in
 | 
			
		||||
	tplink,ex227|\
 | 
			
		||||
	tplink,ex447|\
 | 
			
		||||
	yuncore,ax840|\
 | 
			
		||||
	sonicfi,rap650c|\
 | 
			
		||||
	sercomm,wallaby)
 | 
			
		||||
                caldata_extract "0:ART" 0x1000 0x20000
 | 
			
		||||
		;;
 | 
			
		||||
@@ -97,6 +112,9 @@ ath11k-macs)
 | 
			
		||||
	cig,wf196)
 | 
			
		||||
		ath11k_generate_macs_wf196
 | 
			
		||||
		;;
 | 
			
		||||
	sonicfi,rap650c)
 | 
			
		||||
		ath11k_generate_macs_rap650c
 | 
			
		||||
		;;
 | 
			
		||||
	esac
 | 
			
		||||
	;;
 | 
			
		||||
ath11k/IPQ8074/hw2.0/board.bin)
 | 
			
		||||
 
 | 
			
		||||
@@ -10,7 +10,8 @@ case "$board" in
 | 
			
		||||
        ln -s /sys/kernel/debug/ath11k/ipq6018\ hw1.0/mac1/fw_stats/pdev_stats /tmp/pdev_stats_phy2g
 | 
			
		||||
        ;;
 | 
			
		||||
    "edgecore,eap102"|\
 | 
			
		||||
    "edgecore,oap103")
 | 
			
		||||
    "edgecore,oap103"|\
 | 
			
		||||
    "sonicfi,rap650c")
 | 
			
		||||
        ln -s /sys/kernel/debug/ath11k/ipq8074\ hw2.0/mac0/fw_stats/pdev_stats /tmp/pdev_stats_phy5g
 | 
			
		||||
        ln -s /sys/kernel/debug/ath11k/ipq8074\ hw2.0/mac1/fw_stats/pdev_stats /tmp/pdev_stats_phy2g
 | 
			
		||||
        ;;
 | 
			
		||||
 
 | 
			
		||||
@@ -29,6 +29,7 @@ platform_check_image() {
 | 
			
		||||
	edgecore,oap102|\
 | 
			
		||||
	edgecore,oap103|\
 | 
			
		||||
	edgecore,eap106|\
 | 
			
		||||
	sonicfi,rap650c|\
 | 
			
		||||
	tplink,ex227|\
 | 
			
		||||
	tplink,ex447)
 | 
			
		||||
		[ "$magic_long" = "73797375" ] && return 0
 | 
			
		||||
@@ -83,5 +84,17 @@ platform_do_upgrade() {
 | 
			
		||||
		fi
 | 
			
		||||
		nand_upgrade_tar "$1"
 | 
			
		||||
		;;
 | 
			
		||||
	sonicfi,rap650c)
 | 
			
		||||
		boot_part=$(fw_printenv -n bootfrom)
 | 
			
		||||
		[ ${#boot_part} -eq 0 ] && boot_part=0
 | 
			
		||||
		echo "Current bootfrom is $boot_part"
 | 
			
		||||
		if [[ $boot_part == 1 ]]; then
 | 
			
		||||
			CI_UBIPART="rootfs"
 | 
			
		||||
			CI_FWSETENV="bootfrom 0"
 | 
			
		||||
		elif [[ $boot_part == 0 ]]; then
 | 
			
		||||
			CI_UBIPART="rootfs_1"
 | 
			
		||||
			CI_FWSETENV="bootfrom 1"
 | 
			
		||||
		fi
 | 
			
		||||
		nand_upgrade_tar "$1"
 | 
			
		||||
	esac
 | 
			
		||||
}
 | 
			
		||||
 
 | 
			
		||||
@@ -0,0 +1,650 @@
 | 
			
		||||
// SPDX-License-Identifier: GPL-2.0-only
 | 
			
		||||
/dts-v1/;
 | 
			
		||||
/* Copyright (c) 2020 The Linux Foundation. All rights reserved.
 | 
			
		||||
 */
 | 
			
		||||
#include "ipq8074.dtsi"
 | 
			
		||||
#include "ipq8074-hk-cpu.dtsi"
 | 
			
		||||
 | 
			
		||||
/ {
 | 
			
		||||
	#address-cells = <0x2>;
 | 
			
		||||
	#size-cells = <0x2>;
 | 
			
		||||
	model = "SonicFi RAP650C";
 | 
			
		||||
	compatible = "sonicfi,rap650c", "qcom,ipq8074-ap-hk09", "qcom,ipq8074";
 | 
			
		||||
	qcom,msm-id = <0x157 0x0>, <0x187 0x0>;
 | 
			
		||||
	interrupt-parent = <&intc>;
 | 
			
		||||
 | 
			
		||||
	aliases {
 | 
			
		||||
		serial0 = &blsp1_uart5;
 | 
			
		||||
		/* Aliases as required by u-boot to patch MAC addresses */
 | 
			
		||||
		ethernet0 = "/soc/dp1";
 | 
			
		||||
		ethernet1 = "/soc/dp2";
 | 
			
		||||
 | 
			
		||||
		led-boot = &led_power;
 | 
			
		||||
		led-failsafe = &led_power;
 | 
			
		||||
		led-running = &led_power;
 | 
			
		||||
		led-upgrade = &led_power;
 | 
			
		||||
	};
 | 
			
		||||
 | 
			
		||||
	chosen {
 | 
			
		||||
		stdout-path = "serial0";
 | 
			
		||||
	};
 | 
			
		||||
 | 
			
		||||
	soc {
 | 
			
		||||
		pinctrl@1000000 {
 | 
			
		||||
			button_pins: button_pins {
 | 
			
		||||
				reset_button {
 | 
			
		||||
					pins = "gpio57";
 | 
			
		||||
					function = "gpio";
 | 
			
		||||
					drive-strength = <8>;
 | 
			
		||||
					bias-pull-up;
 | 
			
		||||
				};
 | 
			
		||||
			};
 | 
			
		||||
 | 
			
		||||
			usb_mux_sel_pins: usb_mux_pins {
 | 
			
		||||
				mux {
 | 
			
		||||
					pins = "gpio27";
 | 
			
		||||
					function = "gpio";
 | 
			
		||||
					drive-strength = <8>;
 | 
			
		||||
					bias-pull-down;
 | 
			
		||||
				};
 | 
			
		||||
			};
 | 
			
		||||
 | 
			
		||||
			pcie0_pins: pcie_pins {
 | 
			
		||||
				pcie0_rst {
 | 
			
		||||
					pins = "gpio58";
 | 
			
		||||
					function = "pcie0_rst";
 | 
			
		||||
					drive-strength = <8>;
 | 
			
		||||
					bias-pull-down;
 | 
			
		||||
				};
 | 
			
		||||
				pcie0_wake {
 | 
			
		||||
					pins = "gpio59";
 | 
			
		||||
					function = "pcie0_wake";
 | 
			
		||||
					drive-strength = <8>;
 | 
			
		||||
					bias-pull-down;
 | 
			
		||||
				};
 | 
			
		||||
			};
 | 
			
		||||
 | 
			
		||||
			mdio_pins: mdio_pinmux {
 | 
			
		||||
				mux_0 {
 | 
			
		||||
					pins = "gpio68";
 | 
			
		||||
					function = "mdc";
 | 
			
		||||
					drive-strength = <8>;
 | 
			
		||||
					bias-pull-up;
 | 
			
		||||
				};
 | 
			
		||||
				mux_1 {
 | 
			
		||||
					pins = "gpio69";
 | 
			
		||||
					function = "mdio";
 | 
			
		||||
					drive-strength = <8>;
 | 
			
		||||
					bias-pull-up;
 | 
			
		||||
				};
 | 
			
		||||
				mux_2 {
 | 
			
		||||
					pins = "gpio25";
 | 
			
		||||
					function = "gpio";
 | 
			
		||||
					bias-pull-up;
 | 
			
		||||
				};
 | 
			
		||||
				mux_3 {
 | 
			
		||||
					pins = "gpio44";
 | 
			
		||||
					function = "gpio";
 | 
			
		||||
					bias-pull-up;
 | 
			
		||||
				};
 | 
			
		||||
			};
 | 
			
		||||
 | 
			
		||||
			led_pins: led_pins {
 | 
			
		||||
				red {
 | 
			
		||||
					pins = "gpio0";
 | 
			
		||||
					function = "gpio";
 | 
			
		||||
					drive-strength = <8>;
 | 
			
		||||
					bias-pull-down;
 | 
			
		||||
				};
 | 
			
		||||
 | 
			
		||||
				green {
 | 
			
		||||
					pins = "gpio2";
 | 
			
		||||
					function = "gpio";
 | 
			
		||||
					drive-strength = <8>;
 | 
			
		||||
					bias-pull-down;
 | 
			
		||||
				};
 | 
			
		||||
 | 
			
		||||
				blue {
 | 
			
		||||
					pins = "gpio9";
 | 
			
		||||
					function = "gpio";
 | 
			
		||||
					drive-strength = <8>;
 | 
			
		||||
					bias-pull-down;
 | 
			
		||||
				};
 | 
			
		||||
			};
 | 
			
		||||
 | 
			
		||||
			spi_3_pins: spi_3_pins {
 | 
			
		||||
				mux {
 | 
			
		||||
					pins = "gpio50", "gpio52", "gpio53";
 | 
			
		||||
					function = "blsp3_spi";
 | 
			
		||||
					drive-strength = <8>;
 | 
			
		||||
					bias-disable;
 | 
			
		||||
				};
 | 
			
		||||
				spi_cs {
 | 
			
		||||
					pins = "gpio22";
 | 
			
		||||
					function = "blsp3_spi2";
 | 
			
		||||
					drive-strength = <8>;
 | 
			
		||||
					bias-disable;
 | 
			
		||||
				};
 | 
			
		||||
				quartz_interrupt {
 | 
			
		||||
					pins = "gpio47";
 | 
			
		||||
					function = "gpio";
 | 
			
		||||
					input;
 | 
			
		||||
					bias-disable;
 | 
			
		||||
				};
 | 
			
		||||
				quartz_reset {
 | 
			
		||||
					pins = "gpio21";
 | 
			
		||||
					function = "gpio";
 | 
			
		||||
					output-low;
 | 
			
		||||
					bias-disable;
 | 
			
		||||
				};
 | 
			
		||||
			};
 | 
			
		||||
		};
 | 
			
		||||
 | 
			
		||||
		serial@78b3000 {
 | 
			
		||||
			status = "ok";
 | 
			
		||||
		};
 | 
			
		||||
 | 
			
		||||
		dp1 {
 | 
			
		||||
			device_type = "network";
 | 
			
		||||
			compatible = "qcom,nss-dp";
 | 
			
		||||
			qcom,id = <5>;
 | 
			
		||||
			reg = <0x3a001800 0x200>;
 | 
			
		||||
			qcom,mactype = <0>;
 | 
			
		||||
			local-mac-address = [000000000000];
 | 
			
		||||
			qcom,link-poll = <1>;
 | 
			
		||||
			qcom,phy-mdio-addr = <24>;
 | 
			
		||||
			phy-mode = "sgmii";
 | 
			
		||||
		};
 | 
			
		||||
 | 
			
		||||
		dp2 {
 | 
			
		||||
			device_type = "network";
 | 
			
		||||
			compatible = "qcom,nss-dp";
 | 
			
		||||
			qcom,id = <6>;
 | 
			
		||||
			reg = <0x3a001a00 0x200>;
 | 
			
		||||
			qcom,mactype = <0>;
 | 
			
		||||
			local-mac-address = [000000000000];
 | 
			
		||||
			qcom,link-poll = <1>;
 | 
			
		||||
			qcom,phy-mdio-addr = <28>;
 | 
			
		||||
			phy-mode = "sgmii";
 | 
			
		||||
		};
 | 
			
		||||
 | 
			
		||||
		spi@78b5000 {
 | 
			
		||||
			status = "ok";
 | 
			
		||||
			pinctrl-0 = <&spi_0_pins>;
 | 
			
		||||
			pinctrl-names = "default";
 | 
			
		||||
			cs-select = <0>;
 | 
			
		||||
 | 
			
		||||
			m25p80@0 {
 | 
			
		||||
				  compatible = "n25q128a11";
 | 
			
		||||
				  #address-cells = <1>;
 | 
			
		||||
				  #size-cells = <1>;
 | 
			
		||||
				  reg = <0>;
 | 
			
		||||
				  spi-max-frequency = <50000000>;
 | 
			
		||||
			};
 | 
			
		||||
		};
 | 
			
		||||
 | 
			
		||||
		spi@78b8000 {
 | 
			
		||||
			status = "ok";
 | 
			
		||||
			pinctrl-0 = <&spi_3_pins>;
 | 
			
		||||
			pinctrl-names = "default";
 | 
			
		||||
			cs-select = <2>;
 | 
			
		||||
			quartz-reset-gpio = <&tlmm 21 1>;
 | 
			
		||||
 | 
			
		||||
			spidev3: spi@3 {
 | 
			
		||||
				  compatible = "qti,spidev";
 | 
			
		||||
				  reg = <0>;
 | 
			
		||||
				  spi-max-frequency = <24000000>;
 | 
			
		||||
			};
 | 
			
		||||
		};
 | 
			
		||||
 | 
			
		||||
		dma@7984000 {
 | 
			
		||||
			 status = "ok";
 | 
			
		||||
		};
 | 
			
		||||
 | 
			
		||||
		nand@79b0000 {
 | 
			
		||||
			status = "ok";
 | 
			
		||||
 | 
			
		||||
			nand@0 {
 | 
			
		||||
				reg = <0>;
 | 
			
		||||
				#address-cells = <1>;
 | 
			
		||||
				#size-cells = <1>;
 | 
			
		||||
 | 
			
		||||
				nand-ecc-strength = <4>;
 | 
			
		||||
				nand-ecc-step-size = <512>;
 | 
			
		||||
				nand-bus-width = <8>;
 | 
			
		||||
			};
 | 
			
		||||
		};
 | 
			
		||||
 | 
			
		||||
		qusb@79000 {
 | 
			
		||||
			status = "ok";
 | 
			
		||||
		};
 | 
			
		||||
 | 
			
		||||
		ssphy@78000 {
 | 
			
		||||
			status = "ok";
 | 
			
		||||
		};
 | 
			
		||||
 | 
			
		||||
		usb3@8A00000 {
 | 
			
		||||
			status = "ok";
 | 
			
		||||
		};
 | 
			
		||||
 | 
			
		||||
		qusb@59000 {
 | 
			
		||||
			status = "ok";
 | 
			
		||||
		};
 | 
			
		||||
 | 
			
		||||
		ssphy@58000 {
 | 
			
		||||
			status = "ok";
 | 
			
		||||
		};
 | 
			
		||||
 | 
			
		||||
		usb3@8C00000 {
 | 
			
		||||
			status = "ok";
 | 
			
		||||
		};
 | 
			
		||||
 | 
			
		||||
		phy@84000 {
 | 
			
		||||
			status = "ok";
 | 
			
		||||
		};
 | 
			
		||||
 | 
			
		||||
		phy@86000 {
 | 
			
		||||
			status = "ok";
 | 
			
		||||
		};
 | 
			
		||||
 | 
			
		||||
		pci@20000000 {
 | 
			
		||||
			perst-gpio = <&tlmm 58 1>;
 | 
			
		||||
			status = "ok";
 | 
			
		||||
		};
 | 
			
		||||
 | 
			
		||||
		gpio_keys {
 | 
			
		||||
			compatible = "gpio-keys";
 | 
			
		||||
			pinctrl-0 = <&button_pins>;
 | 
			
		||||
			pinctrl-names = "default";
 | 
			
		||||
			status = "ok";
 | 
			
		||||
 | 
			
		||||
			button@1 {
 | 
			
		||||
				label = "reset";
 | 
			
		||||
				linux,code = <KEY_RESTART>;
 | 
			
		||||
				gpios = <&tlmm 57 GPIO_ACTIVE_LOW>;
 | 
			
		||||
				linux,input-type = <1>;
 | 
			
		||||
				debounce-interval = <60>;
 | 
			
		||||
			};
 | 
			
		||||
		};
 | 
			
		||||
 | 
			
		||||
		leds {
 | 
			
		||||
			compatible = "gpio-leds";
 | 
			
		||||
			pinctrl-0 = <&led_pins>;
 | 
			
		||||
			pinctrl-names = "default";
 | 
			
		||||
 | 
			
		||||
			red {
 | 
			
		||||
				label = "sys:red";
 | 
			
		||||
				gpio = <&tlmm 0 GPIO_ACTIVE_HIGH>;
 | 
			
		||||
				default-state = "off";
 | 
			
		||||
			};
 | 
			
		||||
 | 
			
		||||
			green {
 | 
			
		||||
				label = "sys:green";
 | 
			
		||||
				gpio = <&tlmm 2 GPIO_ACTIVE_HIGH>;
 | 
			
		||||
				default-state = "off";
 | 
			
		||||
			};
 | 
			
		||||
 | 
			
		||||
			led_power: blue {
 | 
			
		||||
				label = "sys:blue";
 | 
			
		||||
				gpio = <&tlmm 9 GPIO_ACTIVE_HIGH>;
 | 
			
		||||
				default-state = "off";
 | 
			
		||||
			};
 | 
			
		||||
		};
 | 
			
		||||
 | 
			
		||||
		mdio: mdio@90000 {
 | 
			
		||||
			pinctrl-0 = <&mdio_pins>;
 | 
			
		||||
			pinctrl-names = "default";
 | 
			
		||||
			phy-reset-gpio = <&tlmm 37 0 &tlmm 25 0 &tlmm 44 0>;
 | 
			
		||||
			phy0: ethernet-phy@0 {
 | 
			
		||||
				reg = <0>;
 | 
			
		||||
			};
 | 
			
		||||
			phy1: ethernet-phy@1 {
 | 
			
		||||
				reg = <1>;
 | 
			
		||||
			};
 | 
			
		||||
			phy2: ethernet-phy@2 {
 | 
			
		||||
				reg = <2>;
 | 
			
		||||
			};
 | 
			
		||||
			phy3: ethernet-phy@3 {
 | 
			
		||||
				reg = <3>;
 | 
			
		||||
			};
 | 
			
		||||
			phy4: ethernet-phy@4 {
 | 
			
		||||
				reg = <24>;
 | 
			
		||||
			};
 | 
			
		||||
			phy5: ethernet-phy@5 {
 | 
			
		||||
				reg = <28>;
 | 
			
		||||
			};
 | 
			
		||||
		};
 | 
			
		||||
 | 
			
		||||
		ess-switch@3a000000 {
 | 
			
		||||
			switch_cpu_bmp = <0x1>;  /* cpu port bitmap */
 | 
			
		||||
			switch_lan_bmp = <0x3e>; /* lan port bitmap */
 | 
			
		||||
			switch_wan_bmp = <0x40>; /* wan port bitmap */
 | 
			
		||||
			switch_mac_mode = <0x0>; /* mac mode for uniphy instance0*/
 | 
			
		||||
			switch_mac_mode1 = <0xf>; /* mac mode for uniphy instance1*/
 | 
			
		||||
			switch_mac_mode2 = <0xf>; /* mac mode for uniphy instance2*/
 | 
			
		||||
			bm_tick_mode = <0>; /* bm tick mode */
 | 
			
		||||
			tm_tick_mode = <0>; /* tm tick mode */
 | 
			
		||||
			qcom,port_phyinfo {
 | 
			
		||||
				port@0 {
 | 
			
		||||
					port_id = <1>;
 | 
			
		||||
					phy_address = <0>;
 | 
			
		||||
				};
 | 
			
		||||
				port@1 {
 | 
			
		||||
					port_id = <2>;
 | 
			
		||||
					phy_address = <1>;
 | 
			
		||||
				};
 | 
			
		||||
				port@2 {
 | 
			
		||||
					port_id = <3>;
 | 
			
		||||
					phy_address = <2>;
 | 
			
		||||
				};
 | 
			
		||||
				port@3 {
 | 
			
		||||
					port_id = <4>;
 | 
			
		||||
					phy_address = <3>;
 | 
			
		||||
				};
 | 
			
		||||
				port@4 {
 | 
			
		||||
					port_id = <5>;
 | 
			
		||||
					phy_address = <24>;
 | 
			
		||||
					port_mac_sel = "QGMAC_PORT";
 | 
			
		||||
				};
 | 
			
		||||
				port@5 {
 | 
			
		||||
					port_id = <6>;
 | 
			
		||||
					phy_address = <28>;
 | 
			
		||||
					port_mac_sel = "QGMAC_PORT";
 | 
			
		||||
				};
 | 
			
		||||
			};
 | 
			
		||||
			port_scheduler_resource {
 | 
			
		||||
				port@0 {
 | 
			
		||||
					port_id = <0>;
 | 
			
		||||
					ucast_queue = <0 143>;
 | 
			
		||||
					mcast_queue = <256 271>;
 | 
			
		||||
					l0sp = <0 35>;
 | 
			
		||||
					l0cdrr = <0 47>;
 | 
			
		||||
					l0edrr = <0 47>;
 | 
			
		||||
					l1cdrr = <0 7>;
 | 
			
		||||
					l1edrr = <0 7>;
 | 
			
		||||
				};
 | 
			
		||||
				port@1 {
 | 
			
		||||
					port_id = <1>;
 | 
			
		||||
					ucast_queue = <144 159>;
 | 
			
		||||
					mcast_queue = <272 275>;
 | 
			
		||||
					l0sp = <36 39>;
 | 
			
		||||
					l0cdrr = <48 63>;
 | 
			
		||||
					l0edrr = <48 63>;
 | 
			
		||||
					l1cdrr = <8 11>;
 | 
			
		||||
					l1edrr = <8 11>;
 | 
			
		||||
				};
 | 
			
		||||
				port@2 {
 | 
			
		||||
					port_id = <2>;
 | 
			
		||||
					ucast_queue = <160 175>;
 | 
			
		||||
					mcast_queue = <276 279>;
 | 
			
		||||
					l0sp = <40 43>;
 | 
			
		||||
					l0cdrr = <64 79>;
 | 
			
		||||
					l0edrr = <64 79>;
 | 
			
		||||
					l1cdrr = <12 15>;
 | 
			
		||||
					l1edrr = <12 15>;
 | 
			
		||||
				};
 | 
			
		||||
				port@3 {
 | 
			
		||||
					port_id = <3>;
 | 
			
		||||
					ucast_queue = <176 191>;
 | 
			
		||||
					mcast_queue = <280 283>;
 | 
			
		||||
					l0sp = <44 47>;
 | 
			
		||||
					l0cdrr = <80 95>;
 | 
			
		||||
					l0edrr = <80 95>;
 | 
			
		||||
					l1cdrr = <16 19>;
 | 
			
		||||
					l1edrr = <16 19>;
 | 
			
		||||
				};
 | 
			
		||||
				port@4 {
 | 
			
		||||
					port_id = <4>;
 | 
			
		||||
					ucast_queue = <192 207>;
 | 
			
		||||
					mcast_queue = <284 287>;
 | 
			
		||||
					l0sp = <48 51>;
 | 
			
		||||
					l0cdrr = <96 111>;
 | 
			
		||||
					l0edrr = <96 111>;
 | 
			
		||||
					l1cdrr = <20 23>;
 | 
			
		||||
					l1edrr = <20 23>;
 | 
			
		||||
				};
 | 
			
		||||
				port@5 {
 | 
			
		||||
					port_id = <5>;
 | 
			
		||||
					ucast_queue = <208 223>;
 | 
			
		||||
					mcast_queue = <288 291>;
 | 
			
		||||
					l0sp = <52 55>;
 | 
			
		||||
					l0cdrr = <112 127>;
 | 
			
		||||
					l0edrr = <112 127>;
 | 
			
		||||
					l1cdrr = <24 27>;
 | 
			
		||||
					l1edrr = <24 27>;
 | 
			
		||||
				};
 | 
			
		||||
				port@6 {
 | 
			
		||||
					port_id = <6>;
 | 
			
		||||
					ucast_queue = <224 239>;
 | 
			
		||||
					mcast_queue = <292 295>;
 | 
			
		||||
					l0sp = <56 59>;
 | 
			
		||||
					l0cdrr = <128 143>;
 | 
			
		||||
					l0edrr = <128 143>;
 | 
			
		||||
					l1cdrr = <28 31>;
 | 
			
		||||
					l1edrr = <28 31>;
 | 
			
		||||
				};
 | 
			
		||||
				port@7 {
 | 
			
		||||
					port_id = <7>;
 | 
			
		||||
					ucast_queue = <240 255>;
 | 
			
		||||
					mcast_queue = <296 299>;
 | 
			
		||||
					l0sp = <60 63>;
 | 
			
		||||
					l0cdrr = <144 159>;
 | 
			
		||||
					l0edrr = <144 159>;
 | 
			
		||||
					l1cdrr = <32 35>;
 | 
			
		||||
					l1edrr = <32 35>;
 | 
			
		||||
				};
 | 
			
		||||
			};
 | 
			
		||||
			port_scheduler_config {
 | 
			
		||||
				port@0 {
 | 
			
		||||
					port_id = <0>;
 | 
			
		||||
					l1scheduler {
 | 
			
		||||
						group@0 {
 | 
			
		||||
							sp = <0 1>; /*L0 SPs*/
 | 
			
		||||
							/*cpri cdrr epri edrr*/
 | 
			
		||||
							cfg = <0 0 0 0>;
 | 
			
		||||
						};
 | 
			
		||||
					};
 | 
			
		||||
					l0scheduler {
 | 
			
		||||
						group@0 {
 | 
			
		||||
							/*unicast queues*/
 | 
			
		||||
							ucast_queue = <0 4 8>;
 | 
			
		||||
							/*multicast queues*/
 | 
			
		||||
							mcast_queue = <256 260>;
 | 
			
		||||
							/*sp cpri cdrr epri edrr*/
 | 
			
		||||
							cfg = <0 0 0 0 0>;
 | 
			
		||||
						};
 | 
			
		||||
						group@1 {
 | 
			
		||||
							ucast_queue = <1 5 9>;
 | 
			
		||||
							mcast_queue = <257 261>;
 | 
			
		||||
							cfg = <0 1 1 1 1>;
 | 
			
		||||
						};
 | 
			
		||||
						group@2 {
 | 
			
		||||
							ucast_queue = <2 6 10>;
 | 
			
		||||
							mcast_queue = <258 262>;
 | 
			
		||||
							cfg = <0 2 2 2 2>;
 | 
			
		||||
						};
 | 
			
		||||
						group@3 {
 | 
			
		||||
							ucast_queue = <3 7 11>;
 | 
			
		||||
							mcast_queue = <259 263>;
 | 
			
		||||
							cfg = <0 3 3 3 3>;
 | 
			
		||||
						};
 | 
			
		||||
					};
 | 
			
		||||
				};
 | 
			
		||||
				port@1 {
 | 
			
		||||
					port_id = <1>;
 | 
			
		||||
					l1scheduler {
 | 
			
		||||
						group@0 {
 | 
			
		||||
							sp = <36>;
 | 
			
		||||
							cfg = <0 8 0 8>;
 | 
			
		||||
						};
 | 
			
		||||
						group@1 {
 | 
			
		||||
							sp = <37>;
 | 
			
		||||
							cfg = <1 9 1 9>;
 | 
			
		||||
						};
 | 
			
		||||
					};
 | 
			
		||||
					l0scheduler {
 | 
			
		||||
						group@0 {
 | 
			
		||||
							ucast_queue = <144>;
 | 
			
		||||
							ucast_loop_pri = <16>;
 | 
			
		||||
							mcast_queue = <272>;
 | 
			
		||||
							mcast_loop_pri = <4>;
 | 
			
		||||
							cfg = <36 0 48 0 48>;
 | 
			
		||||
						};
 | 
			
		||||
					};
 | 
			
		||||
				};
 | 
			
		||||
				port@2 {
 | 
			
		||||
					port_id = <2>;
 | 
			
		||||
					l1scheduler {
 | 
			
		||||
						group@0 {
 | 
			
		||||
							sp = <40>;
 | 
			
		||||
							cfg = <0 12 0 12>;
 | 
			
		||||
						};
 | 
			
		||||
						group@1 {
 | 
			
		||||
							sp = <41>;
 | 
			
		||||
							cfg = <1 13 1 13>;
 | 
			
		||||
						};
 | 
			
		||||
					};
 | 
			
		||||
					l0scheduler {
 | 
			
		||||
						group@0 {
 | 
			
		||||
							ucast_queue = <160>;
 | 
			
		||||
							ucast_loop_pri = <16>;
 | 
			
		||||
							mcast_queue = <276>;
 | 
			
		||||
							mcast_loop_pri = <4>;
 | 
			
		||||
							cfg = <40 0 64 0 64>;
 | 
			
		||||
						};
 | 
			
		||||
					};
 | 
			
		||||
				};
 | 
			
		||||
				port@3 {
 | 
			
		||||
					port_id = <3>;
 | 
			
		||||
					l1scheduler {
 | 
			
		||||
						group@0 {
 | 
			
		||||
							sp = <44>;
 | 
			
		||||
							cfg = <0 16 0 16>;
 | 
			
		||||
						};
 | 
			
		||||
						group@1 {
 | 
			
		||||
							sp = <45>;
 | 
			
		||||
							cfg = <1 17 1 17>;
 | 
			
		||||
						};
 | 
			
		||||
					};
 | 
			
		||||
					l0scheduler {
 | 
			
		||||
						group@0 {
 | 
			
		||||
							ucast_queue = <176>;
 | 
			
		||||
							ucast_loop_pri = <16>;
 | 
			
		||||
							mcast_queue = <280>;
 | 
			
		||||
							mcast_loop_pri = <4>;
 | 
			
		||||
							cfg = <44 0 80 0 80>;
 | 
			
		||||
						};
 | 
			
		||||
					};
 | 
			
		||||
				};
 | 
			
		||||
				port@4 {
 | 
			
		||||
					port_id = <4>;
 | 
			
		||||
					l1scheduler {
 | 
			
		||||
						group@0 {
 | 
			
		||||
							sp = <48>;
 | 
			
		||||
							cfg = <0 20 0 20>;
 | 
			
		||||
						};
 | 
			
		||||
						group@1 {
 | 
			
		||||
							sp = <49>;
 | 
			
		||||
							cfg = <1 21 1 21>;
 | 
			
		||||
						};
 | 
			
		||||
					};
 | 
			
		||||
					l0scheduler {
 | 
			
		||||
						group@0 {
 | 
			
		||||
							ucast_queue = <192>;
 | 
			
		||||
							ucast_loop_pri = <16>;
 | 
			
		||||
							mcast_queue = <284>;
 | 
			
		||||
							mcast_loop_pri = <4>;
 | 
			
		||||
							cfg = <48 0 96 0 96>;
 | 
			
		||||
						};
 | 
			
		||||
					};
 | 
			
		||||
				};
 | 
			
		||||
				port@5 {
 | 
			
		||||
					port_id = <5>;
 | 
			
		||||
					l1scheduler {
 | 
			
		||||
						group@0 {
 | 
			
		||||
							sp = <52>;
 | 
			
		||||
							cfg = <0 24 0 24>;
 | 
			
		||||
						};
 | 
			
		||||
						group@1 {
 | 
			
		||||
							sp = <53>;
 | 
			
		||||
							cfg = <1 25 1 25>;
 | 
			
		||||
						};
 | 
			
		||||
					};
 | 
			
		||||
					l0scheduler {
 | 
			
		||||
						group@0 {
 | 
			
		||||
							ucast_queue = <208>;
 | 
			
		||||
							ucast_loop_pri = <16>;
 | 
			
		||||
							mcast_queue = <288>;
 | 
			
		||||
							mcast_loop_pri = <4>;
 | 
			
		||||
							cfg = <52 0 112 0 112>;
 | 
			
		||||
						};
 | 
			
		||||
					};
 | 
			
		||||
				};
 | 
			
		||||
				port@6 {
 | 
			
		||||
					port_id = <6>;
 | 
			
		||||
					l1scheduler {
 | 
			
		||||
						group@0 {
 | 
			
		||||
							sp = <56>;
 | 
			
		||||
							cfg = <0 28 0 28>;
 | 
			
		||||
						};
 | 
			
		||||
						group@1 {
 | 
			
		||||
							sp = <57>;
 | 
			
		||||
							cfg = <1 29 1 29>;
 | 
			
		||||
						};
 | 
			
		||||
					};
 | 
			
		||||
					l0scheduler {
 | 
			
		||||
						group@0 {
 | 
			
		||||
							ucast_queue = <224>;
 | 
			
		||||
							ucast_loop_pri = <16>;
 | 
			
		||||
							mcast_queue = <292>;
 | 
			
		||||
							mcast_loop_pri = <4>;
 | 
			
		||||
							cfg = <56 0 128 0 128>;
 | 
			
		||||
						};
 | 
			
		||||
					};
 | 
			
		||||
				};
 | 
			
		||||
				port@7 {
 | 
			
		||||
					port_id = <7>;
 | 
			
		||||
					l1scheduler {
 | 
			
		||||
						group@0 {
 | 
			
		||||
							sp = <60>;
 | 
			
		||||
							cfg = <0 32 0 32>;
 | 
			
		||||
						};
 | 
			
		||||
						group@1 {
 | 
			
		||||
							sp = <61>;
 | 
			
		||||
							cfg = <1 33 1 33>;
 | 
			
		||||
						};
 | 
			
		||||
					};
 | 
			
		||||
					l0scheduler {
 | 
			
		||||
						group@0 {
 | 
			
		||||
							ucast_queue = <240>;
 | 
			
		||||
							ucast_loop_pri = <16>;
 | 
			
		||||
							mcast_queue = <296>;
 | 
			
		||||
							cfg = <60 0 144 0 144>;
 | 
			
		||||
						};
 | 
			
		||||
					};
 | 
			
		||||
				};
 | 
			
		||||
			};
 | 
			
		||||
		};
 | 
			
		||||
 | 
			
		||||
		nss-macsec0 {
 | 
			
		||||
			compatible = "qcom,nss-macsec";
 | 
			
		||||
			phy_addr = <0x18>;
 | 
			
		||||
			phy_access_mode = <0>;
 | 
			
		||||
			mdiobus = <&mdio>;
 | 
			
		||||
		};
 | 
			
		||||
		nss-macsec1 {
 | 
			
		||||
			compatible = "qcom,nss-macsec";
 | 
			
		||||
			phy_addr = <0x1c>;
 | 
			
		||||
			phy_access_mode = <0>;
 | 
			
		||||
			mdiobus = <&mdio>;
 | 
			
		||||
		};
 | 
			
		||||
	};
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
&wifi0 {
 | 
			
		||||
	qcom,board_id = <0x90>;
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
&wifi1 {
 | 
			
		||||
	qcom,board_id = <0x290>;
 | 
			
		||||
};
 | 
			
		||||
@@ -57,6 +57,17 @@ define Device/edgecore_eap106
 | 
			
		||||
endef
 | 
			
		||||
#TARGET_DEVICES += edgecore_eap106
 | 
			
		||||
 | 
			
		||||
define Device/sonicfi_rap650c
 | 
			
		||||
  DEVICE_TITLE := SonicFi RAP650C
 | 
			
		||||
  DEVICE_DTS := qcom-ipq807x-rap650c
 | 
			
		||||
  DEVICE_DTS_CONFIG=config@hk09
 | 
			
		||||
  SUPPORTED_DEVICES := sonicfi,rap650c
 | 
			
		||||
  DEVICE_PACKAGES := ath11k-wifi-sonicfi-rap650c uboot-envtools
 | 
			
		||||
  IMAGES := sysupgrade.tar nand-factory.bin nand-factory.ubi
 | 
			
		||||
  IMAGE/nand-factory.ubi := append-ubi
 | 
			
		||||
endef
 | 
			
		||||
TARGET_DEVICES += sonicfi_rap650c
 | 
			
		||||
 | 
			
		||||
define Device/tplink_ex227
 | 
			
		||||
  DEVICE_TITLE := TP-Link EX227
 | 
			
		||||
  DEVICE_DTS := qcom-ipq807x-ex227
 | 
			
		||||
 
 | 
			
		||||
@@ -6,7 +6,7 @@
 | 
			
		||||
 		return 0;
 | 
			
		||||
-	if (WARN_ON_ONCE(rate->nss < 1 || rate->nss > 8))
 | 
			
		||||
+	if (rate->nss < 1 || rate->nss > 8) {
 | 
			
		||||
+		printk_once(1, "invalid rate->nss: %d\n", rate->nss);
 | 
			
		||||
+		printk_once(KERN_WARNING "cfg80211_calculate_bitrate_he: invalid rate->nss: %d\n", rate->nss);
 | 
			
		||||
 		return 0;
 | 
			
		||||
-
 | 
			
		||||
+	}
 | 
			
		||||
 
 | 
			
		||||
@@ -0,0 +1,116 @@
 | 
			
		||||
Index: backports-20210222_001-5.4.164-b157d2276/drivers/net/wireless/ath/ath11k/peer.c
 | 
			
		||||
===================================================================
 | 
			
		||||
--- backports-20210222_001-5.4.164-b157d2276.orig/drivers/net/wireless/ath/ath11k/peer.c
 | 
			
		||||
+++ backports-20210222_001-5.4.164-b157d2276/drivers/net/wireless/ath/ath11k/peer.c
 | 
			
		||||
@@ -789,8 +789,6 @@ int ath11k_peer_delete(struct ath11k *ar
 | 
			
		||||
 #endif
 | 
			
		||||
 	lockdep_assert_held(&ar->conf_mutex);
 | 
			
		||||
 
 | 
			
		||||
-	reinit_completion(&ar->peer_delete_done);
 | 
			
		||||
-
 | 
			
		||||
 	ath11k_nss_peer_delete(ar->ab, vdev_id, addr);
 | 
			
		||||
 #ifdef CCPTCFG_ATH11K_NSS_SUPPORTPTCFG_ATH11K_NSS_SUPPORT
 | 
			
		||||
 	mutex_lock(&ar->ab->base_ast_lock);
 | 
			
		||||
@@ -799,33 +797,60 @@ int ath11k_peer_delete(struct ath11k *ar
 | 
			
		||||
 	spin_lock_bh(&ar->ab->base_lock);
 | 
			
		||||
 
 | 
			
		||||
 	peer = ath11k_peer_find_by_addr(ar->ab, addr);
 | 
			
		||||
-	if (peer) {
 | 
			
		||||
+	/* Check if the found peer is what we want to remove.
 | 
			
		||||
+	 * While the sta is transitioning to another band we may
 | 
			
		||||
+	 * have 2 peer with the same addr assigned to different
 | 
			
		||||
+	 * vdev_id. Make sure we are deleting the correct peer.
 | 
			
		||||
+	 */
 | 
			
		||||
+	if (peer && peer->vdev_id == vdev_id)
 | 
			
		||||
+		ath11k_peer_rhash_delete(ar->ab, peer);
 | 
			
		||||
+
 | 
			
		||||
+	/* Fallback to peer list search if the correct peer can't be found.
 | 
			
		||||
+	 * Skip the deletion of the peer from the rhash since it has already
 | 
			
		||||
+	 * been deleted in peer add.
 | 
			
		||||
+	 */
 | 
			
		||||
+	if (!peer)
 | 
			
		||||
+		peer = ath11k_peer_find(ar->ab, vdev_id, addr);
 | 
			
		||||
+
 | 
			
		||||
+
 | 
			
		||||
+	if (!peer) {
 | 
			
		||||
+		spin_unlock_bh(&ar->ab->base_lock);
 | 
			
		||||
+		mutex_unlock(&ar->ab->tbl_mtx_lock);
 | 
			
		||||
 #ifdef CPTCFG_ATH11K_NSS_SUPPORT
 | 
			
		||||
-		peer->delete_in_progress = true;
 | 
			
		||||
-		if (peer->self_ast_entry) {
 | 
			
		||||
-			ath11k_peer_del_ast(ar, peer->self_ast_entry);
 | 
			
		||||
-			peer->self_ast_entry = NULL;
 | 
			
		||||
-		}
 | 
			
		||||
+		mutex_unlock(&ar->ab->base_ast_lock);
 | 
			
		||||
+#endif
 | 
			
		||||
+		ath11k_warn(ar->ab,
 | 
			
		||||
+			    "failed to find peer vdev_id %d addr %pM in delete\n",
 | 
			
		||||
+			    vdev_id, addr);
 | 
			
		||||
+		return -EINVAL;
 | 
			
		||||
+        }
 | 
			
		||||
+
 | 
			
		||||
+#ifdef CPTCFG_ATH11K_NSS_SUPPORT
 | 
			
		||||
+	peer->delete_in_progress = true;
 | 
			
		||||
+	if (peer->self_ast_entry) {
 | 
			
		||||
+		ath11k_peer_del_ast(ar, peer->self_ast_entry);
 | 
			
		||||
+		peer->self_ast_entry = NULL;
 | 
			
		||||
+	}
 | 
			
		||||
 
 | 
			
		||||
-		list_for_each_entry_safe(ast_entry, tmp_ast,
 | 
			
		||||
-					 &peer->ast_entry_list, ase_list)
 | 
			
		||||
-			if ((ast_entry->type == ATH11K_AST_TYPE_WDS) ||
 | 
			
		||||
-			    (ast_entry->type == ATH11K_AST_TYPE_MEC)) {
 | 
			
		||||
-				if (!list_empty(&ast_entry->wmi_list)) {
 | 
			
		||||
-					ath11k_dbg(ar->ab, ATH11K_DBG_MAC,
 | 
			
		||||
-						   "%s deleting unprocessed ast entry %pM of peer %pM from wmi list\n",
 | 
			
		||||
-						    __func__, ast_entry->addr, addr);
 | 
			
		||||
-					list_del_init(&ast_entry->wmi_list);
 | 
			
		||||
-				}
 | 
			
		||||
+	list_for_each_entry_safe(ast_entry, tmp_ast,
 | 
			
		||||
+				 &peer->ast_entry_list, ase_list)
 | 
			
		||||
+		if ((ast_entry->type == ATH11K_AST_TYPE_WDS) ||
 | 
			
		||||
+		    (ast_entry->type == ATH11K_AST_TYPE_MEC)) {
 | 
			
		||||
+			if (!list_empty(&ast_entry->wmi_list)) {
 | 
			
		||||
+				ath11k_dbg(ar->ab, ATH11K_DBG_MAC,
 | 
			
		||||
+					   "%s deleting unprocessed ast entry %pM of peer %pM from wmi list\n",
 | 
			
		||||
+					    __func__, ast_entry->addr, addr);
 | 
			
		||||
+				list_del_init(&ast_entry->wmi_list);
 | 
			
		||||
 			}
 | 
			
		||||
+		}
 | 
			
		||||
 #endif
 | 
			
		||||
-		ath11k_peer_rhash_delete(ar->ab, peer);
 | 
			
		||||
-	}
 | 
			
		||||
 	spin_unlock_bh(&ar->ab->base_lock);
 | 
			
		||||
 	mutex_unlock(&ar->ab->tbl_mtx_lock);
 | 
			
		||||
 #ifdef CPTCFG_ATH11K_NSS_SUPPORT
 | 
			
		||||
 	mutex_unlock(&ar->ab->base_ast_lock);
 | 
			
		||||
 #endif
 | 
			
		||||
+	reinit_completion(&ar->peer_delete_done);
 | 
			
		||||
+
 | 
			
		||||
 	ret = ath11k_wmi_send_peer_delete_cmd(ar, addr, vdev_id);
 | 
			
		||||
 	if (ret) {
 | 
			
		||||
 		ath11k_warn(ar->ab,
 | 
			
		||||
@@ -866,14 +891,20 @@ int ath11k_peer_create(struct ath11k *ar
 | 
			
		||||
 			    "failed to create peer due to insufficient peer entry resource in firmware\n");
 | 
			
		||||
 		return -ENOBUFS;
 | 
			
		||||
 	}
 | 
			
		||||
-
 | 
			
		||||
+	mutex_lock(&ar->ab->tbl_mtx_lock);
 | 
			
		||||
 	spin_lock_bh(&ar->ab->base_lock);
 | 
			
		||||
 	peer = ath11k_peer_find_by_addr(ar->ab, param->peer_addr);
 | 
			
		||||
 	if (peer) {
 | 
			
		||||
-		spin_unlock_bh(&ar->ab->base_lock);
 | 
			
		||||
-		return -EINVAL;
 | 
			
		||||
+		if (peer->vdev_id == param->vdev_id) {
 | 
			
		||||
+			spin_unlock_bh(&ar->ab->base_lock);
 | 
			
		||||
+			mutex_unlock(&ar->ab->tbl_mtx_lock);
 | 
			
		||||
+			return -EINVAL;
 | 
			
		||||
+		}
 | 
			
		||||
+		ath11k_peer_rhash_delete(ar->ab, peer);
 | 
			
		||||
 	}
 | 
			
		||||
+
 | 
			
		||||
 	spin_unlock_bh(&ar->ab->base_lock);
 | 
			
		||||
+	mutex_unlock(&ar->ab->tbl_mtx_lock);
 | 
			
		||||
 
 | 
			
		||||
 	ret = ath11k_wmi_send_peer_create_cmd(ar, param);
 | 
			
		||||
 	if (ret) {
 | 
			
		||||
@@ -0,0 +1,119 @@
 | 
			
		||||
--- a/drivers/net/wireless/ath/ath11k/peer.c
 | 
			
		||||
+++ b/drivers/net/wireless/ath/ath11k/peer.c
 | 
			
		||||
@@ -819,10 +819,7 @@ int ath11k_peer_delete(struct ath11k *ar
 | 
			
		||||
 #ifdef CPTCFG_ATH11K_NSS_SUPPORT
 | 
			
		||||
 		mutex_unlock(&ar->ab->base_ast_lock);
 | 
			
		||||
 #endif
 | 
			
		||||
-		ath11k_warn(ar->ab,
 | 
			
		||||
-			    "failed to find peer vdev_id %d addr %pM in delete\n",
 | 
			
		||||
-			    vdev_id, addr);
 | 
			
		||||
-		return -EINVAL;
 | 
			
		||||
+		return 0;
 | 
			
		||||
         }
 | 
			
		||||
 
 | 
			
		||||
 #ifdef CPTCFG_ATH11K_NSS_SUPPORT
 | 
			
		||||
@@ -883,6 +880,7 @@ int ath11k_peer_create(struct ath11k *ar
 | 
			
		||||
 	struct ieee80211_vif *vif = arvif->vif;
 | 
			
		||||
 	struct ath11k_sta *arsta;
 | 
			
		||||
 	int ret, fbret;
 | 
			
		||||
+	u8 vdev_id = 0;
 | 
			
		||||
 
 | 
			
		||||
 	lockdep_assert_held(&ar->conf_mutex);
 | 
			
		||||
 
 | 
			
		||||
@@ -891,20 +889,21 @@ int ath11k_peer_create(struct ath11k *ar
 | 
			
		||||
 			    "failed to create peer due to insufficient peer entry resource in firmware\n");
 | 
			
		||||
 		return -ENOBUFS;
 | 
			
		||||
 	}
 | 
			
		||||
+
 | 
			
		||||
 	mutex_lock(&ar->ab->tbl_mtx_lock);
 | 
			
		||||
 	spin_lock_bh(&ar->ab->base_lock);
 | 
			
		||||
 	peer = ath11k_peer_find_by_addr(ar->ab, param->peer_addr);
 | 
			
		||||
+	if (peer)
 | 
			
		||||
+		vdev_id = peer->vdev_id;
 | 
			
		||||
+	spin_unlock_bh(&ar->ab->base_lock);
 | 
			
		||||
+	mutex_unlock(&ar->ab->tbl_mtx_lock);
 | 
			
		||||
+
 | 
			
		||||
 	if (peer) {
 | 
			
		||||
-		if (peer->vdev_id == param->vdev_id) {
 | 
			
		||||
-			spin_unlock_bh(&ar->ab->base_lock);
 | 
			
		||||
-			mutex_unlock(&ar->ab->tbl_mtx_lock);
 | 
			
		||||
+		if (vdev_id == param->vdev_id)
 | 
			
		||||
 			return -EINVAL;
 | 
			
		||||
-		}
 | 
			
		||||
-		ath11k_peer_rhash_delete(ar->ab, peer);
 | 
			
		||||
-	}
 | 
			
		||||
 
 | 
			
		||||
-	spin_unlock_bh(&ar->ab->base_lock);
 | 
			
		||||
-	mutex_unlock(&ar->ab->tbl_mtx_lock);
 | 
			
		||||
+		ath11k_peer_delete(ar, vdev_id, param->peer_addr);
 | 
			
		||||
+	}
 | 
			
		||||
 
 | 
			
		||||
 	ret = ath11k_wmi_send_peer_create_cmd(ar, param);
 | 
			
		||||
 	if (ret) {
 | 
			
		||||
--- a/drivers/net/wireless/ath/ath11k/dp.c
 | 
			
		||||
+++ b/drivers/net/wireless/ath/ath11k/dp.c
 | 
			
		||||
@@ -28,7 +28,7 @@ void ath11k_dp_peer_cleanup(struct ath11
 | 
			
		||||
 	spin_lock_bh(&ab->base_lock);
 | 
			
		||||
 	peer = ath11k_peer_find(ab, vdev_id, addr);
 | 
			
		||||
 	if (!peer) {
 | 
			
		||||
-		ath11k_warn(ab, "failed to lookup peer %pM on vdev %d\n",
 | 
			
		||||
+		ath11k_dbg(ab, ATH11K_DBG_MAC, "failed to lookup peer %pM on vdev %d\n",
 | 
			
		||||
 			    addr, vdev_id);
 | 
			
		||||
 		spin_unlock_bh(&ab->base_lock);
 | 
			
		||||
 		return;
 | 
			
		||||
--- a/drivers/net/wireless/ath/ath11k/dp_rx.c
 | 
			
		||||
+++ b/drivers/net/wireless/ath/ath11k/dp_rx.c
 | 
			
		||||
@@ -1204,9 +1204,9 @@ int ath11k_dp_rx_ampdu_stop(struct ath11
 | 
			
		||||
 
 | 
			
		||||
 	peer = ath11k_peer_find(ab, vdev_id, params->sta->addr);
 | 
			
		||||
 	if (!peer) {
 | 
			
		||||
-		ath11k_warn(ab, "failed to find the peer to stop rx aggregation\n");
 | 
			
		||||
+		ath11k_dbg(ab, ATH11K_DBG_MAC, "failed to find the peer to stop rx aggregation\n");
 | 
			
		||||
 		spin_unlock_bh(&ab->base_lock);
 | 
			
		||||
-		return -ENOENT;
 | 
			
		||||
+		return 0;
 | 
			
		||||
 	}
 | 
			
		||||
 
 | 
			
		||||
 	paddr = peer->rx_tid[params->tid].paddr;
 | 
			
		||||
--- a/drivers/net/wireless/ath/ath11k/mac.c
 | 
			
		||||
+++ b/drivers/net/wireless/ath/ath11k/mac.c
 | 
			
		||||
@@ -4075,7 +4075,7 @@ static int ath11k_clear_peer_keys(struct
 | 
			
		||||
 	peer = ath11k_peer_find(ab, arvif->vdev_id, addr);
 | 
			
		||||
 	if (!peer) {
 | 
			
		||||
 		spin_unlock_bh(&ab->base_lock);
 | 
			
		||||
-		return -ENOENT;
 | 
			
		||||
+		return 0;
 | 
			
		||||
 	}
 | 
			
		||||
 	for (i = 0; i < ARRAY_SIZE(keys); i++) {
 | 
			
		||||
 		keys[i]= peer->keys[i];
 | 
			
		||||
@@ -4325,6 +4325,10 @@ static int ath11k_mac_op_set_key(struct
 | 
			
		||||
 
 | 
			
		||||
 	spin_lock_bh(&ab->base_lock);
 | 
			
		||||
 	peer = ath11k_peer_find(ab, arvif->vdev_id, peer_addr);
 | 
			
		||||
+	if (!peer && cmd == DISABLE_KEY) {
 | 
			
		||||
+		ret = 0;
 | 
			
		||||
+		goto unlock;
 | 
			
		||||
+	}
 | 
			
		||||
 
 | 
			
		||||
 	/* TODO: Check if vdev specific security cfg is mandatory */
 | 
			
		||||
 	ret = ath11k_nss_vdev_set_cmd(arvif, ATH11K_NSS_WIFI_VDEV_SECURITY_TYPE_CMD, key->cipher);
 | 
			
		||||
@@ -5961,7 +5965,7 @@ static void ath11k_mac_op_sta_rc_update(
 | 
			
		||||
 	peer = ath11k_peer_find(ar->ab, arvif->vdev_id, sta->addr);
 | 
			
		||||
 	if (!peer) {
 | 
			
		||||
 		spin_unlock_bh(&ar->ab->base_lock);
 | 
			
		||||
-		ath11k_warn(ar->ab, "mac sta rc update failed to find peer %pM on vdev %i\n",
 | 
			
		||||
+		ath11k_dbg(ar->ab, ATH11K_DBG_MAC, "mac sta rc update failed to find peer %pM on vdev %i\n",
 | 
			
		||||
 			    sta->addr, arvif->vdev_id);
 | 
			
		||||
 		return;
 | 
			
		||||
 	}
 | 
			
		||||
--- a/drivers/net/wireless/ath/ath11k/wmi.c
 | 
			
		||||
+++ b/drivers/net/wireless/ath/ath11k/wmi.c
 | 
			
		||||
@@ -8425,7 +8425,7 @@ static void ath11k_peer_sta_kickout_even
 | 
			
		||||
 	peer = ath11k_peer_find_by_addr(ab, arg.mac_addr);
 | 
			
		||||
 	if (!peer) {
 | 
			
		||||
 		spin_unlock_bh(&ab->base_lock);
 | 
			
		||||
-		ath11k_warn(ab, "peer not found %pM\n",
 | 
			
		||||
+		ath11k_dbg(ab, ATH11K_DBG_WMI, "peer not found %pM\n",
 | 
			
		||||
 			    arg.mac_addr);
 | 
			
		||||
 		goto exit;
 | 
			
		||||
 	}
 | 
			
		||||
@@ -146,6 +146,40 @@ check_board_phy() {
 | 
			
		||||
	fi
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
is_morse_phy() {
 | 
			
		||||
	local dev="$1"
 | 
			
		||||
	local morse_path="/sys/class/ieee80211/${dev}/device/morse/"
 | 
			
		||||
 | 
			
		||||
	if [ -d "$morse_path" ]; then
 | 
			
		||||
		return 0  # This is a Morse PHY
 | 
			
		||||
	else
 | 
			
		||||
		return 1  # Not a Morse PHY
 | 
			
		||||
	fi
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
# Set up Morse-specific wireless configuration
 | 
			
		||||
setup_morse_wireless() {
 | 
			
		||||
	local dev="$1"
 | 
			
		||||
	local name="$2"
 | 
			
		||||
 | 
			
		||||
	# Create Morse-specific wireless configuration with exact settings
 | 
			
		||||
	uci -q batch <<-EOF
 | 
			
		||||
		set wireless.${name}=wifi-device
 | 
			
		||||
		set wireless.${name}.disabled='0'
 | 
			
		||||
		set wireless.${name}.mode='ap'
 | 
			
		||||
		set wireless.${name}.type='morse'
 | 
			
		||||
		set wireless.${name}.path='platform/11009000.spi/spi_master/spi1/spi1.0'
 | 
			
		||||
		set wireless.${name}.channel='12'
 | 
			
		||||
		set wireless.${name}.hwmode='a'
 | 
			
		||||
		set wireless.${name}.band='s1g'
 | 
			
		||||
		set wireless.${name}.htmode='8'
 | 
			
		||||
		set wireless.${name}.country='US'
 | 
			
		||||
		set wireless.${name}.channels=''
 | 
			
		||||
EOF
 | 
			
		||||
 | 
			
		||||
	uci -q commit wireless
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
detect_mac80211() {
 | 
			
		||||
	devidx=0
 | 
			
		||||
	config_load wireless
 | 
			
		||||
@@ -158,13 +192,6 @@ detect_mac80211() {
 | 
			
		||||
 | 
			
		||||
		dev="${_dev##*/}"
 | 
			
		||||
 | 
			
		||||
		mode_band=""
 | 
			
		||||
		channel=""
 | 
			
		||||
		htmode=""
 | 
			
		||||
		ht_capab=""
 | 
			
		||||
 | 
			
		||||
		get_band_defaults "$dev"
 | 
			
		||||
 | 
			
		||||
		path="$(iwinfo nl80211 path "$dev")"
 | 
			
		||||
		macaddr="$(cat /sys/class/ieee80211/${dev}/macaddress)"
 | 
			
		||||
 | 
			
		||||
@@ -183,35 +210,51 @@ detect_mac80211() {
 | 
			
		||||
 | 
			
		||||
		name="radio${devidx}"
 | 
			
		||||
		devidx=$(($devidx + 1))
 | 
			
		||||
		case "$dev" in
 | 
			
		||||
			phy*)
 | 
			
		||||
				if [ -n "$path" ]; then
 | 
			
		||||
					dev_id="set wireless.${name}.path='$path'"
 | 
			
		||||
				else
 | 
			
		||||
					dev_id="set wireless.${name}.macaddr='$macaddr'"
 | 
			
		||||
				fi
 | 
			
		||||
				;;
 | 
			
		||||
			*)
 | 
			
		||||
				dev_id="set wireless.${name}.phy='$dev'"
 | 
			
		||||
				;;
 | 
			
		||||
		esac
 | 
			
		||||
 | 
			
		||||
		uci -q batch <<-EOF
 | 
			
		||||
			set wireless.${name}=wifi-device
 | 
			
		||||
			set wireless.${name}.type=mac80211
 | 
			
		||||
			${dev_id}
 | 
			
		||||
			set wireless.${name}.channel=${channel}
 | 
			
		||||
			set wireless.${name}.band=${mode_band}
 | 
			
		||||
			set wireless.${name}.htmode=$htmode
 | 
			
		||||
			set wireless.${name}.disabled=1
 | 
			
		||||
		# Check if this is a Morse PHY
 | 
			
		||||
		if is_morse_phy "$dev"; then
 | 
			
		||||
			# Use dedicated Morse configuration
 | 
			
		||||
			setup_morse_wireless "$dev" "$name"
 | 
			
		||||
		else
 | 
			
		||||
			# Standard wireless configuration for non-Morse devices
 | 
			
		||||
			mode_band=""
 | 
			
		||||
			channel=""
 | 
			
		||||
			htmode=""
 | 
			
		||||
			ht_capab=""
 | 
			
		||||
 | 
			
		||||
			set wireless.default_${name}=wifi-iface
 | 
			
		||||
			set wireless.default_${name}.device=${name}
 | 
			
		||||
			set wireless.default_${name}.network=lan
 | 
			
		||||
			set wireless.default_${name}.mode=ap
 | 
			
		||||
			set wireless.default_${name}.ssid=OpenWrt
 | 
			
		||||
			set wireless.default_${name}.encryption=none
 | 
			
		||||
			# Get default settings for standard devices
 | 
			
		||||
			get_band_defaults "$dev"
 | 
			
		||||
 | 
			
		||||
			case "$dev" in
 | 
			
		||||
				phy*)
 | 
			
		||||
					if [ -n "$path" ]; then
 | 
			
		||||
						dev_id="set wireless.${name}.path='$path'"
 | 
			
		||||
					else
 | 
			
		||||
						dev_id="set wireless.${name}.macaddr='$macaddr'"
 | 
			
		||||
					fi
 | 
			
		||||
					;;
 | 
			
		||||
				*)
 | 
			
		||||
					dev_id="set wireless.${name}.phy='$dev'"
 | 
			
		||||
					;;
 | 
			
		||||
			esac
 | 
			
		||||
 | 
			
		||||
			uci -q batch <<-EOF
 | 
			
		||||
				set wireless.${name}=wifi-device
 | 
			
		||||
				set wireless.${name}.type=mac80211
 | 
			
		||||
				${dev_id}
 | 
			
		||||
				set wireless.${name}.channel=${channel}
 | 
			
		||||
				set wireless.${name}.band=${mode_band}
 | 
			
		||||
				set wireless.${name}.htmode=$htmode
 | 
			
		||||
				set wireless.${name}.disabled=1
 | 
			
		||||
 | 
			
		||||
				set wireless.default_${name}=wifi-iface
 | 
			
		||||
				set wireless.default_${name}.device=${name}
 | 
			
		||||
				set wireless.default_${name}.network=lan
 | 
			
		||||
				set wireless.default_${name}.mode=ap
 | 
			
		||||
				set wireless.default_${name}.ssid=OpenWrt
 | 
			
		||||
				set wireless.default_${name}.encryption=none
 | 
			
		||||
EOF
 | 
			
		||||
		uci -q commit wireless
 | 
			
		||||
			uci -q commit wireless
 | 
			
		||||
		fi
 | 
			
		||||
	done
 | 
			
		||||
}
 | 
			
		||||
 
 | 
			
		||||
@@ -0,0 +1,13 @@
 | 
			
		||||
--- a/net/mac80211/rx.c
 | 
			
		||||
+++ b/net/mac80211/rx.c
 | 
			
		||||
@@ -4193,8 +4196,10 @@
 | 
			
		||||
	case NL80211_IFTYPE_STATION:
 | 
			
		||||
		if (!bssid && !sdata->u.mgd.use_4addr)
 | 
			
		||||
			return false;
 | 
			
		||||
+#if 0
 | 
			
		||||
		if (ieee80211_is_robust_mgmt_frame(skb) && !rx->sta)
 | 
			
		||||
			return false;
 | 
			
		||||
+#endif
 | 
			
		||||
		if (multicast)
 | 
			
		||||
			return true;
 | 
			
		||||
		return ether_addr_equal(sdata->vif.addr, hdr->addr1);
 | 
			
		||||
@@ -0,0 +1,443 @@
 | 
			
		||||
--- a/include/linux/ieee80211.h
 | 
			
		||||
+++ b/include/linux/ieee80211.h
 | 
			
		||||
@@ -3434,6 +3434,9 @@
 | 
			
		||||
 	WLAN_ACTION_ADDBA_REQ = 0,
 | 
			
		||||
 	WLAN_ACTION_ADDBA_RESP = 1,
 | 
			
		||||
 	WLAN_ACTION_DELBA = 2,
 | 
			
		||||
+	WLAN_ACTION_NDP_ADDBA_REQ = 128,
 | 
			
		||||
+	WLAN_ACTION_NDP_ADDBA_RESP = 129,
 | 
			
		||||
+	WLAN_ACTION_NDP_DELBA = 130,    
 | 
			
		||||
 };
 | 
			
		||||
 
 | 
			
		||||
 /* BACK (block-ack) parties */
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
--- a/include/net/mac80211.h
 | 
			
		||||
+++ b/include/net/mac80211.h
 | 
			
		||||
@@ -125,6 +125,13 @@
 | 
			
		||||
  * via the usual ieee80211_tx_dequeue).
 | 
			
		||||
  */
 | 
			
		||||
 
 | 
			
		||||
+ /** Morse Micro patches which add functionality that the driver needs to know about, can be
 | 
			
		||||
+  * signalled by adding a define here.
 | 
			
		||||
+  */
 | 
			
		||||
+
 | 
			
		||||
+ /** mac80211 has the capability to negotiate NDP block acknowledgements */
 | 
			
		||||
+ #define MORSE_MAC80211_S1G_FEATURE_NDP_BLOCKACK
 | 
			
		||||
+
 | 
			
		||||
 struct device;
 | 
			
		||||
 
 | 
			
		||||
 /**
 | 
			
		||||
@@ -2437,7 +2444,10 @@
 | 
			
		||||
  *
 | 
			
		||||
  * @IEEE80211_HW_DETECTS_COLOR_COLLISION: HW/driver has support for BSS color
 | 
			
		||||
  *	collision detection and doesn't need it in software.
 | 
			
		||||
- *
 | 
			
		||||
+ * 
 | 
			
		||||
+ + @IEEE80211_HW_SUPPORTS_NDP_BLOCKACK: Hardware supports 11ah A-MPDU aggregation with NDP block
 | 
			
		||||
+ +  ACKs
 | 
			
		||||
+ +
 | 
			
		||||
  * @NUM_IEEE80211_HW_FLAGS: number of hardware flags, used for sizing arrays
 | 
			
		||||
  */
 | 
			
		||||
 enum ieee80211_hw_flags {
 | 
			
		||||
@@ -2494,6 +2504,7 @@
 | 
			
		||||
 	IEEE80211_HW_SUPPORTS_RX_DECAP_OFFLOAD,
 | 
			
		||||
 	IEEE80211_HW_SUPPORTS_CONC_MON_RX_DECAP,
 | 
			
		||||
 	IEEE80211_HW_DETECTS_COLOR_COLLISION,
 | 
			
		||||
+	IEEE80211_HW_SUPPORTS_NDP_BLOCKACK,
 | 
			
		||||
 
 | 
			
		||||
 	/* keep last, obviously */
 | 
			
		||||
 	NUM_IEEE80211_HW_FLAGS
 | 
			
		||||
@@ -3315,7 +3326,8 @@
 | 
			
		||||
  *	action is set to %IEEE80211_AMPDU_RX_START or
 | 
			
		||||
  *	%IEEE80211_AMPDU_TX_OPERATIONAL
 | 
			
		||||
  * @amsdu: indicates the peer's ability to receive A-MSDU within A-MPDU.
 | 
			
		||||
- *	valid when the action is set to %IEEE80211_AMPDU_TX_OPERATIONAL
 | 
			
		||||
+ *	valid when the action is set to %IEEE80211_AMPDU_TX_OPERATIONAL 
 | 
			
		||||
+ * @ndp: indicates the driver has requested the session to use NDP block ACKs
 | 
			
		||||
  * @timeout: BA session timeout. Valid only when the action is set to
 | 
			
		||||
  *	%IEEE80211_AMPDU_RX_START
 | 
			
		||||
  */
 | 
			
		||||
@@ -3326,6 +3338,7 @@
 | 
			
		||||
 	u16 ssn;
 | 
			
		||||
 	u16 buf_size;
 | 
			
		||||
 	bool amsdu;
 | 
			
		||||
+       bool ndp;
 | 
			
		||||
 	u16 timeout;
 | 
			
		||||
 };
 | 
			
		||||
 
 | 
			
		||||
 | 
			
		||||
--- a/net/mac80211/agg-rx.c
 | 
			
		||||
+++ b/net/mac80211/agg-rx.c
 | 
			
		||||
@@ -80,6 +80,8 @@
 | 
			
		||||
 	RCU_INIT_POINTER(sta->ampdu_mlme.tid_rx[tid], NULL);
 | 
			
		||||
 	__clear_bit(tid, sta->ampdu_mlme.agg_session_valid);
 | 
			
		||||
 
 | 
			
		||||
+       if (tid_rx) params.ndp = tid_rx->ndp;
 | 
			
		||||
+
 | 
			
		||||
 	ht_dbg(sta->sdata,
 | 
			
		||||
 	       "Rx BA session stop requested for %pM tid %u %s reason: %d\n",
 | 
			
		||||
 	       sta->sta.addr, tid,
 | 
			
		||||
@@ -94,7 +96,7 @@
 | 
			
		||||
 	/* check if this is a self generated aggregation halt */
 | 
			
		||||
 	if (initiator == WLAN_BACK_RECIPIENT && tx)
 | 
			
		||||
 		ieee80211_send_delba(sta->sdata, sta->sta.addr,
 | 
			
		||||
-				     tid, WLAN_BACK_RECIPIENT, reason);
 | 
			
		||||
+				     tid, params.ndp, WLAN_BACK_RECIPIENT, reason);
 | 
			
		||||
 
 | 
			
		||||
 	/*
 | 
			
		||||
 	 * return here in case tid_rx is not assigned - which will happen if
 | 
			
		||||
@@ -214,7 +216,7 @@
 | 
			
		||||
 
 | 
			
		||||
 static void ieee80211_send_addba_resp(struct sta_info *sta, u8 *da, u16 tid,
 | 
			
		||||
 				      u8 dialog_token, u16 status, u16 policy,
 | 
			
		||||
-				      u16 buf_size, u16 timeout,
 | 
			
		||||
+				      u16 buf_size, u16 timeout, bool ndp,
 | 
			
		||||
 				      const struct ieee80211_addba_ext_ie *addbaext)
 | 
			
		||||
 {
 | 
			
		||||
 	struct ieee80211_sub_if_data *sdata = sta->sdata;
 | 
			
		||||
@@ -248,7 +250,8 @@
 | 
			
		||||
 
 | 
			
		||||
 	skb_put(skb, 1 + sizeof(mgmt->u.action.u.addba_resp));
 | 
			
		||||
 	mgmt->u.action.category = WLAN_CATEGORY_BACK;
 | 
			
		||||
-	mgmt->u.action.u.addba_resp.action_code = WLAN_ACTION_ADDBA_RESP;
 | 
			
		||||
+	mgmt->u.action.u.addba_resp.action_code = ndp ?
 | 
			
		||||
+                       WLAN_ACTION_NDP_ADDBA_RESP : WLAN_ACTION_ADDBA_RESP;
 | 
			
		||||
 	mgmt->u.action.u.addba_resp.dialog_token = dialog_token;
 | 
			
		||||
 
 | 
			
		||||
 	capab = 0;
 | 
			
		||||
@@ -273,7 +276,7 @@
 | 
			
		||||
 void ___ieee80211_start_rx_ba_session(struct sta_info *sta,
 | 
			
		||||
 				      u8 dialog_token, u16 timeout,
 | 
			
		||||
 				      u16 start_seq_num, u16 ba_policy, u16 tid,
 | 
			
		||||
-				      u16 buf_size, bool tx, bool auto_seq,
 | 
			
		||||
+				      u16 buf_size, bool tx, bool auto_seq, bool ndp,
 | 
			
		||||
 				      const struct ieee80211_addba_ext_ie *addbaext)
 | 
			
		||||
 {
 | 
			
		||||
 	struct ieee80211_local *local = sta->sdata->local;
 | 
			
		||||
@@ -284,6 +287,7 @@
 | 
			
		||||
 		.tid = tid,
 | 
			
		||||
 		.amsdu = false,
 | 
			
		||||
 		.timeout = timeout,
 | 
			
		||||
+		.ndp = ndp,
 | 
			
		||||
 		.ssn = start_seq_num,
 | 
			
		||||
 	};
 | 
			
		||||
 	int i, ret = -EOPNOTSUPP;
 | 
			
		||||
@@ -306,6 +310,12 @@
 | 
			
		||||
 		goto end;
 | 
			
		||||
 	}
 | 
			
		||||
 
 | 
			
		||||
+    
 | 
			
		||||
+       if (ndp && !ieee80211_hw_check(&local->hw, SUPPORTS_NDP_BLOCKACK)) {
 | 
			
		||||
+       	ht_dbg(sta->sdata, "Requested NDP BA but HW does not support it\n");
 | 
			
		||||
+       	goto end;
 | 
			
		||||
+       }
 | 
			
		||||
+
 | 
			
		||||
 	if (test_sta_flag(sta, WLAN_STA_BLOCK_BA)) {
 | 
			
		||||
 		ht_dbg(sta->sdata,
 | 
			
		||||
 		       "Suspend in progress - Denying ADDBA request (%pM tid %d)\n",
 | 
			
		||||
@@ -438,6 +448,7 @@
 | 
			
		||||
 	tid_agg_rx->started = false;
 | 
			
		||||
 	tid_agg_rx->reorder_buf_filtered = 0;
 | 
			
		||||
 	tid_agg_rx->tid = tid;
 | 
			
		||||
+       tid_agg_rx->ndp = params.ndp;
 | 
			
		||||
 	tid_agg_rx->sta = sta;
 | 
			
		||||
 	status = WLAN_STATUS_SUCCESS;
 | 
			
		||||
 
 | 
			
		||||
@@ -459,20 +470,20 @@
 | 
			
		||||
 	if (tx)
 | 
			
		||||
 		ieee80211_send_addba_resp(sta, sta->sta.addr, tid,
 | 
			
		||||
 					  dialog_token, status, 1, buf_size,
 | 
			
		||||
-					  timeout, addbaext);
 | 
			
		||||
+					  timeout, params.ndp, addbaext);
 | 
			
		||||
 }
 | 
			
		||||
 
 | 
			
		||||
 static void __ieee80211_start_rx_ba_session(struct sta_info *sta,
 | 
			
		||||
 					    u8 dialog_token, u16 timeout,
 | 
			
		||||
 					    u16 start_seq_num, u16 ba_policy,
 | 
			
		||||
 					    u16 tid, u16 buf_size, bool tx,
 | 
			
		||||
-					    bool auto_seq,
 | 
			
		||||
+					    bool auto_seq, bool ndp,
 | 
			
		||||
 					    const struct ieee80211_addba_ext_ie *addbaext)
 | 
			
		||||
 {
 | 
			
		||||
 	mutex_lock(&sta->ampdu_mlme.mtx);
 | 
			
		||||
 	___ieee80211_start_rx_ba_session(sta, dialog_token, timeout,
 | 
			
		||||
 					 start_seq_num, ba_policy, tid,
 | 
			
		||||
-					 buf_size, tx, auto_seq, addbaext);
 | 
			
		||||
+					 buf_size, tx, auto_seq, ndp, addbaext);
 | 
			
		||||
 	mutex_unlock(&sta->ampdu_mlme.mtx);
 | 
			
		||||
 }
 | 
			
		||||
 
 | 
			
		||||
@@ -485,6 +496,7 @@
 | 
			
		||||
 	struct ieee802_11_elems *elems = NULL;
 | 
			
		||||
 	u8 dialog_token;
 | 
			
		||||
 	int ies_len;
 | 
			
		||||
+       bool ndp_ba;
 | 
			
		||||
 
 | 
			
		||||
 	/* extract session parameters from addba request frame */
 | 
			
		||||
 	dialog_token = mgmt->u.action.u.addba_req.dialog_token;
 | 
			
		||||
@@ -496,6 +508,7 @@
 | 
			
		||||
 	ba_policy = (capab & IEEE80211_ADDBA_PARAM_POLICY_MASK) >> 1;
 | 
			
		||||
 	tid = (capab & IEEE80211_ADDBA_PARAM_TID_MASK) >> 2;
 | 
			
		||||
 	buf_size = (capab & IEEE80211_ADDBA_PARAM_BUF_SIZE_MASK) >> 6;
 | 
			
		||||
+       ndp_ba = (mgmt->u.action.u.addba_req.action_code == WLAN_ACTION_NDP_ADDBA_REQ);
 | 
			
		||||
 
 | 
			
		||||
 	ies_len = len - offsetof(struct ieee80211_mgmt,
 | 
			
		||||
 				 u.action.u.addba_req.variable);
 | 
			
		||||
@@ -508,7 +521,7 @@
 | 
			
		||||
 
 | 
			
		||||
 	__ieee80211_start_rx_ba_session(sta, dialog_token, timeout,
 | 
			
		||||
 					start_seq_num, ba_policy, tid,
 | 
			
		||||
-					buf_size, true, false,
 | 
			
		||||
+					buf_size, true, false, ndp_ba,
 | 
			
		||||
 					elems ? elems->addba_ext_ie : NULL);
 | 
			
		||||
 free:
 | 
			
		||||
 	kfree(elems);
 | 
			
		||||
	
 | 
			
		||||
--- a/net/mac80211/agg-tx.c
 | 
			
		||||
+++ b/net/mac80211/agg-tx.c
 | 
			
		||||
@@ -65,7 +65,7 @@
 | 
			
		||||
  */
 | 
			
		||||
 
 | 
			
		||||
 static void ieee80211_send_addba_request(struct ieee80211_sub_if_data *sdata,
 | 
			
		||||
-					 const u8 *da, u16 tid,
 | 
			
		||||
+					 const u8 *da, u16 tid, bool ndp,
 | 
			
		||||
 					 u8 dialog_token, u16 start_seq_num,
 | 
			
		||||
 					 u16 agg_size, u16 timeout)
 | 
			
		||||
 {
 | 
			
		||||
@@ -99,7 +99,8 @@
 | 
			
		||||
 	skb_put(skb, 1 + sizeof(mgmt->u.action.u.addba_req));
 | 
			
		||||
 
 | 
			
		||||
 	mgmt->u.action.category = WLAN_CATEGORY_BACK;
 | 
			
		||||
-	mgmt->u.action.u.addba_req.action_code = WLAN_ACTION_ADDBA_REQ;
 | 
			
		||||
+	mgmt->u.action.u.addba_req.action_code = ndp ? WLAN_ACTION_NDP_ADDBA_REQ :
 | 
			
		||||
+                       WLAN_ACTION_ADDBA_REQ;
 | 
			
		||||
 
 | 
			
		||||
 	mgmt->u.action.u.addba_req.dialog_token = dialog_token;
 | 
			
		||||
 	if (amsdu)
 | 
			
		||||
@@ -488,7 +489,7 @@
 | 
			
		||||
 	}
 | 
			
		||||
 
 | 
			
		||||
 	/* send AddBA request */
 | 
			
		||||
-	ieee80211_send_addba_request(sdata, sta->sta.addr, tid,
 | 
			
		||||
+	ieee80211_send_addba_request(sdata, sta->sta.addr, tid, tid_tx->ndp,
 | 
			
		||||
 				     tid_tx->dialog_token, tid_tx->ssn,
 | 
			
		||||
 				     buf_size, tid_tx->timeout);
 | 
			
		||||
 
 | 
			
		||||
@@ -506,10 +507,18 @@
 | 
			
		||||
 		.tid = tid,
 | 
			
		||||
 		.buf_size = 0,
 | 
			
		||||
 		.amsdu = false,
 | 
			
		||||
+		.ndp = false,
 | 
			
		||||
 		.timeout = 0,
 | 
			
		||||
 	};
 | 
			
		||||
 	int ret;
 | 
			
		||||
 
 | 
			
		||||
+      /* If the HW supports NDP blockacks, try to negotiate. It's the drivers responsibility to
 | 
			
		||||
+       * clear .ndp if the conditions for NDP block acks are not met for this TID.
 | 
			
		||||
+       * TODO: remove driver responsibility when S1G STA caps exist in mac80211
 | 
			
		||||
+       */
 | 
			
		||||
+       if (ieee80211_hw_check(&local->hw, SUPPORTS_NDP_BLOCKACK))
 | 
			
		||||
+       	params.ndp = true;
 | 
			
		||||
+
 | 
			
		||||
 	tid_tx = rcu_dereference_protected_tid_tx(sta, tid);
 | 
			
		||||
 
 | 
			
		||||
 	/*
 | 
			
		||||
@@ -532,6 +541,11 @@
 | 
			
		||||
 	params.ssn = sta->tid_seq[tid] >> 4;
 | 
			
		||||
 	ret = drv_ampdu_action(local, sdata, ¶ms);
 | 
			
		||||
 	tid_tx->ssn = params.ssn;
 | 
			
		||||
+
 | 
			
		||||
+    
 | 
			
		||||
+       /* driver may clear this flag if it does not want NDP for this session */
 | 
			
		||||
+       tid_tx->ndp = params.ndp;
 | 
			
		||||
+      
 | 
			
		||||
 	if (ret == IEEE80211_AMPDU_TX_START_DELAY_ADDBA) {
 | 
			
		||||
 		return;
 | 
			
		||||
 	} else if (ret == IEEE80211_AMPDU_TX_START_IMMEDIATE) {
 | 
			
		||||
@@ -769,6 +783,7 @@
 | 
			
		||||
 	tid_tx = rcu_dereference_protected_tid_tx(sta, tid);
 | 
			
		||||
 	params.buf_size = tid_tx->buf_size;
 | 
			
		||||
 	params.amsdu = tid_tx->amsdu;
 | 
			
		||||
+	params.ndp = tid_tx->ndp;
 | 
			
		||||
 
 | 
			
		||||
 	ht_dbg(sta->sdata, "Aggregation is on for %pM tid %d\n",
 | 
			
		||||
 	       sta->sta.addr, tid);
 | 
			
		||||
@@ -950,7 +965,7 @@
 | 
			
		||||
 		ieee80211_agg_start_txq(sta, tid, false);
 | 
			
		||||
 
 | 
			
		||||
 	if (send_delba)
 | 
			
		||||
-		ieee80211_send_delba(sdata, sta->sta.addr, tid,
 | 
			
		||||
+		ieee80211_send_delba(sdata, sta->sta.addr, tid, tid_tx->ndp,
 | 
			
		||||
 			WLAN_BACK_INITIATOR, WLAN_REASON_QSTA_NOT_USE);
 | 
			
		||||
 }
 | 
			
		||||
 
 | 
			
		||||
@@ -1009,6 +1024,13 @@
 | 
			
		||||
 		goto out;
 | 
			
		||||
 	}
 | 
			
		||||
 
 | 
			
		||||
+       if ((tid_tx->ndp && mgmt->u.action.u.addba_resp.action_code != WLAN_ACTION_NDP_ADDBA_RESP) ||
 | 
			
		||||
+           (!tid_tx->ndp && mgmt->u.action.u.addba_resp.action_code != WLAN_ACTION_ADDBA_RESP)) {
 | 
			
		||||
+            ht_dbg(sta->sdata, "wrong addBA response action code, %d ndp %d\n",
 | 
			
		||||
+                               mgmt->u.action.u.addba_resp.action_code, tid_tx->ndp);
 | 
			
		||||
+           goto out;
 | 
			
		||||
+       }
 | 
			
		||||
+
 | 
			
		||||
 	del_timer_sync(&tid_tx->addba_resp_timer);
 | 
			
		||||
 
 | 
			
		||||
 	ht_dbg(sta->sdata, "switched off addBA timer for %pM tid %d\n",
 | 
			
		||||
--- a/net/mac80211/debugfs.c
 | 
			
		||||
+++ b/net/mac80211/debugfs.c
 | 
			
		||||
@@ -543,6 +543,7 @@
 | 
			
		||||
 	FLAG(SUPPORTS_RX_DECAP_OFFLOAD),
 | 
			
		||||
 	FLAG(SUPPORTS_CONC_MON_RX_DECAP),
 | 
			
		||||
 	FLAG(DETECTS_COLOR_COLLISION),
 | 
			
		||||
+	FLAG(SUPPORTS_NDP_BLOCKACK),
 | 
			
		||||
 #undef FLAG
 | 
			
		||||
 };
 | 
			
		||||
 
 | 
			
		||||
--- a/net/mac80211/ht.c
 | 
			
		||||
+++ b/net/mac80211/ht.c
 | 
			
		||||
@@ -365,7 +365,7 @@
 | 
			
		||||
 				       sta->ampdu_mlme.tid_rx_manage_offl))
 | 
			
		||||
 			___ieee80211_start_rx_ba_session(sta, 0, 0, 0, 1, tid,
 | 
			
		||||
 							 IEEE80211_MAX_AMPDU_BUF_HT,
 | 
			
		||||
-							 false, true, NULL);
 | 
			
		||||
+							 false, true, false, NULL);
 | 
			
		||||
 
 | 
			
		||||
 		if (test_and_clear_bit(tid + IEEE80211_NUM_TIDS,
 | 
			
		||||
 				       sta->ampdu_mlme.tid_rx_manage_offl))
 | 
			
		||||
@@ -412,7 +412,7 @@
 | 
			
		||||
 }
 | 
			
		||||
 
 | 
			
		||||
 void ieee80211_send_delba(struct ieee80211_sub_if_data *sdata,
 | 
			
		||||
-			  const u8 *da, u16 tid,
 | 
			
		||||
+			  const u8 *da, u16 tid, bool ndp,
 | 
			
		||||
 			  u16 initiator, u16 reason_code)
 | 
			
		||||
 {
 | 
			
		||||
 	struct ieee80211_local *local = sdata->local;
 | 
			
		||||
@@ -443,7 +443,7 @@
 | 
			
		||||
 	skb_put(skb, 1 + sizeof(mgmt->u.action.u.delba));
 | 
			
		||||
 
 | 
			
		||||
 	mgmt->u.action.category = WLAN_CATEGORY_BACK;
 | 
			
		||||
-	mgmt->u.action.u.delba.action_code = WLAN_ACTION_DELBA;
 | 
			
		||||
+	mgmt->u.action.u.delba.action_code = ndp ? WLAN_ACTION_NDP_DELBA : WLAN_ACTION_DELBA;
 | 
			
		||||
 	params = (u16)(initiator << 11); 	/* bit 11 initiator */
 | 
			
		||||
 	params |= (u16)(tid << 12); 		/* bit 15:12 TID number */
 | 
			
		||||
 
 | 
			
		||||
--- a/net/mac80211/ieee80211_i.h
 | 
			
		||||
+++ b/net/mac80211/ieee80211_i.h
 | 
			
		||||
@@ -1902,7 +1902,7 @@
 | 
			
		||||
 				       const struct ieee80211_ht_cap *ht_cap_ie,
 | 
			
		||||
 				       struct sta_info *sta);
 | 
			
		||||
 void ieee80211_send_delba(struct ieee80211_sub_if_data *sdata,
 | 
			
		||||
-			  const u8 *da, u16 tid,
 | 
			
		||||
+			  const u8 *da, u16 tid, bool ndp,
 | 
			
		||||
 			  u16 initiator, u16 reason_code);
 | 
			
		||||
 int ieee80211_send_smps_action(struct ieee80211_sub_if_data *sdata,
 | 
			
		||||
 			       enum ieee80211_smps_mode smps, const u8 *da,
 | 
			
		||||
@@ -1919,7 +1919,7 @@
 | 
			
		||||
 void ___ieee80211_start_rx_ba_session(struct sta_info *sta,
 | 
			
		||||
 				      u8 dialog_token, u16 timeout,
 | 
			
		||||
 				      u16 start_seq_num, u16 ba_policy, u16 tid,
 | 
			
		||||
-				      u16 buf_size, bool tx, bool auto_seq,
 | 
			
		||||
+				      u16 buf_size, bool tx, bool auto_seq, bool ndp,
 | 
			
		||||
 				      const struct ieee80211_addba_ext_ie *addbaext);
 | 
			
		||||
 void ieee80211_sta_tear_down_BA_sessions(struct sta_info *sta,
 | 
			
		||||
 					 enum ieee80211_agg_stop_reason reason);
 | 
			
		||||
--- a/net/mac80211/iface.c
 | 
			
		||||
+++ b/net/mac80211/iface.c
 | 
			
		||||
@@ -1551,14 +1551,17 @@
 | 
			
		||||
 		if (sta) {
 | 
			
		||||
 			switch (mgmt->u.action.u.addba_req.action_code) {
 | 
			
		||||
 			case WLAN_ACTION_ADDBA_REQ:
 | 
			
		||||
+			case WLAN_ACTION_NDP_ADDBA_REQ:
 | 
			
		||||
 				ieee80211_process_addba_request(local, sta,
 | 
			
		||||
 								mgmt, len);
 | 
			
		||||
 				break;
 | 
			
		||||
 			case WLAN_ACTION_ADDBA_RESP:
 | 
			
		||||
+			case WLAN_ACTION_NDP_ADDBA_RESP:
 | 
			
		||||
 				ieee80211_process_addba_resp(local, sta,
 | 
			
		||||
 							     mgmt, len);
 | 
			
		||||
 				break;
 | 
			
		||||
 			case WLAN_ACTION_DELBA:
 | 
			
		||||
+			case WLAN_ACTION_NDP_DELBA:
 | 
			
		||||
 				ieee80211_process_delba(sdata, sta,
 | 
			
		||||
 							mgmt, len);
 | 
			
		||||
 				break;
 | 
			
		||||
--- a/net/mac80211/rx.c
 | 
			
		||||
+++ b/net/mac80211/rx.c
 | 
			
		||||
@@ -1389,7 +1389,7 @@
 | 
			
		||||
 		if (ack_policy == IEEE80211_QOS_CTL_ACK_POLICY_BLOCKACK &&
 | 
			
		||||
 		    !test_bit(tid, rx->sta->ampdu_mlme.agg_session_valid) &&
 | 
			
		||||
 		    !test_and_set_bit(tid, rx->sta->ampdu_mlme.unexpected_agg))
 | 
			
		||||
-			ieee80211_send_delba(rx->sdata, rx->sta->sta.addr, tid,
 | 
			
		||||
+			ieee80211_send_delba(rx->sdata, rx->sta->sta.addr, tid, false,
 | 
			
		||||
 					     WLAN_BACK_RECIPIENT,
 | 
			
		||||
 					     WLAN_REASON_QSTA_REQUIRE_SETUP);
 | 
			
		||||
 		goto dont_reorder;
 | 
			
		||||
@@ -3101,7 +3101,7 @@
 | 
			
		||||
 
 | 
			
		||||
 		if (!test_bit(tid, rx->sta->ampdu_mlme.agg_session_valid) &&
 | 
			
		||||
 		    !test_and_set_bit(tid, rx->sta->ampdu_mlme.unexpected_agg))
 | 
			
		||||
-			ieee80211_send_delba(rx->sdata, rx->sta->sta.addr, tid,
 | 
			
		||||
+			ieee80211_send_delba(rx->sdata, rx->sta->sta.addr, tid, false,
 | 
			
		||||
 					     WLAN_BACK_RECIPIENT,
 | 
			
		||||
 					     WLAN_REASON_QSTA_REQUIRE_SETUP);
 | 
			
		||||
 
 | 
			
		||||
@@ -3526,16 +3526,19 @@
 | 
			
		||||
 
 | 
			
		||||
 		switch (mgmt->u.action.u.addba_req.action_code) {
 | 
			
		||||
 		case WLAN_ACTION_ADDBA_REQ:
 | 
			
		||||
+		case WLAN_ACTION_NDP_ADDBA_REQ:
 | 
			
		||||
 			if (len < (IEEE80211_MIN_ACTION_SIZE +
 | 
			
		||||
 				   sizeof(mgmt->u.action.u.addba_req)))
 | 
			
		||||
 				goto invalid;
 | 
			
		||||
 			break;
 | 
			
		||||
 		case WLAN_ACTION_ADDBA_RESP:
 | 
			
		||||
+		case WLAN_ACTION_NDP_ADDBA_RESP:
 | 
			
		||||
 			if (len < (IEEE80211_MIN_ACTION_SIZE +
 | 
			
		||||
 				   sizeof(mgmt->u.action.u.addba_resp)))
 | 
			
		||||
 				goto invalid;
 | 
			
		||||
 			break;
 | 
			
		||||
 		case WLAN_ACTION_DELBA:
 | 
			
		||||
+		case WLAN_ACTION_NDP_DELBA:
 | 
			
		||||
 			if (len < (IEEE80211_MIN_ACTION_SIZE +
 | 
			
		||||
 				   sizeof(mgmt->u.action.u.delba)))
 | 
			
		||||
 				goto invalid;
 | 
			
		||||
--- a/net/mac80211/sta_info.h
 | 
			
		||||
+++ b/net/mac80211/sta_info.h
 | 
			
		||||
@@ -170,6 +170,7 @@
 | 
			
		||||
  * @failed_bar_ssn: ssn of the last failed BAR tx attempt
 | 
			
		||||
  * @bar_pending: BAR needs to be re-sent
 | 
			
		||||
  * @amsdu: support A-MSDU withing A-MDPU
 | 
			
		||||
+ * @ndp: this session is using NDP block ACKs
 | 
			
		||||
  *
 | 
			
		||||
  * This structure's lifetime is managed by RCU, assignments to
 | 
			
		||||
  * the array holding it must hold the aggregation mutex.
 | 
			
		||||
@@ -198,6 +199,7 @@
 | 
			
		||||
 	u16 failed_bar_ssn;
 | 
			
		||||
 	bool bar_pending;
 | 
			
		||||
 	bool amsdu;
 | 
			
		||||
+	bool ndp;
 | 
			
		||||
 	u8 tid;
 | 
			
		||||
 };
 | 
			
		||||
 
 | 
			
		||||
@@ -225,6 +227,7 @@
 | 
			
		||||
  *	and ssn.
 | 
			
		||||
  * @removed: this session is removed (but might have been found due to RCU)
 | 
			
		||||
  * @started: this session has started (head ssn or higher was received)
 | 
			
		||||
+ * @ndp: this session is using NDP block ACKs
 | 
			
		||||
  *
 | 
			
		||||
  * This structure's lifetime is managed by RCU, assignments to
 | 
			
		||||
  * the array holding it must hold the aggregation mutex.
 | 
			
		||||
@@ -252,7 +255,8 @@
 | 
			
		||||
 	u8 tid;
 | 
			
		||||
 	u8 auto_seq:1,
 | 
			
		||||
 	   removed:1,
 | 
			
		||||
-	   started:1;
 | 
			
		||||
+	   started:1,
 | 
			
		||||
+	   ndp:1;
 | 
			
		||||
 };
 | 
			
		||||
 
 | 
			
		||||
 /**
 | 
			
		||||
@@ -169,7 +169,8 @@
 | 
			
		||||
		compatible = "mediatek,eth-mac";
 | 
			
		||||
		reg = <0>;
 | 
			
		||||
		phy-mode = "sgmii";
 | 
			
		||||
		phy-handle = <&phy1>;      // add phy handler
 | 
			
		||||
		phy-handle = <&phy30>;
 | 
			
		||||
		phy-handle2 = <&phy1>;
 | 
			
		||||
		mtd-mac-address = <&factory 0x24>;
 | 
			
		||||
	};
 | 
			
		||||
 | 
			
		||||
@@ -181,9 +182,9 @@
 | 
			
		||||
		mtd-mac-address = <&factory 0x2a>;
 | 
			
		||||
	};
 | 
			
		||||
 | 
			
		||||
        mdio: mdio-bus {
 | 
			
		||||
                #address-cells = <1>;
 | 
			
		||||
                #size-cells = <0>;
 | 
			
		||||
	mdio: mdio-bus {
 | 
			
		||||
		#address-cells = <1>;
 | 
			
		||||
		#size-cells = <0>;
 | 
			
		||||
 | 
			
		||||
		phy0: ethernet-phy@0 {
 | 
			
		||||
			compatible = "ethernet-phy-id03a2.9461";
 | 
			
		||||
@@ -193,6 +194,16 @@
 | 
			
		||||
			nvmem-cell-names = "phy-cal-data";
 | 
			
		||||
		};
 | 
			
		||||
 | 
			
		||||
		phy30: ethernet-phy@30 { // AN8801SB
 | 
			
		||||
			compatible = "ethernet-phy-idc0ff.0421";
 | 
			
		||||
			reg = <30>; //0x1e
 | 
			
		||||
			phy-mode = "sgmii";
 | 
			
		||||
			full-duplex;
 | 
			
		||||
			pause;
 | 
			
		||||
			airoha,surge = <1>;
 | 
			
		||||
			airoha,polarity = <2>;
 | 
			
		||||
		};
 | 
			
		||||
 | 
			
		||||
		phy1: ethernet-phy@1 {
 | 
			
		||||
			compatible = "ethernet-phy-id03a2.9471";
 | 
			
		||||
			reg = <24>;            // set phy address to 0x18
 | 
			
		||||
@@ -200,9 +211,8 @@
 | 
			
		||||
			reset-assert-us = <600>;
 | 
			
		||||
			reset-deassert-us = <20000>;
 | 
			
		||||
			phy-mode = "sgmii";
 | 
			
		||||
    };
 | 
			
		||||
 | 
			
		||||
        };
 | 
			
		||||
		};
 | 
			
		||||
	};
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
&hnat {
 | 
			
		||||
 
 | 
			
		||||
@@ -255,18 +255,21 @@
 | 
			
		||||
&spi2 {
 | 
			
		||||
	pinctrl-names = "default";
 | 
			
		||||
	pinctrl-0 = <&spi2_pins>;
 | 
			
		||||
        address-cells = <1>;
 | 
			
		||||
        size-cells = <0>;
 | 
			
		||||
	status = "okay";
 | 
			
		||||
 | 
			
		||||
	slb9670: slb9670@0 {
 | 
			
		||||
		compatible = "infineon,slb9670";
 | 
			
		||||
		reg = <0>; /* CE0 */
 | 
			
		||||
		#address-cells = <1>;
 | 
			
		||||
		#size-cells = <0>;
 | 
			
		||||
		spi-cal-enable;
 | 
			
		||||
		spi-cal-mode = "read-data";
 | 
			
		||||
		spi-cal-datalen = <2>;
 | 
			
		||||
		spi-cal-data = /bits/ 8 <0x00 0x1b>;
 | 
			
		||||
		spi-max-frequency = <40000000>;
 | 
			
		||||
 | 
			
		||||
        mm6108: mm6108@0 {
 | 
			
		||||
                compatible = "morse,mm610x-spi";
 | 
			
		||||
                reg = <0>;
 | 
			
		||||
                reset-gpios = <&pio 31 0>;
 | 
			
		||||
                power-gpios = <&pio 5 0>,<&pio 0 0>;
 | 
			
		||||
                spi-irq-gpios = <&pio 30 0>;
 | 
			
		||||
                status = "okay";
 | 
			
		||||
                spi-max-frequency = <52000000>;
 | 
			
		||||
                spi-tx-bus-width = <1>;
 | 
			
		||||
                spi-rx-bus-width = <1>;
 | 
			
		||||
	};
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
@@ -338,6 +341,18 @@
 | 
			
		||||
			function = "spi";
 | 
			
		||||
			groups = "spi2";
 | 
			
		||||
		};
 | 
			
		||||
 | 
			
		||||
                conf-pu {
 | 
			
		||||
                        pins = "SPI2_CS";
 | 
			
		||||
                        drive-strength = <8>;
 | 
			
		||||
                        mediatek,pull-up-adv = <3>;
 | 
			
		||||
                };
 | 
			
		||||
 | 
			
		||||
                conf-pd {
 | 
			
		||||
                        pins = "SPI2_CLK", "SPI2_MOSI", "SPI2_MISO";
 | 
			
		||||
                        drive-strength = <8>;
 | 
			
		||||
                        mediatek,pull-down-adv = <3>;
 | 
			
		||||
                };
 | 
			
		||||
	};
 | 
			
		||||
 | 
			
		||||
	uart1_pins: uart1-pins-g1 {
 | 
			
		||||
 
 | 
			
		||||
@@ -0,0 +1,349 @@
 | 
			
		||||
/dts-v1/;
 | 
			
		||||
#include "mt7981.dtsi"
 | 
			
		||||
/ {
 | 
			
		||||
	model = "Emplus WAP588M";
 | 
			
		||||
	compatible = "emplus,wap588m";
 | 
			
		||||
	chosen {
 | 
			
		||||
		bootargs = "console=ttyS0,115200n1 loglevel=8  \
 | 
			
		||||
				earlycon=uart8250,mmio32,0x11002000";
 | 
			
		||||
	};
 | 
			
		||||
 | 
			
		||||
	memory {
 | 
			
		||||
		reg = <0 0x40000000 0 0x10000000>;
 | 
			
		||||
	};
 | 
			
		||||
 | 
			
		||||
	gpio-keys {
 | 
			
		||||
		compatible = "gpio-keys";
 | 
			
		||||
 | 
			
		||||
		reset {
 | 
			
		||||
			label = "reset";
 | 
			
		||||
			linux,code = <KEY_RESTART>;
 | 
			
		||||
			gpios = <&pio 1 GPIO_ACTIVE_LOW>;
 | 
			
		||||
				};
 | 
			
		||||
	};
 | 
			
		||||
 | 
			
		||||
	leds {
 | 
			
		||||
		compatible = "gpio-leds";
 | 
			
		||||
		power {
 | 
			
		||||
			label = "power";
 | 
			
		||||
			gpios = <&pio 11 GPIO_ACTIVE_LOW>;
 | 
			
		||||
			linux,default-trigger = "timer";
 | 
			
		||||
			default-state = "on";
 | 
			
		||||
 | 
			
		||||
		};
 | 
			
		||||
		wifi2g {
 | 
			
		||||
			label = "wifi2g";
 | 
			
		||||
			gpios = <&pio 9 GPIO_ACTIVE_LOW>;
 | 
			
		||||
			linux,default-trigger = "ra0";
 | 
			
		||||
		};
 | 
			
		||||
		wifi5g {
 | 
			
		||||
			label = "wifi5g";
 | 
			
		||||
			gpios = <&pio 12 GPIO_ACTIVE_LOW>;
 | 
			
		||||
			linux,default-trigger = "rax0";
 | 
			
		||||
		};
 | 
			
		||||
		lan {
 | 
			
		||||
			label = "lan";
 | 
			
		||||
			gpios = <&pio 10 GPIO_ACTIVE_LOW>;
 | 
			
		||||
			linux,default-trigger = "eth0";
 | 
			
		||||
		};
 | 
			
		||||
		wan {
 | 
			
		||||
			label = "wan";
 | 
			
		||||
			gpios = <&pio 13 GPIO_ACTIVE_LOW>;
 | 
			
		||||
			linux,default-trigger = "eth1";
 | 
			
		||||
		};
 | 
			
		||||
	};
 | 
			
		||||
 | 
			
		||||
	nmbm_spim_nand {
 | 
			
		||||
		compatible = "generic,nmbm";
 | 
			
		||||
 | 
			
		||||
		#address-cells = <1>;
 | 
			
		||||
		#size-cells = <1>;
 | 
			
		||||
 | 
			
		||||
		lower-mtd-device = <&spi_nand>;
 | 
			
		||||
		forced-create;
 | 
			
		||||
 | 
			
		||||
		partitions {
 | 
			
		||||
			compatible = "fixed-partitions";
 | 
			
		||||
			#address-cells = <1>;
 | 
			
		||||
			#size-cells = <1>;
 | 
			
		||||
 | 
			
		||||
			partition@0 {
 | 
			
		||||
				label = "BL2";
 | 
			
		||||
				reg = <0x00000 0x0100000>;
 | 
			
		||||
				read-only;
 | 
			
		||||
			};
 | 
			
		||||
 | 
			
		||||
			partition@100000 {
 | 
			
		||||
				label = "u-boot-env";
 | 
			
		||||
				reg = <0x0100000 0x0080000>;
 | 
			
		||||
			};
 | 
			
		||||
 | 
			
		||||
			factory: partition@180000 {
 | 
			
		||||
				label = "Factory";
 | 
			
		||||
				reg = <0x180000 0x0200000>;
 | 
			
		||||
			};
 | 
			
		||||
 | 
			
		||||
			partition@380000 {
 | 
			
		||||
				label = "FIP";
 | 
			
		||||
				reg = <0x380000 0x0200000>;
 | 
			
		||||
			};
 | 
			
		||||
 | 
			
		||||
			partition@580000 {
 | 
			
		||||
				label = "ubi"; //110MB
 | 
			
		||||
				reg = <0x580000 0x3700000>;
 | 
			
		||||
			};
 | 
			
		||||
 | 
			
		||||
			partition@3C80000 {
 | 
			
		||||
				label = "ubi_1"; //110MB
 | 
			
		||||
				reg = <0x3C80000 0x3700000>;
 | 
			
		||||
			};
 | 
			
		||||
 | 
			
		||||
			partition@7380000 {
 | 
			
		||||
				label = "cert"; //384KB
 | 
			
		||||
				reg = <0x7380000 0x0060000>;
 | 
			
		||||
			};
 | 
			
		||||
 | 
			
		||||
			partition@73E0000 {
 | 
			
		||||
				label = "userconfig"; //640KB
 | 
			
		||||
				reg = <0x73E0000 0x00a0000>;
 | 
			
		||||
			};
 | 
			
		||||
 | 
			
		||||
			partition@7480000 {
 | 
			
		||||
				label = "crashdump"; //384KB
 | 
			
		||||
				reg = <0x7480000 0x0060000>;
 | 
			
		||||
			};
 | 
			
		||||
		};
 | 
			
		||||
	};
 | 
			
		||||
 | 
			
		||||
	sound_wm8960 {
 | 
			
		||||
		compatible = "mediatek,mt79xx-wm8960-machine";
 | 
			
		||||
		mediatek,platform = <&afe>;
 | 
			
		||||
		audio-routing = "Headphone", "HP_L",
 | 
			
		||||
				"Headphone", "HP_R",
 | 
			
		||||
				"LINPUT1", "AMIC",
 | 
			
		||||
				"RINPUT1", "AMIC";
 | 
			
		||||
		mediatek,audio-codec = <&wm8960>;
 | 
			
		||||
		status = "disabled";
 | 
			
		||||
	};
 | 
			
		||||
 | 
			
		||||
	sound_si3218x {
 | 
			
		||||
		compatible = "mediatek,mt79xx-si3218x-machine";
 | 
			
		||||
		mediatek,platform = <&afe>;
 | 
			
		||||
		mediatek,ext-codec = <&proslic_spi>;
 | 
			
		||||
		status = "disabled";
 | 
			
		||||
	};
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
&afe {
 | 
			
		||||
	pinctrl-names = "default";
 | 
			
		||||
	pinctrl-0 = <&pcm_pins>;
 | 
			
		||||
	status = "okay";
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
&i2c0 {
 | 
			
		||||
	pinctrl-names = "default";
 | 
			
		||||
	pinctrl-0 = <&i2c_pins>;
 | 
			
		||||
	status = "disabled";
 | 
			
		||||
 | 
			
		||||
	wm8960: wm8960@1a {
 | 
			
		||||
		compatible = "wlf,wm8960";
 | 
			
		||||
		reg = <0x1a>;
 | 
			
		||||
	};
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
&uart0 {
 | 
			
		||||
	status = "okay";
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
&watchdog {
 | 
			
		||||
	status = "okay";
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
ð {
 | 
			
		||||
        status = "okay";
 | 
			
		||||
 | 
			
		||||
        gmac0: mac@0 {
 | 
			
		||||
                compatible = "mediatek,eth-mac";
 | 
			
		||||
                reg = <0>;
 | 
			
		||||
                phy-mode = "sgmii";
 | 
			
		||||
                phy-handle = <&phy1>;
 | 
			
		||||
        };
 | 
			
		||||
 | 
			
		||||
	gmac1: mac@1 {
 | 
			
		||||
		compatible = "mediatek,eth-mac";
 | 
			
		||||
		reg = <1>;
 | 
			
		||||
		phy-mode = "gmii";
 | 
			
		||||
		phy-handle = <&phy0>;
 | 
			
		||||
	};
 | 
			
		||||
 | 
			
		||||
        mdio: mdio-bus {
 | 
			
		||||
                #address-cells = <1>;
 | 
			
		||||
                #size-cells = <0>;
 | 
			
		||||
 | 
			
		||||
		// MT7981 internal PHY
 | 
			
		||||
		phy0: ethernet-phy@0 {
 | 
			
		||||
			compatible = "ethernet-phy-id03a2.9461";
 | 
			
		||||
			reg = <0>;
 | 
			
		||||
			phy-mode = "gmii";
 | 
			
		||||
			nvmem-cells = <&phy_calibration>;
 | 
			
		||||
			nvmem-cell-names = "phy-cal-data";
 | 
			
		||||
		};
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
		// RTL8211FS PHY
 | 
			
		||||
		phy1: ethernet-phy@1 {
 | 
			
		||||
			compatible = "ethernet-phy-id001c.c916";
 | 
			
		||||
			reg = <1>;
 | 
			
		||||
			reset-gpios = <&pio 39 GPIO_ACTIVE_LOW>;
 | 
			
		||||
			reset-assert-us = <120000>;
 | 
			
		||||
			reset-deassert-us = <120000>;
 | 
			
		||||
			phy-mode = "sgmii";
 | 
			
		||||
		};
 | 
			
		||||
    };
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
&hnat {
 | 
			
		||||
	mtketh-wan = "eth1";
 | 
			
		||||
	mtketh-lan = "eth0";
 | 
			
		||||
	mtketh-max-gmac = <2>;
 | 
			
		||||
	status = "okay";
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
&spi0 {
 | 
			
		||||
	pinctrl-names = "default";
 | 
			
		||||
	pinctrl-0 = <&spi0_flash_pins>;
 | 
			
		||||
	status = "okay";
 | 
			
		||||
	spi_nand: spi_nand@0 {
 | 
			
		||||
		#address-cells = <1>;
 | 
			
		||||
		#size-cells = <1>;
 | 
			
		||||
		compatible = "spi-nand";
 | 
			
		||||
		reg = <0>;
 | 
			
		||||
		spi-max-frequency = <52000000>;
 | 
			
		||||
		spi-tx-bus-width = <4>;
 | 
			
		||||
		spi-rx-bus-width = <4>;
 | 
			
		||||
	};
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
&spi1 {
 | 
			
		||||
	pinctrl-names = "default";
 | 
			
		||||
	pinctrl-0 = <&spic_pins>;
 | 
			
		||||
	status = "okay";
 | 
			
		||||
 | 
			
		||||
	proslic_spi: proslic_spi@0 {
 | 
			
		||||
		compatible = "silabs,proslic_spi";
 | 
			
		||||
		reg = <0>;
 | 
			
		||||
		spi-max-frequency = <10000000>;
 | 
			
		||||
		spi-cpha = <1>;
 | 
			
		||||
		spi-cpol = <1>;
 | 
			
		||||
		channel_count = <1>;
 | 
			
		||||
		debug_level = <4>;       /* 1 = TRC, 2 = DBG, 4 = ERR */
 | 
			
		||||
		reset_gpio = <&pio 15 0>;
 | 
			
		||||
		ig,enable-spi = <1>;     /* 1: Enable, 0: Disable */
 | 
			
		||||
	};
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
&wbsys {
 | 
			
		||||
	mediatek,mtd-eeprom = <&factory 0x0000>;
 | 
			
		||||
	status = "okay";
 | 
			
		||||
	pinctrl-names = "dbdc";
 | 
			
		||||
	pinctrl-0 = <&wf_dbdc_pins>;
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
&pio {
 | 
			
		||||
 | 
			
		||||
	i2c_pins: i2c-pins-g0 {
 | 
			
		||||
                mux {
 | 
			
		||||
                        function = "i2c";
 | 
			
		||||
                        groups = "i2c0_0";
 | 
			
		||||
                };
 | 
			
		||||
        };
 | 
			
		||||
 | 
			
		||||
        pcm_pins: pcm-pins-g0 {
 | 
			
		||||
                mux {
 | 
			
		||||
                        function = "pcm";
 | 
			
		||||
                        groups = "pcm";
 | 
			
		||||
                };
 | 
			
		||||
        };
 | 
			
		||||
 | 
			
		||||
        pwm0_pin: pwm0-pin-g0 {
 | 
			
		||||
                mux {
 | 
			
		||||
                        function = "pwm";
 | 
			
		||||
                        groups = "pwm0_0";
 | 
			
		||||
                };
 | 
			
		||||
        };
 | 
			
		||||
 | 
			
		||||
        pwm1_pin: pwm1-pin-g0 {
 | 
			
		||||
                mux {
 | 
			
		||||
                        function = "pwm";
 | 
			
		||||
                        groups = "pwm1_0";
 | 
			
		||||
                };
 | 
			
		||||
        };
 | 
			
		||||
 | 
			
		||||
        pwm2_pin: pwm2-pin {
 | 
			
		||||
                mux {
 | 
			
		||||
                        function = "pwm";
 | 
			
		||||
                        groups = "pwm2";
 | 
			
		||||
                };
 | 
			
		||||
        };
 | 
			
		||||
 | 
			
		||||
	spi0_flash_pins: spi0-pins {
 | 
			
		||||
		mux {
 | 
			
		||||
			function = "spi";
 | 
			
		||||
			groups = "spi0", "spi0_wp_hold";
 | 
			
		||||
		};
 | 
			
		||||
 | 
			
		||||
		conf-pu {
 | 
			
		||||
			pins = "SPI0_CS", "SPI0_HOLD", "SPI0_WP";
 | 
			
		||||
			drive-strength = <MTK_DRIVE_8mA>;
 | 
			
		||||
			bias-pull-up = <MTK_PUPD_SET_R1R0_11>;
 | 
			
		||||
		};
 | 
			
		||||
 | 
			
		||||
		conf-pd {
 | 
			
		||||
			pins = "SPI0_CLK", "SPI0_MOSI", "SPI0_MISO";
 | 
			
		||||
			drive-strength = <MTK_DRIVE_8mA>;
 | 
			
		||||
			bias-pull-down = <MTK_PUPD_SET_R1R0_11>;
 | 
			
		||||
		};
 | 
			
		||||
	};
 | 
			
		||||
 | 
			
		||||
	spic_pins: spi1-pins {
 | 
			
		||||
		mux {
 | 
			
		||||
			function = "spi";
 | 
			
		||||
			groups = "spi1_1";
 | 
			
		||||
		};
 | 
			
		||||
	};
 | 
			
		||||
 | 
			
		||||
	uart1_pins: uart1-pins-g1 {
 | 
			
		||||
                mux {
 | 
			
		||||
                        function = "uart";
 | 
			
		||||
                        groups = "uart1_1";
 | 
			
		||||
                };
 | 
			
		||||
        };
 | 
			
		||||
 | 
			
		||||
	uart2_pins: uart2-pins-g1 {
 | 
			
		||||
		mux {
 | 
			
		||||
                        function = "uart";
 | 
			
		||||
                        groups = "uart2_1";
 | 
			
		||||
                };
 | 
			
		||||
        };
 | 
			
		||||
	wf_dbdc_pins: wf_dbdc-pins {
 | 
			
		||||
		mux {
 | 
			
		||||
			function = "eth";
 | 
			
		||||
			groups = "wf0_mode1";
 | 
			
		||||
		};
 | 
			
		||||
		conf {
 | 
			
		||||
			pins = "WF_HB1", "WF_HB2", "WF_HB3", "WF_HB4",
 | 
			
		||||
			       "WF_HB0", "WF_HB0_B", "WF_HB5", "WF_HB6",
 | 
			
		||||
			       "WF_HB7", "WF_HB8", "WF_HB9", "WF_HB10",
 | 
			
		||||
			       "WF_TOP_CLK", "WF_TOP_DATA", "WF_XO_REQ",
 | 
			
		||||
			       "WF_CBA_RESETB", "WF_DIG_RESETB";
 | 
			
		||||
			drive-strength = <MTK_DRIVE_4mA>;
 | 
			
		||||
		};
 | 
			
		||||
	};
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
&xhci {
 | 
			
		||||
	mediatek,u3p-dis-msk = <0x0>;
 | 
			
		||||
	phys = <&u2port0 PHY_TYPE_USB2>,
 | 
			
		||||
	       <&u3port0 PHY_TYPE_USB3>;
 | 
			
		||||
	status = "disabled";
 | 
			
		||||
};
 | 
			
		||||
@@ -9,6 +9,11 @@
 | 
			
		||||
/ {
 | 
			
		||||
	aliases {
 | 
			
		||||
		serial0 = &uart0;
 | 
			
		||||
 | 
			
		||||
		led-boot = &led_power;
 | 
			
		||||
		led-failsafe = &led_power;
 | 
			
		||||
		led-running = &led_power;
 | 
			
		||||
		led-upgrade = &led_power;
 | 
			
		||||
	};
 | 
			
		||||
 | 
			
		||||
	chosen {
 | 
			
		||||
@@ -39,31 +44,22 @@
 | 
			
		||||
	leds {
 | 
			
		||||
		compatible = "gpio-leds";
 | 
			
		||||
 | 
			
		||||
		led_blue {
 | 
			
		||||
		led_power: led_blue {
 | 
			
		||||
			label = "sys:blue";
 | 
			
		||||
			gpios = <&pio 23 GPIO_ACTIVE_HIGH>;
 | 
			
		||||
			linux,default-trigger = "timer";
 | 
			
		||||
			active-delay = <500>;
 | 
			
		||||
			inactive-delay = <500>;
 | 
			
		||||
			default-state="on";
 | 
			
		||||
			default-state="off";
 | 
			
		||||
		};
 | 
			
		||||
 | 
			
		||||
		led_green {
 | 
			
		||||
			label = "sys:green";
 | 
			
		||||
			gpios = <&pio 24 GPIO_ACTIVE_HIGH>;
 | 
			
		||||
			linux,default-trigger = "timer";
 | 
			
		||||
			active-delay = <500>;
 | 
			
		||||
			inactive-delay = <500>;
 | 
			
		||||
			default-state="on";
 | 
			
		||||
			default-state="off";
 | 
			
		||||
		};
 | 
			
		||||
 | 
			
		||||
		led_red {
 | 
			
		||||
			label = "sys:red";
 | 
			
		||||
			gpios = <&pio 25 GPIO_ACTIVE_LOW>;
 | 
			
		||||
			linux,default-trigger = "timer";
 | 
			
		||||
			active-delay = <500>;
 | 
			
		||||
			inactive-delay = <500>;
 | 
			
		||||
			default-state="on";
 | 
			
		||||
			default-state="off";
 | 
			
		||||
		};
 | 
			
		||||
	};
 | 
			
		||||
};
 | 
			
		||||
@@ -113,7 +109,7 @@
 | 
			
		||||
 | 
			
		||||
							port@0 {
 | 
			
		||||
									reg = <0>;
 | 
			
		||||
									label = "lan1";
 | 
			
		||||
									label = "lan3";
 | 
			
		||||
							};
 | 
			
		||||
 | 
			
		||||
							port@1 {
 | 
			
		||||
@@ -123,7 +119,7 @@
 | 
			
		||||
 | 
			
		||||
							port@2 {
 | 
			
		||||
									reg = <2>;
 | 
			
		||||
									label = "lan3";
 | 
			
		||||
									label = "lan1";
 | 
			
		||||
							};
 | 
			
		||||
 | 
			
		||||
							port@6 {
 | 
			
		||||
 
 | 
			
		||||
@@ -113,7 +113,6 @@ static const struct AIR_LED_CFG_T led_cfg_dlt[MAX_LED_SIZE] = {
 | 
			
		||||
	/* LED2 */
 | 
			
		||||
	{LED_ENABLE, AIR_LED_GPIO9, AIR_ACTIVE_LOW,  AIR_LED2_ON, AIR_LED2_BLK},
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
static const u16 led_blink_cfg_dlt = AIR_LED_BLK_DUR_64M;
 | 
			
		||||
/* RGMII delay */
 | 
			
		||||
static const u8 rxdelay_force = FALSE;
 | 
			
		||||
@@ -140,7 +139,6 @@ static int __air_buckpbus_reg_write(struct phy_device *phydev, u32 addr,
 | 
			
		||||
	err |= mbus->write(mbus, phy_addr, 0x13, (u16)(data >> 16));
 | 
			
		||||
	err |= mbus->write(mbus, phy_addr, 0x14, (u16)(data & 0xffff));
 | 
			
		||||
	err |= mbus->write(mbus, phy_addr, 0x1F, 0);
 | 
			
		||||
 | 
			
		||||
	return err;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
@@ -167,6 +165,41 @@ static u32 __air_buckpbus_reg_read(struct phy_device *phydev, u32 addr)
 | 
			
		||||
	return data;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static u32 __air_buckpbus_reg_modify(struct phy_device *phydev, u32 addr,
 | 
			
		||||
					u32 mask, u32 set)
 | 
			
		||||
{
 | 
			
		||||
	int err = 0;
 | 
			
		||||
	u32 data_h, data_l, data_old, data_new;
 | 
			
		||||
	int phy_addr = phydev_phy_addr(phydev);
 | 
			
		||||
	struct mii_bus *mbus = phydev_mdiobus(phydev);
 | 
			
		||||
 | 
			
		||||
	err = mbus->write(mbus, phy_addr, 0x1F, 4);
 | 
			
		||||
	err |= mbus->write(mbus, phy_addr, 0x10, 0);
 | 
			
		||||
	err |= mbus->write(mbus, phy_addr, 0x15, (u16)(addr >> 16));
 | 
			
		||||
	err |= mbus->write(mbus, phy_addr, 0x16, (u16)(addr & 0xffff));
 | 
			
		||||
	data_h = mbus->read(mbus, phy_addr, 0x17);
 | 
			
		||||
	data_l = mbus->read(mbus, phy_addr, 0x18);
 | 
			
		||||
	if (err < 0) {
 | 
			
		||||
		mbus->write(mbus, phy_addr, 0x1F, 0);
 | 
			
		||||
		return INVALID_DATA;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	data_old = ((data_h & 0xffff) << 16) | (data_l & 0xffff);
 | 
			
		||||
	data_new = (data_old & ~mask) | set;
 | 
			
		||||
	if (data_new == data_old) {
 | 
			
		||||
		mbus->write(mbus, phy_addr, 0x1F, 0);
 | 
			
		||||
		return 0;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	err |= mbus->write(mbus, phy_addr, 0x11, (u16)(addr >> 16));
 | 
			
		||||
	err |= mbus->write(mbus, phy_addr, 0x12, (u16)(addr & 0xffff));
 | 
			
		||||
	err |= mbus->write(mbus, phy_addr, 0x13, (u16)(data_new >> 16));
 | 
			
		||||
	err |= mbus->write(mbus, phy_addr, 0x14, (u16)(data_new & 0xffff));
 | 
			
		||||
	err |= mbus->write(mbus, phy_addr, 0x1F, 0);
 | 
			
		||||
 | 
			
		||||
	return err;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static int air_buckpbus_reg_write(struct phy_device *phydev, u32 addr, u32 data)
 | 
			
		||||
{
 | 
			
		||||
	int err = 0;
 | 
			
		||||
@@ -189,82 +222,18 @@ static u32 air_buckpbus_reg_read(struct phy_device *phydev, u32 addr)
 | 
			
		||||
	return data;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static int __an8801_cl45_write(struct phy_device *phydev, int devad, u16 reg,
 | 
			
		||||
				u16 val)
 | 
			
		||||
{
 | 
			
		||||
	u32 addr = (AN8801_EPHY_ADDR | AN8801_CL22 | (devad << 18) |
 | 
			
		||||
				(reg << 2));
 | 
			
		||||
 | 
			
		||||
	return __air_buckpbus_reg_write(phydev, addr, val);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static int __an8801_cl45_read(struct phy_device *phydev, int devad, u16 reg)
 | 
			
		||||
{
 | 
			
		||||
	u32 addr = (AN8801_EPHY_ADDR | AN8801_CL22 | (devad << 18) |
 | 
			
		||||
				(reg << 2));
 | 
			
		||||
 | 
			
		||||
	return __air_buckpbus_reg_read(phydev, addr);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
int __an8801_modify_cl45_changed(struct phy_device *phydev, int devad, u32 regnum,
 | 
			
		||||
				u16 mask, u16 set)
 | 
			
		||||
{
 | 
			
		||||
	int new, ret;
 | 
			
		||||
 | 
			
		||||
	ret = __an8801_cl45_read(phydev, devad, regnum);
 | 
			
		||||
	if (ret < 0)
 | 
			
		||||
		return ret;
 | 
			
		||||
 | 
			
		||||
	new = (ret & ~mask) | set;
 | 
			
		||||
	if (new == ret)
 | 
			
		||||
		return 0;
 | 
			
		||||
 | 
			
		||||
	ret = __an8801_cl45_write(phydev, devad, regnum, new);
 | 
			
		||||
 | 
			
		||||
	return ret < 0 ? ret : 1;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static int an8801_modify_cl45_changed(struct phy_device *phydev, int devad,
 | 
			
		||||
				u32 regnum, u16 mask, u16 set)
 | 
			
		||||
static int air_buckpbus_reg_modify(struct phy_device *phydev, u32 addr,
 | 
			
		||||
					u32 mask, u32 set)
 | 
			
		||||
{
 | 
			
		||||
	int err = 0;
 | 
			
		||||
 | 
			
		||||
	mdiobus_lock(phydev);
 | 
			
		||||
	err = __an8801_modify_cl45_changed(phydev, devad, regnum, mask, set);
 | 
			
		||||
	err = __air_buckpbus_reg_modify(phydev, addr, mask, set);
 | 
			
		||||
	mdiobus_unlock(phydev);
 | 
			
		||||
 | 
			
		||||
	return err;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static int an8801_cl45_write(struct phy_device *phydev, int devad, u16 reg,
 | 
			
		||||
			      u16 val)
 | 
			
		||||
{
 | 
			
		||||
	int err = 0;
 | 
			
		||||
 | 
			
		||||
	mdiobus_lock(phydev);
 | 
			
		||||
	err = __an8801_cl45_write(phydev, devad, reg, val);
 | 
			
		||||
	mdiobus_unlock(phydev);
 | 
			
		||||
 | 
			
		||||
	return err;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static int an8801_cl45_read(struct phy_device *phydev, int devad, u16 reg,
 | 
			
		||||
			     u16 *read_data)
 | 
			
		||||
{
 | 
			
		||||
	int data = 0;
 | 
			
		||||
 | 
			
		||||
	mdiobus_lock(phydev);
 | 
			
		||||
	data = __an8801_cl45_read(phydev, devad, reg);
 | 
			
		||||
	mdiobus_unlock(phydev);
 | 
			
		||||
 | 
			
		||||
	if (data == INVALID_DATA)
 | 
			
		||||
		return -EINVAL;
 | 
			
		||||
 | 
			
		||||
	*read_data = data;
 | 
			
		||||
 | 
			
		||||
	return 0;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static int air_sw_reset(struct phy_device *phydev)
 | 
			
		||||
{
 | 
			
		||||
	u32 reg_value;
 | 
			
		||||
@@ -298,50 +267,36 @@ static int an8801_led_set_usr_def(struct phy_device *phydev, u8 entity,
 | 
			
		||||
 | 
			
		||||
	on_evt |= LED_ON_EN;
 | 
			
		||||
 | 
			
		||||
	err = an8801_cl45_write(phydev, 0x1f, LED_ON_CTRL(entity), on_evt);
 | 
			
		||||
	err = phy_write_mmd(phydev, 0x1f, LED_ON_CTRL(entity), on_evt);
 | 
			
		||||
	if (err)
 | 
			
		||||
		return -1;
 | 
			
		||||
 | 
			
		||||
	return an8801_cl45_write(phydev, 0x1f, LED_BLK_CTRL(entity), blk_evt);
 | 
			
		||||
	return phy_write_mmd(phydev, 0x1f, LED_BLK_CTRL(entity), blk_evt);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static int an8801_led_set_mode(struct phy_device *phydev, u8 mode)
 | 
			
		||||
{
 | 
			
		||||
	int err;
 | 
			
		||||
	u16 data;
 | 
			
		||||
 | 
			
		||||
	err = an8801_cl45_read(phydev, 0x1f, LED_BCR, &data);
 | 
			
		||||
	if (err)
 | 
			
		||||
		return -1;
 | 
			
		||||
 | 
			
		||||
	switch (mode) {
 | 
			
		||||
	case AIR_LED_MODE_DISABLE:
 | 
			
		||||
		data &= ~LED_BCR_EXT_CTRL;
 | 
			
		||||
		data &= ~LED_BCR_MODE_MASK;
 | 
			
		||||
		data |= LED_BCR_MODE_DISABLE;
 | 
			
		||||
		break;
 | 
			
		||||
		return phy_modify_mmd(phydev, 0x1f, LED_BCR,
 | 
			
		||||
						(LED_BCR_EXT_CTRL | LED_BCR_CLK_EN),
 | 
			
		||||
						0x0);
 | 
			
		||||
	case AIR_LED_MODE_USER_DEFINE:
 | 
			
		||||
		data |= (LED_BCR_EXT_CTRL | LED_BCR_CLK_EN);
 | 
			
		||||
		return phy_modify_mmd(phydev, 0x1f, LED_BCR,
 | 
			
		||||
						(LED_BCR_EXT_CTRL | LED_BCR_CLK_EN),
 | 
			
		||||
						(LED_BCR_EXT_CTRL | LED_BCR_CLK_EN));
 | 
			
		||||
	default:
 | 
			
		||||
		break;
 | 
			
		||||
	}
 | 
			
		||||
	return an8801_cl45_write(phydev, 0x1f, LED_BCR, data);
 | 
			
		||||
	dev_err(phydev_dev(phydev),
 | 
			
		||||
				"LED mode %d is not supported\n", mode);
 | 
			
		||||
	return -EINVAL;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static int an8801_led_set_state(struct phy_device *phydev, u8 entity, u8 state)
 | 
			
		||||
{
 | 
			
		||||
	u16 data;
 | 
			
		||||
	int err;
 | 
			
		||||
 | 
			
		||||
	err = an8801_cl45_read(phydev, 0x1f, LED_ON_CTRL(entity), &data);
 | 
			
		||||
	if (err)
 | 
			
		||||
		return err;
 | 
			
		||||
 | 
			
		||||
	if (state)
 | 
			
		||||
		data |= LED_ON_EN;
 | 
			
		||||
	else
 | 
			
		||||
		data &= ~LED_ON_EN;
 | 
			
		||||
 | 
			
		||||
	return an8801_cl45_write(phydev, 0x1f, LED_ON_CTRL(entity), data);
 | 
			
		||||
	return phy_modify_mmd(phydev, 0x1f, LED_ON_CTRL(entity), LED_ON_EN,
 | 
			
		||||
					(state) ? LED_ON_EN : 0x0);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static int an8801_led_init(struct phy_device *phydev)
 | 
			
		||||
@@ -352,12 +307,12 @@ static int an8801_led_init(struct phy_device *phydev)
 | 
			
		||||
	u32 data;
 | 
			
		||||
	u16 led_blink_cfg = priv->led_blink_cfg;
 | 
			
		||||
 | 
			
		||||
	ret = an8801_cl45_write(phydev, 0x1f, LED_BLK_DUR,
 | 
			
		||||
	ret = phy_write_mmd(phydev, 0x1f, LED_BLK_DUR,
 | 
			
		||||
				 LED_BLINK_DURATION(led_blink_cfg));
 | 
			
		||||
	if (ret < 0)
 | 
			
		||||
		return ret;
 | 
			
		||||
 | 
			
		||||
	ret = an8801_cl45_write(phydev, 0x1f, LED_ON_DUR,
 | 
			
		||||
	ret = phy_write_mmd(phydev, 0x1f, LED_ON_DUR,
 | 
			
		||||
				 (LED_BLINK_DURATION(led_blink_cfg) >> 1));
 | 
			
		||||
	if (ret < 0)
 | 
			
		||||
		return ret;
 | 
			
		||||
@@ -406,6 +361,56 @@ static int an8801_led_init(struct phy_device *phydev)
 | 
			
		||||
	return 0;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static int an8801_ack_interrupt(struct phy_device *phydev)
 | 
			
		||||
{
 | 
			
		||||
	u32 reg_val = 0;
 | 
			
		||||
 | 
			
		||||
	air_buckpbus_reg_write(phydev, 0x10285404, 0x102);
 | 
			
		||||
	reg_val = air_buckpbus_reg_read(phydev, 0x10285400);
 | 
			
		||||
	air_buckpbus_reg_write(phydev, 0x10285400, 0x0);
 | 
			
		||||
	air_buckpbus_reg_write(phydev, 0x10285400, reg_val | 0x10);
 | 
			
		||||
	air_buckpbus_reg_write(phydev, 0x10285404, 0x12);
 | 
			
		||||
	air_buckpbus_reg_write(phydev, 0x10285704, 0x1f);
 | 
			
		||||
	return 0;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static int an8801_config_intr(struct phy_device *phydev)
 | 
			
		||||
{
 | 
			
		||||
	if (phydev->interrupts == PHY_INTERRUPT_ENABLED) {
 | 
			
		||||
		air_buckpbus_reg_write(phydev, 0x1000007c, BIT(AIR_INTERRUPT_GPIO) << 16);
 | 
			
		||||
		air_buckpbus_reg_modify(phydev, 0x10285700, 0x1, 0x1);
 | 
			
		||||
	} else {
 | 
			
		||||
		air_buckpbus_reg_write(phydev, 0x1000007c, 0x0);
 | 
			
		||||
		air_buckpbus_reg_modify(phydev, 0x10285700, 0x1, 0x0);
 | 
			
		||||
	}
 | 
			
		||||
	an8801_ack_interrupt(phydev);
 | 
			
		||||
	return 0;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static int an8801_did_interrupt(struct phy_device *phydev)
 | 
			
		||||
{
 | 
			
		||||
	u32 reg_val = 0;
 | 
			
		||||
 | 
			
		||||
	reg_val = air_buckpbus_reg_read(phydev, 0x10285704);
 | 
			
		||||
 | 
			
		||||
	if (reg_val & 0x11)
 | 
			
		||||
		return 1;
 | 
			
		||||
 | 
			
		||||
	return 0;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
#if (KERNEL_VERSION(5, 11, 0) < LINUX_VERSION_CODE)
 | 
			
		||||
static irqreturn_t an8801_handle_interrupt(struct phy_device *phydev)
 | 
			
		||||
{
 | 
			
		||||
	if (!an8801_did_interrupt(phydev))
 | 
			
		||||
		return IRQ_NONE;
 | 
			
		||||
 | 
			
		||||
	an8801_ack_interrupt(phydev);
 | 
			
		||||
	phy_trigger_machine(phydev);
 | 
			
		||||
	return IRQ_HANDLED;
 | 
			
		||||
}
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
static int findClosestNumber(const u16 *arr, u16 size, u16 target)
 | 
			
		||||
{
 | 
			
		||||
	int left = 0, right = size - 1;
 | 
			
		||||
@@ -431,77 +436,77 @@ static int findClosestNumber(const u16 *arr, u16 size, u16 target)
 | 
			
		||||
static int an8801sb_i2mpb_config(struct phy_device *phydev)
 | 
			
		||||
{
 | 
			
		||||
	int ret = 0;
 | 
			
		||||
	u16 cl45_value = 0, temp_cl45 = 0, set = 0;
 | 
			
		||||
	u16 cl45_value = 0, temp_cl45 = 0;
 | 
			
		||||
	u16 mask = 0;
 | 
			
		||||
 | 
			
		||||
	ret = an8801_cl45_read(phydev, MMD_DEV_VSPEC1, 0x12, &cl45_value);
 | 
			
		||||
	cl45_value = phy_read_mmd(phydev, MMD_DEV_VSPEC1, 0x12);
 | 
			
		||||
	dev_dbg(phydev_dev(phydev), "%s:%d cl45_value 0x%x!\n", __func__, __LINE__, cl45_value);
 | 
			
		||||
	cl45_value = (cl45_value & GENMASK(15, 10)) + (6 << 10);
 | 
			
		||||
	ret = an8801_modify_cl45_changed(phydev, MMD_DEV_VSPEC1, 0x12, GENMASK(15, 10), cl45_value);
 | 
			
		||||
	ret = phy_modify_mmd(phydev, MMD_DEV_VSPEC1, 0x12, GENMASK(15, 10), cl45_value);
 | 
			
		||||
	if (ret < 0)
 | 
			
		||||
		return ret;
 | 
			
		||||
	ret = an8801_cl45_read(phydev, MMD_DEV_VSPEC1, 0x16, &temp_cl45);
 | 
			
		||||
	temp_cl45 = phy_read_mmd(phydev, MMD_DEV_VSPEC1, 0x16);
 | 
			
		||||
	dev_dbg(phydev_dev(phydev), "%s:%d cl45_value 0x%x!\n", __func__, __LINE__, temp_cl45);
 | 
			
		||||
	mask = GENMASK(15, 10) | GENMASK(5, 0);
 | 
			
		||||
	cl45_value = (temp_cl45 & GENMASK(15, 10)) + (9 << 10);
 | 
			
		||||
	cl45_value = ((temp_cl45 & GENMASK(5, 0)) + 6) | cl45_value;
 | 
			
		||||
	ret = an8801_modify_cl45_changed(phydev, MMD_DEV_VSPEC1, 0x16, mask, cl45_value);
 | 
			
		||||
	ret = phy_modify_mmd(phydev, MMD_DEV_VSPEC1, 0x16, mask, cl45_value);
 | 
			
		||||
	if (ret < 0)
 | 
			
		||||
		return ret;
 | 
			
		||||
	ret = an8801_cl45_read(phydev, MMD_DEV_VSPEC1, 0x17, &cl45_value);
 | 
			
		||||
	cl45_value = phy_read_mmd(phydev, MMD_DEV_VSPEC1, 0x17);
 | 
			
		||||
	dev_dbg(phydev_dev(phydev), "%s:%d cl45_value 0x%x!\n", __func__, __LINE__, cl45_value);
 | 
			
		||||
	cl45_value = (cl45_value & GENMASK(13, 8)) + (6 << 8);
 | 
			
		||||
	ret = an8801_modify_cl45_changed(phydev, MMD_DEV_VSPEC1, 0x17, GENMASK(13, 8), cl45_value);
 | 
			
		||||
	ret = phy_modify_mmd(phydev, MMD_DEV_VSPEC1, 0x17, GENMASK(13, 8), cl45_value);
 | 
			
		||||
	if (ret < 0)
 | 
			
		||||
		return ret;
 | 
			
		||||
	ret = an8801_cl45_read(phydev, MMD_DEV_VSPEC1, 0x18, &temp_cl45);
 | 
			
		||||
	temp_cl45 = phy_read_mmd(phydev, MMD_DEV_VSPEC1, 0x18);
 | 
			
		||||
	dev_dbg(phydev_dev(phydev), "%s:%d cl45_value 0x%x!\n", __func__, __LINE__, temp_cl45);
 | 
			
		||||
	mask = GENMASK(13, 8) | GENMASK(5, 0);
 | 
			
		||||
	cl45_value = (temp_cl45 & GENMASK(13, 8)) + (9 << 8);
 | 
			
		||||
	cl45_value = ((temp_cl45 & GENMASK(5, 0)) + 6) | cl45_value;
 | 
			
		||||
	ret = an8801_modify_cl45_changed(phydev, MMD_DEV_VSPEC1, 0x18, mask, cl45_value);
 | 
			
		||||
	ret = phy_modify_mmd(phydev, MMD_DEV_VSPEC1, 0x18, mask, cl45_value);
 | 
			
		||||
	if (ret < 0)
 | 
			
		||||
		return ret;
 | 
			
		||||
	ret = an8801_cl45_read(phydev, MMD_DEV_VSPEC1, 0x19, &cl45_value);
 | 
			
		||||
	cl45_value = phy_read_mmd(phydev, MMD_DEV_VSPEC1, 0x19);
 | 
			
		||||
	dev_dbg(phydev_dev(phydev), "%s:%d cl45_value 0x%x!\n", __func__, __LINE__, cl45_value);
 | 
			
		||||
	cl45_value = (cl45_value & GENMASK(13, 8)) + (6 << 8);
 | 
			
		||||
	ret = an8801_modify_cl45_changed(phydev, MMD_DEV_VSPEC1, 0x19, GENMASK(13, 8), cl45_value);
 | 
			
		||||
	ret = phy_modify_mmd(phydev, MMD_DEV_VSPEC1, 0x19, GENMASK(13, 8), cl45_value);
 | 
			
		||||
	if (ret < 0)
 | 
			
		||||
		return ret;
 | 
			
		||||
	ret = an8801_cl45_read(phydev, MMD_DEV_VSPEC1, 0x20, &cl45_value);
 | 
			
		||||
	cl45_value = phy_read_mmd(phydev, MMD_DEV_VSPEC1, 0x20);
 | 
			
		||||
	dev_dbg(phydev_dev(phydev), "%s:%d cl45_value 0x%x!\n", __func__, __LINE__, cl45_value);
 | 
			
		||||
	cl45_value = (cl45_value & GENMASK(5, 0)) + 6;
 | 
			
		||||
	ret = an8801_modify_cl45_changed(phydev, MMD_DEV_VSPEC1, 0x20, GENMASK(5, 0), cl45_value);
 | 
			
		||||
	ret = phy_modify_mmd(phydev, MMD_DEV_VSPEC1, 0x20, GENMASK(5, 0), cl45_value);
 | 
			
		||||
	if (ret < 0)
 | 
			
		||||
		return ret;
 | 
			
		||||
	ret = an8801_cl45_read(phydev, MMD_DEV_VSPEC1, 0x21, &cl45_value);
 | 
			
		||||
	cl45_value = phy_read_mmd(phydev, MMD_DEV_VSPEC1, 0x21);
 | 
			
		||||
	dev_dbg(phydev_dev(phydev), "%s:%d cl45_value 0x%x!\n", __func__, __LINE__, cl45_value);
 | 
			
		||||
	cl45_value = (cl45_value & GENMASK(13, 8)) + (6 << 8);
 | 
			
		||||
	ret = an8801_modify_cl45_changed(phydev, MMD_DEV_VSPEC1, 0x21, GENMASK(13, 8), cl45_value);
 | 
			
		||||
	ret = phy_modify_mmd(phydev, MMD_DEV_VSPEC1, 0x21, GENMASK(13, 8), cl45_value);
 | 
			
		||||
	if (ret < 0)
 | 
			
		||||
		return ret;
 | 
			
		||||
	ret = an8801_cl45_read(phydev, MMD_DEV_VSPEC1, 0x22, &cl45_value);
 | 
			
		||||
	cl45_value = phy_read_mmd(phydev, MMD_DEV_VSPEC1, 0x22);
 | 
			
		||||
	dev_dbg(phydev_dev(phydev), "%s:%d cl45_value 0x%x!\n", __func__, __LINE__, cl45_value);
 | 
			
		||||
	cl45_value = (cl45_value & GENMASK(5, 0)) + 6;
 | 
			
		||||
	ret = an8801_modify_cl45_changed(phydev, MMD_DEV_VSPEC1, 0x22, GENMASK(5, 0), cl45_value);
 | 
			
		||||
	ret = phy_modify_mmd(phydev, MMD_DEV_VSPEC1, 0x22, GENMASK(5, 0), cl45_value);
 | 
			
		||||
	if (ret < 0)
 | 
			
		||||
		return ret;
 | 
			
		||||
	ret = an8801_cl45_write(phydev, MMD_DEV_VSPEC1, 0x23, 0x883);
 | 
			
		||||
	ret |= an8801_cl45_write(phydev, MMD_DEV_VSPEC1, 0x24, 0x883);
 | 
			
		||||
	ret |= an8801_cl45_write(phydev, MMD_DEV_VSPEC1, 0x25, 0x883);
 | 
			
		||||
	ret |= an8801_cl45_write(phydev, MMD_DEV_VSPEC1, 0x26, 0x883);
 | 
			
		||||
	ret |= an8801_cl45_write(phydev, MMD_DEV_VSPEC1, 0x0, 0x100);
 | 
			
		||||
	ret |= an8801_cl45_write(phydev, MMD_DEV_VSPEC1, 0x1, 0x1bc);
 | 
			
		||||
	ret |= an8801_cl45_write(phydev, MMD_DEV_VSPEC1, 0x2, 0x1d0);
 | 
			
		||||
	ret |= an8801_cl45_write(phydev, MMD_DEV_VSPEC1, 0x3, 0x186);
 | 
			
		||||
	ret |= an8801_cl45_write(phydev, MMD_DEV_VSPEC1, 0x4, 0x202);
 | 
			
		||||
	ret |= an8801_cl45_write(phydev, MMD_DEV_VSPEC1, 0x5, 0x20e);
 | 
			
		||||
	ret |= an8801_cl45_write(phydev, MMD_DEV_VSPEC1, 0x6, 0x300);
 | 
			
		||||
	ret |= an8801_cl45_write(phydev, MMD_DEV_VSPEC1, 0x7, 0x3c0);
 | 
			
		||||
	ret |= an8801_cl45_write(phydev, MMD_DEV_VSPEC1, 0x8, 0x3d0);
 | 
			
		||||
	ret |= an8801_cl45_write(phydev, MMD_DEV_VSPEC1, 0x9, 0x317);
 | 
			
		||||
	ret |= an8801_cl45_write(phydev, MMD_DEV_VSPEC1, 0xa, 0x206);
 | 
			
		||||
	ret |= an8801_cl45_write(phydev, MMD_DEV_VSPEC1, 0xb, 0xe);
 | 
			
		||||
	ret = phy_write_mmd(phydev, MMD_DEV_VSPEC1, 0x23, 0x883);
 | 
			
		||||
	ret |= phy_write_mmd(phydev, MMD_DEV_VSPEC1, 0x24, 0x883);
 | 
			
		||||
	ret |= phy_write_mmd(phydev, MMD_DEV_VSPEC1, 0x25, 0x883);
 | 
			
		||||
	ret |= phy_write_mmd(phydev, MMD_DEV_VSPEC1, 0x26, 0x883);
 | 
			
		||||
	ret |= phy_write_mmd(phydev, MMD_DEV_VSPEC1, 0x0, 0x100);
 | 
			
		||||
	ret |= phy_write_mmd(phydev, MMD_DEV_VSPEC1, 0x1, 0x1bc);
 | 
			
		||||
	ret |= phy_write_mmd(phydev, MMD_DEV_VSPEC1, 0x2, 0x1d0);
 | 
			
		||||
	ret |= phy_write_mmd(phydev, MMD_DEV_VSPEC1, 0x3, 0x186);
 | 
			
		||||
	ret |= phy_write_mmd(phydev, MMD_DEV_VSPEC1, 0x4, 0x202);
 | 
			
		||||
	ret |= phy_write_mmd(phydev, MMD_DEV_VSPEC1, 0x5, 0x20e);
 | 
			
		||||
	ret |= phy_write_mmd(phydev, MMD_DEV_VSPEC1, 0x6, 0x300);
 | 
			
		||||
	ret |= phy_write_mmd(phydev, MMD_DEV_VSPEC1, 0x7, 0x3c0);
 | 
			
		||||
	ret |= phy_write_mmd(phydev, MMD_DEV_VSPEC1, 0x8, 0x3d0);
 | 
			
		||||
	ret |= phy_write_mmd(phydev, MMD_DEV_VSPEC1, 0x9, 0x317);
 | 
			
		||||
	ret |= phy_write_mmd(phydev, MMD_DEV_VSPEC1, 0xa, 0x206);
 | 
			
		||||
	ret |= phy_write_mmd(phydev, MMD_DEV_VSPEC1, 0xb, 0xe);
 | 
			
		||||
	if (ret < 0)
 | 
			
		||||
		return ret;
 | 
			
		||||
 | 
			
		||||
@@ -510,14 +515,14 @@ static int an8801sb_i2mpb_config(struct phy_device *phydev)
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void update_r50_value(struct phy_device *phydev,
 | 
			
		||||
			u16 *cl45_value, int pos1, int pos2)
 | 
			
		||||
	u16 *cl45_value, int pos1, int pos2)
 | 
			
		||||
{
 | 
			
		||||
	*cl45_value &= ~(0x007f << 8);
 | 
			
		||||
	*cl45_value |= ((r50ohm_table[pos1]) & 0x007f) << 8;
 | 
			
		||||
	*cl45_value &= ~(0x007f);
 | 
			
		||||
	*cl45_value |= (r50ohm_table[pos2]) & 0x007f;
 | 
			
		||||
	dev_dbg(phydev_dev(phydev), "Read: r50ohm_tx_1=%d r50ohm_tx_2=%d\n",
 | 
			
		||||
			r50ohm_table[pos1], r50ohm_table[pos2]);
 | 
			
		||||
		r50ohm_table[pos1], r50ohm_table[pos2]);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
int calculate_position(int pos, int shift, int table_size)
 | 
			
		||||
@@ -529,7 +534,7 @@ int calculate_position(int pos, int shift, int table_size)
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
int process_r50(struct phy_device *phydev, int reg,
 | 
			
		||||
			u16 *cl45_value, u16 *r50ohm_tx_a, u16 *r50ohm_tx_b)
 | 
			
		||||
	u16 *cl45_value, u16 *r50ohm_tx_a, u16 *r50ohm_tx_b)
 | 
			
		||||
{
 | 
			
		||||
	int pos1 = findClosestNumber(r50ohm_table, r50ohm_table_size, *r50ohm_tx_a);
 | 
			
		||||
	int pos2 = findClosestNumber(r50ohm_table, r50ohm_table_size, *r50ohm_tx_b);
 | 
			
		||||
@@ -539,7 +544,7 @@ int process_r50(struct phy_device *phydev, int reg,
 | 
			
		||||
		pos2 = calculate_position(pos2, R50_SHIFT, r50ohm_table_size);
 | 
			
		||||
 | 
			
		||||
		update_r50_value(phydev, cl45_value, pos1, pos2);
 | 
			
		||||
		return an8801_cl45_write(phydev, 0x1e, reg, *cl45_value);
 | 
			
		||||
		return phy_write_mmd(phydev, 0x1e, reg, *cl45_value);
 | 
			
		||||
	}
 | 
			
		||||
	return 0;
 | 
			
		||||
}
 | 
			
		||||
@@ -558,10 +563,10 @@ static int an8801r_of_init(struct phy_device *phydev)
 | 
			
		||||
			return -1;
 | 
			
		||||
		}
 | 
			
		||||
		if (val < AIR_RGMII_DELAY_NOSTEP ||
 | 
			
		||||
		    val > AIR_RGMII_DELAY_STEP_7) {
 | 
			
		||||
			val > AIR_RGMII_DELAY_STEP_7) {
 | 
			
		||||
			dev_err(phydev_dev(phydev),
 | 
			
		||||
				   "airoha,rxclk-delay value %u out of range.",
 | 
			
		||||
				   val);
 | 
			
		||||
					"airoha,rxclk-delay value %u out of range.",
 | 
			
		||||
					val);
 | 
			
		||||
			return -1;
 | 
			
		||||
		}
 | 
			
		||||
		priv->rxdelay_force = TRUE;
 | 
			
		||||
@@ -574,14 +579,14 @@ static int an8801r_of_init(struct phy_device *phydev)
 | 
			
		||||
		if (of_property_read_u32(of_node, "airoha,txclk-delay",
 | 
			
		||||
					 &val) != 0) {
 | 
			
		||||
			dev_err(phydev_dev(phydev),
 | 
			
		||||
				   "airoha,txclk-delay value is invalid.");
 | 
			
		||||
					"airoha,txclk-delay value is invalid.");
 | 
			
		||||
			return -1;
 | 
			
		||||
		}
 | 
			
		||||
		if (val < AIR_RGMII_DELAY_NOSTEP ||
 | 
			
		||||
		    val > AIR_RGMII_DELAY_STEP_7) {
 | 
			
		||||
			val > AIR_RGMII_DELAY_STEP_7) {
 | 
			
		||||
			dev_err(phydev_dev(phydev),
 | 
			
		||||
				   "airoha,txclk-delay value %u out of range.",
 | 
			
		||||
				   val);
 | 
			
		||||
					"airoha,txclk-delay value %u out of range.",
 | 
			
		||||
					val);
 | 
			
		||||
			return -1;
 | 
			
		||||
		}
 | 
			
		||||
		priv->txdelay_force = TRUE;
 | 
			
		||||
@@ -603,10 +608,10 @@ static int an8801sb_of_init(struct phy_device *phydev)
 | 
			
		||||
			return -1;
 | 
			
		||||
		}
 | 
			
		||||
		if (val < AIR_POL_TX_NOR_RX_REV ||
 | 
			
		||||
		    val > AIR_POL_TX_REV_RX_NOR) {
 | 
			
		||||
			val > AIR_POL_TX_REV_RX_NOR) {
 | 
			
		||||
			dev_err(phydev_dev(phydev),
 | 
			
		||||
				   "airoha,polarity value %u out of range.",
 | 
			
		||||
				   val);
 | 
			
		||||
					"airoha,polarity value %u out of range.",
 | 
			
		||||
					val);
 | 
			
		||||
			return -1;
 | 
			
		||||
		}
 | 
			
		||||
		priv->pol = val;
 | 
			
		||||
@@ -615,15 +620,15 @@ static int an8801sb_of_init(struct phy_device *phydev)
 | 
			
		||||
 | 
			
		||||
	if (of_find_property(of_node, "airoha,surge", NULL)) {
 | 
			
		||||
		if (of_property_read_u32(of_node, "airoha,surge",
 | 
			
		||||
					&val) != 0) {
 | 
			
		||||
					 &val) != 0) {
 | 
			
		||||
			dev_err(phydev_dev(phydev), "airoha,surge value is invalid.");
 | 
			
		||||
			return -1;
 | 
			
		||||
		}
 | 
			
		||||
		if (val < AIR_SURGE_0R ||
 | 
			
		||||
			val > AIR_SURGE_5R) {
 | 
			
		||||
			dev_err(phydev_dev(phydev),
 | 
			
		||||
				"airoha,surge value %u out of range.",
 | 
			
		||||
				val);
 | 
			
		||||
					"airoha,surge value %u out of range.",
 | 
			
		||||
					val);
 | 
			
		||||
			return -1;
 | 
			
		||||
		}
 | 
			
		||||
		priv->surge = val;
 | 
			
		||||
@@ -693,23 +698,19 @@ int an8801sb_surge_protect_cfg(struct phy_device *phydev)
 | 
			
		||||
	u16 cl45_value = 0;
 | 
			
		||||
 | 
			
		||||
	if (priv->surge) {
 | 
			
		||||
		ret = an8801_cl45_read(phydev, 0x1e, 0x174, &cl45_value);
 | 
			
		||||
		if (ret < 0)
 | 
			
		||||
			return ret;
 | 
			
		||||
		cl45_value = phy_read_mmd(phydev, 0x1e, 0x174);
 | 
			
		||||
		r50ohm_tx_a = (cl45_value >> 8) & 0x007f;
 | 
			
		||||
		r50ohm_tx_b = cl45_value & 0x007f;
 | 
			
		||||
		dev_dbg(phydev_dev(phydev), "Read: (0x174) value=0x%04x r50ohm_tx_a=%d r50ohm_tx_b=%d\n",
 | 
			
		||||
		cl45_value, r50ohm_tx_a, r50ohm_tx_b);
 | 
			
		||||
			cl45_value, r50ohm_tx_a, r50ohm_tx_b);
 | 
			
		||||
		ret = process_r50(phydev, 0x174, &cl45_value, &r50ohm_tx_a, &r50ohm_tx_b);
 | 
			
		||||
		if (ret < 0)
 | 
			
		||||
			return ret;
 | 
			
		||||
		ret = an8801_cl45_read(phydev, 0x1e, 0x175, &cl45_value);
 | 
			
		||||
		if (ret < 0)
 | 
			
		||||
			return ret;
 | 
			
		||||
		cl45_value = phy_read_mmd(phydev, 0x1e, 0x175);
 | 
			
		||||
		r50ohm_tx_c = (cl45_value >> 8) & 0x007f;
 | 
			
		||||
		r50ohm_tx_d = cl45_value & 0x007f;
 | 
			
		||||
		dev_dbg(phydev_dev(phydev), "Read: (0x175) value=0x%04x r50ohm_tx_c=%d r50ohm_tx_d=%d\n",
 | 
			
		||||
		cl45_value, r50ohm_tx_c, r50ohm_tx_d);
 | 
			
		||||
			cl45_value, r50ohm_tx_c, r50ohm_tx_d);
 | 
			
		||||
		ret = process_r50(phydev, 0x175, &cl45_value, &r50ohm_tx_c, &r50ohm_tx_d);
 | 
			
		||||
		if (ret < 0)
 | 
			
		||||
			return ret;
 | 
			
		||||
@@ -764,10 +765,10 @@ static int an8801sb_config_init(struct phy_device *phydev)
 | 
			
		||||
	dev_info(phydev_dev(phydev),
 | 
			
		||||
		"Tx, Rx Polarity : %08x\n", pbus_value);
 | 
			
		||||
 | 
			
		||||
	ret = an8801_cl45_write(phydev, MMD_DEV_VSPEC2, 0x600, 0x1e);
 | 
			
		||||
	ret |= an8801_cl45_write(phydev, MMD_DEV_VSPEC2, 0x601, 0x02);
 | 
			
		||||
	ret = phy_write_mmd(phydev, MMD_DEV_VSPEC2, 0x600, 0x1e);
 | 
			
		||||
	ret |= phy_write_mmd(phydev, MMD_DEV_VSPEC2, 0x601, 0x02);
 | 
			
		||||
 | 
			
		||||
	ret |= an8801_cl45_write(phydev, 7, 60, 0x0);
 | 
			
		||||
	ret |= phy_write_mmd(phydev, 7, 60, 0x0);
 | 
			
		||||
	if (ret != 0) {
 | 
			
		||||
		dev_err(phydev_dev(phydev),
 | 
			
		||||
			"AN8801SB initialize fail, ret %d !\n", ret);
 | 
			
		||||
@@ -940,7 +941,7 @@ static ssize_t an8801_polarity_write(struct file *file, const char __user *ptr,
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static ssize_t an8801_mdio_write(struct file *file, const char __user *ptr,
 | 
			
		||||
				size_t len, loff_t *off)
 | 
			
		||||
					size_t len, loff_t *off)
 | 
			
		||||
{
 | 
			
		||||
	struct phy_device *phydev = file->private_data;
 | 
			
		||||
	char buf[64], param1[32], param2[32];
 | 
			
		||||
@@ -955,7 +956,7 @@ static ssize_t an8801_mdio_write(struct file *file, const char __user *ptr,
 | 
			
		||||
	if (count > sizeof(buf) - 1)
 | 
			
		||||
		return -EINVAL;
 | 
			
		||||
	if (copy_from_user(buf, ptr, len))
 | 
			
		||||
	return -EFAULT;
 | 
			
		||||
		return -EFAULT;
 | 
			
		||||
 | 
			
		||||
	ret = sscanf(buf, "%s %s", param1, param2);
 | 
			
		||||
	if (ret < 0)
 | 
			
		||||
@@ -991,16 +992,16 @@ static ssize_t an8801_mdio_write(struct file *file, const char __user *ptr,
 | 
			
		||||
			pr_notice("\nphy=0x%x, devad=0x%x, reg=0x%x, val=0x%x\n",
 | 
			
		||||
				phydev_phy_addr(phydev), devad, reg, val);
 | 
			
		||||
 | 
			
		||||
			ret = an8801_cl45_write(phydev, devad, reg, val);
 | 
			
		||||
			ret = phy_write_mmd(phydev, devad, reg, val);
 | 
			
		||||
			if (ret < 0)
 | 
			
		||||
				return ret;
 | 
			
		||||
			an8801_cl45_read(phydev, devad, reg, ®_val);
 | 
			
		||||
			reg_val = phy_read_mmd(phydev, devad, reg);
 | 
			
		||||
			pr_notice("\nphy=0x%x, devad=0x%x, reg=0x%x, val=0x%x confirm..\n",
 | 
			
		||||
				phydev_phy_addr(phydev), devad, reg, reg_val);
 | 
			
		||||
		} else if (!strncmp("r", param2, strlen("r"))) {
 | 
			
		||||
			if (sscanf(buf, "cl45 r %x %x", &devad, ®) == -1)
 | 
			
		||||
				return -EFAULT;
 | 
			
		||||
			an8801_cl45_read(phydev, devad, reg, ®_val);
 | 
			
		||||
			reg_val = phy_read_mmd(phydev, devad, reg);
 | 
			
		||||
			pr_notice("\nphy=0x%x, devad=0x%x, reg=0x%x, val=0x%x\n",
 | 
			
		||||
				phydev_phy_addr(phydev), devad, reg, reg_val);
 | 
			
		||||
		} else {
 | 
			
		||||
@@ -1020,7 +1021,6 @@ static int an8801_counter_show(struct seq_file *seq, void *v)
 | 
			
		||||
	struct phy_device *phydev = seq->private;
 | 
			
		||||
	int ret = 0;
 | 
			
		||||
	u32 pkt_cnt = 0;
 | 
			
		||||
	struct mii_bus *mbus = phydev_mdiobus(phydev);
 | 
			
		||||
 | 
			
		||||
	seq_puts(seq, "==========AIR PHY COUNTER==========\n");
 | 
			
		||||
	seq_puts(seq, "|\t<<SERDES COUNTER>>\n");
 | 
			
		||||
@@ -1143,8 +1143,9 @@ static ssize_t an8801_debugfs_pbus(struct file *file,
 | 
			
		||||
	if (buf[0] == 'w') {
 | 
			
		||||
		if (sscanf(buf, "w %x %x", ®, &val) == -1)
 | 
			
		||||
			return -EFAULT;
 | 
			
		||||
 | 
			
		||||
		pr_notice("\nphy=0x%x, reg=0x%x, val=0x%x\n",
 | 
			
		||||
			phydev_phy_addr(phydev), reg, val);
 | 
			
		||||
				phydev_phy_addr(phydev), reg, val);
 | 
			
		||||
 | 
			
		||||
		ret = air_buckpbus_reg_write(phydev, reg, val);
 | 
			
		||||
		if (ret < 0)
 | 
			
		||||
@@ -1188,10 +1189,9 @@ int an8801_info_show(struct seq_file *seq, void *v)
 | 
			
		||||
	for (reg = MII_BMCR; reg <= MII_STAT1000; reg++) {
 | 
			
		||||
		if ((reg <= MII_LPA) || (reg >= MII_CTRL1000))
 | 
			
		||||
			seq_printf(seq, "| RG_MII 0x%02x     : 0x%08x\n",
 | 
			
		||||
			reg, phy_read(phydev, reg));
 | 
			
		||||
				reg, phy_read(phydev, reg));
 | 
			
		||||
	}
 | 
			
		||||
	seq_puts(seq, "\n");
 | 
			
		||||
 | 
			
		||||
	return 0;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
@@ -1231,10 +1231,10 @@ static const struct file_operations an8801_polarity_fops = {
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
static const struct file_operations an8801_mdio_fops = {
 | 
			
		||||
   .owner = THIS_MODULE,
 | 
			
		||||
   .open = simple_open,
 | 
			
		||||
   .write = an8801_mdio_write,
 | 
			
		||||
   .llseek = noop_llseek,
 | 
			
		||||
	.owner = THIS_MODULE,
 | 
			
		||||
	.open = simple_open,
 | 
			
		||||
	.write = an8801_mdio_write,
 | 
			
		||||
	.llseek = noop_llseek,
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
int an8801_debugfs_init(struct phy_device *phydev)
 | 
			
		||||
@@ -1354,13 +1354,22 @@ static int an8801sb_read_status(struct phy_device *phydev)
 | 
			
		||||
	if (phydev->link == LINK_DOWN) {
 | 
			
		||||
		prespeed = 0;
 | 
			
		||||
		phydev->speed = 0;
 | 
			
		||||
		ret |= an8801_cl45_write(
 | 
			
		||||
		ret |= phy_write_mmd(
 | 
			
		||||
			phydev, MMD_DEV_VSPEC2, PHY_PRE_SPEED_REG, prespeed);
 | 
			
		||||
 | 
			
		||||
		mdelay(10);        /* delay 10 ms */
 | 
			
		||||
		reg_value = air_buckpbus_reg_read(phydev, 0x10220010);
 | 
			
		||||
		reg_value &= 0x7fff;
 | 
			
		||||
		air_buckpbus_reg_write(phydev, 0x10220010, reg_value);
 | 
			
		||||
 | 
			
		||||
		reg_value = air_buckpbus_reg_read(phydev, 0x10220000);
 | 
			
		||||
		reg_value |= AN8801SB_SGMII_AN0_ANRESTART;
 | 
			
		||||
		air_buckpbus_reg_write(phydev, 0x10220000, reg_value);
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	if (prespeed != phydev->speed && phydev->link == LINK_UP) {
 | 
			
		||||
		prespeed = phydev->speed;
 | 
			
		||||
		ret |= an8801_cl45_write(
 | 
			
		||||
		ret |= phy_write_mmd(
 | 
			
		||||
			phydev, MMD_DEV_VSPEC2, PHY_PRE_SPEED_REG, prespeed);
 | 
			
		||||
		dev_info(phydev_dev(phydev), "AN8801SB SPEED %d\n", prespeed);
 | 
			
		||||
		while (an_retry > 0) {
 | 
			
		||||
@@ -1374,28 +1383,19 @@ static int an8801sb_read_status(struct phy_device *phydev)
 | 
			
		||||
		mdelay(10);        /* delay 10 ms */
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
		if (phydev->autoneg == AUTONEG_DISABLE) {
 | 
			
		||||
			dev_info(phydev_dev(phydev),
 | 
			
		||||
				"AN8801SB force speed = %d\n", prespeed);
 | 
			
		||||
			if (prespeed == SPEED_1000) {
 | 
			
		||||
				air_buckpbus_reg_write(
 | 
			
		||||
					phydev, 0x10220010, 0xd801);
 | 
			
		||||
			} else if (prespeed == SPEED_100) {
 | 
			
		||||
				air_buckpbus_reg_write(
 | 
			
		||||
					phydev, 0x10220010, 0xd401);
 | 
			
		||||
			} else {
 | 
			
		||||
				air_buckpbus_reg_write(
 | 
			
		||||
					phydev, 0x10220010, 0xd001);
 | 
			
		||||
			}
 | 
			
		||||
 | 
			
		||||
			reg_value = air_buckpbus_reg_read(
 | 
			
		||||
				phydev, 0x10220000);
 | 
			
		||||
			reg_value |= AN8801SB_SGMII_AN0_ANRESTART;
 | 
			
		||||
		if (prespeed == SPEED_1000) {
 | 
			
		||||
			air_buckpbus_reg_write(
 | 
			
		||||
				phydev, 0x10220000, reg_value);
 | 
			
		||||
				phydev, 0x10220010, 0xd801);
 | 
			
		||||
		} else if (prespeed == SPEED_100) {
 | 
			
		||||
			air_buckpbus_reg_write(
 | 
			
		||||
				phydev, 0x10220010, 0xd401);
 | 
			
		||||
		} else {
 | 
			
		||||
			air_buckpbus_reg_write(
 | 
			
		||||
				phydev, 0x10220010, 0xd001);
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		reg_value = air_buckpbus_reg_read(phydev, 0x10220000);
 | 
			
		||||
		reg_value |= AN8801SB_SGMII_AN0_RESET;
 | 
			
		||||
		reg_value |= (AN8801SB_SGMII_AN0_RESET | AN8801SB_SGMII_AN0_ANRESTART);
 | 
			
		||||
		air_buckpbus_reg_write(phydev, 0x10220000, reg_value);
 | 
			
		||||
	}
 | 
			
		||||
	return ret;
 | 
			
		||||
@@ -1451,9 +1451,12 @@ static struct phy_driver airoha_driver[] = {
 | 
			
		||||
		.probe          = an8801_phy_probe,
 | 
			
		||||
		.remove         = an8801_phy_remove,
 | 
			
		||||
		.read_status    = an8801_read_status,
 | 
			
		||||
#if (KERNEL_VERSION(4, 5, 0) < LINUX_VERSION_CODE)
 | 
			
		||||
		.read_mmd       = __an8801_cl45_read,
 | 
			
		||||
		.write_mmd      = __an8801_cl45_write,
 | 
			
		||||
		.config_intr	= an8801_config_intr,
 | 
			
		||||
#if (KERNEL_VERSION(5, 11, 0) < LINUX_VERSION_CODE)
 | 
			
		||||
		.handle_interrupt = an8801_handle_interrupt,
 | 
			
		||||
#else
 | 
			
		||||
		.did_interrupt	= an8801_did_interrupt,
 | 
			
		||||
		.ack_interrupt	= an8801_ack_interrupt,
 | 
			
		||||
#endif
 | 
			
		||||
	}
 | 
			
		||||
};
 | 
			
		||||
 
 | 
			
		||||
@@ -12,10 +12,10 @@
 | 
			
		||||
 | 
			
		||||
/* NAMING DECLARATIONS
 | 
			
		||||
 */
 | 
			
		||||
#define AN8801_DRIVER_VERSION  "1.1.4"
 | 
			
		||||
#define AN8801_DRIVER_VERSION  "1.1.6"
 | 
			
		||||
 | 
			
		||||
#define DEBUGFS_COUNTER         "counter"
 | 
			
		||||
#define DEBUGFS_INFO     "driver_info"
 | 
			
		||||
#define DEBUGFS_INFO            "driver_info"
 | 
			
		||||
#define DEBUGFS_PBUS_OP         "pbus_op"
 | 
			
		||||
#define DEBUGFS_POLARITY        "polarity"
 | 
			
		||||
#define DEBUGFS_MDIO            "mdio"
 | 
			
		||||
@@ -88,7 +88,7 @@
 | 
			
		||||
#define LED_BLK_EVT_1000M_RX        BIT(1)
 | 
			
		||||
#define LED_BLK_EVT_1000M_TX        BIT(0)
 | 
			
		||||
 | 
			
		||||
#define UNIT_LED_BLINK_DURATION     1024
 | 
			
		||||
#define UNIT_LED_BLINK_DURATION     780
 | 
			
		||||
 | 
			
		||||
/* Serdes auto negotation restart */
 | 
			
		||||
#define AN8801SB_SGMII_AN0_ANRESTART    (0x0200)
 | 
			
		||||
@@ -135,6 +135,9 @@ For reference only
 | 
			
		||||
#define LED_BLINK_DURATION(f)       (UNIT_LED_BLINK_DURATION << (f))
 | 
			
		||||
#define LED_GPIO_SEL(led, gpio)     ((led) << ((gpio) * 3))
 | 
			
		||||
 | 
			
		||||
/* Interrupt GPIO number, should not conflict with LED */
 | 
			
		||||
#define AIR_INTERRUPT_GPIO	3
 | 
			
		||||
 | 
			
		||||
/* DATA TYPE DECLARATIONS
 | 
			
		||||
 */
 | 
			
		||||
enum AIR_LED_GPIO_PIN_T {
 | 
			
		||||
 
 | 
			
		||||
@@ -587,7 +587,7 @@ static int en8801s_phase1_init(struct phy_device *phydev)
 | 
			
		||||
 | 
			
		||||
	phydev->dev_flags = PHY_STATE_INIT;
 | 
			
		||||
 | 
			
		||||
	dev_info(dev, "Phase1 initialize OK ! (%s)\n", EN8801S_DRIVER_VERSION);
 | 
			
		||||
	dev_info(dev, "Phase1 initialize OK ! (%s) 10Te TP_IDL fixed.\n", EN8801S_DRIVER_VERSION);
 | 
			
		||||
	if (priv->pro_version == 4) {
 | 
			
		||||
		ret = en8801s_phase2_init(phydev);
 | 
			
		||||
		if (ret != 0) {
 | 
			
		||||
@@ -811,14 +811,7 @@ static int en8801s_phase2_init(struct phy_device *phydev)
 | 
			
		||||
		retry--;
 | 
			
		||||
	}
 | 
			
		||||
	pbus_data = airoha_pbus_read(mbus, pbus_addr, 0x1C38); /* RAW#2 */
 | 
			
		||||
	ret = airoha_cl45_read(mbus, phy_addr, 0x1E, 0x12, &cl45_value);
 | 
			
		||||
	if (ret < 0)
 | 
			
		||||
		return ret;
 | 
			
		||||
	GPHY_RG_1E_012.DATA = cl45_value;
 | 
			
		||||
	GPHY_RG_1E_012.DataBitField.da_tx_i2mpb_a_tbt =
 | 
			
		||||
				(u16)(pbus_data & 0x03f);
 | 
			
		||||
	ret = airoha_cl45_write(mbus, phy_addr, 0x1E, 0x12,
 | 
			
		||||
				GPHY_RG_1E_012.DATA);
 | 
			
		||||
	ret = airoha_cl45_write(mbus, phy_addr, 0x1E, 0x12, 0xA018);
 | 
			
		||||
	if (ret < 0)
 | 
			
		||||
		return ret;
 | 
			
		||||
	ret = airoha_cl45_read(mbus, phy_addr, 0x1E, 0x17, &cl45_value);
 | 
			
		||||
@@ -893,6 +886,17 @@ static int en8801s_phase2_init(struct phy_device *phydev)
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	//Fix 10Te TP_IDL
 | 
			
		||||
	ret = airoha_cl45_read(mbus, phy_addr, 0x1E,
 | 
			
		||||
				0x1A3, &cl45_value);
 | 
			
		||||
	if (ret < 0)
 | 
			
		||||
		return ret;
 | 
			
		||||
	cl45_value &= ~0xf0;
 | 
			
		||||
	ret = airoha_cl45_write(mbus, phy_addr, 0x1E,
 | 
			
		||||
				0x1A3, cl45_value);
 | 
			
		||||
	if (ret < 0)
 | 
			
		||||
		return ret;
 | 
			
		||||
 | 
			
		||||
	priv->first_init = false;
 | 
			
		||||
	dev_info(phydev_dev(phydev), "Phase2 initialize OK !\n");
 | 
			
		||||
	return 0;
 | 
			
		||||
 
 | 
			
		||||
@@ -307,3 +307,28 @@ define Device/senao_jeap6500
 | 
			
		||||
endef
 | 
			
		||||
TARGET_DEVICES += senao_jeap6500
 | 
			
		||||
DEFAULT_DEVICE_VARS += FIT_KEY_DIR FIT_KEY_NAME
 | 
			
		||||
 | 
			
		||||
define Device/emplus_wap588m
 | 
			
		||||
   DEVICE_VENDOR := EMPLUS
 | 
			
		||||
   DEVICE_MODEL := WAP588M
 | 
			
		||||
   DEVICE_DTS := mt7981-emplus-wap588m
 | 
			
		||||
   DEVICE_DTS_DIR := $(DTS_DIR)/mediatek
 | 
			
		||||
   SUPPORTED_DEVICES := emplus,wap588m
 | 
			
		||||
   DEVICE_PACKAGES := kmod-mt7981-firmware kmod-mt7915e uboot-envtools -procd-ujail
 | 
			
		||||
   UBINIZE_OPTS := -E 5
 | 
			
		||||
   BLOCKSIZE := 128k
 | 
			
		||||
   PAGESIZE := 2048
 | 
			
		||||
   IMAGE_SIZE := 65536k
 | 
			
		||||
   KERNEL_IN_UBI := 1
 | 
			
		||||
   FIT_KEY_DIR := $(DTS_DIR)/mediatek/keys/emplus_wap588m
 | 
			
		||||
   FIT_KEY_NAME := fit_key
 | 
			
		||||
   IMAGES += factory.bin
 | 
			
		||||
   IMAGE/factory.bin := append-ubi | check-size $$$$(IMAGE_SIZE)
 | 
			
		||||
   IMAGE/sysupgrade.bin := sysupgrade-tar | append-metadata
 | 
			
		||||
   KERNEL = kernel-bin | lzma | \
 | 
			
		||||
     fit-sign lzma $$(KDIR)/image-$$(firstword $$(DEVICE_DTS)).dtb
 | 
			
		||||
   KERNEL_INITRAMFS = kernel-bin | lzma | \
 | 
			
		||||
     fit-sign lzma $$(KDIR)/image-$$(firstword $$(DEVICE_DTS)).dtb with-initrd
 | 
			
		||||
 endef
 | 
			
		||||
 TARGET_DEVICES += emplus_wap588m
 | 
			
		||||
 DEFAULT_DEVICE_VARS += FIT_KEY_DIR FIT_KEY_NAME
 | 
			
		||||
 
 | 
			
		||||
@@ -32,6 +32,9 @@ mediatek_setup_interfaces()
 | 
			
		||||
	sonicfi,rap630w-211g)
 | 
			
		||||
		ucidef_set_interfaces_lan_wan "lan1 lan2 lan3" eth1
 | 
			
		||||
		;;
 | 
			
		||||
    emplus,wap588m)
 | 
			
		||||
        ucidef_set_interfaces_lan_wan "eth0" "eth1"
 | 
			
		||||
        ;;
 | 
			
		||||
	*)	
 | 
			
		||||
		ucidef_set_interfaces_lan_wan "eth1" "eth0"
 | 
			
		||||
		;;
 | 
			
		||||
 
 | 
			
		||||
@@ -8,6 +8,9 @@ boot() {
 | 
			
		||||
	edgecore,eap112)
 | 
			
		||||
		bootcount=$(fw_printenv -n bootcount)
 | 
			
		||||
		[ "$bootcount" != 0 ] && fw_setenv bootcount 0
 | 
			
		||||
		# enable dualboot
 | 
			
		||||
		avail=$(fw_printenv -n upgrade_available)
 | 
			
		||||
		[ ${avail} -eq 0 ] && fw_setenv upgrade_available 1
 | 
			
		||||
		;;
 | 
			
		||||
	esac
 | 
			
		||||
}
 | 
			
		||||
@@ -18,6 +18,7 @@ case "$board" in
 | 
			
		||||
edgecore,eap111|\
 | 
			
		||||
edgecore,eap112|\
 | 
			
		||||
senao,iap2300m|\
 | 
			
		||||
emplus,wap588m|\
 | 
			
		||||
senao,jeap6500)
 | 
			
		||||
	ubootenv_add_uci_config "/dev/mtd2" "0x0" "0x20000" "0x20000"
 | 
			
		||||
	;;
 | 
			
		||||
 
 | 
			
		||||
@@ -1,5 +1,17 @@
 | 
			
		||||
REQUIRE_IMAGE_METADATA=1
 | 
			
		||||
 | 
			
		||||
swap_wap588m_active_fw() {
 | 
			
		||||
	echo "Doing swap active_fw" > /dev/console
 | 
			
		||||
        tmp_active_fw=$(fw_printenv | grep active_fw | awk -F= {'print $2'})
 | 
			
		||||
	if [ $tmp_active_fw == "0" ]; then
 | 
			
		||||
		fw_setenv active_fw 1
 | 
			
		||||
                fw_setenv mtdparts nmbm0:1024k\(bl2\),512k\(u-boot-env\),2048k\(factory\),2048k\(fip\),56320k\(ubi_1\),56320k\(ubi\),384k\(cert\),640k\(userconfig\),384k\(crashdump\)
 | 
			
		||||
	else
 | 
			
		||||
		fw_setenv active_fw 0
 | 
			
		||||
                fw_setenv mtdparts nmbm0:1024k\(bl2\),512k\(u-boot-env\),2048k\(factory\),2048k\(fip\),56320k\(ubi\),56320k\(ubi_1\),384k\(cert\),640k\(userconfig\),384k\(crashdump\)
 | 
			
		||||
	fi
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
senao_swap_active_fw() {
 | 
			
		||||
	echo "Doing swap active_fw" > /dev/console
 | 
			
		||||
	tmp_active_fw=$(fw_printenv -n active_fw)
 | 
			
		||||
@@ -47,6 +59,7 @@ platform_do_upgrade() {
 | 
			
		||||
		nand_do_upgrade "$1"
 | 
			
		||||
		;;
 | 
			
		||||
	senao,iap2300m|\
 | 
			
		||||
	emplus,wap588m|\
 | 
			
		||||
	senao,jeap6500)
 | 
			
		||||
		CI_UBIPART="ubi_1"
 | 
			
		||||
		nand_do_upgrade "$1"
 | 
			
		||||
@@ -68,6 +81,7 @@ platform_check_image() {
 | 
			
		||||
	edgecore,eap111|\
 | 
			
		||||
	edgecore,eap112|\
 | 
			
		||||
	senao,iap2300m|\
 | 
			
		||||
	emplus,wap588m|\
 | 
			
		||||
	senao,jeap6500)
 | 
			
		||||
		nand_do_platform_check "$board" "$1"
 | 
			
		||||
		return $?
 | 
			
		||||
@@ -92,5 +106,8 @@ platform_post_upgrade_success() {
 | 
			
		||||
		senao,jeap6500)
 | 
			
		||||
			senao_swap_active_fw
 | 
			
		||||
		;;
 | 
			
		||||
		emplus,wap588m)
 | 
			
		||||
			swap_wap588m_active_fw
 | 
			
		||||
		;;
 | 
			
		||||
	esac
 | 
			
		||||
}
 | 
			
		||||
 
 | 
			
		||||
@@ -2,7 +2,6 @@ CONFIG_64BIT=y
 | 
			
		||||
CONFIG_AHCI_MTK=y
 | 
			
		||||
CONFIG_AIROHA_EN8801SC_PHY=y
 | 
			
		||||
# CONFIG_AIROHA_EN8811H_PHY is not set
 | 
			
		||||
# CONFIG_AIROHA_AN8801_PHY is not set
 | 
			
		||||
CONFIG_AN8855_GSW=y
 | 
			
		||||
CONFIG_ARCH_CLOCKSOURCE_DATA=y
 | 
			
		||||
CONFIG_ARCH_DMA_ADDR_T_64BIT=y
 | 
			
		||||
 
 | 
			
		||||
@@ -1,15 +1,3 @@
 | 
			
		||||
From 535fdc6dfce7def996a5188819ffc96231c36f98 Mon Sep 17 00:00:00 2001
 | 
			
		||||
From: Bo-Cun Chen <bc-bocun.chen@mediatek.com>
 | 
			
		||||
Date: Tue, 2 Jan 2024 18:13:43 +0800
 | 
			
		||||
Subject: [PATCH] [networking][999-2738-an8801sb-gphy-support.patch]
 | 
			
		||||
 | 
			
		||||
---
 | 
			
		||||
 drivers/net/phy/Kconfig  |   5 +
 | 
			
		||||
 drivers/net/phy/Makefile |   1 +
 | 
			
		||||
 2 files changed, 6 insertions(+)
 | 
			
		||||
 | 
			
		||||
diff --git a/drivers/net/phy/Kconfig b/drivers/net/phy/Kconfig
 | 
			
		||||
index ccd3f3f..5dbfb17 100644
 | 
			
		||||
--- a/drivers/net/phy/Kconfig
 | 
			
		||||
+++ b/drivers/net/phy/Kconfig
 | 
			
		||||
@@ -345,6 +345,11 @@ config SFP
 | 
			
		||||
@@ -24,8 +12,6 @@ index ccd3f3f..5dbfb17 100644
 | 
			
		||||
 config AIROHA_EN8801SC_PHY
 | 
			
		||||
 	tristate "Drivers for Airoha EN8801S Gigabit PHYs for MediaTek SoC."
 | 
			
		||||
 	---help---
 | 
			
		||||
diff --git a/drivers/net/phy/Makefile b/drivers/net/phy/Makefile
 | 
			
		||||
index 1e8d67b..d39e54b 100644
 | 
			
		||||
--- a/drivers/net/phy/Makefile
 | 
			
		||||
+++ b/drivers/net/phy/Makefile
 | 
			
		||||
@@ -74,6 +74,7 @@ endif
 | 
			
		||||
@@ -36,6 +22,64 @@ index 1e8d67b..d39e54b 100644
 | 
			
		||||
 obj-$(CONFIG_AIROHA_EN8801SC_PHY)	+= en8801sc.o
 | 
			
		||||
 air_en8811h-y := air_en8811h_main.o air_en8811h_api.o
 | 
			
		||||
 obj-$(CONFIG_AIROHA_EN8811H_PHY)	+= air_en8811h.o
 | 
			
		||||
-- 
 | 
			
		||||
2.18.0
 | 
			
		||||
--- a/drivers/net/phy/phylink.c
 | 
			
		||||
+++ b/drivers/net/phy/phylink.c
 | 
			
		||||
@@ -870,12 +870,17 @@
 | 
			
		||||
 	of_node_put(phy_node);
 | 
			
		||||
 
 | 
			
		||||
 	if (!phy_dev)
 | 
			
		||||
-		return -ENODEV;
 | 
			
		||||
-
 | 
			
		||||
+	{
 | 
			
		||||
+		phylink_info(pl, "[phylink] reload phy-handle2. %s %d\n",__func__, __LINE__);
 | 
			
		||||
+		phy_node = of_parse_phandle(dn, "phy-handle2", 0);
 | 
			
		||||
+		phy_dev = of_phy_attach(pl->netdev, phy_node, flags, pl->link_interface);
 | 
			
		||||
+		if (!phy_dev)
 | 
			
		||||
+			return -ENODEV;
 | 
			
		||||
+	}
 | 
			
		||||
+	
 | 
			
		||||
 	ret = phylink_bringup_phy(pl, phy_dev, pl->link_config.interface);
 | 
			
		||||
 	if (ret)
 | 
			
		||||
 		phy_detach(phy_dev);
 | 
			
		||||
-
 | 
			
		||||
 	return ret;
 | 
			
		||||
 }
 | 
			
		||||
 EXPORT_SYMBOL_GPL(phylink_of_phy_connect);
 | 
			
		||||
--- a/drivers/of/of_mdio.c
 | 
			
		||||
+++ b/drivers/of/of_mdio.c
 | 
			
		||||
@@ -226,7 +226,9 @@
 | 
			
		||||
 		return rc;
 | 
			
		||||
 
 | 
			
		||||
 	/* Loop over the child nodes and register a phy_device for each phy */
 | 
			
		||||
+	int an8801=0;
 | 
			
		||||
 	for_each_available_child_of_node(np, child) {
 | 
			
		||||
+		if(an8801==1)break;
 | 
			
		||||
 		addr = of_mdio_parse_addr(&mdio->dev, child);
 | 
			
		||||
 		if (addr < 0) {
 | 
			
		||||
 			scanphys = true;
 | 
			
		||||
@@ -234,7 +236,25 @@
 | 
			
		||||
 		}
 | 
			
		||||
 
 | 
			
		||||
 		if (of_mdiobus_child_is_phy(child))
 | 
			
		||||
+		{
 | 
			
		||||
+			if(addr==30)
 | 
			
		||||
+			{
 | 
			
		||||
+				int phy_id ;
 | 
			
		||||
+
 | 
			
		||||
+				phy_id = mdiobus_read(mdio, addr, MII_PHYSID1) << 16 ;
 | 
			
		||||
+				phy_id = phy_id + mdiobus_read(mdio, addr, MII_PHYSID2);
 | 
			
		||||
+				dev_info(&mdio->dev, "[of_mdio] %s %d  addr:%d phy_id:0x%x  \n",__func__, __LINE__, addr, phy_id);
 | 
			
		||||
+
 | 
			
		||||
+				if (phy_id==0 || phy_id==0x1a750000)
 | 
			
		||||
+				{
 | 
			
		||||
+					dev_info(&mdio->dev, "[of_mdio] %s %d  continue  \n",__func__, __LINE__);
 | 
			
		||||
+					continue;
 | 
			
		||||
+				}
 | 
			
		||||
+				else
 | 
			
		||||
+					an8801=1;
 | 
			
		||||
+			}
 | 
			
		||||
 			rc = of_mdiobus_register_phy(mdio, child, addr);
 | 
			
		||||
+		}
 | 
			
		||||
 		else
 | 
			
		||||
 			rc = of_mdiobus_register_device(mdio, child, addr);
 | 
			
		||||
 
 | 
			
		||||
 
 | 
			
		||||
@@ -493,10 +493,22 @@ define Build/Compile
 | 
			
		||||
	$(MAKE) -C $(PKG_BUILD_DIR)/tools
 | 
			
		||||
endef
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
define Build/Install
 | 
			
		||||
	:
 | 
			
		||||
endef
 | 
			
		||||
 | 
			
		||||
ifdef CONFIG_TARGET_PROFILE
 | 
			
		||||
TARGET_PROFILE=$(subst ",,$(CONFIG_TARGET_PROFILE))
 | 
			
		||||
PATCH_PROFILE_NAME=patches-$(subst DEVICE_,,$(TARGET_PROFILE))
 | 
			
		||||
endif
 | 
			
		||||
 | 
			
		||||
define Build/Patch
 | 
			
		||||
	$(Build/Patch/Default)
 | 
			
		||||
	$(call PatchDir,$(PKG_BUILD_DIR),$(PATCH_PROFILE_NAME)/,profile/)
 | 
			
		||||
endef
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
define Package/kmod-mt76/install
 | 
			
		||||
	true
 | 
			
		||||
endef
 | 
			
		||||
 
 | 
			
		||||
@@ -0,0 +1,26 @@
 | 
			
		||||
Index: mt76-2024-04-03-1e336a85/mt7915/mt7915.h
 | 
			
		||||
===================================================================
 | 
			
		||||
--- mt76-2024-04-03-1e336a85.orig/mt7915/mt7915.h
 | 
			
		||||
+++ mt76-2024-04-03-1e336a85/mt7915/mt7915.h
 | 
			
		||||
@@ -71,8 +71,8 @@
 | 
			
		||||
 #define MT7915_CFEND_RATE_DEFAULT	0x49	/* OFDM 24M */
 | 
			
		||||
 #define MT7915_CFEND_RATE_11B		0x03	/* 11B LP, 11M */
 | 
			
		||||
 
 | 
			
		||||
-#define MT7915_THERMAL_THROTTLE_MAX	100
 | 
			
		||||
-#define MT7915_CDEV_THROTTLE_MAX	99
 | 
			
		||||
+#define MT7915_THERMAL_THROTTLE_MAX	80
 | 
			
		||||
+#define MT7915_CDEV_THROTTLE_MAX	79
 | 
			
		||||
 
 | 
			
		||||
 #define MT7915_SKU_RATE_NUM		161
 | 
			
		||||
 #define MT7915_SKU_PATH_NUM		185
 | 
			
		||||
@@ -86,8 +86,8 @@
 | 
			
		||||
 
 | 
			
		||||
 #define MT7915_CRIT_TEMP_IDX		0
 | 
			
		||||
 #define MT7915_MAX_TEMP_IDX		1
 | 
			
		||||
-#define MT7915_CRIT_TEMP		110
 | 
			
		||||
-#define MT7915_MAX_TEMP			120
 | 
			
		||||
+#define MT7915_CRIT_TEMP		103
 | 
			
		||||
+#define MT7915_MAX_TEMP			118
 | 
			
		||||
 
 | 
			
		||||
 struct mt7915_vif;
 | 
			
		||||
 struct mt7915_sta;
 | 
			
		||||
							
								
								
									
										125
									
								
								feeds/morse/kernel/mm-board-config/LICENSE.binaries
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										125
									
								
								feeds/morse/kernel/mm-board-config/LICENSE.binaries
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,125 @@
 | 
			
		||||
                                  MORSE MICRO
 | 
			
		||||
                     BINARY DISTRIBUTION LICENSE AGREEMENT
 | 
			
		||||
 | 
			
		||||
1. Parties.
 | 
			
		||||
This Software License Agreement (SLA) is between Morse Micro Pty. Ltd. and the
 | 
			
		||||
user of the Software set forth (“you”, “user”, “customer”), and is effective as
 | 
			
		||||
of the date of first access or download of the software by you. Morse Micro is
 | 
			
		||||
licensing this software to you free of charge upon the condition that you
 | 
			
		||||
accept all the terms of this SLA and only use this Software in conjunction with
 | 
			
		||||
Morse Micro products. ANY USE, REPRODUCTION, OR DISTRIBUTION OF THE SOFTWARE
 | 
			
		||||
CONSTITUTES YOUR ACCEPTANCE OF THIS AGREEMENT.
 | 
			
		||||
 | 
			
		||||
2. Definitions.
 | 
			
		||||
"Software" means any binary or source code that you have received from Morse
 | 
			
		||||
Micro or its authorized licensees and/or those portions of such software
 | 
			
		||||
produced by Program’s code within the Software, as well as any other machine
 | 
			
		||||
readable materials (including, but not limited to, libraries, source files,
 | 
			
		||||
header files, and data files), any updates or error corrections provided by
 | 
			
		||||
Morse Micro, and any user manuals, programming guides and other documentation
 | 
			
		||||
provided to you by Morse Micro under this SLA.
 | 
			
		||||
 | 
			
		||||
3. License and Restrictions.
 | 
			
		||||
Morse Micro grants you a non-exclusive, non-transferable, limited license
 | 
			
		||||
without license fees to:
 | 
			
		||||
 | 
			
		||||
    a. use the software solely with a hardware product that includes one of the
 | 
			
		||||
    Morse Micro Wi-Fi HaLow chips, including
 | 
			
		||||
    wireless modules or evaluation kits;
 | 
			
		||||
 | 
			
		||||
    b. to reproduce and distribute the Software complete, unmodified, and as
 | 
			
		||||
    provided by Morse Micro, solely for use with a hardware product that
 | 
			
		||||
    includes one of the Morse Micro Wi-Fi HaLow chips, including wireless
 | 
			
		||||
    modules or evaluation kits.
 | 
			
		||||
 | 
			
		||||
4. Reservation of Rights.
 | 
			
		||||
You should distribute Software with a copy of this SLA. Software is
 | 
			
		||||
copyrighted. Title to Software and all associated intellectual property rights
 | 
			
		||||
is retained by Morse Micro. Except as expressly provided herein, no license or
 | 
			
		||||
right, express or implied, is hereby conveyed or granted to you by Morse Micro.
 | 
			
		||||
You must retain all copyright notices on all Software, derivative works and
 | 
			
		||||
documentation. The intellectual property and proprietary rights of whatever
 | 
			
		||||
nature in the Software and derivative works are and will remain the exclusive
 | 
			
		||||
property of Morse Micro or its suppliers. Nothing in this Agreement should be
 | 
			
		||||
construed as transferring any aspects of such rights to you or any third party.
 | 
			
		||||
Morse Micro and its suppliers reserve any and all rights not expressly granted
 | 
			
		||||
in this Agreement. You may not sell, assign, sublicense, lease, or otherwise
 | 
			
		||||
transfer any part of this license. You must not:
 | 
			
		||||
 | 
			
		||||
    a. use, license, sell or otherwise distribute the Software except as
 | 
			
		||||
    provided in this SLA;
 | 
			
		||||
 | 
			
		||||
    b. attempt to modify in any way, reverse engineer, decompile or disassemble
 | 
			
		||||
    any portion of the Software;
 | 
			
		||||
 | 
			
		||||
    c. use the Software or other material in violation of any applicable law or
 | 
			
		||||
    regulation, including but not limited to any regulatory agency.
 | 
			
		||||
 | 
			
		||||
5. Ownership.
 | 
			
		||||
The Software is licensed and not sold.  Title to and ownership of the Software,
 | 
			
		||||
including all intellectual property rights thereto, and any portion thereof
 | 
			
		||||
remain with Morse Micro or its licensors. You hereby covenant that you will not
 | 
			
		||||
assert any claim that the Software created by or for Morse Micro infringe any
 | 
			
		||||
intellectual property right owned or controlled by you.
 | 
			
		||||
 | 
			
		||||
6. Termination.
 | 
			
		||||
This SLA will terminate immediately without notice from Morse Micro if you fail
 | 
			
		||||
to comply with any of its provisions, including the export laws provisions and
 | 
			
		||||
Section 10 that may govern the export of the Software from certain
 | 
			
		||||
jurisdictions, including technical data.
 | 
			
		||||
 | 
			
		||||
7. Disclaimer and Limitation of Liability.
 | 
			
		||||
THE SOFTWARE IS PROVIDED "AS IS" WITHOUT WARRANTY OF ANY KIND. MORSE MICRO
 | 
			
		||||
FURTHER DISCLAIMS ALL WARRANTIES, EXPRESS AND IMPLIED, INCLUDING WITHOUT
 | 
			
		||||
LIMITATION, ANY IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
 | 
			
		||||
PURPOSE OR NON-INFRINGEMENT. IN NO EVENT SHALL MORSE MICRO BE LIABLE FOR ANY
 | 
			
		||||
INDIRECT, INCIDENTAL, SPECIAL, PUNITIVE OR CONSEQUENTIAL DAMAGES, OR DAMAGES
 | 
			
		||||
FOR LOSS OF PROFITS, REVENUE, DATA OR DATA USE, INCURRED BY YOU OR ANY THIRD
 | 
			
		||||
PARTY, WHETHER IN AN ACTION IN CONTRACT OR TORT, EVEN IF MORSE MICRO HAS BEEN
 | 
			
		||||
ADVISED OF THE POSSIBILITY OF SUCH DAMAGES. THE SOFTWARE IS NOT INTENDED FOR
 | 
			
		||||
USE IN ENVIRONMENTS OR APPLICATIONS WHERE EXTRAORDINARILY HIGH LEVELS OF
 | 
			
		||||
QUALITY, RELIABILITY, AND FAILURE TOLERANCE ARE DEMANDED, AND/OR WHERE A
 | 
			
		||||
MALFUNCTION OR FAILURE COULD LEAD TO SIGNIFICANT HARM TO LIFE, HEALTH,
 | 
			
		||||
PROPERTY, OR RESULT IN SEVERE SOCIETAL REPERCUSSIONS ("CRITICAL APPLICATIONS").
 | 
			
		||||
CRITICAL APPLICATIONS ENCOMPASS, BUT ARE NOT LIMITED TO, EQUIPMENT UTILIZED IN
 | 
			
		||||
NUCLEAR FACILITIES, AVIATION AND SPACE EQUIPMENT, MEDICAL DEVICES, AUTOMOTIVE,
 | 
			
		||||
TRAIN, MARINE, AND OTHER TRANSPORTATION EQUIPMENT, DEVICES INVOLVED IN
 | 
			
		||||
CONTROLLING COMBUSTION OR EXPLOSIONS, SAFETY DEVICES, ELEVATORS AND ESCALATORS,
 | 
			
		||||
DEVICES ASSOCIATED WITH ELECTRIC POWER, AND EQUIPMENT USED IN FINANCE-RELATED
 | 
			
		||||
FIELDS.
 | 
			
		||||
 | 
			
		||||
8. Survival.
 | 
			
		||||
Sections 4, 5, 6, 7 and 10 will survive termination or expiration of this SLA.
 | 
			
		||||
 | 
			
		||||
9. Privacy.
 | 
			
		||||
Some features of the Software, if activated, may transmit a limited amount of
 | 
			
		||||
data to Morse Micro (or its service provider) about the status of the system
 | 
			
		||||
before a crash event. Morse Micro does not associate the data with personally
 | 
			
		||||
identifiable information.
 | 
			
		||||
 | 
			
		||||
10. Export Laws.
 | 
			
		||||
YOU UNDERSTAND AND AGREE THAT THE SOFTWARE IS SUBJECT TO ALL APPLICABLE EXPORT-
 | 
			
		||||
RELATED LAWS AND REGULATIONS AND THAT YOU MAY NOT EXPORT, RE-EXPORT OR TRANSFER
 | 
			
		||||
THE SOFTWARE OR ANY DIRECT PRODUCT OF THE SOFTWARE EXCEPT AS PERMITTED UNDER
 | 
			
		||||
THOSE LAWS. WITHOUT LIMITING THE FOREGOING, EXPORT, RE-EXPORT, OR TRANSFER OF
 | 
			
		||||
THE SOFTWARE TO CUBA, IRAN, NORTH KOREA, SUDAN, AND SYRIA IS PROHIBITED.
 | 
			
		||||
 | 
			
		||||
11. Governing Law.
 | 
			
		||||
The laws of New South Wales, Australia, govern all matters arising out of or
 | 
			
		||||
relating to this SLA without giving effect to any conflict of law principles.
 | 
			
		||||
If any provision of this SLA is held to be unenforceable, this SLA will remain
 | 
			
		||||
in effect with the provision omitted, unless omission would frustrate the
 | 
			
		||||
intent of the parties, in which case this Agreement will immediately terminate.
 | 
			
		||||
 | 
			
		||||
12. Entire Agreement.
 | 
			
		||||
This Agreement constitutes the entire agreement between the parties and
 | 
			
		||||
supersedes all prior and contemporaneous agreements, proposals or
 | 
			
		||||
representations, written or oral, concerning its subject matter. No
 | 
			
		||||
modification, amendment, or waiver of any provision of this Agreement will be
 | 
			
		||||
effective unless in writing and either signed or accepted electronically by the
 | 
			
		||||
party against whom the modification, amendment or waiver is to be asserted. A
 | 
			
		||||
waiver of any breach under this Agreement does not constitute a waiver of any
 | 
			
		||||
other breach or future breach.
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
MORSE MICRO
 | 
			
		||||
							
								
								
									
										86
									
								
								feeds/morse/kernel/mm-board-config/Makefile
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										86
									
								
								feeds/morse/kernel/mm-board-config/Makefile
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,86 @@
 | 
			
		||||
#
 | 
			
		||||
# Copyright 2022 Morse Micro
 | 
			
		||||
#
 | 
			
		||||
# This is free software, licensed under the MIT License.
 | 
			
		||||
#
 | 
			
		||||
# This package installs Morse Micro board configuration binaries, which are
 | 
			
		||||
# distributed under the Morse Micro Binary Distribution License.
 | 
			
		||||
# This license is available in LICENSE.binaries.
 | 
			
		||||
#
 | 
			
		||||
 | 
			
		||||
include $(TOPDIR)/rules.mk
 | 
			
		||||
 | 
			
		||||
PKG_NAME:=morse-board-config
 | 
			
		||||
PKG_RELEASE=6
 | 
			
		||||
 | 
			
		||||
PKG_VERSION:=rel_1_12_4_2024_Jun_11
 | 
			
		||||
 | 
			
		||||
PKG_SOURCE:=morsemicro-bcf-rel_1_12_4_2024_Jun_11.tar
 | 
			
		||||
PKG_SOURCE_URL:=https://github.com/MorseMicro/bcf_binaries/releases/download/v1.12.4/
 | 
			
		||||
PKG_HASH:=e403764730aa149e78874135da154bab2a24574308d3f2df88c9b4c125766ae3
 | 
			
		||||
 | 
			
		||||
PKG_MAINTAINER:=Morse Micro <info@morsemicro.com>
 | 
			
		||||
PKG_BUILD_PARALLEL:=1
 | 
			
		||||
 | 
			
		||||
RSTRIP:=:
 | 
			
		||||
 | 
			
		||||
include $(INCLUDE_DIR)/kernel.mk
 | 
			
		||||
include $(INCLUDE_DIR)/package.mk
 | 
			
		||||
 | 
			
		||||
define Package/morse-board-config
 | 
			
		||||
  SECTION:=firmware
 | 
			
		||||
  CATEGORY:=Firmware
 | 
			
		||||
  URL:=$(PKG_SOURCE_URL)
 | 
			
		||||
  TITLE:=Morse Micro WIFI HaLow Board Config File
 | 
			
		||||
  PROVIDES:=morse-board-config
 | 
			
		||||
endef
 | 
			
		||||
 | 
			
		||||
define Package/morse-board-config-hotplug-model
 | 
			
		||||
  SECTION:=firmware
 | 
			
		||||
  CATEGORY:=Firmware
 | 
			
		||||
  TITLE:=Hotplug scripts for module type reporting
 | 
			
		||||
  DEPENDS:=+morse-board-config
 | 
			
		||||
endef
 | 
			
		||||
 | 
			
		||||
define Package/morse-board-config-hotplug-model/description
 | 
			
		||||
  When enabled, a hotplug script will be installed to
 | 
			
		||||
  append a relevant module type suffix based on the value
 | 
			
		||||
  programmed into the Morse chips OTP bits.
 | 
			
		||||
endef
 | 
			
		||||
 | 
			
		||||
TAR_CMD=$(HOST_TAR) -C $(1) $(TAR_OPTIONS)
 | 
			
		||||
 | 
			
		||||
define Build/Compile
 | 
			
		||||
 | 
			
		||||
endef
 | 
			
		||||
 | 
			
		||||
define Package/morse-board-config/install
 | 
			
		||||
	$(INSTALL_DIR) $(1)/usr/share/morse-bcf
 | 
			
		||||
	$(INSTALL_DIR) $(1)/lib/firmware/morse
 | 
			
		||||
 | 
			
		||||
	$(INSTALL_DATA) $(PKG_BUILD_DIR)/lib/firmware/morse/* $(1)/lib/firmware/morse/
 | 
			
		||||
 | 
			
		||||
	# Install all files from override folder, including failsafe.
 | 
			
		||||
	$(INSTALL_DATA) ./files/lib/firmware/morse/* $(1)/lib/firmware/morse/
 | 
			
		||||
 | 
			
		||||
ifeq ($(CONFIG_TARGET_PROFILE), "DEVICE_edgecore_eap112")
 | 
			
		||||
	ln -s /lib/firmware/morse/bcf_edgecore_eap112_fcc.bin $(1)/lib/firmware/morse/bcf_default.bin
 | 
			
		||||
else
 | 
			
		||||
	# Link the failsafe bcf by default so userspace can query the driver.
 | 
			
		||||
	ln -s /lib/firmware/morse/bcf_failsafe.bin $(1)/lib/firmware/morse/bcf_default.bin
 | 
			
		||||
endif
 | 
			
		||||
	# Create symlinks for the production programmed otp devices
 | 
			
		||||
	while IFS=, read -r board_type suffix serial; do \
 | 
			
		||||
		ln -s /lib/firmware/morse/bcf_$$$${serial}.bin $(1)/lib/firmware/morse/bcf_boardtype_$$$${board_type}.bin; \
 | 
			
		||||
	done < ./files/usr/share/morse-bcf/db.txt
 | 
			
		||||
 | 
			
		||||
	$(INSTALL_DATA) ./files/usr/share/morse-bcf/db.txt $(1)/usr/share/morse-bcf/db.txt
 | 
			
		||||
endef
 | 
			
		||||
 | 
			
		||||
define Package/morse-board-config-hotplug-model/install
 | 
			
		||||
	$(INSTALL_DIR) $(1)/etc/hotplug.d/ieee80211
 | 
			
		||||
	$(INSTALL_DATA) ./files/etc/hotplug.d/ieee80211/20-module-type $(1)/etc/hotplug.d/ieee80211/20-module-type
 | 
			
		||||
endef
 | 
			
		||||
 | 
			
		||||
$(eval $(call BuildPackage,morse-board-config))
 | 
			
		||||
$(eval $(call BuildPackage,morse-board-config-hotplug-model))
 | 
			
		||||
@@ -0,0 +1,19 @@
 | 
			
		||||
#!/bin/sh
 | 
			
		||||
 | 
			
		||||
[ "${ACTION}" = "add" ] && {
 | 
			
		||||
	basename "$(readlink -f "/sys/${DEVPATH}/device/driver")" | grep '^morse_' || return;
 | 
			
		||||
 | 
			
		||||
	board_type=$(printf "%04x" "$(cat /sys/${DEVPATH}/device/board_type)");
 | 
			
		||||
 | 
			
		||||
	# Avoid mutating model information when OTP is not burnt, ie 0000.
 | 
			
		||||
	[ "$board_type" = "0000" ] && return;
 | 
			
		||||
 | 
			
		||||
	module_id=$(awk -F, '$1==b{print toupper($2)}' b="$board_type" /usr/share/morse-bcf/db.txt)
 | 
			
		||||
 | 
			
		||||
	model=$(cat /tmp/sysinfo/model)
 | 
			
		||||
 | 
			
		||||
	# Don't append a module id if that module id already exists in the model
 | 
			
		||||
	[ "${model%-"$module_id"}" != "${model}" ] && return;
 | 
			
		||||
 | 
			
		||||
	echo "$model-$module_id" > /tmp/sysinfo/model
 | 
			
		||||
}
 | 
			
		||||
										
											Binary file not shown.
										
									
								
							
										
											Binary file not shown.
										
									
								
							
							
								
								
									
										
											BIN
										
									
								
								feeds/morse/kernel/mm-board-config/files/lib/firmware/morse/bcf_mf08651_us.bin
									
									
									
									
									
										Executable file
									
								
							
							
						
						
									
										
											BIN
										
									
								
								feeds/morse/kernel/mm-board-config/files/lib/firmware/morse/bcf_mf08651_us.bin
									
									
									
									
									
										Executable file
									
								
							
										
											Binary file not shown.
										
									
								
							@@ -0,0 +1 @@
 | 
			
		||||
0801,05us,mf08651_us
 | 
			
		||||
							
								
								
									
										183
									
								
								feeds/morse/kernel/mm61xx/Makefile
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										183
									
								
								feeds/morse/kernel/mm61xx/Makefile
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,183 @@
 | 
			
		||||
#
 | 
			
		||||
# Copyright 2022 Morse Micro
 | 
			
		||||
#
 | 
			
		||||
# This is free software, licensed under the GPL 2 license.
 | 
			
		||||
#
 | 
			
		||||
 | 
			
		||||
include $(TOPDIR)/rules.mk
 | 
			
		||||
 | 
			
		||||
PKG_NAME:=morse_driver
 | 
			
		||||
PKG_RELEASE=3
 | 
			
		||||
 | 
			
		||||
PKG_VERSION:=1.11.4
 | 
			
		||||
 | 
			
		||||
PKG_LICENSE:=GPLv2
 | 
			
		||||
PKG_LICENSE_FILES:=LICENSE
 | 
			
		||||
 | 
			
		||||
PKG_SOURCE_VERSION:=$(PKG_VERSION)
 | 
			
		||||
PKG_SOURCE_URL:=https://github.com/MorseMicro/morse_driver.git
 | 
			
		||||
PKG_HASH:=159d018a92e0cf742795ed49bd94fb6ed324163012bb91c2a2e4e0f6037bbf23
 | 
			
		||||
PKG_SOURCE_PROTO:=git
 | 
			
		||||
PKG_SOURCE_VERSION:=b2ab42a5f22527422adf6afab73f2d019c16f162
 | 
			
		||||
 | 
			
		||||
PKG_MAINTAINER:=Morse Micro
 | 
			
		||||
PKG_BUILD_PARALLEL:=1
 | 
			
		||||
 | 
			
		||||
include $(INCLUDE_DIR)/kernel.mk
 | 
			
		||||
include $(INCLUDE_DIR)/package.mk
 | 
			
		||||
 | 
			
		||||
DTC=$(wildcard $(LINUX_DIR)/scripts/dtc/dtc)
 | 
			
		||||
 | 
			
		||||
define KernelPackage/morse
 | 
			
		||||
  SUBMENU:=Wireless Drivers
 | 
			
		||||
  TITLE:=Morse Micro WIFI HaLow driver
 | 
			
		||||
  DEPENDS:= +kmod-mmc +kmod-mac80211 +kmod-trelay +kmod-lib-crc7 +morse-fw +morse-board-config
 | 
			
		||||
  FILES:=\
 | 
			
		||||
    $(PKG_BUILD_DIR)/morse.ko \
 | 
			
		||||
    $(PKG_BUILD_DIR)/dot11ah/dot11ah.ko
 | 
			
		||||
  AUTOLOAD:=$(call AutoProbe,morse)
 | 
			
		||||
  MODPARAMS.morse:=country=US
 | 
			
		||||
  PROVIDES:=kmod-morse
 | 
			
		||||
endef
 | 
			
		||||
 | 
			
		||||
define KernelPackage/morse/config
 | 
			
		||||
 | 
			
		||||
       config MORSE_SDIO
 | 
			
		||||
            bool "SDIO support "
 | 
			
		||||
            default n
 | 
			
		||||
            depends on PACKAGE_kmod-morse
 | 
			
		||||
 | 
			
		||||
       config MORSE_SPI
 | 
			
		||||
            bool "SPI support "
 | 
			
		||||
            default y
 | 
			
		||||
            depends on PACKAGE_kmod-morse
 | 
			
		||||
 | 
			
		||||
       config MORSE_USER_ACCESS
 | 
			
		||||
            bool "User space access support "
 | 
			
		||||
            default y
 | 
			
		||||
            depends on PACKAGE_kmod-morse
 | 
			
		||||
 | 
			
		||||
       config MORSE_VENDOR_COMMAND
 | 
			
		||||
            bool "Vendor command support "
 | 
			
		||||
            default y
 | 
			
		||||
            depends on PACKAGE_kmod-morse
 | 
			
		||||
 | 
			
		||||
       config MORSE_MONITOR
 | 
			
		||||
            bool "Monitor mode support "
 | 
			
		||||
            default n
 | 
			
		||||
            depends on PACKAGE_kmod-morse
 | 
			
		||||
 | 
			
		||||
       config MORSE_DEBUG
 | 
			
		||||
            bool "Enable debug "
 | 
			
		||||
            default n
 | 
			
		||||
            depends on PACKAGE_kmod-morse
 | 
			
		||||
            help
 | 
			
		||||
              Compiles the driver with debug info and some additional debug features.
 | 
			
		||||
 | 
			
		||||
      config MORSE_DEBUG_LOGGING
 | 
			
		||||
            bool "Enable debug logging"
 | 
			
		||||
            default n
 | 
			
		||||
            depends on PACKAGE_kmod-morse
 | 
			
		||||
            select KERNEL_DYNAMIC_DEBUG_CORE
 | 
			
		||||
            help
 | 
			
		||||
              Enables debug level logging from the driver. Logging must be enabled at run time.
 | 
			
		||||
              There may be a binary size and performance impact when this is y.
 | 
			
		||||
 | 
			
		||||
       config MORSE_RC
 | 
			
		||||
            bool "Enable MMRC (Morse Micro Rate Control) "
 | 
			
		||||
            default y
 | 
			
		||||
            depends on PACKAGE_kmod-morse
 | 
			
		||||
 | 
			
		||||
       config MORSE_SDIO_ALIGNMENT
 | 
			
		||||
            int "Required alignment for bulk SDIO reads/writes"
 | 
			
		||||
            default 2
 | 
			
		||||
            range 2 8
 | 
			
		||||
            depends on MORSE_SDIO
 | 
			
		||||
            help
 | 
			
		||||
              Number of bytes to align data buffers for bulk SDIO transactions. Some hosts have
 | 
			
		||||
              specific alignment requirements for DMA, use this setting to
 | 
			
		||||
              adjust the alignment required.
 | 
			
		||||
 | 
			
		||||
              Must be a power of 2.
 | 
			
		||||
 | 
			
		||||
endef
 | 
			
		||||
 | 
			
		||||
ifeq ($(CONFIG_MORSE_SDIO),y)
 | 
			
		||||
  NOSTDINC_FLAGS += -DCONFIG_MORSE_SDIO
 | 
			
		||||
  MORSE_MAKEDEFS += CONFIG_MORSE_SDIO=y
 | 
			
		||||
endif
 | 
			
		||||
 | 
			
		||||
ifeq ($(CONFIG_MORSE_SPI),y)
 | 
			
		||||
  MORSE_MAKEDEFS += CONFIG_MORSE_SPI=y
 | 
			
		||||
endif
 | 
			
		||||
 | 
			
		||||
ifeq ($(CONFIG_MORSE_USER_ACCESS),y)
 | 
			
		||||
  NOSTDINC_FLAGS += -DCONFIG_MORSE_USER_ACCESS
 | 
			
		||||
  MORSE_MAKEDEFS += CONFIG_MORSE_USER_ACCESS=y
 | 
			
		||||
endif
 | 
			
		||||
 | 
			
		||||
ifeq ($(CONFIG_MORSE_VENDOR_COMMAND),y)
 | 
			
		||||
  NOSTDINC_FLAGS += -DCONFIG_MORSE_VENDOR_COMMAND
 | 
			
		||||
  MORSE_MAKEDEFS += CONFIG_MORSE_VENDOR_COMMAND=y
 | 
			
		||||
endif
 | 
			
		||||
 | 
			
		||||
ifeq ($(CONFIG_MORSE_MONITOR),y)
 | 
			
		||||
  NOSTDINC_FLAGS += -DCONFIG_MORSE_MONITOR
 | 
			
		||||
  MORSE_MAKEDEFS += CONFIG_MORSE_MONITOR=y
 | 
			
		||||
endif
 | 
			
		||||
 | 
			
		||||
ifeq ($(CONFIG_MORSE_DEBUG),y)
 | 
			
		||||
  # This DEBUG (used by the driver Makefile) should not be confused with
 | 
			
		||||
  # -DDEBUG (used by the kernel build system).
 | 
			
		||||
  MORSE_MAKEDEFS += DEBUG=y
 | 
			
		||||
  MORSE_MAKEDEFS += CONFIG_MORSE_DEBUGFS=y
 | 
			
		||||
  MORSE_MAKEDEFS += CONFIG_MORSE_ENABLE_TEST_MODES=y
 | 
			
		||||
else
 | 
			
		||||
  MORSE_MAKEDEFS += DEBUG=n
 | 
			
		||||
endif
 | 
			
		||||
 | 
			
		||||
ifeq ($(CONFIG_MORSE_RC),y)
 | 
			
		||||
  NOSTDINC_FLAGS += -DCONFIG_MORSE_RC
 | 
			
		||||
  MORSE_MAKEDEFS += CONFIG_MORSE_RC=y
 | 
			
		||||
endif
 | 
			
		||||
 | 
			
		||||
MORSE_MAKEDEFS += \
 | 
			
		||||
  MORSE_VERSION=0-$(PKG_VERSION) \
 | 
			
		||||
  KERNEL_SRC=$(LINUX_DIR) \
 | 
			
		||||
  CONFIG_MORSE_SDIO_ALIGNMENT=$(CONFIG_MORSE_SDIO_ALIGNMENT) \
 | 
			
		||||
  CONFIG_BACKPORT_VERSION=v5.18.1
 | 
			
		||||
# This refers to the version of mac80211 backported to OpenWrt
 | 
			
		||||
# Occasionally patches are required to remove some parts of the driver
 | 
			
		||||
# as OpenWrt may sometimes pull in further patches from later kernel versions
 | 
			
		||||
# than that of the mac80211 backport.
 | 
			
		||||
 | 
			
		||||
NOSTDINC_FLAGS = \
 | 
			
		||||
	-I$(PKG_BUILD_DIR) \
 | 
			
		||||
	-I$(STAGING_DIR)/usr/include/mac80211-backport/uapi \
 | 
			
		||||
	-I$(STAGING_DIR)/usr/include/mac80211-backport \
 | 
			
		||||
	-I$(STAGING_DIR)/usr/include/mac80211/uapi \
 | 
			
		||||
	-I$(STAGING_DIR)/usr/include/mac80211 \
 | 
			
		||||
	-include backport/autoconf.h \
 | 
			
		||||
	-include backport/backport.h
 | 
			
		||||
 | 
			
		||||
ifeq ($(CONFIG_MORSE_DEBUG_LOGGING),y)
 | 
			
		||||
  NOSTDINC_FLAGS += -DDYNAMIC_DEBUG_MODULE
 | 
			
		||||
  NOSTDINC_FLAGS += -DDEBUG
 | 
			
		||||
endif
 | 
			
		||||
 | 
			
		||||
MORSE_MAKEDEFS += CONFIG_WLAN_VENDOR_MORSE=m
 | 
			
		||||
MORSE_MAKEDEFS += V=1
 | 
			
		||||
 | 
			
		||||
NOSTDINC_FLAGS += -DMORSE_TRACE_PATH=.
 | 
			
		||||
 | 
			
		||||
include $(INCLUDE_DIR)/kernel-defaults.mk
 | 
			
		||||
 | 
			
		||||
define Build/Compile
 | 
			
		||||
	$(MAKE) $(MORSE_MAKEDEFS) $(PKG_JOBS) -C "$(LINUX_DIR)" \
 | 
			
		||||
		$(KERNEL_MAKE_FLAGS) \
 | 
			
		||||
		M="$(PKG_BUILD_DIR)" \
 | 
			
		||||
		NOSTDINC_FLAGS="$(NOSTDINC_FLAGS)" \
 | 
			
		||||
		modules
 | 
			
		||||
endef
 | 
			
		||||
 | 
			
		||||
$(eval $(call KernelPackage,morse))
 | 
			
		||||
@@ -0,0 +1,15 @@
 | 
			
		||||
--- a/watchdog.c
 | 
			
		||||
+++ b/watchdog.c
 | 
			
		||||
@@ -54,12 +54,7 @@ static enum hrtimer_restart morse_watchd
 | 
			
		||||
 static void watchdog_timer_start(struct morse *mors)
 | 
			
		||||
 {
 | 
			
		||||
 	ktime_t interval = ktime_set(mors->watchdog.interval_secs, 0);
 | 
			
		||||
-
 | 
			
		||||
-#if defined(MAC80211_BACKPORT_VERSION_CODE) && (KERNEL_VERSION(4, 10, 0) <= MAC80211_VERSION_CODE)
 | 
			
		||||
-	hrtimer_start(&mors->watchdog.timer, interval.tv64, HRTIMER_MODE_REL);
 | 
			
		||||
-#else
 | 
			
		||||
 	hrtimer_start(&mors->watchdog.timer, interval, HRTIMER_MODE_REL);
 | 
			
		||||
-#endif
 | 
			
		||||
 }
 | 
			
		||||
 | 
			
		||||
 int morse_watchdog_start(struct morse *mors)
 | 
			
		||||
							
								
								
									
										60
									
								
								feeds/morse/kernel/mm61xx/patches/003-ekh01-spi-fix.patch
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										60
									
								
								feeds/morse/kernel/mm61xx/patches/003-ekh01-spi-fix.patch
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,60 @@
 | 
			
		||||
--- a/spi.c
 | 
			
		||||
+++ b/spi.c
 | 
			
		||||
@@ -175,10 +175,12 @@ static int morse_spi_setup(struct spi_de
 | 
			
		||||
 	spi->bits_per_word = 8;
 | 
			
		||||
 	spi->max_speed_hz = max_speed_hz;
 | 
			
		||||
 
 | 
			
		||||
+#if 0
 | 
			
		||||
 	if (spi->max_speed_hz > MAX_SPI_CLK_SPEED) {
 | 
			
		||||
 		dev_err(&spi->dev, "SPI clocks above 50MHz are not supported by Morse chip\n");
 | 
			
		||||
 		return -EPERM;
 | 
			
		||||
 	}
 | 
			
		||||
+#endif
 | 
			
		||||
 
 | 
			
		||||
 	ret = spi_setup(spi);
 | 
			
		||||
 	if (ret < 0) {
 | 
			
		||||
@@ -432,7 +434,7 @@ static u8 *morse_spi_find_data_ack(struc
 | 
			
		||||
 {
 | 
			
		||||
 	u8 *cp = data;
 | 
			
		||||
 
 | 
			
		||||
-	while (cp < end && *cp == 0xff)
 | 
			
		||||
+	while (cp < end && (SPI_MMC_RESPONSE_CODE(*cp) != SPI_RESPONSE_ACCEPTED))
 | 
			
		||||
 		cp++;
 | 
			
		||||
 
 | 
			
		||||
 	if (cp == end)
 | 
			
		||||
@@ -529,13 +531,10 @@ static int morse_spi_cmd53_read(struct m
 | 
			
		||||
 	cp += 4;
 | 
			
		||||
 
 | 
			
		||||
 	if (!block) {
 | 
			
		||||
-		/* Scale bytes delay to block */
 | 
			
		||||
-		u32 extra_bytes = (count * mspi->inter_block_delay_bytes) / MMC_SPI_BLOCKSIZE;
 | 
			
		||||
-
 | 
			
		||||
 		/* Allow 4 bytes for CRC and another 10 bytes for start block token & chip delays
 | 
			
		||||
 		 * (usually comes in 2).
 | 
			
		||||
 		 */
 | 
			
		||||
-		data_size = count + 4 + 4 + extra_bytes;
 | 
			
		||||
+		data_size = count + 4 + 4 + mspi->inter_block_delay_bytes;
 | 
			
		||||
 		if (is_rk3288)
 | 
			
		||||
 			/* Short transactions are sometimes delayed. These extra bytes give enough
 | 
			
		||||
 			 * cycles to receive all the data. This could be optimised to a lower
 | 
			
		||||
@@ -601,6 +600,7 @@ static int morse_spi_cmd53_write(struct
 | 
			
		||||
 	u8 *resp;
 | 
			
		||||
 	u8 *end;
 | 
			
		||||
 	u8 *ack = cp;
 | 
			
		||||
+	u8 *test_ack;
 | 
			
		||||
 	u32 data_size;
 | 
			
		||||
 	int i;
 | 
			
		||||
 
 | 
			
		||||
@@ -656,10 +656,11 @@ static int morse_spi_cmd53_write(struct
 | 
			
		||||
 		/* crc */
 | 
			
		||||
 		*cp = (crc & 0xFF00) >> 8;
 | 
			
		||||
 		*(cp + 1) = (crc & 0xFF);
 | 
			
		||||
+		test_ack = cp + 2;
 | 
			
		||||
 		cp += sizeof(crc);
 | 
			
		||||
 
 | 
			
		||||
 		/* Allow more bytes for status and chip processing (depends on CLK) */
 | 
			
		||||
-		cp += block ? mspi->inter_block_delay_bytes : 4;
 | 
			
		||||
+		cp += mspi->inter_block_delay_bytes;
 | 
			
		||||
 	}
 | 
			
		||||
 
 | 
			
		||||
 	/* Do the actual transfer */
 | 
			
		||||
@@ -0,0 +1,13 @@
 | 
			
		||||
Index: morse_driver-rel_1_12_3_2024_May_23/sdio.c
 | 
			
		||||
===================================================================
 | 
			
		||||
--- morse_driver-rel_1_12_3_2024_May_23.orig/sdio.c
 | 
			
		||||
+++ morse_driver-rel_1_12_3_2024_May_23/sdio.c
 | 
			
		||||
@@ -572,7 +572,7 @@ static int morse_sdio_reset(int reset_pi
 | 
			
		||||
 
 | 
			
		||||
 	sdio_claim_host(func);
 | 
			
		||||
 	sdio_disable_func(func);
 | 
			
		||||
-#if KERNEL_VERSION(5, 18, 0) > LINUX_VERSION_CODE
 | 
			
		||||
+#if KERNEL_VERSION(5, 18, 0) > MAC80211_VERSION_CODE
 | 
			
		||||
 	mmc_hw_reset(func->card->host);
 | 
			
		||||
 #else
 | 
			
		||||
 	mmc_hw_reset(func->card);
 | 
			
		||||
@@ -0,0 +1,160 @@
 | 
			
		||||
From 9ebc9a01e90f65f058ed21d3190800dc130b6ef4 Mon Sep 17 00:00:00 2001
 | 
			
		||||
From: Arien Judge <arien.judge@morsemicro.com>
 | 
			
		||||
Date: Wed, 28 Feb 2024 13:29:28 +1100
 | 
			
		||||
Subject: [PATCH] sysfs: add sysfs to export board type as a device attribute
 | 
			
		||||
 | 
			
		||||
The driver reads the board type from OTP to decide which bcf file to load,
 | 
			
		||||
but doesn't report this information anywhere useful.
 | 
			
		||||
 | 
			
		||||
Read the value read from OTP as a sysfs device attribute to allow userspace
 | 
			
		||||
applications to reliably report the module type on chip.
 | 
			
		||||
 | 
			
		||||
Opted for creating a proper sysfs device attribute here instead of using
 | 
			
		||||
debugfs as we shouldn't expect user tooling to have such a hard dependency
 | 
			
		||||
 | 
			
		||||
cache board id on firmware init for sysfs reporting
 | 
			
		||||
---
 | 
			
		||||
 Makefile   |  1 +
 | 
			
		||||
 firmware.c |  3 +++
 | 
			
		||||
 mac.c      |  6 ++++++
 | 
			
		||||
 morse.h    |  1 +
 | 
			
		||||
 sysfs.c    | 46 ++++++++++++++++++++++++++++++++++++++++++++++
 | 
			
		||||
 sysfs.h    |  9 +++++++++
 | 
			
		||||
 6 files changed, 66 insertions(+)
 | 
			
		||||
 create mode 100644 sysfs.c
 | 
			
		||||
 create mode 100644 sysfs.h
 | 
			
		||||
 | 
			
		||||
Index: morse_driver-rel_1_12_3_2024_May_23/Makefile
 | 
			
		||||
===================================================================
 | 
			
		||||
--- morse_driver-rel_1_12_3_2024_May_23.orig/Makefile
 | 
			
		||||
+++ morse_driver-rel_1_12_3_2024_May_23/Makefile
 | 
			
		||||
@@ -96,6 +96,7 @@ endif
 | 
			
		||||
 obj-$(CONFIG_WLAN_VENDOR_MORSE) += morse.o dot11ah/
 | 
			
		||||
 
 | 
			
		||||
 morse-y = mac.o
 | 
			
		||||
+morse-y += sysfs.o
 | 
			
		||||
 morse-y += init.o
 | 
			
		||||
 morse-y += skbq.o
 | 
			
		||||
 morse-y += debug.o
 | 
			
		||||
Index: morse_driver-rel_1_12_3_2024_May_23/firmware.c
 | 
			
		||||
===================================================================
 | 
			
		||||
--- morse_driver-rel_1_12_3_2024_May_23.orig/firmware.c
 | 
			
		||||
+++ morse_driver-rel_1_12_3_2024_May_23/firmware.c
 | 
			
		||||
@@ -881,6 +881,9 @@ int morse_firmware_init(struct morse *mo
 | 
			
		||||
 	if (mors->cfg->get_board_type && enable_otp_check)
 | 
			
		||||
 		board_id = mors->cfg->get_board_type(mors);
 | 
			
		||||
 
 | 
			
		||||
+	/* store the board id for sysfs reporting. Propagate the error */
 | 
			
		||||
+	mors->board_id = board_id;
 | 
			
		||||
+
 | 
			
		||||
 	if (strlen(board_config_file) > 0) {
 | 
			
		||||
 		n = snprintf(bcf_path, sizeof(bcf_path), "%s/%s", MORSE_FW_DIR, board_config_file);
 | 
			
		||||
 	} else if (strlen(mors->board_serial) > 0) {
 | 
			
		||||
Index: morse_driver-rel_1_12_3_2024_May_23/mac.c
 | 
			
		||||
===================================================================
 | 
			
		||||
--- morse_driver-rel_1_12_3_2024_May_23.orig/mac.c
 | 
			
		||||
+++ morse_driver-rel_1_12_3_2024_May_23/mac.c
 | 
			
		||||
@@ -14,6 +14,7 @@
 | 
			
		||||
 #include "mac.h"
 | 
			
		||||
 #include "s1g_ies.h"
 | 
			
		||||
 #include "bus.h"
 | 
			
		||||
+#include "sysfs.h"
 | 
			
		||||
 #include "debug.h"
 | 
			
		||||
 #include "command.h"
 | 
			
		||||
 #include "vendor.h"
 | 
			
		||||
@@ -6422,6 +6423,10 @@ int morse_mac_register(struct morse *mor
 | 
			
		||||
 	INIT_WORK(&mors->driver_restart, morse_mac_restart_work);
 | 
			
		||||
 	INIT_WORK(&mors->health_check, morse_health_check_work);
 | 
			
		||||
 
 | 
			
		||||
+	ret = morse_sysfs_init(mors);
 | 
			
		||||
+	if (ret)
 | 
			
		||||
+		MORSE_ERR(mors, "Unable to initialise sysfs\n");
 | 
			
		||||
+
 | 
			
		||||
 	ret = morse_init_debug(mors);
 | 
			
		||||
 	if (ret)
 | 
			
		||||
 		MORSE_ERR(mors, "Unable to create debugfs files\n");
 | 
			
		||||
@@ -6593,6 +6598,7 @@ static void morse_mac_deinit(struct mors
 | 
			
		||||
 
 | 
			
		||||
 void morse_mac_unregister(struct morse *mors)
 | 
			
		||||
 {
 | 
			
		||||
+	morse_sysfs_free(mors);
 | 
			
		||||
 	morse_deinit_debug(mors);
 | 
			
		||||
 	morse_ps_disable(mors);
 | 
			
		||||
 
 | 
			
		||||
Index: morse_driver-rel_1_12_3_2024_May_23/morse.h
 | 
			
		||||
===================================================================
 | 
			
		||||
--- morse_driver-rel_1_12_3_2024_May_23.orig/morse.h
 | 
			
		||||
+++ morse_driver-rel_1_12_3_2024_May_23/morse.h
 | 
			
		||||
@@ -979,6 +979,7 @@ struct morse {
 | 
			
		||||
 	struct morse_debug debug;
 | 
			
		||||
 
 | 
			
		||||
 	char *board_serial;
 | 
			
		||||
+	int board_id;
 | 
			
		||||
 
 | 
			
		||||
 	/* Stored Channel Information, sta_type, enc_mode, RAW */
 | 
			
		||||
 	struct morse_custom_configs custom_configs;
 | 
			
		||||
Index: morse_driver-rel_1_12_3_2024_May_23/sysfs.c
 | 
			
		||||
===================================================================
 | 
			
		||||
--- /dev/null
 | 
			
		||||
+++ morse_driver-rel_1_12_3_2024_May_23/sysfs.c
 | 
			
		||||
@@ -0,0 +1,46 @@
 | 
			
		||||
+/*
 | 
			
		||||
+ * Copyright 2024 Morse Micro
 | 
			
		||||
+ *
 | 
			
		||||
+ */
 | 
			
		||||
+
 | 
			
		||||
+#include <linux/sysfs.h>
 | 
			
		||||
+#include "morse.h"
 | 
			
		||||
+#include "sysfs.h"
 | 
			
		||||
+#include "debug.h"
 | 
			
		||||
+
 | 
			
		||||
+static ssize_t board_type_show(struct device *dev,
 | 
			
		||||
+					   struct device_attribute *attr,
 | 
			
		||||
+					   char *buf)
 | 
			
		||||
+{
 | 
			
		||||
+	struct morse *mors = dev_get_drvdata(dev);
 | 
			
		||||
+
 | 
			
		||||
+	if (!mors)
 | 
			
		||||
+		return -EINVAL;
 | 
			
		||||
+
 | 
			
		||||
+	if (mors->board_id < 0)
 | 
			
		||||
+		return mors->board_id;
 | 
			
		||||
+
 | 
			
		||||
+#if KERNEL_VERSION(5, 10, 0) <= LINUX_VERSION_CODE
 | 
			
		||||
+	return sysfs_emit(buf, "%d\n", mors->board_id);
 | 
			
		||||
+#else
 | 
			
		||||
+	return snprintf(buf, PAGE_SIZE, "%d\n", mors->board_id);
 | 
			
		||||
+#endif
 | 
			
		||||
+}
 | 
			
		||||
+
 | 
			
		||||
+static DEVICE_ATTR_RO(board_type);
 | 
			
		||||
+
 | 
			
		||||
+int morse_sysfs_init(struct morse *mors)
 | 
			
		||||
+{
 | 
			
		||||
+	int ret;
 | 
			
		||||
+
 | 
			
		||||
+	ret = device_create_file(mors->dev, &dev_attr_board_type);
 | 
			
		||||
+	if (ret < 0)
 | 
			
		||||
+		MORSE_ERR(mors, "failed to create sysfs file board_type");
 | 
			
		||||
+
 | 
			
		||||
+	return ret;
 | 
			
		||||
+}
 | 
			
		||||
+
 | 
			
		||||
+void morse_sysfs_free(struct morse *mors)
 | 
			
		||||
+{
 | 
			
		||||
+	device_remove_file(mors->dev, &dev_attr_board_type);
 | 
			
		||||
+}
 | 
			
		||||
Index: morse_driver-rel_1_12_3_2024_May_23/sysfs.h
 | 
			
		||||
===================================================================
 | 
			
		||||
--- /dev/null
 | 
			
		||||
+++ morse_driver-rel_1_12_3_2024_May_23/sysfs.h
 | 
			
		||||
@@ -0,0 +1,9 @@
 | 
			
		||||
+/*
 | 
			
		||||
+ * Copyright 2024 Morse Micro
 | 
			
		||||
+ *
 | 
			
		||||
+ */
 | 
			
		||||
+
 | 
			
		||||
+#pragma once
 | 
			
		||||
+
 | 
			
		||||
+int morse_sysfs_init(struct morse *mors);
 | 
			
		||||
+void morse_sysfs_free(struct morse *mors);
 | 
			
		||||
							
								
								
									
										13
									
								
								feeds/morse/kernel/mm61xx/patches/010-fix-sdio-error.patch
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										13
									
								
								feeds/morse/kernel/mm61xx/patches/010-fix-sdio-error.patch
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,13 @@
 | 
			
		||||
--- a/sdio.c
 | 
			
		||||
+++ b/sdio.c
 | 
			
		||||
@@ -587,9 +587,5 @@ static int morse_sdio_reset(int reset_pi
 | 
			
		||||
	sdio_claim_host(func);
 | 
			
		||||
	sdio_disable_func(func);
 | 
			
		||||
-#if KERNEL_VERSION(5, 18, 0) > MAC80211_VERSION_CODE
 | 
			
		||||
	mmc_hw_reset(func->card->host);
 | 
			
		||||
-#else
 | 
			
		||||
-	mmc_hw_reset(func->card);
 | 
			
		||||
-#endif
 | 
			
		||||
	sdio_enable_func(func);
 | 
			
		||||
	sdio_release_host(func);
 | 
			
		||||
 | 
			
		||||
							
								
								
									
										73
									
								
								feeds/morse/kernel/mm61xx/patches/011-update-spi.patch
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										73
									
								
								feeds/morse/kernel/mm61xx/patches/011-update-spi.patch
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,73 @@
 | 
			
		||||
--- a/spi.c	2025-01-10 18:08:57.753837165 +0800
 | 
			
		||||
+++ b/spi.c	2025-01-13 14:17:01.746850459 +0800
 | 
			
		||||
@@ -1057,7 +1057,7 @@ static irqreturn_t morse_spi_irq_handler
 | 
			
		||||
	struct morse *mors = spi_get_drvdata(mspi->spi);
 | 
			
		||||
 | 
			
		||||
	MORSE_WARN_ON(FEATURE_ID_SPI, !mors);
 | 
			
		||||
-	if (irq == gpio_to_irq(mors->cfg->mm_spi_irq_gpio)) {
 | 
			
		||||
+
 | 
			
		||||
		/*
 | 
			
		||||
		 * If we are using edge interrupts, we need to continuously service the IRQ until
 | 
			
		||||
		 * either the chip has cleared all its IRQ bits, or the pin goes high again.
 | 
			
		||||
@@ -1067,8 +1067,7 @@ static irqreturn_t morse_spi_irq_handler
 | 
			
		||||
		} while (spi_use_edge_irq && ret && !gpio_get_value(mors->cfg->mm_spi_irq_gpio));
 | 
			
		||||
 | 
			
		||||
		return IRQ_HANDLED;
 | 
			
		||||
-	}
 | 
			
		||||
-	return IRQ_NONE;
 | 
			
		||||
+
 | 
			
		||||
 }
 | 
			
		||||
 | 
			
		||||
 static void morse_spi_enable_irq(struct morse_spi *mspi)
 | 
			
		||||
@@ -1311,10 +1310,15 @@ static int morse_spi_probe(struct spi_de
 | 
			
		||||
		ret = morse_spi_cmd(mspi, SD_IO_MORSE_INIT, 0x00000000);
 | 
			
		||||
		if (!ret)
 | 
			
		||||
			break;
 | 
			
		||||
-		pr_info("%s: SD_IO_RESET\n", __func__);
 | 
			
		||||
+		MORSE_DBG(mors, "%s: SD_IO_RESET\n", __func__);
 | 
			
		||||
		morse_spi_cmd(mspi, SD_IO_RESET, 0x00000000);
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
+	if (ret) {
 | 
			
		||||
+		MORSE_SPI_ERR(mors, "failed initialise SPI: %d\n", ret);
 | 
			
		||||
+		goto err_cfg;
 | 
			
		||||
+	}
 | 
			
		||||
+
 | 
			
		||||
	ret = morse_chip_cfg_detect_and_init(mors, mors_chip_series);
 | 
			
		||||
	if (ret) {
 | 
			
		||||
		MORSE_SPI_ERR(mors, "morse_chip_cfg_detect_and_init failed: %d\n", ret);
 | 
			
		||||
@@ -1327,7 +1331,11 @@ static int morse_spi_probe(struct spi_de
 | 
			
		||||
	mors->cfg->mm_ps_gpios_supported = true;
 | 
			
		||||
	ret = morse_spi_reg32_read(mors, MORSE_REG_CHIP_ID(mors), &mors->chip_id);
 | 
			
		||||
 | 
			
		||||
-	if (!ret) {
 | 
			
		||||
+	if (ret) {
 | 
			
		||||
+		MORSE_SPI_ERR(mors, "failed to read chip id: %d\n", ret);
 | 
			
		||||
+		goto err_cfg;
 | 
			
		||||
+	}
 | 
			
		||||
+
 | 
			
		||||
		/* Find out if the chip id matches our records */
 | 
			
		||||
		if (!morse_hw_is_valid_chip_id(mors->chip_id, mors->cfg->valid_chip_ids)) {
 | 
			
		||||
			MORSE_SPI_ERR(mors, "%s Morse chip (ChipId=0x%x) not supported\n",
 | 
			
		||||
@@ -1357,9 +1365,6 @@ static int morse_spi_probe(struct spi_de
 | 
			
		||||
								mspi->inter_block_delay_bytes);
 | 
			
		||||
			}
 | 
			
		||||
		}
 | 
			
		||||
-	} else {
 | 
			
		||||
-		goto err_cfg;
 | 
			
		||||
-	}
 | 
			
		||||
 | 
			
		||||
	MORSE_SPI_INFO(mors, "Morse Micro SPI device found, chip ID=0x%04x\n", mors->chip_id);
 | 
			
		||||
	MORSE_SPI_INFO(mors, "Board serial: %s\n", mors->board_serial);
 | 
			
		||||
@@ -1442,6 +1447,11 @@ static int morse_spi_probe(struct spi_de
 | 
			
		||||
 #ifdef CONFIG_MORSE_ENABLE_TEST_MODES
 | 
			
		||||
	if (test_mode == MORSE_CONFIG_TEST_MODE_BUS)
 | 
			
		||||
		ret = morse_bus_test(mors, "SPI");
 | 
			
		||||
+
 | 
			
		||||
+	if (test_mode == MORSE_CONFIG_TEST_MODE_BUS_PROFILE) {
 | 
			
		||||
+		morse_bus_throughput_profiler(mors);
 | 
			
		||||
+		morse_spi_disable_irq(mspi);
 | 
			
		||||
+	}
 | 
			
		||||
 #endif
 | 
			
		||||
 
 | 
			
		||||
 	return ret;
 | 
			
		||||
							
								
								
									
										125
									
								
								feeds/morse/kernel/morse-fw/LICENSE.binaries
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										125
									
								
								feeds/morse/kernel/morse-fw/LICENSE.binaries
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,125 @@
 | 
			
		||||
                                  MORSE MICRO
 | 
			
		||||
                     BINARY DISTRIBUTION LICENSE AGREEMENT
 | 
			
		||||
 | 
			
		||||
1. Parties.
 | 
			
		||||
This Software License Agreement (SLA) is between Morse Micro Pty. Ltd. and the
 | 
			
		||||
user of the Software set forth (“you”, “user”, “customer”), and is effective as
 | 
			
		||||
of the date of first access or download of the software by you. Morse Micro is
 | 
			
		||||
licensing this software to you free of charge upon the condition that you
 | 
			
		||||
accept all the terms of this SLA and only use this Software in conjunction with
 | 
			
		||||
Morse Micro products. ANY USE, REPRODUCTION, OR DISTRIBUTION OF THE SOFTWARE
 | 
			
		||||
CONSTITUTES YOUR ACCEPTANCE OF THIS AGREEMENT.
 | 
			
		||||
 | 
			
		||||
2. Definitions.
 | 
			
		||||
"Software" means any binary or source code that you have received from Morse
 | 
			
		||||
Micro or its authorized licensees and/or those portions of such software
 | 
			
		||||
produced by Program’s code within the Software, as well as any other machine
 | 
			
		||||
readable materials (including, but not limited to, libraries, source files,
 | 
			
		||||
header files, and data files), any updates or error corrections provided by
 | 
			
		||||
Morse Micro, and any user manuals, programming guides and other documentation
 | 
			
		||||
provided to you by Morse Micro under this SLA.
 | 
			
		||||
 | 
			
		||||
3. License and Restrictions.
 | 
			
		||||
Morse Micro grants you a non-exclusive, non-transferable, limited license
 | 
			
		||||
without license fees to:
 | 
			
		||||
 | 
			
		||||
    a. use the software solely with a hardware product that includes one of the
 | 
			
		||||
    Morse Micro Wi-Fi HaLow chips, including
 | 
			
		||||
    wireless modules or evaluation kits;
 | 
			
		||||
 | 
			
		||||
    b. to reproduce and distribute the Software complete, unmodified, and as
 | 
			
		||||
    provided by Morse Micro, solely for use with a hardware product that
 | 
			
		||||
    includes one of the Morse Micro Wi-Fi HaLow chips, including wireless
 | 
			
		||||
    modules or evaluation kits.
 | 
			
		||||
 | 
			
		||||
4. Reservation of Rights.
 | 
			
		||||
You should distribute Software with a copy of this SLA. Software is
 | 
			
		||||
copyrighted. Title to Software and all associated intellectual property rights
 | 
			
		||||
is retained by Morse Micro. Except as expressly provided herein, no license or
 | 
			
		||||
right, express or implied, is hereby conveyed or granted to you by Morse Micro.
 | 
			
		||||
You must retain all copyright notices on all Software, derivative works and
 | 
			
		||||
documentation. The intellectual property and proprietary rights of whatever
 | 
			
		||||
nature in the Software and derivative works are and will remain the exclusive
 | 
			
		||||
property of Morse Micro or its suppliers. Nothing in this Agreement should be
 | 
			
		||||
construed as transferring any aspects of such rights to you or any third party.
 | 
			
		||||
Morse Micro and its suppliers reserve any and all rights not expressly granted
 | 
			
		||||
in this Agreement. You may not sell, assign, sublicense, lease, or otherwise
 | 
			
		||||
transfer any part of this license. You must not:
 | 
			
		||||
 | 
			
		||||
    a. use, license, sell or otherwise distribute the Software except as
 | 
			
		||||
    provided in this SLA;
 | 
			
		||||
 | 
			
		||||
    b. attempt to modify in any way, reverse engineer, decompile or disassemble
 | 
			
		||||
    any portion of the Software;
 | 
			
		||||
 | 
			
		||||
    c. use the Software or other material in violation of any applicable law or
 | 
			
		||||
    regulation, including but not limited to any regulatory agency.
 | 
			
		||||
 | 
			
		||||
5. Ownership.
 | 
			
		||||
The Software is licensed and not sold.  Title to and ownership of the Software,
 | 
			
		||||
including all intellectual property rights thereto, and any portion thereof
 | 
			
		||||
remain with Morse Micro or its licensors. You hereby covenant that you will not
 | 
			
		||||
assert any claim that the Software created by or for Morse Micro infringe any
 | 
			
		||||
intellectual property right owned or controlled by you.
 | 
			
		||||
 | 
			
		||||
6. Termination.
 | 
			
		||||
This SLA will terminate immediately without notice from Morse Micro if you fail
 | 
			
		||||
to comply with any of its provisions, including the export laws provisions and
 | 
			
		||||
Section 10 that may govern the export of the Software from certain
 | 
			
		||||
jurisdictions, including technical data.
 | 
			
		||||
 | 
			
		||||
7. Disclaimer and Limitation of Liability.
 | 
			
		||||
THE SOFTWARE IS PROVIDED "AS IS" WITHOUT WARRANTY OF ANY KIND. MORSE MICRO
 | 
			
		||||
FURTHER DISCLAIMS ALL WARRANTIES, EXPRESS AND IMPLIED, INCLUDING WITHOUT
 | 
			
		||||
LIMITATION, ANY IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
 | 
			
		||||
PURPOSE OR NON-INFRINGEMENT. IN NO EVENT SHALL MORSE MICRO BE LIABLE FOR ANY
 | 
			
		||||
INDIRECT, INCIDENTAL, SPECIAL, PUNITIVE OR CONSEQUENTIAL DAMAGES, OR DAMAGES
 | 
			
		||||
FOR LOSS OF PROFITS, REVENUE, DATA OR DATA USE, INCURRED BY YOU OR ANY THIRD
 | 
			
		||||
PARTY, WHETHER IN AN ACTION IN CONTRACT OR TORT, EVEN IF MORSE MICRO HAS BEEN
 | 
			
		||||
ADVISED OF THE POSSIBILITY OF SUCH DAMAGES. THE SOFTWARE IS NOT INTENDED FOR
 | 
			
		||||
USE IN ENVIRONMENTS OR APPLICATIONS WHERE EXTRAORDINARILY HIGH LEVELS OF
 | 
			
		||||
QUALITY, RELIABILITY, AND FAILURE TOLERANCE ARE DEMANDED, AND/OR WHERE A
 | 
			
		||||
MALFUNCTION OR FAILURE COULD LEAD TO SIGNIFICANT HARM TO LIFE, HEALTH,
 | 
			
		||||
PROPERTY, OR RESULT IN SEVERE SOCIETAL REPERCUSSIONS ("CRITICAL APPLICATIONS").
 | 
			
		||||
CRITICAL APPLICATIONS ENCOMPASS, BUT ARE NOT LIMITED TO, EQUIPMENT UTILIZED IN
 | 
			
		||||
NUCLEAR FACILITIES, AVIATION AND SPACE EQUIPMENT, MEDICAL DEVICES, AUTOMOTIVE,
 | 
			
		||||
TRAIN, MARINE, AND OTHER TRANSPORTATION EQUIPMENT, DEVICES INVOLVED IN
 | 
			
		||||
CONTROLLING COMBUSTION OR EXPLOSIONS, SAFETY DEVICES, ELEVATORS AND ESCALATORS,
 | 
			
		||||
DEVICES ASSOCIATED WITH ELECTRIC POWER, AND EQUIPMENT USED IN FINANCE-RELATED
 | 
			
		||||
FIELDS.
 | 
			
		||||
 | 
			
		||||
8. Survival.
 | 
			
		||||
Sections 4, 5, 6, 7 and 10 will survive termination or expiration of this SLA.
 | 
			
		||||
 | 
			
		||||
9. Privacy.
 | 
			
		||||
Some features of the Software, if activated, may transmit a limited amount of
 | 
			
		||||
data to Morse Micro (or its service provider) about the status of the system
 | 
			
		||||
before a crash event. Morse Micro does not associate the data with personally
 | 
			
		||||
identifiable information.
 | 
			
		||||
 | 
			
		||||
10. Export Laws.
 | 
			
		||||
YOU UNDERSTAND AND AGREE THAT THE SOFTWARE IS SUBJECT TO ALL APPLICABLE EXPORT-
 | 
			
		||||
RELATED LAWS AND REGULATIONS AND THAT YOU MAY NOT EXPORT, RE-EXPORT OR TRANSFER
 | 
			
		||||
THE SOFTWARE OR ANY DIRECT PRODUCT OF THE SOFTWARE EXCEPT AS PERMITTED UNDER
 | 
			
		||||
THOSE LAWS. WITHOUT LIMITING THE FOREGOING, EXPORT, RE-EXPORT, OR TRANSFER OF
 | 
			
		||||
THE SOFTWARE TO CUBA, IRAN, NORTH KOREA, SUDAN, AND SYRIA IS PROHIBITED.
 | 
			
		||||
 | 
			
		||||
11. Governing Law.
 | 
			
		||||
The laws of New South Wales, Australia, govern all matters arising out of or
 | 
			
		||||
relating to this SLA without giving effect to any conflict of law principles.
 | 
			
		||||
If any provision of this SLA is held to be unenforceable, this SLA will remain
 | 
			
		||||
in effect with the provision omitted, unless omission would frustrate the
 | 
			
		||||
intent of the parties, in which case this Agreement will immediately terminate.
 | 
			
		||||
 | 
			
		||||
12. Entire Agreement.
 | 
			
		||||
This Agreement constitutes the entire agreement between the parties and
 | 
			
		||||
supersedes all prior and contemporaneous agreements, proposals or
 | 
			
		||||
representations, written or oral, concerning its subject matter. No
 | 
			
		||||
modification, amendment, or waiver of any provision of this Agreement will be
 | 
			
		||||
effective unless in writing and either signed or accepted electronically by the
 | 
			
		||||
party against whom the modification, amendment or waiver is to be asserted. A
 | 
			
		||||
waiver of any breach under this Agreement does not constitute a waiver of any
 | 
			
		||||
other breach or future breach.
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
MORSE MICRO
 | 
			
		||||
							
								
								
									
										53
									
								
								feeds/morse/kernel/morse-fw/Makefile
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										53
									
								
								feeds/morse/kernel/morse-fw/Makefile
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,53 @@
 | 
			
		||||
#
 | 
			
		||||
# Copyright 2022 Morse Micro
 | 
			
		||||
#
 | 
			
		||||
# This is free software, licensed under the MIT License.
 | 
			
		||||
#
 | 
			
		||||
# This package installs Morse Micro firmware binaries, which are
 | 
			
		||||
# distributed under the Morse Micro Binary Distribution License.
 | 
			
		||||
# This license is available in LICENSE.binaries.
 | 
			
		||||
#
 | 
			
		||||
 | 
			
		||||
include $(TOPDIR)/rules.mk
 | 
			
		||||
 | 
			
		||||
PKG_NAME:=morse-fw
 | 
			
		||||
PKG_RELEASE=2
 | 
			
		||||
 | 
			
		||||
PKG_VERSION:=rel_1_11_4_2024_Jul_09
 | 
			
		||||
 | 
			
		||||
PKG_SOURCE:=morsemicro-fw-rel_1_11_4_2024_Jul_09.tar
 | 
			
		||||
PKG_SOURCE_URL:=https://github.com/MorseMicro/firmware_binaries/releases/download/v1.11.4/
 | 
			
		||||
PKG_HASH:=6df1e39655278adf140776b3e76b8faced41828a9d482363aed0795e96f5d241
 | 
			
		||||
 | 
			
		||||
PKG_MAINTAINER:=Morse Micro <info@morsemicro.com>
 | 
			
		||||
PKG_BUILD_PARALLEL:=1
 | 
			
		||||
 | 
			
		||||
RSTRIP:=:
 | 
			
		||||
 | 
			
		||||
include $(INCLUDE_DIR)/kernel.mk
 | 
			
		||||
include $(INCLUDE_DIR)/package.mk
 | 
			
		||||
 | 
			
		||||
define Package/morse-fw
 | 
			
		||||
  SECTION:=firmware
 | 
			
		||||
  CATEGORY:=Firmware
 | 
			
		||||
  URL:=$(PKG_SOURCE_URL)
 | 
			
		||||
  TITLE:=Morse Micro WIFI HaLow firmware
 | 
			
		||||
  PROVIDES:=morse-fw
 | 
			
		||||
endef
 | 
			
		||||
 | 
			
		||||
TAR_CMD=$(HOST_TAR) -C $(1) $(TAR_OPTIONS)
 | 
			
		||||
 | 
			
		||||
define Build/Compile
 | 
			
		||||
 | 
			
		||||
endef
 | 
			
		||||
 | 
			
		||||
define Package/morse-fw/install
 | 
			
		||||
	$(INSTALL_DIR) $(1)/lib/firmware/morse/.
 | 
			
		||||
	if [ -e ./files/lib/firmware/morse/mm6108.bin ]; then \
 | 
			
		||||
		$(INSTALL_DATA) ./files/lib/firmware/morse/mm6108.bin $(1)/lib/firmware/morse/; \
 | 
			
		||||
	else \
 | 
			
		||||
		$(INSTALL_DATA) $(PKG_BUILD_DIR)/lib/firmware/morse/mm6108.bin $(1)/lib/firmware/morse/; \
 | 
			
		||||
	fi
 | 
			
		||||
endef
 | 
			
		||||
 | 
			
		||||
$(eval $(call BuildPackage,morse-fw))
 | 
			
		||||
										
											Binary file not shown.
										
									
								
							
										
											Binary file not shown.
										
									
								
							
							
								
								
									
										68
									
								
								feeds/morse/morse-regdb/Makefile
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										68
									
								
								feeds/morse/morse-regdb/Makefile
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,68 @@
 | 
			
		||||
#
 | 
			
		||||
# Copyright 2023 Morse Micro
 | 
			
		||||
#
 | 
			
		||||
# This is free software, licensed under the 3-Clause BSD License.
 | 
			
		||||
#
 | 
			
		||||
 | 
			
		||||
# Because the contents of morse_regdb are private, this package does
 | 
			
		||||
# some tricky things to _avoid_ downloading under normal circumstances,
 | 
			
		||||
# instead using a cached file stored in this repository. If you'd like
 | 
			
		||||
# to regenerate the cached file, do:
 | 
			
		||||
#
 | 
			
		||||
#   make package/morse-regdb/clean package/morse-regdb/download package/morse-regdb/compile V=sc REGENERATE=1
 | 
			
		||||
#
 | 
			
		||||
include $(TOPDIR)/rules.mk
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
PKG_NAME:=morse-regdb
 | 
			
		||||
PKG_RELEASE:=1
 | 
			
		||||
PKG_BUILD_DEPENDS:=python3/host
 | 
			
		||||
 | 
			
		||||
PKG_SOURCE_VERSION:=v2.1.1
 | 
			
		||||
PKG_SOURCE_URL:=https://github.com/MorseMicro/morse_regdb.git
 | 
			
		||||
PKG_SOURCE_PROTO:=git
 | 
			
		||||
PKG_MIRROR_HASH:=0d074d2810f520c138427ab63ce0b8ab61f0f073cf7cd91177ad840a3322540a
 | 
			
		||||
 | 
			
		||||
PKG_VERSION:=$(PKG_SOURCE_VERSION)
 | 
			
		||||
 | 
			
		||||
include $(INCLUDE_DIR)/package.mk
 | 
			
		||||
 | 
			
		||||
# Skip download unless REGENERATE is on.
 | 
			
		||||
# This must occur after including package.mk, as PKG_SKIP_DOWNLOAD is defined there.
 | 
			
		||||
PKG_SKIP_DOWNLOAD=$(USE_SOURCE_DIR)$(USE_GIT_TREE)$(USE_GIT_SRC_CHECKOUT)$(if $(REGENERATE),,1)
 | 
			
		||||
 | 
			
		||||
define Package/morse-regdb
 | 
			
		||||
  SECTION:=net
 | 
			
		||||
  CATEGORY:=Network
 | 
			
		||||
  TITLE:=Regulatory data for 802.11ah
 | 
			
		||||
  URL:=https://bitbucket.org/morsemicro/morse_regdb/src/master/
 | 
			
		||||
  PKGARCH:=all
 | 
			
		||||
endef
 | 
			
		||||
 | 
			
		||||
define Package/morse-regdb/description
 | 
			
		||||
	Regulatory data for 802.11ah in a csv.
 | 
			
		||||
endef
 | 
			
		||||
 | 
			
		||||
define Build/Prepare
 | 
			
		||||
	$(if $(REGENERATE),$(call Build/Prepare/Default))
 | 
			
		||||
endef
 | 
			
		||||
 | 
			
		||||
define Build/Compile
 | 
			
		||||
	$(if $(REGENERATE),
 | 
			
		||||
		mkdir -p artefacts
 | 
			
		||||
		python3 $(PKG_BUILD_DIR)/regdbconverter.py -v -f csv $(PKG_BUILD_DIR)/regdb_Sub-1_GHz.tsv > artefacts/repo_channels.csv
 | 
			
		||||
	)
 | 
			
		||||
	mkdir -p $(PKG_BUILD_DIR)/artefacts
 | 
			
		||||
	# Mash the 5g shim channels in.
 | 
			
		||||
	python3 add_5g_shim_channels.py < artefacts/repo_channels.csv > $(PKG_BUILD_DIR)/artefacts/channels.csv
 | 
			
		||||
endef
 | 
			
		||||
 | 
			
		||||
define Package/morse-regdb/install
 | 
			
		||||
	$(INSTALL_DIR) $(1)/usr/share/morse-regdb
 | 
			
		||||
	$(INSTALL_DATA) $(PKG_BUILD_DIR)/artefacts/* $(1)/usr/share/morse-regdb
 | 
			
		||||
	# Make channels.csv accessible from the web.
 | 
			
		||||
	$(INSTALL_DIR) $(1)/www
 | 
			
		||||
	ln -sf /usr/share/morse-regdb/channels.csv $(1)/www/halow-channels.csv
 | 
			
		||||
endef
 | 
			
		||||
 | 
			
		||||
$(eval $(call BuildPackage,morse-regdb))
 | 
			
		||||
							
								
								
									
										88
									
								
								feeds/morse/morse-regdb/add_5g_shim_channels.py
									
									
									
									
									
										Executable file
									
								
							
							
						
						
									
										88
									
								
								feeds/morse/morse-regdb/add_5g_shim_channels.py
									
									
									
									
									
										Executable file
									
								
							@@ -0,0 +1,88 @@
 | 
			
		||||
#!/usr/bin/env python3
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
import csv
 | 
			
		||||
import sys
 | 
			
		||||
 | 
			
		||||
# Fake 5g channels reported by netlink instead of 1g channels.
 | 
			
		||||
S1G_TO_5G= {
 | 
			
		||||
    1: 132,
 | 
			
		||||
    2: 134,
 | 
			
		||||
    3: 136,
 | 
			
		||||
    4: 'NA',
 | 
			
		||||
    5: 36,
 | 
			
		||||
    6: 38,
 | 
			
		||||
    7: 40,
 | 
			
		||||
    8: 42,
 | 
			
		||||
    9: 44,
 | 
			
		||||
    10: 46,
 | 
			
		||||
    11: 48,
 | 
			
		||||
    12: 50,
 | 
			
		||||
    13: 52,
 | 
			
		||||
    14: 54,
 | 
			
		||||
    15: 56,
 | 
			
		||||
    16: 58,
 | 
			
		||||
    17: 60,
 | 
			
		||||
    18: 62,
 | 
			
		||||
    19: 64,
 | 
			
		||||
    20: 'NA',
 | 
			
		||||
    21: 100,
 | 
			
		||||
    22: 102,
 | 
			
		||||
    23: 104,
 | 
			
		||||
    24: 106,
 | 
			
		||||
    25: 108,
 | 
			
		||||
    26: 110,
 | 
			
		||||
    27: 112,
 | 
			
		||||
    28: 114,
 | 
			
		||||
    29: 116,
 | 
			
		||||
    30: 118,
 | 
			
		||||
    31: 120,
 | 
			
		||||
    32: 122,
 | 
			
		||||
    33: 124,
 | 
			
		||||
    34: 126,
 | 
			
		||||
    35: 128,
 | 
			
		||||
    36: 'NA',
 | 
			
		||||
    37: 149,
 | 
			
		||||
    38: 151,
 | 
			
		||||
    39: 153,
 | 
			
		||||
    40: 155,
 | 
			
		||||
    41: 157,
 | 
			
		||||
    42: 159,
 | 
			
		||||
    43: 161,
 | 
			
		||||
    44: 163,
 | 
			
		||||
    45: 165,
 | 
			
		||||
    46: 167,
 | 
			
		||||
    47: 169,
 | 
			
		||||
    48: 171,
 | 
			
		||||
    49: 173,
 | 
			
		||||
    50: 175,
 | 
			
		||||
    51: 177,
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
# Japanese channels are... different.
 | 
			
		||||
JAPAN_S1G_TO_5G = {
 | 
			
		||||
    9: 108,
 | 
			
		||||
    13: 36,
 | 
			
		||||
    15: 40,
 | 
			
		||||
    17: 44,
 | 
			
		||||
    19: 48,
 | 
			
		||||
    21: 64,
 | 
			
		||||
    2: 38,
 | 
			
		||||
    6: 46,
 | 
			
		||||
    4: 54,
 | 
			
		||||
    8: 62,
 | 
			
		||||
    36: 42,
 | 
			
		||||
    38: 58,
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
dr = csv.DictReader(sys.stdin)
 | 
			
		||||
dw = csv.DictWriter(sys.stdout, dr.fieldnames + ['5g_chan'], lineterminator='\n')
 | 
			
		||||
dw.writeheader()
 | 
			
		||||
for row in dr:
 | 
			
		||||
     m = JAPAN_S1G_TO_5G if row['country_code'] == 'JP' else S1G_TO_5G
 | 
			
		||||
     row['5g_chan'] = m.get(int(row['s1g_chan']))
 | 
			
		||||
 | 
			
		||||
     assert row['5g_chan'], f'Missing 5G chan map for Channel {row["s1g_chan"]} in {row["country_code"]}'
 | 
			
		||||
 | 
			
		||||
     dw.writerow(row)
 | 
			
		||||
							
								
								
									
										473
									
								
								feeds/morse/morse-regdb/artefacts/repo_channels.csv
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										473
									
								
								feeds/morse/morse-regdb/artefacts/repo_channels.csv
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,473 @@
 | 
			
		||||
country_code,bw,s1g_chan,s1g_op_class,global_op_class,centre_freq_mhz,duty_cycle_ap,duty_cycle_sta,country,tx_power_max,duty_cycle_omit_ctrl_resp,pkt_spacing_ms,airtime_min_ms,airtime_max_ms,usable_banff_c
 | 
			
		||||
AL,1,1,6,66,863.5,10.0,2.8,Albania,16.13,False,0.0,0.0,0.0,1
 | 
			
		||||
AL,1,3,6,66,864.5,10.0,2.8,Albania,16.13,False,0.0,0.0,0.0,1
 | 
			
		||||
AL,1,5,6,66,865.5,10.0,2.8,Albania,16.13,False,0.0,0.0,0.0,1
 | 
			
		||||
AL,1,7,6,66,866.5,10.0,2.8,Albania,16.13,False,0.0,0.0,0.0,1
 | 
			
		||||
AL,1,9,6,66,867.5,10.0,2.8,Albania,16.13,False,0.0,0.0,0.0,1
 | 
			
		||||
AR,1,27,1,68,915.5,100.0,100.0,Argentina,36.0,False,0.0,0.0,0.0,1
 | 
			
		||||
AR,1,29,1,68,916.5,100.0,100.0,Argentina,36.0,False,0.0,0.0,0.0,1
 | 
			
		||||
AR,1,31,1,68,917.5,100.0,100.0,Argentina,36.0,False,0.0,0.0,0.0,1
 | 
			
		||||
AR,1,33,1,68,918.5,100.0,100.0,Argentina,36.0,False,0.0,0.0,0.0,1
 | 
			
		||||
AR,1,35,1,68,919.5,100.0,100.0,Argentina,36.0,False,0.0,0.0,0.0,1
 | 
			
		||||
AR,1,37,1,68,920.5,100.0,100.0,Argentina,36.0,False,0.0,0.0,0.0,1
 | 
			
		||||
AR,1,39,1,68,921.5,100.0,100.0,Argentina,36.0,False,0.0,0.0,0.0,1
 | 
			
		||||
AR,1,41,1,68,922.5,100.0,100.0,Argentina,36.0,False,0.0,0.0,0.0,1
 | 
			
		||||
AR,1,43,1,68,923.5,100.0,100.0,Argentina,36.0,False,0.0,0.0,0.0,1
 | 
			
		||||
AR,1,45,1,68,924.5,100.0,100.0,Argentina,36.0,False,0.0,0.0,0.0,1
 | 
			
		||||
AR,1,47,1,68,925.5,100.0,100.0,Argentina,36.0,False,0.0,0.0,0.0,1
 | 
			
		||||
AR,1,49,1,68,926.5,100.0,100.0,Argentina,36.0,False,0.0,0.0,0.0,1
 | 
			
		||||
AR,1,51,1,68,927.5,100.0,100.0,Argentina,36.0,False,0.0,0.0,0.0,1
 | 
			
		||||
AR,2,30,2,69,917.0,100.0,100.0,Argentina,36.0,False,0.0,0.0,0.0,1
 | 
			
		||||
AR,2,34,2,69,919.0,100.0,100.0,Argentina,36.0,False,0.0,0.0,0.0,1
 | 
			
		||||
AR,2,38,2,69,921.0,100.0,100.0,Argentina,36.0,False,0.0,0.0,0.0,1
 | 
			
		||||
AR,2,42,2,69,923.0,100.0,100.0,Argentina,36.0,False,0.0,0.0,0.0,1
 | 
			
		||||
AR,2,46,2,69,925.0,100.0,100.0,Argentina,36.0,False,0.0,0.0,0.0,1
 | 
			
		||||
AR,2,50,2,69,927.0,100.0,100.0,Argentina,36.0,False,0.0,0.0,0.0,1
 | 
			
		||||
AR,4,32,3,70,918.0,100.0,100.0,Argentina,36.0,False,0.0,0.0,0.0,1
 | 
			
		||||
AR,4,40,3,70,922.0,100.0,100.0,Argentina,36.0,False,0.0,0.0,0.0,1
 | 
			
		||||
AR,4,48,3,70,926.0,100.0,100.0,Argentina,36.0,False,0.0,0.0,0.0,1
 | 
			
		||||
AR,8,44,4,71,924.0,100.0,100.0,Argentina,36.0,False,0.0,0.0,0.0,1
 | 
			
		||||
AT,1,1,6,66,863.5,10.0,2.8,Austria,16.13,False,0.0,0.0,0.0,1
 | 
			
		||||
AT,1,3,6,66,864.5,10.0,2.8,Austria,16.13,False,0.0,0.0,0.0,1
 | 
			
		||||
AT,1,5,6,66,865.5,10.0,2.8,Austria,16.13,False,0.0,0.0,0.0,1
 | 
			
		||||
AT,1,7,6,66,866.5,10.0,2.8,Austria,16.13,False,0.0,0.0,0.0,1
 | 
			
		||||
AT,1,9,6,66,867.5,10.0,2.8,Austria,16.13,False,0.0,0.0,0.0,1
 | 
			
		||||
AU,1,27,22,68,915.5,100.0,100.0,Australia,30.0,False,0.0,0.0,0.0,1
 | 
			
		||||
AU,1,29,22,68,916.5,100.0,100.0,Australia,30.0,False,0.0,0.0,0.0,1
 | 
			
		||||
AU,1,31,22,68,917.5,100.0,100.0,Australia,30.0,False,0.0,0.0,0.0,1
 | 
			
		||||
AU,1,33,22,68,918.5,100.0,100.0,Australia,30.0,False,0.0,0.0,0.0,1
 | 
			
		||||
AU,1,35,22,68,919.5,100.0,100.0,Australia,30.0,False,0.0,0.0,0.0,1
 | 
			
		||||
AU,1,37,22,68,920.5,100.0,100.0,Australia,30.0,False,0.0,0.0,0.0,1
 | 
			
		||||
AU,1,39,22,68,921.5,100.0,100.0,Australia,30.0,False,0.0,0.0,0.0,1
 | 
			
		||||
AU,1,41,22,68,922.5,100.0,100.0,Australia,30.0,False,0.0,0.0,0.0,1
 | 
			
		||||
AU,1,43,22,68,923.5,100.0,100.0,Australia,30.0,False,0.0,0.0,0.0,1
 | 
			
		||||
AU,1,45,22,68,924.5,100.0,100.0,Australia,30.0,False,0.0,0.0,0.0,1
 | 
			
		||||
AU,1,47,22,68,925.5,100.0,100.0,Australia,30.0,False,0.0,0.0,0.0,1
 | 
			
		||||
AU,1,49,22,68,926.5,100.0,100.0,Australia,30.0,False,0.0,0.0,0.0,1
 | 
			
		||||
AU,1,51,22,68,927.5,100.0,100.0,Australia,30.0,False,0.0,0.0,0.0,1
 | 
			
		||||
AU,2,30,23,69,917.0,100.0,100.0,Australia,30.0,False,0.0,0.0,0.0,1
 | 
			
		||||
AU,2,34,23,69,919.0,100.0,100.0,Australia,30.0,False,0.0,0.0,0.0,1
 | 
			
		||||
AU,2,38,23,69,921.0,100.0,100.0,Australia,30.0,False,0.0,0.0,0.0,1
 | 
			
		||||
AU,2,42,23,69,923.0,100.0,100.0,Australia,30.0,False,0.0,0.0,0.0,1
 | 
			
		||||
AU,2,46,23,69,925.0,100.0,100.0,Australia,30.0,False,0.0,0.0,0.0,1
 | 
			
		||||
AU,2,50,23,69,927.0,100.0,100.0,Australia,30.0,False,0.0,0.0,0.0,1
 | 
			
		||||
AU,4,32,24,70,918.0,100.0,100.0,Australia,30.0,False,0.0,0.0,0.0,1
 | 
			
		||||
AU,4,40,24,70,922.0,100.0,100.0,Australia,30.0,False,0.0,0.0,0.0,1
 | 
			
		||||
AU,4,48,24,70,926.0,100.0,100.0,Australia,30.0,False,0.0,0.0,0.0,1
 | 
			
		||||
AU,8,44,25,71,924.0,100.0,100.0,Australia,30.0,False,0.0,0.0,0.0,1
 | 
			
		||||
BA,1,1,6,66,863.5,10.0,2.8,Bosnia and Herzegovina,16.13,False,0.0,0.0,0.0,1
 | 
			
		||||
BA,1,3,6,66,864.5,10.0,2.8,Bosnia and Herzegovina,16.13,False,0.0,0.0,0.0,1
 | 
			
		||||
BA,1,5,6,66,865.5,10.0,2.8,Bosnia and Herzegovina,16.13,False,0.0,0.0,0.0,1
 | 
			
		||||
BA,1,7,6,66,866.5,10.0,2.8,Bosnia and Herzegovina,16.13,False,0.0,0.0,0.0,1
 | 
			
		||||
BA,1,9,6,66,867.5,10.0,2.8,Bosnia and Herzegovina,16.13,False,0.0,0.0,0.0,1
 | 
			
		||||
BE,1,1,6,66,863.5,10.0,2.8,Belgium,16.13,False,0.0,0.0,0.0,1
 | 
			
		||||
BE,1,3,6,66,864.5,10.0,2.8,Belgium,16.13,False,0.0,0.0,0.0,1
 | 
			
		||||
BE,1,5,6,66,865.5,10.0,2.8,Belgium,16.13,False,0.0,0.0,0.0,1
 | 
			
		||||
BE,1,7,6,66,866.5,10.0,2.8,Belgium,16.13,False,0.0,0.0,0.0,1
 | 
			
		||||
BE,1,9,6,66,867.5,10.0,2.8,Belgium,16.13,False,0.0,0.0,0.0,1
 | 
			
		||||
BE,1,31,30,77,916.9,10.0,2.8,Belgium,16.13,False,0.0,0.0,0.0,1
 | 
			
		||||
BE,1,33,30,77,917.9,10.0,2.8,Belgium,16.13,False,0.0,0.0,0.0,1
 | 
			
		||||
BE,1,35,30,77,918.9,10.0,2.8,Belgium,16.13,False,0.0,0.0,0.0,1
 | 
			
		||||
BG,1,1,6,66,863.5,10.0,2.8,Bulgaria,16.13,False,0.0,0.0,0.0,1
 | 
			
		||||
BG,1,3,6,66,864.5,10.0,2.8,Bulgaria,16.13,False,0.0,0.0,0.0,1
 | 
			
		||||
BG,1,5,6,66,865.5,10.0,2.8,Bulgaria,16.13,False,0.0,0.0,0.0,1
 | 
			
		||||
BG,1,7,6,66,866.5,10.0,2.8,Bulgaria,16.13,False,0.0,0.0,0.0,1
 | 
			
		||||
BG,1,9,6,66,867.5,10.0,2.8,Bulgaria,16.13,False,0.0,0.0,0.0,1
 | 
			
		||||
BG,1,33,30,77,917.9,10.0,2.8,Bulgaria,16.13,False,0.0,0.0,0.0,1
 | 
			
		||||
BG,1,35,30,77,918.9,10.0,2.8,Bulgaria,16.13,False,0.0,0.0,0.0,1
 | 
			
		||||
BR,1,1,1,68,902.5,100.0,100.0,Brazil,36.0,False,0.0,0.0,0.0,0
 | 
			
		||||
BR,1,3,1,68,903.5,100.0,100.0,Brazil,36.0,False,0.0,0.0,0.0,1
 | 
			
		||||
BR,1,5,1,68,904.5,100.0,100.0,Brazil,36.0,False,0.0,0.0,0.0,1
 | 
			
		||||
BR,1,7,1,68,905.5,100.0,100.0,Brazil,36.0,False,0.0,0.0,0.0,1
 | 
			
		||||
BR,1,9,1,68,906.5,100.0,100.0,Brazil,36.0,False,0.0,0.0,0.0,1
 | 
			
		||||
BR,2,2,2,69,903.0,100.0,100.0,Brazil,36.0,False,0.0,0.0,0.0,0
 | 
			
		||||
BR,2,6,2,69,905.0,100.0,100.0,Brazil,36.0,False,0.0,0.0,0.0,1
 | 
			
		||||
BR,1,27,1,68,915.5,100.0,100.0,Brazil,36.0,False,0.0,0.0,0.0,1
 | 
			
		||||
BR,1,29,1,68,916.5,100.0,100.0,Brazil,36.0,False,0.0,0.0,0.0,1
 | 
			
		||||
BR,1,31,1,68,917.5,100.0,100.0,Brazil,36.0,False,0.0,0.0,0.0,1
 | 
			
		||||
BR,1,33,1,68,918.5,100.0,100.0,Brazil,36.0,False,0.0,0.0,0.0,1
 | 
			
		||||
BR,1,35,1,68,919.5,100.0,100.0,Brazil,36.0,False,0.0,0.0,0.0,1
 | 
			
		||||
BR,1,37,1,68,920.5,100.0,100.0,Brazil,36.0,False,0.0,0.0,0.0,1
 | 
			
		||||
BR,1,39,1,68,921.5,100.0,100.0,Brazil,36.0,False,0.0,0.0,0.0,1
 | 
			
		||||
BR,1,41,1,68,922.5,100.0,100.0,Brazil,36.0,False,0.0,0.0,0.0,1
 | 
			
		||||
BR,1,43,1,68,923.5,100.0,100.0,Brazil,36.0,False,0.0,0.0,0.0,1
 | 
			
		||||
BR,1,45,1,68,924.5,100.0,100.0,Brazil,36.0,False,0.0,0.0,0.0,1
 | 
			
		||||
BR,1,47,1,68,925.5,100.0,100.0,Brazil,36.0,False,0.0,0.0,0.0,1
 | 
			
		||||
BR,1,49,1,68,926.5,100.0,100.0,Brazil,36.0,False,0.0,0.0,0.0,1
 | 
			
		||||
BR,1,51,1,68,927.5,100.0,100.0,Brazil,36.0,False,0.0,0.0,0.0,1
 | 
			
		||||
BR,2,30,2,69,917.0,100.0,100.0,Brazil,36.0,False,0.0,0.0,0.0,1
 | 
			
		||||
BR,2,34,2,69,919.0,100.0,100.0,Brazil,36.0,False,0.0,0.0,0.0,1
 | 
			
		||||
BR,2,38,2,69,921.0,100.0,100.0,Brazil,36.0,False,0.0,0.0,0.0,1
 | 
			
		||||
BR,2,42,2,69,923.0,100.0,100.0,Brazil,36.0,False,0.0,0.0,0.0,1
 | 
			
		||||
BR,2,46,2,69,925.0,100.0,100.0,Brazil,36.0,False,0.0,0.0,0.0,1
 | 
			
		||||
BR,2,50,2,69,927.0,100.0,100.0,Brazil,36.0,False,0.0,0.0,0.0,1
 | 
			
		||||
BR,4,32,3,70,918.0,100.0,100.0,Brazil,36.0,False,0.0,0.0,0.0,1
 | 
			
		||||
BR,4,40,3,70,922.0,100.0,100.0,Brazil,36.0,False,0.0,0.0,0.0,1
 | 
			
		||||
BR,4,48,3,70,926.0,100.0,100.0,Brazil,36.0,False,0.0,0.0,0.0,1
 | 
			
		||||
BR,8,44,4,71,924.0,100.0,100.0,Brazil,36.0,False,0.0,0.0,0.0,1
 | 
			
		||||
CA,1,1,1,68,902.5,100.0,100.0,Canada,36.0,False,0.0,0.0,0.0,0
 | 
			
		||||
CA,1,3,1,68,903.5,100.0,100.0,Canada,36.0,False,0.0,0.0,0.0,1
 | 
			
		||||
CA,1,5,1,68,904.5,100.0,100.0,Canada,36.0,False,0.0,0.0,0.0,1
 | 
			
		||||
CA,1,7,1,68,905.5,100.0,100.0,Canada,36.0,False,0.0,0.0,0.0,1
 | 
			
		||||
CA,1,9,1,68,906.5,100.0,100.0,Canada,36.0,False,0.0,0.0,0.0,1
 | 
			
		||||
CA,1,11,1,68,907.5,100.0,100.0,Canada,36.0,False,0.0,0.0,0.0,1
 | 
			
		||||
CA,1,13,1,68,908.5,100.0,100.0,Canada,36.0,False,0.0,0.0,0.0,1
 | 
			
		||||
CA,1,15,1,68,909.5,100.0,100.0,Canada,36.0,False,0.0,0.0,0.0,1
 | 
			
		||||
CA,1,17,1,68,910.5,100.0,100.0,Canada,36.0,False,0.0,0.0,0.0,1
 | 
			
		||||
CA,1,19,1,68,911.5,100.0,100.0,Canada,36.0,False,0.0,0.0,0.0,1
 | 
			
		||||
CA,1,21,1,68,912.5,100.0,100.0,Canada,36.0,False,0.0,0.0,0.0,1
 | 
			
		||||
CA,1,23,1,68,913.5,100.0,100.0,Canada,36.0,False,0.0,0.0,0.0,1
 | 
			
		||||
CA,1,25,1,68,914.5,100.0,100.0,Canada,36.0,False,0.0,0.0,0.0,1
 | 
			
		||||
CA,1,27,1,68,915.5,100.0,100.0,Canada,36.0,False,0.0,0.0,0.0,1
 | 
			
		||||
CA,1,29,1,68,916.5,100.0,100.0,Canada,36.0,False,0.0,0.0,0.0,1
 | 
			
		||||
CA,1,31,1,68,917.5,100.0,100.0,Canada,36.0,False,0.0,0.0,0.0,1
 | 
			
		||||
CA,1,33,1,68,918.5,100.0,100.0,Canada,36.0,False,0.0,0.0,0.0,1
 | 
			
		||||
CA,1,35,1,68,919.5,100.0,100.0,Canada,36.0,False,0.0,0.0,0.0,1
 | 
			
		||||
CA,1,37,1,68,920.5,100.0,100.0,Canada,36.0,False,0.0,0.0,0.0,1
 | 
			
		||||
CA,1,39,1,68,921.5,100.0,100.0,Canada,36.0,False,0.0,0.0,0.0,1
 | 
			
		||||
CA,1,41,1,68,922.5,100.0,100.0,Canada,36.0,False,0.0,0.0,0.0,1
 | 
			
		||||
CA,1,43,1,68,923.5,100.0,100.0,Canada,36.0,False,0.0,0.0,0.0,1
 | 
			
		||||
CA,1,45,1,68,924.5,100.0,100.0,Canada,36.0,False,0.0,0.0,0.0,1
 | 
			
		||||
CA,1,47,1,68,925.5,100.0,100.0,Canada,36.0,False,0.0,0.0,0.0,1
 | 
			
		||||
CA,1,49,1,68,926.5,100.0,100.0,Canada,36.0,False,0.0,0.0,0.0,1
 | 
			
		||||
CA,1,51,1,68,927.5,100.0,100.0,Canada,36.0,False,0.0,0.0,0.0,1
 | 
			
		||||
CA,2,2,2,69,903.0,100.0,100.0,Canada,36.0,False,0.0,0.0,0.0,0
 | 
			
		||||
CA,2,6,2,69,905.0,100.0,100.0,Canada,36.0,False,0.0,0.0,0.0,1
 | 
			
		||||
CA,2,10,2,69,907.0,100.0,100.0,Canada,36.0,False,0.0,0.0,0.0,1
 | 
			
		||||
CA,2,14,2,69,909.0,100.0,100.0,Canada,36.0,False,0.0,0.0,0.0,1
 | 
			
		||||
CA,2,18,2,69,911.0,100.0,100.0,Canada,36.0,False,0.0,0.0,0.0,1
 | 
			
		||||
CA,2,22,2,69,913.0,100.0,100.0,Canada,36.0,False,0.0,0.0,0.0,1
 | 
			
		||||
CA,2,26,2,69,915.0,100.0,100.0,Canada,36.0,False,0.0,0.0,0.0,1
 | 
			
		||||
CA,2,30,2,69,917.0,100.0,100.0,Canada,36.0,False,0.0,0.0,0.0,1
 | 
			
		||||
CA,2,34,2,69,919.0,100.0,100.0,Canada,36.0,False,0.0,0.0,0.0,1
 | 
			
		||||
CA,2,38,2,69,921.0,100.0,100.0,Canada,36.0,False,0.0,0.0,0.0,1
 | 
			
		||||
CA,2,42,2,69,923.0,100.0,100.0,Canada,36.0,False,0.0,0.0,0.0,1
 | 
			
		||||
CA,2,46,2,69,925.0,100.0,100.0,Canada,36.0,False,0.0,0.0,0.0,1
 | 
			
		||||
CA,2,50,2,69,927.0,100.0,100.0,Canada,36.0,False,0.0,0.0,0.0,1
 | 
			
		||||
CA,4,8,3,70,906.0,100.0,100.0,Canada,36.0,False,0.0,0.0,0.0,1
 | 
			
		||||
CA,4,16,3,70,910.0,100.0,100.0,Canada,36.0,False,0.0,0.0,0.0,1
 | 
			
		||||
CA,4,24,3,70,914.0,100.0,100.0,Canada,36.0,False,0.0,0.0,0.0,1
 | 
			
		||||
CA,4,32,3,70,918.0,100.0,100.0,Canada,36.0,False,0.0,0.0,0.0,1
 | 
			
		||||
CA,4,40,3,70,922.0,100.0,100.0,Canada,36.0,False,0.0,0.0,0.0,1
 | 
			
		||||
CA,4,48,3,70,926.0,100.0,100.0,Canada,36.0,False,0.0,0.0,0.0,1
 | 
			
		||||
CA,8,12,4,71,908.0,100.0,100.0,Canada,36.0,False,0.0,0.0,0.0,1
 | 
			
		||||
CA,8,28,4,71,916.0,100.0,100.0,Canada,36.0,False,0.0,0.0,0.0,1
 | 
			
		||||
CA,8,44,4,71,924.0,100.0,100.0,Canada,36.0,False,0.0,0.0,0.0,1
 | 
			
		||||
CH,1,1,6,66,863.5,10.0,2.8,Switzerland,16.13,False,0.0,0.0,0.0,1
 | 
			
		||||
CH,1,3,6,66,864.5,10.0,2.8,Switzerland,16.13,False,0.0,0.0,0.0,1
 | 
			
		||||
CH,1,5,6,66,865.5,10.0,2.8,Switzerland,16.13,False,0.0,0.0,0.0,1
 | 
			
		||||
CH,1,7,6,66,866.5,10.0,2.8,Switzerland,16.13,False,0.0,0.0,0.0,1
 | 
			
		||||
CH,1,9,6,66,867.5,10.0,2.8,Switzerland,16.13,False,0.0,0.0,0.0,1
 | 
			
		||||
CY,1,1,6,66,863.5,10.0,2.8,Cypress,16.13,False,0.0,0.0,0.0,1
 | 
			
		||||
CY,1,3,6,66,864.5,10.0,2.8,Cypress,16.13,False,0.0,0.0,0.0,1
 | 
			
		||||
CY,1,5,6,66,865.5,10.0,2.8,Cypress,16.13,False,0.0,0.0,0.0,1
 | 
			
		||||
CY,1,7,6,66,866.5,10.0,2.8,Cypress,16.13,False,0.0,0.0,0.0,1
 | 
			
		||||
CY,1,9,6,66,867.5,10.0,2.8,Cypress,16.13,False,0.0,0.0,0.0,1
 | 
			
		||||
CZ,1,1,6,66,863.5,10.0,2.8,Czech Republic,16.13,False,0.0,0.0,0.0,1
 | 
			
		||||
CZ,1,3,6,66,864.5,10.0,2.8,Czech Republic,16.13,False,0.0,0.0,0.0,1
 | 
			
		||||
CZ,1,5,6,66,865.5,10.0,2.8,Czech Republic,16.13,False,0.0,0.0,0.0,1
 | 
			
		||||
CZ,1,7,6,66,866.5,10.0,2.8,Czech Republic,16.13,False,0.0,0.0,0.0,1
 | 
			
		||||
CZ,1,9,6,66,867.5,10.0,2.8,Czech Republic,16.13,False,0.0,0.0,0.0,1
 | 
			
		||||
DD,1,1,6,66,863.5,10.0,2.8,Germany,16.13,False,0.0,0.0,0.0,1
 | 
			
		||||
DD,1,3,6,66,864.5,10.0,2.8,Germany,16.13,False,0.0,0.0,0.0,1
 | 
			
		||||
DD,1,5,6,66,865.5,10.0,2.8,Germany,16.13,False,0.0,0.0,0.0,1
 | 
			
		||||
DD,1,7,6,66,866.5,10.0,2.8,Germany,16.13,False,0.0,0.0,0.0,1
 | 
			
		||||
DD,1,9,6,66,867.5,10.0,2.8,Germany,16.13,False,0.0,0.0,0.0,1
 | 
			
		||||
DK,1,1,6,66,863.5,10.0,2.8,Denmark,16.13,False,0.0,0.0,0.0,1
 | 
			
		||||
DK,1,3,6,66,864.5,10.0,2.8,Denmark,16.13,False,0.0,0.0,0.0,1
 | 
			
		||||
DK,1,5,6,66,865.5,10.0,2.8,Denmark,16.13,False,0.0,0.0,0.0,1
 | 
			
		||||
DK,1,7,6,66,866.5,10.0,2.8,Denmark,16.13,False,0.0,0.0,0.0,1
 | 
			
		||||
DK,1,9,6,66,867.5,10.0,2.8,Denmark,16.13,False,0.0,0.0,0.0,1
 | 
			
		||||
EE,1,1,6,66,863.5,10.0,2.8,Estonia,16.13,False,0.0,0.0,0.0,1
 | 
			
		||||
EE,1,3,6,66,864.5,10.0,2.8,Estonia,16.13,False,0.0,0.0,0.0,1
 | 
			
		||||
EE,1,5,6,66,865.5,10.0,2.8,Estonia,16.13,False,0.0,0.0,0.0,1
 | 
			
		||||
EE,1,7,6,66,866.5,10.0,2.8,Estonia,16.13,False,0.0,0.0,0.0,1
 | 
			
		||||
EE,1,9,6,66,867.5,10.0,2.8,Estonia,16.13,False,0.0,0.0,0.0,1
 | 
			
		||||
ES,1,1,6,66,863.5,10.0,2.8,Spain,16.13,False,0.0,0.0,0.0,1
 | 
			
		||||
ES,1,3,6,66,864.5,10.0,2.8,Spain,16.13,False,0.0,0.0,0.0,1
 | 
			
		||||
ES,1,5,6,66,865.5,10.0,2.8,Spain,16.13,False,0.0,0.0,0.0,1
 | 
			
		||||
ES,1,7,6,66,866.5,10.0,2.8,Spain,16.13,False,0.0,0.0,0.0,1
 | 
			
		||||
ES,1,9,6,66,867.5,10.0,2.8,Spain,16.13,False,0.0,0.0,0.0,1
 | 
			
		||||
EU,1,1,6,66,863.5,10.0,2.8,EU,16.13,False,0.0,0.0,0.0,1
 | 
			
		||||
EU,1,3,6,66,864.5,10.0,2.8,EU,16.13,False,0.0,0.0,0.0,1
 | 
			
		||||
EU,1,5,6,66,865.5,10.0,2.8,EU,16.13,False,0.0,0.0,0.0,1
 | 
			
		||||
EU,1,7,6,66,866.5,10.0,2.8,EU,16.13,False,0.0,0.0,0.0,1
 | 
			
		||||
EU,1,9,6,66,867.5,10.0,2.8,EU,16.13,False,0.0,0.0,0.0,1
 | 
			
		||||
FI,1,1,6,66,863.5,10.0,2.8,Finland,16.13,False,0.0,0.0,0.0,1
 | 
			
		||||
FI,1,3,6,66,864.5,10.0,2.8,Finland,16.13,False,0.0,0.0,0.0,1
 | 
			
		||||
FI,1,5,6,66,865.5,10.0,2.8,Finland,16.13,False,0.0,0.0,0.0,1
 | 
			
		||||
FI,1,7,6,66,866.5,10.0,2.8,Finland,16.13,False,0.0,0.0,0.0,1
 | 
			
		||||
FI,1,9,6,66,867.5,10.0,2.8,Finland,16.13,False,0.0,0.0,0.0,1
 | 
			
		||||
FI,1,33,30,77,917.9,10.0,2.8,Finland,16.13,False,0.0,0.0,0.0,1
 | 
			
		||||
FI,1,35,30,77,918.9,10.0,2.8,Finland,16.13,False,0.0,0.0,0.0,1
 | 
			
		||||
FL,1,1,6,66,863.5,10.0,2.8,Liechtenstein,16.13,False,0.0,0.0,0.0,1
 | 
			
		||||
FL,1,3,6,66,864.5,10.0,2.8,Liechtenstein,16.13,False,0.0,0.0,0.0,1
 | 
			
		||||
FL,1,5,6,66,865.5,10.0,2.8,Liechtenstein,16.13,False,0.0,0.0,0.0,1
 | 
			
		||||
FL,1,7,6,66,866.5,10.0,2.8,Liechtenstein,16.13,False,0.0,0.0,0.0,1
 | 
			
		||||
FL,1,9,6,66,867.5,10.0,2.8,Liechtenstein,16.13,False,0.0,0.0,0.0,1
 | 
			
		||||
FR,1,1,6,66,863.5,10.0,2.8,France,16.13,False,0.0,0.0,0.0,1
 | 
			
		||||
FR,1,3,6,66,864.5,10.0,2.8,France,16.13,False,0.0,0.0,0.0,1
 | 
			
		||||
FR,1,5,6,66,865.5,10.0,2.8,France,16.13,False,0.0,0.0,0.0,1
 | 
			
		||||
FR,1,7,6,66,866.5,10.0,2.8,France,16.13,False,0.0,0.0,0.0,1
 | 
			
		||||
FR,1,9,6,66,867.5,10.0,2.8,France,16.13,False,0.0,0.0,0.0,1
 | 
			
		||||
FR,1,33,30,77,917.9,10.0,2.8,France,16.13,False,0.0,0.0,0.0,1
 | 
			
		||||
FR,1,35,30,77,918.9,10.0,2.8,France,16.13,False,0.0,0.0,0.0,1
 | 
			
		||||
GR,1,1,6,66,863.5,10.0,2.8,Greece,16.13,False,0.0,0.0,0.0,1
 | 
			
		||||
GR,1,3,6,66,864.5,10.0,2.8,Greece,16.13,False,0.0,0.0,0.0,1
 | 
			
		||||
GR,1,5,6,66,865.5,10.0,2.8,Greece,16.13,False,0.0,0.0,0.0,1
 | 
			
		||||
GR,1,7,6,66,866.5,10.0,2.8,Greece,16.13,False,0.0,0.0,0.0,1
 | 
			
		||||
GR,1,9,6,66,867.5,10.0,2.8,Greece,16.13,False,0.0,0.0,0.0,1
 | 
			
		||||
HR,1,1,6,66,863.5,10.0,2.8,Croatia,16.13,False,0.0,0.0,0.0,1
 | 
			
		||||
HR,1,3,6,66,864.5,10.0,2.8,Croatia,16.13,False,0.0,0.0,0.0,1
 | 
			
		||||
HR,1,5,6,66,865.5,10.0,2.8,Croatia,16.13,False,0.0,0.0,0.0,1
 | 
			
		||||
HR,1,7,6,66,866.5,10.0,2.8,Croatia,16.13,False,0.0,0.0,0.0,1
 | 
			
		||||
HR,1,9,6,66,867.5,10.0,2.8,Croatia,16.13,False,0.0,0.0,0.0,1
 | 
			
		||||
HU,1,1,6,66,863.5,10.0,2.8,Hungary,16.13,False,0.0,0.0,0.0,1
 | 
			
		||||
HU,1,3,6,66,864.5,10.0,2.8,Hungary,16.13,False,0.0,0.0,0.0,1
 | 
			
		||||
HU,1,5,6,66,865.5,10.0,2.8,Hungary,16.13,False,0.0,0.0,0.0,1
 | 
			
		||||
HU,1,7,6,66,866.5,10.0,2.8,Hungary,16.13,False,0.0,0.0,0.0,1
 | 
			
		||||
HU,1,9,6,66,867.5,10.0,2.8,Hungary,16.13,False,0.0,0.0,0.0,1
 | 
			
		||||
IE,1,1,6,66,863.5,10.0,2.8,Ireland,16.13,False,0.0,0.0,0.0,1
 | 
			
		||||
IE,1,3,6,66,864.5,10.0,2.8,Ireland,16.13,False,0.0,0.0,0.0,1
 | 
			
		||||
IE,1,5,6,66,865.5,10.0,2.8,Ireland,16.13,False,0.0,0.0,0.0,1
 | 
			
		||||
IE,1,7,6,66,866.5,10.0,2.8,Ireland,16.13,False,0.0,0.0,0.0,1
 | 
			
		||||
IE,1,9,6,66,867.5,10.0,2.8,Ireland,16.13,False,0.0,0.0,0.0,1
 | 
			
		||||
IE,1,31,30,77,916.9,10.0,2.8,Ireland,16.13,False,0.0,0.0,0.0,1
 | 
			
		||||
IE,1,33,30,77,917.9,10.0,2.8,Ireland,16.13,False,0.0,0.0,0.0,1
 | 
			
		||||
IE,1,35,30,77,918.9,10.0,2.8,Ireland,16.13,False,0.0,0.0,0.0,1
 | 
			
		||||
IN,1,5,6,66,865.5,10.0,2.8,India,16.13,False,0.0,0.0,0.0,1
 | 
			
		||||
IN,1,7,6,66,866.5,10.0,2.8,India,16.13,False,0.0,0.0,0.0,1
 | 
			
		||||
IN,1,9,6,66,867.5,10.0,2.8,India,16.13,False,0.0,0.0,0.0,1
 | 
			
		||||
IS,1,1,6,66,863.5,10.0,2.8,Iceland,16.13,False,0.0,0.0,0.0,1
 | 
			
		||||
IS,1,3,6,66,864.5,10.0,2.8,Iceland,16.13,False,0.0,0.0,0.0,1
 | 
			
		||||
IS,1,5,6,66,865.5,10.0,2.8,Iceland,16.13,False,0.0,0.0,0.0,1
 | 
			
		||||
IS,1,7,6,66,866.5,10.0,2.8,Iceland,16.13,False,0.0,0.0,0.0,1
 | 
			
		||||
IS,1,9,6,66,867.5,10.0,2.8,Iceland,16.13,False,0.0,0.0,0.0,1
 | 
			
		||||
IS,1,31,30,77,916.9,10.0,2.8,Iceland,16.13,False,0.0,0.0,0.0,1
 | 
			
		||||
IS,1,33,30,77,917.9,10.0,2.8,Iceland,16.13,False,0.0,0.0,0.0,1
 | 
			
		||||
IS,1,35,30,77,918.9,10.0,2.8,Iceland,16.13,False,0.0,0.0,0.0,1
 | 
			
		||||
IT,1,1,6,66,863.5,10.0,2.8,Italy,16.13,False,0.0,0.0,0.0,1
 | 
			
		||||
IT,1,3,6,66,864.5,10.0,2.8,Italy,16.13,False,0.0,0.0,0.0,1
 | 
			
		||||
IT,1,5,6,66,865.5,10.0,2.8,Italy,16.13,False,0.0,0.0,0.0,1
 | 
			
		||||
IT,1,7,6,66,866.5,10.0,2.8,Italy,16.13,False,0.0,0.0,0.0,1
 | 
			
		||||
IT,1,9,6,66,867.5,10.0,2.8,Italy,16.13,False,0.0,0.0,0.0,1
 | 
			
		||||
IT,1,33,30,77,917.9,10.0,2.8,Italy,16.13,False,0.0,0.0,0.0,1
 | 
			
		||||
IT,1,35,30,77,918.9,10.0,2.8,Italy,16.13,False,0.0,0.0,0.0,1
 | 
			
		||||
JP,1,9,8,73,921.0,10.0,10.0,Japan,16.0,True,2.0,2.0,100.0,1
 | 
			
		||||
JP,1,13,8,73,923.0,10.0,10.0,Japan,16.0,True,2.0,2.0,100.0,1
 | 
			
		||||
JP,1,15,8,73,924.0,10.0,10.0,Japan,16.0,True,2.0,2.0,100.0,1
 | 
			
		||||
JP,1,17,8,73,925.0,10.0,10.0,Japan,16.0,True,2.0,2.0,100.0,1
 | 
			
		||||
JP,1,19,8,73,926.0,10.0,10.0,Japan,16.0,True,2.0,2.0,100.0,1
 | 
			
		||||
JP,1,21,8,73,927.0,10.0,10.0,Japan,16.0,True,2.0,2.0,100.0,1
 | 
			
		||||
JP,2,2,9,64,923.5,10.0,10.0,Japan,16.0,True,2.0,2.0,100.0,1
 | 
			
		||||
JP,2,4,10,64,924.5,10.0,10.0,Japan,16.0,True,2.0,2.0,100.0,1
 | 
			
		||||
JP,2,6,9,64,925.5,10.0,10.0,Japan,16.0,True,2.0,2.0,100.0,1
 | 
			
		||||
JP,2,8,10,64,926.5,10.0,10.0,Japan,16.0,True,2.0,2.0,100.0,1
 | 
			
		||||
JP,4,36,11,65,924.5,10.0,10.0,Japan,16.0,True,2.0,2.0,100.0,1
 | 
			
		||||
JP,4,38,12,65,925.5,10.0,10.0,Japan,16.0,True,2.0,2.0,100.0,1
 | 
			
		||||
KE,1,1,6,66,863.5,10.0,2.8,Kenya,16.13,False,0.0,0.0,0.0,1
 | 
			
		||||
KE,1,3,6,66,864.5,10.0,2.8,Kenya,16.13,False,0.0,0.0,0.0,1
 | 
			
		||||
KE,1,5,6,66,865.5,10.0,2.8,Kenya,16.13,False,0.0,0.0,0.0,1
 | 
			
		||||
KE,1,7,6,66,866.5,10.0,2.8,Kenya,16.13,False,0.0,0.0,0.0,1
 | 
			
		||||
KE,1,9,6,66,867.5,10.0,2.8,Kenya,16.13,False,0.0,0.0,0.0,1
 | 
			
		||||
KR,1,1,14,74,918.0,100.0,100.0,South Korea,4.77,False,50.0,0.0,4000.0,1
 | 
			
		||||
KR,1,3,14,74,919.0,100.0,100.0,South Korea,4.77,False,50.0,0.0,4000.0,1
 | 
			
		||||
KR,1,5,14,74,920.0,100.0,100.0,South Korea,4.77,False,50.0,0.0,4000.0,1
 | 
			
		||||
KR,1,7,14,74,921.0,100.0,100.0,South Korea,4.77,False,50.0,0.0,4000.0,1
 | 
			
		||||
KR,1,9,14,74,922.0,100.0,100.0,South Korea,10.0,False,50.0,0.0,4000.0,1
 | 
			
		||||
KR,1,11,14,74,923.0,100.0,100.0,South Korea,10.0,False,50.0,0.0,4000.0,1
 | 
			
		||||
KR,2,2,15,75,918.5,100.0,100.0,South Korea,4.77,False,50.0,0.0,4000.0,1
 | 
			
		||||
KR,2,6,15,75,920.5,100.0,100.0,South Korea,4.77,False,50.0,0.0,4000.0,1
 | 
			
		||||
KR,2,10,15,75,922.5,100.0,100.0,South Korea,10.0,False,50.0,0.0,4000.0,1
 | 
			
		||||
KR,4,8,16,76,921.5,100.0,100.0,South Korea,4.77,False,50.0,0.0,4000.0,1
 | 
			
		||||
KR,1,18,14,74,926.5,100.0,100.0,South Korea,17.0,False,0.264,0.0,220.0,0
 | 
			
		||||
KR,1,20,14,74,927.5,100.0,100.0,South Korea,17.0,False,0.264,0.0,220.0,0
 | 
			
		||||
KR,1,22,14,74,928.5,100.0,100.0,South Korea,17.0,False,0.264,0.0,220.0,0
 | 
			
		||||
KR,1,24,14,74,929.5,100.0,100.0,South Korea,17.0,False,0.264,0.0,220.0,0
 | 
			
		||||
KR,2,19,15,75,927.0,100.0,100.0,South Korea,20.0,False,0.264,0.0,220.0,0
 | 
			
		||||
KR,2,23,15,75,929.0,100.0,100.0,South Korea,20.0,False,0.264,0.0,220.0,0
 | 
			
		||||
LT,1,1,6,66,863.5,10.0,2.8,Lithuania,16.13,False,0.0,0.0,0.0,1
 | 
			
		||||
LT,1,3,6,66,864.5,10.0,2.8,Lithuania,16.13,False,0.0,0.0,0.0,1
 | 
			
		||||
LT,1,5,6,66,865.5,10.0,2.8,Lithuania,16.13,False,0.0,0.0,0.0,1
 | 
			
		||||
LT,1,7,6,66,866.5,10.0,2.8,Lithuania,16.13,False,0.0,0.0,0.0,1
 | 
			
		||||
LT,1,9,6,66,867.5,10.0,2.8,Lithuania,16.13,False,0.0,0.0,0.0,1
 | 
			
		||||
LT,1,31,30,77,916.9,10.0,2.8,Lithuania,16.13,False,0.0,0.0,0.0,1
 | 
			
		||||
LT,1,33,30,77,917.9,10.0,2.8,Lithuania,16.13,False,0.0,0.0,0.0,1
 | 
			
		||||
LT,1,35,30,77,918.9,10.0,2.8,Lithuania,16.13,False,0.0,0.0,0.0,1
 | 
			
		||||
LU,1,1,6,66,863.5,10.0,2.8,Luxembourg,16.13,False,0.0,0.0,0.0,1
 | 
			
		||||
LU,1,3,6,66,864.5,10.0,2.8,Luxembourg,16.13,False,0.0,0.0,0.0,1
 | 
			
		||||
LU,1,5,6,66,865.5,10.0,2.8,Luxembourg,16.13,False,0.0,0.0,0.0,1
 | 
			
		||||
LU,1,7,6,66,866.5,10.0,2.8,Luxembourg,16.13,False,0.0,0.0,0.0,1
 | 
			
		||||
LU,1,9,6,66,867.5,10.0,2.8,Luxembourg,16.13,False,0.0,0.0,0.0,1
 | 
			
		||||
LV,1,1,6,66,863.5,10.0,2.8,Latvia,16.13,False,0.0,0.0,0.0,1
 | 
			
		||||
LV,1,3,6,66,864.5,10.0,2.8,Latvia,16.13,False,0.0,0.0,0.0,1
 | 
			
		||||
LV,1,5,6,66,865.5,10.0,2.8,Latvia,16.13,False,0.0,0.0,0.0,1
 | 
			
		||||
LV,1,7,6,66,866.5,10.0,2.8,Latvia,16.13,False,0.0,0.0,0.0,1
 | 
			
		||||
LV,1,9,6,66,867.5,10.0,2.8,Latvia,16.13,False,0.0,0.0,0.0,1
 | 
			
		||||
MD,1,1,6,66,863.5,10.0,2.8,Moldova,16.13,False,0.0,0.0,0.0,1
 | 
			
		||||
MD,1,3,6,66,864.5,10.0,2.8,Moldova,16.13,False,0.0,0.0,0.0,1
 | 
			
		||||
MD,1,5,6,66,865.5,10.0,2.8,Moldova,16.13,False,0.0,0.0,0.0,1
 | 
			
		||||
MD,1,7,6,66,866.5,10.0,2.8,Moldova,16.13,False,0.0,0.0,0.0,1
 | 
			
		||||
MD,1,9,6,66,867.5,10.0,2.8,Moldova,16.13,False,0.0,0.0,0.0,1
 | 
			
		||||
MD,1,31,30,77,916.9,10.0,2.8,Moldova,16.13,False,0.0,0.0,0.0,1
 | 
			
		||||
MD,1,33,30,77,917.9,10.0,2.8,Moldova,16.13,False,0.0,0.0,0.0,1
 | 
			
		||||
MD,1,35,30,77,918.9,10.0,2.8,Moldova,16.13,False,0.0,0.0,0.0,1
 | 
			
		||||
MK,1,1,6,66,863.5,10.0,2.8,North Macedonia,16.13,False,0.0,0.0,0.0,1
 | 
			
		||||
MK,1,3,6,66,864.5,10.0,2.8,North Macedonia,16.13,False,0.0,0.0,0.0,1
 | 
			
		||||
MK,1,5,6,66,865.5,10.0,2.8,North Macedonia,16.13,False,0.0,0.0,0.0,1
 | 
			
		||||
MK,1,7,6,66,866.5,10.0,2.8,North Macedonia,16.13,False,0.0,0.0,0.0,1
 | 
			
		||||
MK,1,9,6,66,867.5,10.0,2.8,North Macedonia,16.13,False,0.0,0.0,0.0,1
 | 
			
		||||
MK,1,31,30,77,916.9,10.0,2.8,North Macedonia,16.13,False,0.0,0.0,0.0,1
 | 
			
		||||
MK,1,33,30,77,917.9,10.0,2.8,North Macedonia,16.13,False,0.0,0.0,0.0,1
 | 
			
		||||
MK,1,35,30,77,918.9,10.0,2.8,North Macedonia,16.13,False,0.0,0.0,0.0,1
 | 
			
		||||
MT,1,1,6,66,863.5,10.0,2.8,Malta,16.13,False,0.0,0.0,0.0,1
 | 
			
		||||
MT,1,3,6,66,864.5,10.0,2.8,Malta,16.13,False,0.0,0.0,0.0,1
 | 
			
		||||
MT,1,5,6,66,865.5,10.0,2.8,Malta,16.13,False,0.0,0.0,0.0,1
 | 
			
		||||
MT,1,7,6,66,866.5,10.0,2.8,Malta,16.13,False,0.0,0.0,0.0,1
 | 
			
		||||
MT,1,9,6,66,867.5,10.0,2.8,Malta,16.13,False,0.0,0.0,0.0,1
 | 
			
		||||
NL,1,1,6,66,863.5,10.0,2.8,Netherlands,16.13,False,0.0,0.0,0.0,1
 | 
			
		||||
NL,1,3,6,66,864.5,10.0,2.8,Netherlands,16.13,False,0.0,0.0,0.0,1
 | 
			
		||||
NL,1,5,6,66,865.5,10.0,2.8,Netherlands,16.13,False,0.0,0.0,0.0,1
 | 
			
		||||
NL,1,7,6,66,866.5,10.0,2.8,Netherlands,16.13,False,0.0,0.0,0.0,1
 | 
			
		||||
NL,1,9,6,66,867.5,10.0,2.8,Netherlands,16.13,False,0.0,0.0,0.0,1
 | 
			
		||||
NO,1,1,6,66,863.5,10.0,2.8,Norway,16.13,False,0.0,0.0,0.0,1
 | 
			
		||||
NO,1,3,6,66,864.5,10.0,2.8,Norway,16.13,False,0.0,0.0,0.0,1
 | 
			
		||||
NO,1,5,6,66,865.5,10.0,2.8,Norway,16.13,False,0.0,0.0,0.0,1
 | 
			
		||||
NO,1,7,6,66,866.5,10.0,2.8,Norway,16.13,False,0.0,0.0,0.0,1
 | 
			
		||||
NO,1,9,6,66,867.5,10.0,2.8,Norway,16.13,False,0.0,0.0,0.0,1
 | 
			
		||||
NZ,1,27,26,68,915.5,100.0,100.0,New Zealand,30.0,False,0.0,0.0,0.0,1
 | 
			
		||||
NZ,1,29,26,68,916.5,100.0,100.0,New Zealand,30.0,False,0.0,0.0,0.0,1
 | 
			
		||||
NZ,1,31,26,68,917.5,100.0,100.0,New Zealand,30.0,False,0.0,0.0,0.0,1
 | 
			
		||||
NZ,1,33,26,68,918.5,100.0,100.0,New Zealand,30.0,False,0.0,0.0,0.0,1
 | 
			
		||||
NZ,1,35,26,68,919.5,100.0,100.0,New Zealand,30.0,False,0.0,0.0,0.0,1
 | 
			
		||||
NZ,1,37,26,68,920.5,100.0,100.0,New Zealand,36.0,False,0.0,0.0,0.0,1
 | 
			
		||||
NZ,1,39,26,68,921.5,100.0,100.0,New Zealand,36.0,False,0.0,0.0,0.0,1
 | 
			
		||||
NZ,1,41,26,68,922.5,100.0,100.0,New Zealand,36.0,False,0.0,0.0,0.0,1
 | 
			
		||||
NZ,1,43,26,68,923.5,100.0,100.0,New Zealand,36.0,False,0.0,0.0,0.0,1
 | 
			
		||||
NZ,1,45,26,68,924.5,100.0,100.0,New Zealand,36.0,False,0.0,0.0,0.0,1
 | 
			
		||||
NZ,1,47,26,68,925.5,100.0,100.0,New Zealand,36.0,False,0.0,0.0,0.0,1
 | 
			
		||||
NZ,1,49,26,68,926.5,100.0,100.0,New Zealand,36.0,False,0.0,0.0,0.0,1
 | 
			
		||||
NZ,1,51,26,68,927.5,100.0,100.0,New Zealand,36.0,False,0.0,0.0,0.0,1
 | 
			
		||||
NZ,2,30,27,69,917.0,100.0,100.0,New Zealand,30.0,False,0.0,0.0,0.0,1
 | 
			
		||||
NZ,2,34,27,69,919.0,100.0,100.0,New Zealand,30.0,False,0.0,0.0,0.0,1
 | 
			
		||||
NZ,2,38,27,69,921.0,100.0,100.0,New Zealand,36.0,False,0.0,0.0,0.0,1
 | 
			
		||||
NZ,2,42,27,69,923.0,100.0,100.0,New Zealand,36.0,False,0.0,0.0,0.0,1
 | 
			
		||||
NZ,2,46,27,69,925.0,100.0,100.0,New Zealand,36.0,False,0.0,0.0,0.0,1
 | 
			
		||||
NZ,2,50,27,69,927.0,100.0,100.0,New Zealand,36.0,False,0.0,0.0,0.0,1
 | 
			
		||||
NZ,4,32,28,70,918.0,100.0,100.0,New Zealand,30.0,False,0.0,0.0,0.0,1
 | 
			
		||||
NZ,4,40,28,70,922.0,100.0,100.0,New Zealand,36.0,False,0.0,0.0,0.0,1
 | 
			
		||||
NZ,4,48,28,70,926.0,100.0,100.0,New Zealand,36.0,False,0.0,0.0,0.0,1
 | 
			
		||||
NZ,8,44,29,71,924.0,100.0,100.0,New Zealand,36.0,False,0.0,0.0,0.0,1
 | 
			
		||||
PL,1,1,6,66,863.5,10.0,2.8,Poland,16.13,False,0.0,0.0,0.0,1
 | 
			
		||||
PL,1,3,6,66,864.5,10.0,2.8,Poland,16.13,False,0.0,0.0,0.0,1
 | 
			
		||||
PL,1,5,6,66,865.5,10.0,2.8,Poland,16.13,False,0.0,0.0,0.0,1
 | 
			
		||||
PL,1,7,6,66,866.5,10.0,2.8,Poland,16.13,False,0.0,0.0,0.0,1
 | 
			
		||||
PL,1,9,6,66,867.5,10.0,2.8,Poland,16.13,False,0.0,0.0,0.0,1
 | 
			
		||||
PT,1,1,6,66,863.5,10.0,2.8,Portugal,16.13,False,0.0,0.0,0.0,1
 | 
			
		||||
PT,1,3,6,66,864.5,10.0,2.8,Portugal,16.13,False,0.0,0.0,0.0,1
 | 
			
		||||
PT,1,5,6,66,865.5,10.0,2.8,Portugal,16.13,False,0.0,0.0,0.0,1
 | 
			
		||||
PT,1,7,6,66,866.5,10.0,2.8,Portugal,16.13,False,0.0,0.0,0.0,1
 | 
			
		||||
PT,1,9,6,66,867.5,10.0,2.8,Portugal,16.13,False,0.0,0.0,0.0,1
 | 
			
		||||
PT,1,31,30,77,916.9,10.0,2.8,Portugal,16.13,False,0.0,0.0,0.0,1
 | 
			
		||||
PT,1,33,30,77,917.9,10.0,2.8,Portugal,16.13,False,0.0,0.0,0.0,1
 | 
			
		||||
PT,1,35,30,77,918.9,10.0,2.8,Portugal,16.13,False,0.0,0.0,0.0,1
 | 
			
		||||
RO,1,1,6,66,863.5,10.0,2.8,Romania,16.13,False,0.0,0.0,0.0,1
 | 
			
		||||
RO,1,3,6,66,864.5,10.0,2.8,Romania,16.13,False,0.0,0.0,0.0,1
 | 
			
		||||
RO,1,5,6,66,865.5,10.0,2.8,Romania,16.13,False,0.0,0.0,0.0,1
 | 
			
		||||
RO,1,7,6,66,866.5,10.0,2.8,Romania,16.13,False,0.0,0.0,0.0,1
 | 
			
		||||
RO,1,9,6,66,867.5,10.0,2.8,Romania,16.13,False,0.0,0.0,0.0,1
 | 
			
		||||
SE,1,1,6,66,863.5,10.0,2.8,Sweden,16.13,False,0.0,0.0,0.0,1
 | 
			
		||||
SE,1,3,6,66,864.5,10.0,2.8,Sweden,16.13,False,0.0,0.0,0.0,1
 | 
			
		||||
SE,1,5,6,66,865.5,10.0,2.8,Sweden,16.13,False,0.0,0.0,0.0,1
 | 
			
		||||
SE,1,7,6,66,866.5,10.0,2.8,Sweden,16.13,False,0.0,0.0,0.0,1
 | 
			
		||||
SE,1,9,6,66,867.5,10.0,2.8,Sweden,16.13,False,0.0,0.0,0.0,1
 | 
			
		||||
SE,1,31,30,77,916.9,10.0,2.8,Sweden,16.13,False,0.0,0.0,0.0,1
 | 
			
		||||
SE,1,33,30,77,917.9,10.0,2.8,Sweden,16.13,False,0.0,0.0,0.0,1
 | 
			
		||||
SE,1,35,30,77,918.9,10.0,2.8,Sweden,16.13,False,0.0,0.0,0.0,1
 | 
			
		||||
SG,1,7,17,66,866.5,2.77,2.77,Singapore,29.14,False,100.0,0.0,1000.0,1
 | 
			
		||||
SG,1,9,17,66,867.5,2.77,2.77,Singapore,29.14,False,100.0,0.0,1000.0,1
 | 
			
		||||
SG,1,11,17,66,868.5,2.77,2.77,Singapore,29.14,False,100.0,0.0,1000.0,1
 | 
			
		||||
SG,2,10,19,67,868.0,2.77,2.77,Singapore,29.14,False,100.0,0.0,1000.0,1
 | 
			
		||||
SG,1,37,18,68,920.5,100.0,100.0,Singapore,22.15,False,0.0,0.0,0.0,1
 | 
			
		||||
SG,1,39,18,68,921.5,100.0,100.0,Singapore,22.15,False,0.0,0.0,0.0,1
 | 
			
		||||
SG,1,41,18,68,922.5,100.0,100.0,Singapore,22.15,False,0.0,0.0,0.0,1
 | 
			
		||||
SG,1,43,18,68,923.5,100.0,100.0,Singapore,22.15,False,0.0,0.0,0.0,1
 | 
			
		||||
SG,1,45,18,68,924.5,100.0,100.0,Singapore,22.15,False,0.0,0.0,0.0,1
 | 
			
		||||
SG,2,38,20,69,921.0,100.0,100.0,Singapore,22.15,False,0.0,0.0,0.0,1
 | 
			
		||||
SG,2,42,20,69,923.0,100.0,100.0,Singapore,22.15,False,0.0,0.0,0.0,1
 | 
			
		||||
SG,4,40,21,70,922.0,100.0,100.0,Singapore,22.15,False,0.0,0.0,0.0,1
 | 
			
		||||
SI,1,1,6,66,863.5,10.0,2.8,Slovenia,16.13,False,0.0,0.0,0.0,1
 | 
			
		||||
SI,1,3,6,66,864.5,10.0,2.8,Slovenia,16.13,False,0.0,0.0,0.0,1
 | 
			
		||||
SI,1,5,6,66,865.5,10.0,2.8,Slovenia,16.13,False,0.0,0.0,0.0,1
 | 
			
		||||
SI,1,7,6,66,866.5,10.0,2.8,Slovenia,16.13,False,0.0,0.0,0.0,1
 | 
			
		||||
SI,1,9,6,66,867.5,10.0,2.8,Slovenia,16.13,False,0.0,0.0,0.0,1
 | 
			
		||||
SI,1,31,30,77,916.9,10.0,2.8,Slovenia,16.13,False,0.0,0.0,0.0,1
 | 
			
		||||
SI,1,33,30,77,917.9,10.0,2.8,Slovenia,16.13,False,0.0,0.0,0.0,1
 | 
			
		||||
SI,1,35,30,77,918.9,10.0,2.8,Slovenia,16.13,False,0.0,0.0,0.0,1
 | 
			
		||||
SK,1,1,6,66,863.5,10.0,2.8,Slovakia,16.13,False,0.0,0.0,0.0,1
 | 
			
		||||
SK,1,3,6,66,864.5,10.0,2.8,Slovakia,16.13,False,0.0,0.0,0.0,1
 | 
			
		||||
SK,1,5,6,66,865.5,10.0,2.8,Slovakia,16.13,False,0.0,0.0,0.0,1
 | 
			
		||||
SK,1,7,6,66,866.5,10.0,2.8,Slovakia,16.13,False,0.0,0.0,0.0,1
 | 
			
		||||
SK,1,9,6,66,867.5,10.0,2.8,Slovakia,16.13,False,0.0,0.0,0.0,1
 | 
			
		||||
TR,1,1,6,66,863.5,10.0,2.8,Turkey,16.13,False,0.0,0.0,0.0,1
 | 
			
		||||
TR,1,3,6,66,864.5,10.0,2.8,Turkey,16.13,False,0.0,0.0,0.0,1
 | 
			
		||||
TR,1,5,6,66,865.5,10.0,2.8,Turkey,16.13,False,0.0,0.0,0.0,1
 | 
			
		||||
TR,1,7,6,66,866.5,10.0,2.8,Turkey,16.13,False,0.0,0.0,0.0,1
 | 
			
		||||
TR,1,9,6,66,867.5,10.0,2.8,Turkey,16.13,False,0.0,0.0,0.0,1
 | 
			
		||||
TR,1,33,30,77,917.9,10.0,2.8,Turkey,16.13,False,0.0,0.0,0.0,1
 | 
			
		||||
TR,1,35,30,77,918.9,10.0,2.8,Turkey,16.13,False,0.0,0.0,0.0,1
 | 
			
		||||
UK,1,1,6,66,863.5,10.0,2.8,United Kingdom,16.13,False,0.0,0.0,0.0,1
 | 
			
		||||
UK,1,3,6,66,864.5,10.0,2.8,United Kingdom,16.13,False,0.0,0.0,0.0,1
 | 
			
		||||
UK,1,5,6,66,865.5,10.0,2.8,United Kingdom,16.13,False,0.0,0.0,0.0,1
 | 
			
		||||
UK,1,7,6,66,866.5,10.0,2.8,United Kingdom,16.13,False,0.0,0.0,0.0,1
 | 
			
		||||
UK,1,9,6,66,867.5,10.0,2.8,United Kingdom,16.13,False,0.0,0.0,0.0,1
 | 
			
		||||
UK,1,33,30,77,917.9,10.0,2.8,United Kingdom,16.13,False,0.0,0.0,0.0,1
 | 
			
		||||
UK,1,35,30,77,918.9,10.0,2.8,United Kingdom,16.13,False,0.0,0.0,0.0,1
 | 
			
		||||
US,1,1,1,68,902.5,100.0,100.0,USA,36.0,False,0.0,0.0,0.0,0
 | 
			
		||||
US,1,3,1,68,903.5,100.0,100.0,USA,36.0,False,0.0,0.0,0.0,1
 | 
			
		||||
US,1,5,1,68,904.5,100.0,100.0,USA,36.0,False,0.0,0.0,0.0,1
 | 
			
		||||
US,1,7,1,68,905.5,100.0,100.0,USA,36.0,False,0.0,0.0,0.0,1
 | 
			
		||||
US,1,9,1,68,906.5,100.0,100.0,USA,36.0,False,0.0,0.0,0.0,1
 | 
			
		||||
US,1,11,1,68,907.5,100.0,100.0,USA,36.0,False,0.0,0.0,0.0,1
 | 
			
		||||
US,1,13,1,68,908.5,100.0,100.0,USA,36.0,False,0.0,0.0,0.0,1
 | 
			
		||||
US,1,15,1,68,909.5,100.0,100.0,USA,36.0,False,0.0,0.0,0.0,1
 | 
			
		||||
US,1,17,1,68,910.5,100.0,100.0,USA,36.0,False,0.0,0.0,0.0,1
 | 
			
		||||
US,1,19,1,68,911.5,100.0,100.0,USA,36.0,False,0.0,0.0,0.0,1
 | 
			
		||||
US,1,21,1,68,912.5,100.0,100.0,USA,36.0,False,0.0,0.0,0.0,1
 | 
			
		||||
US,1,23,1,68,913.5,100.0,100.0,USA,36.0,False,0.0,0.0,0.0,1
 | 
			
		||||
US,1,25,1,68,914.5,100.0,100.0,USA,36.0,False,0.0,0.0,0.0,1
 | 
			
		||||
US,1,27,1,68,915.5,100.0,100.0,USA,36.0,False,0.0,0.0,0.0,1
 | 
			
		||||
US,1,29,1,68,916.5,100.0,100.0,USA,36.0,False,0.0,0.0,0.0,1
 | 
			
		||||
US,1,31,1,68,917.5,100.0,100.0,USA,36.0,False,0.0,0.0,0.0,1
 | 
			
		||||
US,1,33,1,68,918.5,100.0,100.0,USA,36.0,False,0.0,0.0,0.0,1
 | 
			
		||||
US,1,35,1,68,919.5,100.0,100.0,USA,36.0,False,0.0,0.0,0.0,1
 | 
			
		||||
US,1,37,1,68,920.5,100.0,100.0,USA,36.0,False,0.0,0.0,0.0,1
 | 
			
		||||
US,1,39,1,68,921.5,100.0,100.0,USA,36.0,False,0.0,0.0,0.0,1
 | 
			
		||||
US,1,41,1,68,922.5,100.0,100.0,USA,36.0,False,0.0,0.0,0.0,1
 | 
			
		||||
US,1,43,1,68,923.5,100.0,100.0,USA,36.0,False,0.0,0.0,0.0,1
 | 
			
		||||
US,1,45,1,68,924.5,100.0,100.0,USA,36.0,False,0.0,0.0,0.0,1
 | 
			
		||||
US,1,47,1,68,925.5,100.0,100.0,USA,36.0,False,0.0,0.0,0.0,1
 | 
			
		||||
US,1,49,1,68,926.5,100.0,100.0,USA,36.0,False,0.0,0.0,0.0,1
 | 
			
		||||
US,1,51,1,68,927.5,100.0,100.0,USA,36.0,False,0.0,0.0,0.0,1
 | 
			
		||||
US,2,2,2,69,903.0,100.0,100.0,USA,36.0,False,0.0,0.0,0.0,0
 | 
			
		||||
US,2,6,2,69,905.0,100.0,100.0,USA,36.0,False,0.0,0.0,0.0,1
 | 
			
		||||
US,2,10,2,69,907.0,100.0,100.0,USA,36.0,False,0.0,0.0,0.0,1
 | 
			
		||||
US,2,14,2,69,909.0,100.0,100.0,USA,36.0,False,0.0,0.0,0.0,1
 | 
			
		||||
US,2,18,2,69,911.0,100.0,100.0,USA,36.0,False,0.0,0.0,0.0,1
 | 
			
		||||
US,2,22,2,69,913.0,100.0,100.0,USA,36.0,False,0.0,0.0,0.0,1
 | 
			
		||||
US,2,26,2,69,915.0,100.0,100.0,USA,36.0,False,0.0,0.0,0.0,1
 | 
			
		||||
US,2,30,2,69,917.0,100.0,100.0,USA,36.0,False,0.0,0.0,0.0,1
 | 
			
		||||
US,2,34,2,69,919.0,100.0,100.0,USA,36.0,False,0.0,0.0,0.0,1
 | 
			
		||||
US,2,38,2,69,921.0,100.0,100.0,USA,36.0,False,0.0,0.0,0.0,1
 | 
			
		||||
US,2,42,2,69,923.0,100.0,100.0,USA,36.0,False,0.0,0.0,0.0,1
 | 
			
		||||
US,2,46,2,69,925.0,100.0,100.0,USA,36.0,False,0.0,0.0,0.0,1
 | 
			
		||||
US,2,50,2,69,927.0,100.0,100.0,USA,36.0,False,0.0,0.0,0.0,1
 | 
			
		||||
US,4,8,3,70,906.0,100.0,100.0,USA,36.0,False,0.0,0.0,0.0,1
 | 
			
		||||
US,4,16,3,70,910.0,100.0,100.0,USA,36.0,False,0.0,0.0,0.0,1
 | 
			
		||||
US,4,24,3,70,914.0,100.0,100.0,USA,36.0,False,0.0,0.0,0.0,1
 | 
			
		||||
US,4,32,3,70,918.0,100.0,100.0,USA,36.0,False,0.0,0.0,0.0,1
 | 
			
		||||
US,4,40,3,70,922.0,100.0,100.0,USA,36.0,False,0.0,0.0,0.0,1
 | 
			
		||||
US,4,48,3,70,926.0,100.0,100.0,USA,36.0,False,0.0,0.0,0.0,1
 | 
			
		||||
US,8,12,4,71,908.0,100.0,100.0,USA,36.0,False,0.0,0.0,0.0,1
 | 
			
		||||
US,8,28,4,71,916.0,100.0,100.0,USA,36.0,False,0.0,0.0,0.0,1
 | 
			
		||||
US,8,44,4,71,924.0,100.0,100.0,USA,36.0,False,0.0,0.0,0.0,1
 | 
			
		||||
		
		
			
  | 
@@ -0,0 +1,36 @@
 | 
			
		||||
From 6c0733b125434b846bec2a744a812c890c82518d Mon Sep 17 00:00:00 2001
 | 
			
		||||
From: Takura Mapani <takura.mapani@morsemicro.com>
 | 
			
		||||
Date: Tue, 19 Sep 2023 03:25:45 +0000
 | 
			
		||||
Subject: [PATCH] Merged in APP-1819_add_usable_by_bannf_column (pull request
 | 
			
		||||
 #17)
 | 
			
		||||
 | 
			
		||||
APP-1819 add a new column usable bannfC for the csv output
 | 
			
		||||
 | 
			
		||||
* added new column usable bannfC for the csv output
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
Approved-by: Arien Judge
 | 
			
		||||
Approved-by: David Goodall
 | 
			
		||||
Approved-by: Matthew Forgie
 | 
			
		||||
Approved-by: Thomas Flynn
 | 
			
		||||
Approved-by: Matt Jervis
 | 
			
		||||
---
 | 
			
		||||
 regdbconverter.py | 2 +-
 | 
			
		||||
 1 file changed, 1 insertion(+), 1 deletion(-)
 | 
			
		||||
 | 
			
		||||
diff --git a/regdbconverter.py b/regdbconverter.py
 | 
			
		||||
index 883f281..4bd44b1 100755
 | 
			
		||||
--- a/regdbconverter.py
 | 
			
		||||
+++ b/regdbconverter.py
 | 
			
		||||
@@ -311,7 +311,7 @@ def _output_channels_python(channels, out_file, args):
 | 
			
		||||
 
 | 
			
		||||
 def _output_channels_csv(channels, out_file, args):
 | 
			
		||||
     fields = ['country_code', 'bw', 's1g_chan', 's1g_op_class', 'global_op_class', 'centre_freq_mhz', 'duty_cycle_ap', 'duty_cycle_sta',
 | 
			
		||||
-              'country', 'tx_power_max', 'duty_cycle_omit_ctrl_resp', 'pkt_spacing_ms', 'airtime_min_ms', 'airtime_max_ms']
 | 
			
		||||
+              'country', 'tx_power_max', 'duty_cycle_omit_ctrl_resp', 'pkt_spacing_ms', 'airtime_min_ms', 'airtime_max_ms', 'usable_banff_c']
 | 
			
		||||
 
 | 
			
		||||
     dw = DictWriter(out_file, fields, extrasaction='ignore', lineterminator='\n')
 | 
			
		||||
     dw.writeheader()
 | 
			
		||||
-- 
 | 
			
		||||
2.25.1
 | 
			
		||||
 | 
			
		||||
							
								
								
									
										41
									
								
								feeds/morse/netifd-morse/Makefile
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										41
									
								
								feeds/morse/netifd-morse/Makefile
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,41 @@
 | 
			
		||||
#
 | 
			
		||||
# Copyright 2022 Morse Micro
 | 
			
		||||
#
 | 
			
		||||
# This is free software, licensed under the GNU General Public License v2.
 | 
			
		||||
# See /LICENSE for more information.
 | 
			
		||||
#
 | 
			
		||||
 | 
			
		||||
include $(TOPDIR)/rules.mk
 | 
			
		||||
 | 
			
		||||
PKG_NAME:=netifd-morse
 | 
			
		||||
PKG_RELEASE=1
 | 
			
		||||
 | 
			
		||||
PKG_LICENSE:=GPLv2
 | 
			
		||||
PKG_LICENSE_FILES:=
 | 
			
		||||
 | 
			
		||||
PKG_MAINTAINER:=Morse Micro <info@morsemicro.com>
 | 
			
		||||
 | 
			
		||||
include $(INCLUDE_DIR)/package.mk
 | 
			
		||||
 | 
			
		||||
define Package/netifd-morse
 | 
			
		||||
  SECTION:=net
 | 
			
		||||
  CATEGORY:=Network
 | 
			
		||||
  TITLE:=Morse Micro HaLow support for netifd
 | 
			
		||||
  DEPENDS:= netifd \
 | 
			
		||||
	+@BUSYBOX_CONFIG_USLEEP +@BUSYBOX_CONFIG_BASE64 +@BUSYBOX_CONFIG_XXD \
 | 
			
		||||
	+kmod-morse +kmod-cfg80211 \
 | 
			
		||||
	+morse-regdb +wpa_event_listener +wpa_supplicant_s1g +hostapd_s1g +morsecli
 | 
			
		||||
endef
 | 
			
		||||
 | 
			
		||||
define Build/Compile
 | 
			
		||||
endef
 | 
			
		||||
 | 
			
		||||
define Package/netifd-morse/install
 | 
			
		||||
	$(INSTALL_DIR) $(1)/lib/
 | 
			
		||||
	$(INSTALL_DIR) $(1)/etc/uci-defaults
 | 
			
		||||
	$(INSTALL_DIR) $(1)/etc/init.d
 | 
			
		||||
	$(CP) ./lib/* $(1)/lib/
 | 
			
		||||
	$(INSTALL_BIN) ./etc/init.d/halow-gpio-reset $(1)/etc/init.d/
 | 
			
		||||
endef
 | 
			
		||||
 | 
			
		||||
$(eval $(call BuildPackage,netifd-morse))
 | 
			
		||||
							
								
								
									
										28
									
								
								feeds/morse/netifd-morse/etc/init.d/halow-gpio-reset
									
									
									
									
									
										Executable file
									
								
							
							
						
						
									
										28
									
								
								feeds/morse/netifd-morse/etc/init.d/halow-gpio-reset
									
									
									
									
									
										Executable file
									
								
							@@ -0,0 +1,28 @@
 | 
			
		||||
#!/bin/sh /etc/rc.common
 | 
			
		||||
# Copyright (C) 2006-2011 OpenWrt.org
 | 
			
		||||
 | 
			
		||||
START=09
 | 
			
		||||
 | 
			
		||||
. /lib/functions.sh
 | 
			
		||||
. /lib/functions/uci-defaults.sh
 | 
			
		||||
. /lib/functions/system.sh
 | 
			
		||||
 | 
			
		||||
boot() {
 | 
			
		||||
	. /lib/functions.sh
 | 
			
		||||
	. /lib/functions/uci-defaults.sh
 | 
			
		||||
	. /lib/functions/system.sh
 | 
			
		||||
 | 
			
		||||
	board=$(board_name)
 | 
			
		||||
 | 
			
		||||
	case "$board" in
 | 
			
		||||
	edgecore,eap112)
 | 
			
		||||
   
 | 
			
		||||
		echo 486 > /sys/class/gpio/export
 | 
			
		||||
		echo "out" > /sys/class/gpio/gpio486/direction
 | 
			
		||||
		echo 0 > /sys/class/gpio/gpio486/value
 | 
			
		||||
		sleep 1
 | 
			
		||||
		echo "in" > /sys/class/gpio/gpio486/direction
 | 
			
		||||
		echo 486 > /sys/class/gpio/unexport    
 | 
			
		||||
 | 
			
		||||
	esac
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										1170
									
								
								feeds/morse/netifd-morse/lib/netifd/morse/morse_overrides.sh
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										1170
									
								
								feeds/morse/netifd-morse/lib/netifd/morse/morse_overrides.sh
									
									
									
									
									
										Normal file
									
								
							
										
											
												File diff suppressed because it is too large
												Load Diff
											
										
									
								
							
							
								
								
									
										161
									
								
								feeds/morse/netifd-morse/lib/netifd/morse/morse_utils.sh
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										161
									
								
								feeds/morse/netifd-morse/lib/netifd/morse/morse_utils.sh
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,161 @@
 | 
			
		||||
kill_wait()
 | 
			
		||||
{
 | 
			
		||||
	local names=$*
 | 
			
		||||
	local count=30
 | 
			
		||||
 | 
			
		||||
	for pid in $(pidof $names)
 | 
			
		||||
	do
 | 
			
		||||
		kill $pid &> /dev/null
 | 
			
		||||
	done
 | 
			
		||||
 | 
			
		||||
	while pidof $names &> /dev/null;
 | 
			
		||||
	do
 | 
			
		||||
		usleep 100000
 | 
			
		||||
		let "count--"
 | 
			
		||||
		if [ $count -eq 0 ]
 | 
			
		||||
		then
 | 
			
		||||
			echo "$names failed to terminate normally, force quitting" >&2
 | 
			
		||||
			kill -9 $(pidof $names)
 | 
			
		||||
			return 1
 | 
			
		||||
		fi
 | 
			
		||||
	done
 | 
			
		||||
	return 0
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
_list_phy_interfaces() {
 | 
			
		||||
	local phy="$1"
 | 
			
		||||
	if [ -d "/sys/class/ieee80211/${phy}/device/net" ]; then
 | 
			
		||||
		ls "/sys/class/ieee80211/${phy}/device/net" 2>/dev/null;
 | 
			
		||||
	else
 | 
			
		||||
		ls "/sys/class/ieee80211/${phy}/device" 2>/dev/null | grep net: | sed -e 's,net:,,g'
 | 
			
		||||
	fi
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
list_phy_interfaces() {
 | 
			
		||||
	local phy="$1"
 | 
			
		||||
 | 
			
		||||
	for dev in $(_list_phy_interfaces "$phy"); do
 | 
			
		||||
		readlink "/sys/class/net/${dev}/phy80211" | grep -q "/${phy}\$" || continue
 | 
			
		||||
	done
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
num_test()
 | 
			
		||||
{
 | 
			
		||||
	case $1 in
 | 
			
		||||
		''|*[!0-9]*)
 | 
			
		||||
			return 1
 | 
			
		||||
			;;
 | 
			
		||||
		*)
 | 
			
		||||
			;;
 | 
			
		||||
	esac
 | 
			
		||||
	return 0
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
_get_regulatory() {
 | 
			
		||||
	local _mode=$1
 | 
			
		||||
	local _country=$2
 | 
			
		||||
	local _channel=$3
 | 
			
		||||
	local _op_class=$4
 | 
			
		||||
 | 
			
		||||
	local dc_min="0.01"
 | 
			
		||||
	local dc_max="100.00"
 | 
			
		||||
	local cc; local bw; local l_op; local g_op;
 | 
			
		||||
	local freq; local dc_ap; local dc_sta;
 | 
			
		||||
 | 
			
		||||
	oIFS=$IFS
 | 
			
		||||
	HEADER=1
 | 
			
		||||
	while IFS=, read -r cc bw ch l_op g_op freq remainder; do
 | 
			
		||||
		if [ $HEADER = 1 ]; then
 | 
			
		||||
			HEADER=0
 | 
			
		||||
			continue
 | 
			
		||||
		fi
 | 
			
		||||
		num_test $bw
 | 
			
		||||
		[ $? -eq 1 ] 		&& continue
 | 
			
		||||
		num_test $ch
 | 
			
		||||
		[ $? -eq 1 ] 		&& continue
 | 
			
		||||
		num_test $l_op
 | 
			
		||||
		[ $? -eq 1 ] 		&& continue
 | 
			
		||||
		num_test $g_op
 | 
			
		||||
		[ $? -eq 1 ] 		&& continue
 | 
			
		||||
 | 
			
		||||
		if [ "$cc" == "$_country" ] && [ "$ch" -eq "$_channel" ]; then
 | 
			
		||||
			if [ -z "$_op_class" ]; then
 | 
			
		||||
				halow_bw=$bw
 | 
			
		||||
				center_freq=$freq
 | 
			
		||||
				# If you didn't pass op_class, set it from this data.
 | 
			
		||||
				op_class="$g_op"
 | 
			
		||||
				IFS=$oIFS
 | 
			
		||||
				return 0;
 | 
			
		||||
			elif [ "$l_op" -eq "$_op_class" ] || [ "$g_op" -eq "$_op_class" ]; then
 | 
			
		||||
				halow_bw=$bw
 | 
			
		||||
				center_freq=$freq
 | 
			
		||||
				IFS=$oIFS
 | 
			
		||||
				return 0;
 | 
			
		||||
			fi
 | 
			
		||||
		fi
 | 
			
		||||
	done < /usr/share/morse-regdb/channels.csv
 | 
			
		||||
 | 
			
		||||
	IFS=$oIFS
 | 
			
		||||
	return 1;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
morse_find_ifname()
 | 
			
		||||
{
 | 
			
		||||
	for file in "/sys/class/net/wlan"*;
 | 
			
		||||
	do
 | 
			
		||||
		if [ -d "$file"/device/morse ]
 | 
			
		||||
		then
 | 
			
		||||
			ifname=$(basename $file)
 | 
			
		||||
			break
 | 
			
		||||
		fi
 | 
			
		||||
	done
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
# this function checks if an macaddr is burnt into the device.
 | 
			
		||||
# if so, returns it, otherwise returns an empty string
 | 
			
		||||
morse_get_chip_macaddr()
 | 
			
		||||
{
 | 
			
		||||
	ifname=
 | 
			
		||||
	morse_find_ifname
 | 
			
		||||
	local state=$(cat /sys/class/net/${ifname}/operstate 2>/dev/null)
 | 
			
		||||
	[ $? -ne 0 ] && return
 | 
			
		||||
 | 
			
		||||
	if [ "$state" == "down" ]; then
 | 
			
		||||
		ip link set ${ifname} up
 | 
			
		||||
		[ $? -ne 0 ] && return
 | 
			
		||||
	fi
 | 
			
		||||
 | 
			
		||||
	local chip_macaddr="$(morse_cli -i ${ifname} macaddr 2>/dev/null)"
 | 
			
		||||
	[ $? -ne 0 ] && printf ""
 | 
			
		||||
	chip_macaddr=${chip_macaddr##"Chip MAC address: "}
 | 
			
		||||
 | 
			
		||||
	#make sure (using regex) that the we got a macaddr
 | 
			
		||||
	if [[ "$chip_macaddr" =~ ^\([0-9A-Fa-f]{2}[:]\){5}\([0-9A-Fa-f]{2}\)$ ]]; then
 | 
			
		||||
		[ "$chip_macaddr" = "00:00:00:00:00:00" ] && printf "" || printf "$chip_macaddr"
 | 
			
		||||
	else
 | 
			
		||||
		printf ""
 | 
			
		||||
	fi
 | 
			
		||||
 | 
			
		||||
	if [ "$state" == "down" ]; then
 | 
			
		||||
		ip link set ${ifname} down
 | 
			
		||||
	fi
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
update_dpp_qrcode()
 | 
			
		||||
{
 | 
			
		||||
	local uci_changes_path="$(mktemp -d)"
 | 
			
		||||
	local private_key_path=$1
 | 
			
		||||
	#remove ':' from the macaddress
 | 
			
		||||
	local mac_address=$(echo "$2" | sed -r 's/://g')
 | 
			
		||||
	#generate the public key string from the private key.
 | 
			
		||||
	#unfortunately, there is no way to quiet the 'read EC key' messages without redirecting stderr.
 | 
			
		||||
	local pubkey=$(openssl ec -in $private_key_path -pubout -conv_form compressed -outform DER 2> /dev/null | hexdump -e '16/1 "%02x " "\n"' | xxd -r -p | base64 -w0)
 | 
			
		||||
	#save qrcode string into /www
 | 
			
		||||
	qrencode --inline --8bit --type=SVG --output=/tmp/dpp_qrcode.svg "DPP:V:2;M:$mac_address;K:$pubkey;;"
 | 
			
		||||
	#only write if necessary
 | 
			
		||||
	if ! cmp -s /tmp/dpp_qrcode.svg /www/dpp_qrcode.svg; then
 | 
			
		||||
		cp /tmp/dpp_qrcode.svg /www/dpp_qrcode.svg
 | 
			
		||||
	fi
 | 
			
		||||
	rm /tmp/dpp_qrcode.svg
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										111
									
								
								feeds/morse/netifd-morse/lib/netifd/morse/wpa_s1g_dpp_action.sh
									
									
									
									
									
										Executable file
									
								
							
							
						
						
									
										111
									
								
								feeds/morse/netifd-morse/lib/netifd/morse/wpa_s1g_dpp_action.sh
									
									
									
									
									
										Executable file
									
								
							@@ -0,0 +1,111 @@
 | 
			
		||||
#!/bin/sh
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
. /lib/functions.sh
 | 
			
		||||
. /usr/share/libubox/jshn.sh
 | 
			
		||||
. /lib/netifd/netifd-wireless.sh
 | 
			
		||||
. /etc/diag.sh
 | 
			
		||||
 | 
			
		||||
#returns 0 if config is complete
 | 
			
		||||
is_config_complete()
 | 
			
		||||
{
 | 
			
		||||
    [ -z "$encryption" ] && return 1
 | 
			
		||||
 | 
			
		||||
    #if encryption is sae, check if we have psk
 | 
			
		||||
    if [ "$encryption" = "sae" ]; then
 | 
			
		||||
        [ -z "$psk" ] && return 1
 | 
			
		||||
    fi
 | 
			
		||||
 | 
			
		||||
    #check if we have ssid
 | 
			
		||||
    [ -z "$ssid" ] && return 1
 | 
			
		||||
 | 
			
		||||
    return 0
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
get_uci_section()
 | 
			
		||||
{
 | 
			
		||||
    local target_iface=$1
 | 
			
		||||
    local dpp_wifi_iface=
 | 
			
		||||
 | 
			
		||||
    check_interface() {
 | 
			
		||||
        json_get_vars section ifname
 | 
			
		||||
        [ "$ifname" = "$target_iface" ] && [ -n "$section" ] && [ -z "$dpp_wifi_iface" ] && dpp_wifi_iface=$section
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    wireless_status=$(ubus call network.wireless status)
 | 
			
		||||
 | 
			
		||||
    json_init
 | 
			
		||||
    json_load "$wireless_status"
 | 
			
		||||
    json_get_keys radios
 | 
			
		||||
 | 
			
		||||
    for radio in $radios; do
 | 
			
		||||
        json_select $radio
 | 
			
		||||
        for_each_interface "sta" check_interface
 | 
			
		||||
        json_select ..
 | 
			
		||||
    done
 | 
			
		||||
    echo "$dpp_wifi_iface"
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
save_and_reload()
 | 
			
		||||
{
 | 
			
		||||
    logger "Saving Received AP Credentials."
 | 
			
		||||
    local uci_section=$(get_uci_section $iface_name)
 | 
			
		||||
    if [ -z "$uci_section" ]; then
 | 
			
		||||
        logger "FATAL: unable to find the correct wifi interface in configs."
 | 
			
		||||
        exit 0
 | 
			
		||||
    fi
 | 
			
		||||
 | 
			
		||||
    uci set wireless.$uci_section.encryption="$encryption"
 | 
			
		||||
 | 
			
		||||
    #if encryption is sae, check if we have psk
 | 
			
		||||
    if [ "$encryption" = "sae" ]; then
 | 
			
		||||
        uci set wireless.$uci_section.key="$psk"
 | 
			
		||||
    fi
 | 
			
		||||
 | 
			
		||||
    uci set wireless.$uci_section.ssid="$ssid"
 | 
			
		||||
 | 
			
		||||
    uci set wireless.$uci_section.dpp='0'
 | 
			
		||||
 | 
			
		||||
    uci commit
 | 
			
		||||
    ubus call service event "{ \"type\": \"config.change\", \"data\": { \"package\": \"wireless\" }}"
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
# Do not name 'config'; will clash with uci functions.
 | 
			
		||||
do_config() {
 | 
			
		||||
    # convert password from hex string to string.
 | 
			
		||||
    psk="$(echo "$psk" | xxd -r -p)"
 | 
			
		||||
 | 
			
		||||
    # if the file contains all the necessary stuff, then save and reload.
 | 
			
		||||
    is_config_complete && save_and_reload
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
failed() {
 | 
			
		||||
    set_state dpp_failed
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
finished() {
 | 
			
		||||
    set_state done
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
started() {
 | 
			
		||||
    set_state dpp_started
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
case "$1" in
 | 
			
		||||
    config)
 | 
			
		||||
        do_config
 | 
			
		||||
    ;;
 | 
			
		||||
    failed)
 | 
			
		||||
        failed
 | 
			
		||||
    ;;
 | 
			
		||||
    finished)
 | 
			
		||||
        finished
 | 
			
		||||
    ;;
 | 
			
		||||
    started)
 | 
			
		||||
        started
 | 
			
		||||
    ;;
 | 
			
		||||
    *)
 | 
			
		||||
        echo "Usage: $0 {config|failed|finished|started}"
 | 
			
		||||
        exit 1
 | 
			
		||||
    ;;
 | 
			
		||||
esac
 | 
			
		||||
							
								
								
									
										1097
									
								
								feeds/morse/netifd-morse/lib/netifd/wireless/morse.sh
									
									
									
									
									
										Executable file
									
								
							
							
						
						
									
										1097
									
								
								feeds/morse/netifd-morse/lib/netifd/wireless/morse.sh
									
									
									
									
									
										Executable file
									
								
							
										
											
												File diff suppressed because it is too large
												Load Diff
											
										
									
								
							
							
								
								
									
										139
									
								
								feeds/morse/netifd-morse/lib/wifi/morse.sh
									
									
									
									
									
										Executable file
									
								
							
							
						
						
									
										139
									
								
								feeds/morse/netifd-morse/lib/wifi/morse.sh
									
									
									
									
									
										Executable file
									
								
							@@ -0,0 +1,139 @@
 | 
			
		||||
#!/bin/sh
 | 
			
		||||
 | 
			
		||||
# This script is copied and modified from
 | 
			
		||||
# package/kernel/mac80211/files/lib/wifi/mac80211.sh
 | 
			
		||||
# and modified (simplified) to work with morse devices.
 | 
			
		||||
 | 
			
		||||
append DRIVERS "morse"
 | 
			
		||||
 | 
			
		||||
# Find and set $phy for this $device (a wifi-device section name)
 | 
			
		||||
lookup_phy() {
 | 
			
		||||
	[ -n "$phy" ] && {
 | 
			
		||||
		[ -d /sys/class/ieee80211/$phy ] && return
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	local devpath
 | 
			
		||||
	config_get devpath "$device" path
 | 
			
		||||
	[ -n "$devpath" ] && {
 | 
			
		||||
		phy="$(iwinfo dot11ah phyname "path=$devpath")"
 | 
			
		||||
		[ -n "$phy" ] && return
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	local macaddr="$(config_get "$device" macaddr | tr 'A-Z' 'a-z')"
 | 
			
		||||
	[ -n "$macaddr" ] && {
 | 
			
		||||
		for _phy in /sys/class/ieee80211/*; do
 | 
			
		||||
			[ -e "$_phy" ] || continue
 | 
			
		||||
 | 
			
		||||
			[ "$macaddr" = "$(cat ${_phy}/macaddress)" ] || continue
 | 
			
		||||
			phy="${_phy##*/}"
 | 
			
		||||
			return
 | 
			
		||||
		done
 | 
			
		||||
	}
 | 
			
		||||
	phy=
 | 
			
		||||
	return
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
# Find and save the phy and macaddr for this $device (a wifi-device section name)
 | 
			
		||||
find_morse_phy() {
 | 
			
		||||
	local device="$1"
 | 
			
		||||
 | 
			
		||||
	config_get phy "$device" phy
 | 
			
		||||
	lookup_phy
 | 
			
		||||
	[ -n "$phy" -a -d "/sys/class/ieee80211/$phy" ] || {
 | 
			
		||||
		echo "PHY for wifi device $1 not found"
 | 
			
		||||
		return 1
 | 
			
		||||
	}
 | 
			
		||||
	config_set "$device" phy "$phy"
 | 
			
		||||
 | 
			
		||||
	config_get macaddr "$device" macaddr
 | 
			
		||||
	[ -z "$macaddr" ] && {
 | 
			
		||||
		config_set "$device" macaddr "$(cat /sys/class/ieee80211/${phy}/macaddress)"
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	return 0
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
# Set found=1 if the $phy for this $device (a wifi-device section name) is the same as $dev
 | 
			
		||||
check_morse_device() {
 | 
			
		||||
	config_get phy "$1" phy
 | 
			
		||||
	[ -z "$phy" ] && {
 | 
			
		||||
		find_morse_phy "$1" >/dev/null || return 0
 | 
			
		||||
		config_get phy "$1" phy
 | 
			
		||||
	}
 | 
			
		||||
	[ "$phy" = "$dev" ] && found=1
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
detect_morse() {
 | 
			
		||||
	devidx=0
 | 
			
		||||
	config_load wireless
 | 
			
		||||
	while :; do
 | 
			
		||||
		config_get type "radio$devidx" type
 | 
			
		||||
		[ -n "$type" ] || break
 | 
			
		||||
		devidx=$(($devidx + 1))
 | 
			
		||||
	done
 | 
			
		||||
 | 
			
		||||
	for _dev in /sys/class/ieee80211/*; do
 | 
			
		||||
		[ -e "$_dev" ] || continue
 | 
			
		||||
 | 
			
		||||
		# Only configure morse devices.
 | 
			
		||||
		basename "$(readlink -f "$_dev/device/driver/")" | grep '^morse_' || continue
 | 
			
		||||
 | 
			
		||||
		dev="${_dev##*/}"
 | 
			
		||||
 | 
			
		||||
		# Skip already configured devices.
 | 
			
		||||
		# The path or macaddr are used to find the corresponding phy.
 | 
			
		||||
		found=0
 | 
			
		||||
		config_foreach check_morse_device wifi-device
 | 
			
		||||
		[ "$found" -gt 0 ] && continue
 | 
			
		||||
 | 
			
		||||
		path="$(iwinfo dot11ah path "$dev")"
 | 
			
		||||
		if [ -n "$path" ]; then
 | 
			
		||||
			dev_id="set wireless.radio${devidx}.path='$path'"
 | 
			
		||||
		else
 | 
			
		||||
			dev_id="set wireless.radio${devidx}.macaddr=$(cat /sys/class/ieee80211/${dev}/macaddress)"
 | 
			
		||||
		fi
 | 
			
		||||
 | 
			
		||||
		uci -q batch <<-EOF
 | 
			
		||||
			set wireless.radio${devidx}=wifi-device
 | 
			
		||||
			set wireless.radio${devidx}.type=morse
 | 
			
		||||
			${dev_id}
 | 
			
		||||
			set wireless.radio${devidx}.band=s1g
 | 
			
		||||
			set wireless.radio${devidx}.hwmode=11ah
 | 
			
		||||
			set wireless.radio${devidx}.reconf=0
 | 
			
		||||
			set wireless.radio${devidx}.disabled=1
 | 
			
		||||
 | 
			
		||||
			set wireless.default_radio${devidx}=wifi-iface
 | 
			
		||||
			set wireless.default_radio${devidx}.mode=ap
 | 
			
		||||
			set wireless.default_radio${devidx}.wds=1
 | 
			
		||||
			set wireless.default_radio${devidx}.device=radio${devidx}
 | 
			
		||||
			set wireless.default_radio${devidx}.network=lan
 | 
			
		||||
			set wireless.default_radio${devidx}.ssid=MorseMicro
 | 
			
		||||
			set wireless.default_radio${devidx}.encryption=sae
 | 
			
		||||
			set wireless.default_radio${devidx}.key=12345678
 | 
			
		||||
EOF
 | 
			
		||||
 | 
			
		||||
		board=$(board_name)
 | 
			
		||||
 | 
			
		||||
		case "$board" in
 | 
			
		||||
			morse,ekh01-03 |\
 | 
			
		||||
			morse,ekh03v3)
 | 
			
		||||
				bcf=bcf_mf08551.bin
 | 
			
		||||
			;;
 | 
			
		||||
			morse,ekh01v1)
 | 
			
		||||
				bcf=bcf_mf03120.bin
 | 
			
		||||
			;;
 | 
			
		||||
			morse,ekh01v2)
 | 
			
		||||
				bcf=bcf_mf08251.bin
 | 
			
		||||
			;;
 | 
			
		||||
			morse,ekh04v4)
 | 
			
		||||
				bcf=bcf_ekh04_v4.bin
 | 
			
		||||
			;;
 | 
			
		||||
		esac
 | 
			
		||||
 | 
			
		||||
		[ -n "${bcf}" ] && uci -q set wireless.radio${devidx}.bcf="${bcf}"
 | 
			
		||||
 | 
			
		||||
		uci -q commit wireless
 | 
			
		||||
 | 
			
		||||
		devidx=$(($devidx + 1))
 | 
			
		||||
	done
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										17
									
								
								feeds/morse/utils/hostapd_s1g/Config.in
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										17
									
								
								feeds/morse/utils/hostapd_s1g/Config.in
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,17 @@
 | 
			
		||||
if PACKAGE_hostapd_s1g
 | 
			
		||||
 | 
			
		||||
	config MORSE_HOSTAPD_S1G_EAP
 | 
			
		||||
		bool
 | 
			
		||||
		default n
 | 
			
		||||
		prompt "Enable Extensible Authentication Protocol (EAP) support"
 | 
			
		||||
 | 
			
		||||
	config MORSE_HOSTAPD_S1G_ACS
 | 
			
		||||
		bool
 | 
			
		||||
		default n
 | 
			
		||||
		prompt "Enable automatic channel selection (ACS) support"
 | 
			
		||||
		help
 | 
			
		||||
			This will allow hostapd to pick the channel automatically when channel is set
 | 
			
		||||
			to "acs_survey" or "0". Eventually, other ACS algorithms can be added in
 | 
			
		||||
			similar way.
 | 
			
		||||
 | 
			
		||||
endif
 | 
			
		||||
							
								
								
									
										167
									
								
								feeds/morse/utils/hostapd_s1g/Makefile
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										167
									
								
								feeds/morse/utils/hostapd_s1g/Makefile
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,167 @@
 | 
			
		||||
#
 | 
			
		||||
# Copyright 2022 Morse Micro
 | 
			
		||||
#
 | 
			
		||||
# This is free software, licensed under the 3-Clause BSD License.
 | 
			
		||||
# See /LICENSE for more information.
 | 
			
		||||
#
 | 
			
		||||
 | 
			
		||||
include $(TOPDIR)/rules.mk
 | 
			
		||||
 | 
			
		||||
PKG_NAME:=hostapd_s1g
 | 
			
		||||
PKG_RELEASE=2
 | 
			
		||||
 | 
			
		||||
PKG_VERSION:=1.12.4
 | 
			
		||||
 | 
			
		||||
PKG_LICENSE:=BSD-3-Clause
 | 
			
		||||
 | 
			
		||||
PKG_SOURCE_VERSION:=$(PKG_VERSION)
 | 
			
		||||
PKG_SOURCE_URL:=https://github.com/MorseMicro/hostap.git
 | 
			
		||||
PKG_HASH:=a2f17ce3d2fe25d45cc2d6869e9ea644bcac441ec9b541972034768d4fc63608
 | 
			
		||||
PKG_SOURCE_PROTO:=git
 | 
			
		||||
 | 
			
		||||
PKG_MAINTAINER:=Morse Micro <info@morsemicro.com>
 | 
			
		||||
PKG_BUILD_PARALLEL:=1
 | 
			
		||||
 | 
			
		||||
PKG_CONFIG_DEPENDS:= \
 | 
			
		||||
	CONFIG_PACKAGE_kmod-morse \
 | 
			
		||||
	CONFIG_PACKAGE_kmod-cfg80211 \
 | 
			
		||||
	CONFIG_PACKAGE_hostapd \
 | 
			
		||||
	CONFIG_PACKAGE_hostapd-basic \
 | 
			
		||||
	CONFIG_PACKAGE_hostapd-mini \
 | 
			
		||||
	CONFIG_WPA_RFKILL_SUPPORT \
 | 
			
		||||
	CONFIG_DRIVER_WEXT_SUPPORT \
 | 
			
		||||
	CONFIG_DRIVER_11N_SUPPORT \
 | 
			
		||||
	CONFIG_DRIVER_11AC_SUPPORT \
 | 
			
		||||
	CONFIG_DRIVER_11AX_SUPPORT \
 | 
			
		||||
	CONFIG_WPA_ENABLE_WEP
 | 
			
		||||
 | 
			
		||||
include $(INCLUDE_DIR)/package.mk
 | 
			
		||||
 | 
			
		||||
MAKE_FLAGS += \
 | 
			
		||||
	MORSEHOSTAPD_VERSION_STRING=$(PKG_VERSION)
 | 
			
		||||
 | 
			
		||||
MMHOSTAPD_CONFIG_ENABLE = \
 | 
			
		||||
	CONFIG_INTERNAL_LIBTOMMATH \
 | 
			
		||||
	CONFIG_DEBUG_FILE \
 | 
			
		||||
	CONFIG_DEBUG_SYSLOG \
 | 
			
		||||
	CONFIG_PMKSA_CACHE_EXTERNAL \
 | 
			
		||||
	CONFIG_SAE \
 | 
			
		||||
	CONFIG_TESTING_OPTIONS \
 | 
			
		||||
	CONFIG_WNM \
 | 
			
		||||
	CONFIG_DRIVER_ACS \
 | 
			
		||||
	CONFIG_DRIVER_HOSTAP \
 | 
			
		||||
	CONFIG_DRIVER_NL80211 \
 | 
			
		||||
	CONFIG_HS20 \
 | 
			
		||||
	CONFIG_IEEE80211AC \
 | 
			
		||||
	CONFIG_IEEE80211N \
 | 
			
		||||
	CONFIG_IEEE80211AH \
 | 
			
		||||
	CONFIG_IEEE80211R \
 | 
			
		||||
	CONFIG_INTERWORKING \
 | 
			
		||||
	CONFIG_FULL_DYNAMIC_VLAN \
 | 
			
		||||
	CONFIG_VLAN_NETLINK \
 | 
			
		||||
	CONFIG_OWE \
 | 
			
		||||
	CONFIG_LIBNL32 \
 | 
			
		||||
	CONFIG_DPP \
 | 
			
		||||
	CONFIG_DPP2 \
 | 
			
		||||
	CONFIG_WPS
 | 
			
		||||
 | 
			
		||||
MMHOSTAPD_CONFIG_SET = \
 | 
			
		||||
	NEED_LINUX_IOCTL \
 | 
			
		||||
	CONFIG_DPP \
 | 
			
		||||
	CONFIG_SAE
 | 
			
		||||
 | 
			
		||||
MMHOSTAPD_CONFIG_DISABLE = \
 | 
			
		||||
    CONFIG_DRIVER_NONE \
 | 
			
		||||
	CONFIG_DRIVER_RTW \
 | 
			
		||||
	CONFIG_DRIVER_WIRED
 | 
			
		||||
 | 
			
		||||
MMHOSTAPD_CONFIG_EDITS += 's/\#\(CONFIG_TLS=openssl\)/\1/'
 | 
			
		||||
 | 
			
		||||
ifeq ($(CONFIG_MORSE_HOSTAPD_S1G_ACS),y)
 | 
			
		||||
	MMHOSTAPD_CONFIG_ENABLE += CONFIG_ACS
 | 
			
		||||
endif
 | 
			
		||||
 | 
			
		||||
ifeq ($(CONFIG_MORSE_HOSTAPD_S1G_EAP),y)
 | 
			
		||||
	MMHOSTAPD_CONFIG_ENABLE += \
 | 
			
		||||
		CONFIG_EAP \
 | 
			
		||||
		CONFIG_RADIUS_SERVER \
 | 
			
		||||
		CONFIG_TLSV1
 | 
			
		||||
else
 | 
			
		||||
	MMHOSTAPD_CONFIG_DISABLE += CONFIG_HOSTAPD_EAP
 | 
			
		||||
	MMHOSTAPD_CONFIG_ENABLE += \
 | 
			
		||||
		CONFIG_NO_ACCOUNTING \
 | 
			
		||||
		CONFIG_NO_RADIUS
 | 
			
		||||
endif
 | 
			
		||||
 | 
			
		||||
define Package/hostapd_s1g
 | 
			
		||||
  SECTION:=net
 | 
			
		||||
  CATEGORY:=Network
 | 
			
		||||
  SUBMENU:=WirelessAPD
 | 
			
		||||
  TITLE:=Morse Micro HaLow hostapd
 | 
			
		||||
  DEPENDS:= +kmod-morse +libnl +libopenssl +libubus
 | 
			
		||||
  USERID:=network=101:network=101
 | 
			
		||||
  PROVIDES:=hostapd_s1g
 | 
			
		||||
endef
 | 
			
		||||
 | 
			
		||||
define Package/hostapd_s1g/description
 | 
			
		||||
 This package contains a full featured Morse Micro patched
 | 
			
		||||
 Authenticator.
 | 
			
		||||
endef
 | 
			
		||||
 | 
			
		||||
define Package/hostapd_s1g/config
 | 
			
		||||
    source "$(SOURCE)/Config.in"
 | 
			
		||||
endef
 | 
			
		||||
 | 
			
		||||
MMHOSTAPD_CONFIG = $(PKG_BUILD_DIR)/hostapd/.config
 | 
			
		||||
 | 
			
		||||
define Build/Prepare
 | 
			
		||||
    $(call Build/Prepare/Default)
 | 
			
		||||
	$(CP) $(PKG_BUILD_DIR)/hostapd/defconfig $(MMHOSTAPD_CONFIG)
 | 
			
		||||
	sed -i $(patsubst %,-e 's/^#\(%\)/\1/',$(MMHOSTAPD_CONFIG_ENABLE)) \
 | 
			
		||||
		$(patsubst %,-e 's/^\(%\)/#\1/',$(MMHOSTAPD_CONFIG_DISABLE)) \
 | 
			
		||||
		$(patsubst %,-e '1i%=y',$(MMHOSTAPD_CONFIG_SET)) \
 | 
			
		||||
		$(patsubst %,-e %,$(MMHOSTAPD_CONFIG_EDITS)) \
 | 
			
		||||
		$(MMHOSTAPD_CONFIG)
 | 
			
		||||
endef
 | 
			
		||||
 | 
			
		||||
TARGET_CPPFLAGS := \
 | 
			
		||||
	-I$(STAGING_DIR)/usr/include/libnl3 \
 | 
			
		||||
	-I$(PKG_BUILD_DIR)/src/crypto \
 | 
			
		||||
	$(TARGET_CPPFLAGS) \
 | 
			
		||||
	-DCONFIG_LIBNL20 \
 | 
			
		||||
	-D_GNU_SOURCE
 | 
			
		||||
 | 
			
		||||
TARGET_LDFLAGS += -lnl-3 -lnl-genl-3 -lnl-route-3
 | 
			
		||||
TARGET_LDFLAGS += -lm -lpthread -lcrypto -lssl
 | 
			
		||||
 | 
			
		||||
TARGET_LDFLAGS += -lrt
 | 
			
		||||
TARGET_LDFLAGS_C += -lrt
 | 
			
		||||
 | 
			
		||||
define Build/RunMake
 | 
			
		||||
	CFLAGS="$(TARGET_CPPFLAGS) $(TARGET_CFLAGS)" \
 | 
			
		||||
	$(MAKE) $(PKG_JOBS) -C $(PKG_BUILD_DIR)/$(1) \
 | 
			
		||||
		$(TARGET_CONFIGURE_OPTS) \
 | 
			
		||||
		$(DRIVER_MAKEOPTS) \
 | 
			
		||||
		LIBS="$(TARGET_LDFLAGS)" \
 | 
			
		||||
		LIBS_c="$(TARGET_LDFLAGS_C)" \
 | 
			
		||||
		AR="$(TARGET_CROSS)gcc-ar" \
 | 
			
		||||
		BCHECK= \
 | 
			
		||||
		$(2)
 | 
			
		||||
endef
 | 
			
		||||
 | 
			
		||||
define Build/Compile
 | 
			
		||||
	+$(call Build/RunMake,hostapd, \
 | 
			
		||||
		hostapd_s1g hostapd_cli_s1g \
 | 
			
		||||
	)
 | 
			
		||||
endef
 | 
			
		||||
 | 
			
		||||
#Ian
 | 
			
		||||
define Package/hostapd_s1g/install
 | 
			
		||||
	$(INSTALL_DIR) $(1)/sbin
 | 
			
		||||
	$(INSTALL_BIN) $(PKG_BUILD_DIR)/hostapd/hostapd_s1g $(1)/sbin
 | 
			
		||||
	$(INSTALL_BIN) $(PKG_BUILD_DIR)/hostapd/hostapd_cli_s1g $(1)/sbin
 | 
			
		||||
	$(INSTALL_DIR) $(1)/lib/netifd
 | 
			
		||||
	$(INSTALL_DATA) ./files/lib/netifd/hostapd_s1g.sh $(1)/lib/netifd 
 | 
			
		||||
endef
 | 
			
		||||
 | 
			
		||||
$(eval $(call BuildPackage,hostapd_s1g))
 | 
			
		||||
							
								
								
									
										1603
									
								
								feeds/morse/utils/hostapd_s1g/files/lib/netifd/hostapd_s1g.sh
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										1603
									
								
								feeds/morse/utils/hostapd_s1g/files/lib/netifd/hostapd_s1g.sh
									
									
									
									
									
										Normal file
									
								
							
										
											
												File diff suppressed because it is too large
												Load Diff
											
										
									
								
							@@ -0,0 +1,45 @@
 | 
			
		||||
From 5433351ed5ab62c2d4fbd15a2c4d8c4aeacb93dc Mon Sep 17 00:00:00 2001
 | 
			
		||||
From: Evan Benn <evan.benn@morsemicro.com>
 | 
			
		||||
Date: Thu, 29 Feb 2024 11:09:38 +1100
 | 
			
		||||
Subject: [PATCH] APP-2573: Emit a DPP PB_STATUS event when push button starts
 | 
			
		||||
 | 
			
		||||
---
 | 
			
		||||
 src/ap/dpp_hostapd.c            | 1 +
 | 
			
		||||
 wpa_supplicant/dpp_supplicant.c | 2 ++
 | 
			
		||||
 2 files changed, 3 insertions(+)
 | 
			
		||||
 | 
			
		||||
diff --git a/src/ap/dpp_hostapd.c b/src/ap/dpp_hostapd.c
 | 
			
		||||
index b7cca47c714b..3025eef204d2 100644
 | 
			
		||||
--- a/src/ap/dpp_hostapd.c
 | 
			
		||||
+++ b/src/ap/dpp_hostapd.c
 | 
			
		||||
@@ -3960,6 +3960,7 @@ int hostapd_dpp_push_button(struct hostapd_data *hapd, const char *cmd)
 | 
			
		||||
 	eloop_register_timeout(100, 0, hostapd_dpp_push_button_expire,
 | 
			
		||||
 			       hapd, NULL);
 | 
			
		||||
 
 | 
			
		||||
+	wpa_msg(hapd->msg_ctx, MSG_INFO, DPP_EVENT_PB_STATUS "started");
 | 
			
		||||
 	return 0;
 | 
			
		||||
 }
 | 
			
		||||
 
 | 
			
		||||
diff --git a/wpa_supplicant/dpp_supplicant.c b/wpa_supplicant/dpp_supplicant.c
 | 
			
		||||
index ab06ff8d32c1..24e4bb3c444d 100644
 | 
			
		||||
--- a/wpa_supplicant/dpp_supplicant.c
 | 
			
		||||
+++ b/wpa_supplicant/dpp_supplicant.c
 | 
			
		||||
@@ -5676,6 +5676,7 @@ static int wpas_dpp_push_button_configurator(struct wpa_supplicant *wpa_s,
 | 
			
		||||
 	eloop_register_timeout(100, 0, wpas_dpp_push_button_expire,
 | 
			
		||||
 			       wpa_s, NULL);
 | 
			
		||||
 
 | 
			
		||||
+	wpa_msg(wpa_s, MSG_INFO, DPP_EVENT_PB_STATUS "started");
 | 
			
		||||
 	return 0;
 | 
			
		||||
 }
 | 
			
		||||
 
 | 
			
		||||
@@ -5749,6 +5750,7 @@ int wpas_dpp_push_button(struct wpa_supplicant *wpa_s, const char *cmd)
 | 
			
		||||
 	wpa_supplicant_req_scan(wpa_s, 0, 0);
 | 
			
		||||
 
 | 
			
		||||
 	res = 0;
 | 
			
		||||
+	wpa_msg(wpa_s, MSG_INFO, DPP_EVENT_PB_STATUS "started");
 | 
			
		||||
 out:
 | 
			
		||||
 
 | 
			
		||||
 	/* If push button mode failed to start, restart the chirp forever timer */
 | 
			
		||||
-- 
 | 
			
		||||
2.42.0.530.g692be87cbba5
 | 
			
		||||
 | 
			
		||||
@@ -0,0 +1,90 @@
 | 
			
		||||
From 25631fa387af430b8d7f03302218c66dc161cc6f Mon Sep 17 00:00:00 2001
 | 
			
		||||
From: Andrew Pope <andrew.pope@morsemicro.com>
 | 
			
		||||
Date: Tue, 4 Jun 2024 23:12:37 +0000
 | 
			
		||||
Subject: [PATCH] Merged in SW-11943-dpp-does-not-associate-in-us-regdom (pull
 | 
			
		||||
 request #213)
 | 
			
		||||
 | 
			
		||||
SW-11943: DPP does not associate in US regdom
 | 
			
		||||
 | 
			
		||||
Two problems contributed to the originally reported issue:
 | 
			
		||||
 | 
			
		||||
1. The DPP-PB state machine function will unconditionally cancel any pending off-channel actions - even if the DPP PB discovery phase is over. To fix this, avoid unconditionally completing offchannel actions from DPP-PB state machine function if DPP PB discovery phase is over.
 | 
			
		||||
 | 
			
		||||
2. Logic around PKEX retries will manually attempt to complete the exchange on adjacent non-S1G channels. These retries inevitably fail, leading to a quicker collapse of the PKEX exchange attempts and eventual downgrade from v2 to v1 (bad). To fix this, remove non-S1G frequency hopping logic from DPP PB discovery and PKEX exchange phases.
 | 
			
		||||
 | 
			
		||||
Approved-by: Neville Young
 | 
			
		||||
Approved-by: Simon Wadsworth
 | 
			
		||||
Approved-by: Ayman Grais
 | 
			
		||||
Approved-by: James Herbert
 | 
			
		||||
---
 | 
			
		||||
 src/ap/dpp_hostapd.c            |  6 ++++++
 | 
			
		||||
 wpa_supplicant/dpp_supplicant.c | 17 +++++++++++++++--
 | 
			
		||||
 2 files changed, 21 insertions(+), 2 deletions(-)
 | 
			
		||||
 | 
			
		||||
diff --git a/src/ap/dpp_hostapd.c b/src/ap/dpp_hostapd.c
 | 
			
		||||
index b7cca47c7..282581fe5 100644
 | 
			
		||||
--- a/src/ap/dpp_hostapd.c
 | 
			
		||||
+++ b/src/ap/dpp_hostapd.c
 | 
			
		||||
@@ -260,6 +260,12 @@ static int hostapd_dpp_allow_ir(struct hostapd_data *hapd, unsigned int freq)
 | 
			
		||||
 static int hostapd_dpp_pkex_next_channel(struct hostapd_data *hapd,
 | 
			
		||||
 					 struct dpp_pkex *pkex)
 | 
			
		||||
 {
 | 
			
		||||
+	/* Following logic is not S1G compatible. Attempting PKEX on non-adjacent S1G channels
 | 
			
		||||
+	 * results in guaranteed failure.
 | 
			
		||||
+	 */
 | 
			
		||||
+	if (hapd->iconf->ieee80211ah)
 | 
			
		||||
+		return -1;
 | 
			
		||||
+
 | 
			
		||||
 	if (pkex->freq == 2437)
 | 
			
		||||
 		pkex->freq = 5745;
 | 
			
		||||
 	else if (pkex->freq == 5745)
 | 
			
		||||
diff --git a/wpa_supplicant/dpp_supplicant.c b/wpa_supplicant/dpp_supplicant.c
 | 
			
		||||
index ab06ff8d3..e90e4a163 100644
 | 
			
		||||
--- a/wpa_supplicant/dpp_supplicant.c
 | 
			
		||||
+++ b/wpa_supplicant/dpp_supplicant.c
 | 
			
		||||
@@ -2840,6 +2840,12 @@ static int wpas_dpp_allow_ir(struct wpa_supplicant *wpa_s, unsigned int freq)
 | 
			
		||||
 static int wpas_dpp_pkex_next_channel(struct wpa_supplicant *wpa_s,
 | 
			
		||||
 				      struct dpp_pkex *pkex)
 | 
			
		||||
 {
 | 
			
		||||
+#if defined(CONFIG_IEEE80211AH)
 | 
			
		||||
+	/* Following logic is not S1G compatible. Attempting PKEX on non-adjacent S1G channels
 | 
			
		||||
+	 * results in guaranteed failure.
 | 
			
		||||
+	 */
 | 
			
		||||
+	return -1;
 | 
			
		||||
+#endif
 | 
			
		||||
 	if (pkex->freq == 2437)
 | 
			
		||||
 		pkex->freq = 5745;
 | 
			
		||||
 	else if (pkex->freq == 5745)
 | 
			
		||||
@@ -5113,10 +5119,16 @@ static int * wpas_dpp_presence_ann_channels(struct wpa_supplicant *wpa_s,
 | 
			
		||||
 
 | 
			
		||||
 			if (chan->flag & (HOSTAPD_CHAN_DISABLED | HOSTAPD_CHAN_RADAR))
 | 
			
		||||
 				continue;
 | 
			
		||||
+#if defined(CONFIG_IEEE80211AH)
 | 
			
		||||
+			/* Adding channels 44 and 149 at end of scan list is not required
 | 
			
		||||
+			 * for HaLow
 | 
			
		||||
+			 */
 | 
			
		||||
+#else
 | 
			
		||||
 			if (chan->freq == 5220)
 | 
			
		||||
 				chan44 = 1;
 | 
			
		||||
 			if (chan->freq == 5745)
 | 
			
		||||
 				chan149 = 1;
 | 
			
		||||
+#endif
 | 
			
		||||
 
 | 
			
		||||
 			/* Morse - All 5GHz channels that are mapped to 1 MHz and 2 MHz.
 | 
			
		||||
 			 * Channels that aren't relevant to a regulatory domain will be
 | 
			
		||||
@@ -5573,9 +5585,10 @@ static void wpas_dpp_pb_next(void *eloop_ctx, void *timeout_ctx)
 | 
			
		||||
 	if (!wpa_s->dpp_pb_freqs)
 | 
			
		||||
 		return;
 | 
			
		||||
 
 | 
			
		||||
-	os_get_reltime(&now);
 | 
			
		||||
-	offchannel_send_action_done(wpa_s);
 | 
			
		||||
+	if (!wpa_s->dpp_pb_discovery_done)
 | 
			
		||||
+		offchannel_send_action_done(wpa_s);
 | 
			
		||||
 
 | 
			
		||||
+	os_get_reltime(&now);
 | 
			
		||||
 	if (os_reltime_expired(&now, &wpa_s->dpp_pb_time, 100)) {
 | 
			
		||||
 		wpa_printf(MSG_DEBUG, "DPP: Push button wait time expired");
 | 
			
		||||
 		wpas_dpp_push_button_stop(wpa_s);
 | 
			
		||||
-- 
 | 
			
		||||
2.25.1
 | 
			
		||||
 | 
			
		||||
@@ -0,0 +1,35 @@
 | 
			
		||||
From 591ec24748525171d5647d2a35cd1da1445e7a0b Mon Sep 17 00:00:00 2001
 | 
			
		||||
From: James Haggerty <james.haggerty@morsemicro.com>
 | 
			
		||||
Date: Fri, 26 Jul 2024 09:55:03 +1000
 | 
			
		||||
Subject: [PATCH] Hack out channel 50 (and typo for 51)
 | 
			
		||||
 | 
			
		||||
If we use these channels on a board with those channels disabled,
 | 
			
		||||
the DPP presence announcement fails.
 | 
			
		||||
 | 
			
		||||
This is rubbish: see SW-12450
 | 
			
		||||
---
 | 
			
		||||
 wpa_supplicant/dpp_supplicant.c | 4 ++--
 | 
			
		||||
 1 file changed, 2 insertions(+), 2 deletions(-)
 | 
			
		||||
 | 
			
		||||
diff --git a/wpa_supplicant/dpp_supplicant.c b/wpa_supplicant/dpp_supplicant.c
 | 
			
		||||
index 09f8ceb07..46e4add95 100644
 | 
			
		||||
--- a/wpa_supplicant/dpp_supplicant.c
 | 
			
		||||
+++ b/wpa_supplicant/dpp_supplicant.c
 | 
			
		||||
@@ -5199,12 +5199,12 @@ static int * wpas_dpp_presence_ann_channels(struct wpa_supplicant *wpa_s,
 | 
			
		||||
 			static const int s1g_chirp_channels[] = {
 | 
			
		||||
 				/* 2MHz channels */
 | 
			
		||||
 				5190, 5230, 5270, 5310, 5510, 5550,
 | 
			
		||||
-				5630, 5670, 5755, 5795, 5835, 5875,
 | 
			
		||||
+				5630, 5670, 5755, 5795, 5835,
 | 
			
		||||
 				/* 1MHz channels */
 | 
			
		||||
 				5660, 5680, 5180, 5200, 5240, 5260,
 | 
			
		||||
 				5280, 5300, 5320, 5500, 5520, 5540,
 | 
			
		||||
 				5560, 5580, 5600, 5620, 5640, 5765,
 | 
			
		||||
-				5785, 5805, 5825, 5845, 5865, 5855
 | 
			
		||||
+				5785, 5805, 5825, 5845, 5865
 | 
			
		||||
 			};
 | 
			
		||||
 
 | 
			
		||||
 			if (chan->flag & (HOSTAPD_CHAN_DISABLED | HOSTAPD_CHAN_RADAR))
 | 
			
		||||
-- 
 | 
			
		||||
2.25.1
 | 
			
		||||
 | 
			
		||||
							
								
								
									
										73
									
								
								feeds/morse/utils/morse_mesh11sd/Makefile
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										73
									
								
								feeds/morse/utils/morse_mesh11sd/Makefile
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,73 @@
 | 
			
		||||
# SPDX-License-Identifier: GPL-2.0-only
 | 
			
		||||
#
 | 
			
		||||
#The mesh11sd dameon is designed in such a way that all configuration done to 11s mesh can be directly set to the
 | 
			
		||||
#mac80211 via iw utility and does not require any re-configuration of interfaces. Considering the MorseMicro design and
 | 
			
		||||
#implementation of 802.11s mesh, most of the configuration needs to be applied to the wpa_supplicant.conf which requires
 | 
			
		||||
#re-configuration of the interface.
 | 
			
		||||
#Thus we need a reload_service section to mesh11sd that will re-configure wifi via wifi down and up.
 | 
			
		||||
#
 | 
			
		||||
#Openwrt provided Mesh11sd package is found in: https://github.com/openwrt/routing/tree/master/mesh11sd
 | 
			
		||||
#
 | 
			
		||||
# This is free software, licensed under the GNU General Public License v2.
 | 
			
		||||
# See /LICENSE for more information.
 | 
			
		||||
# Copyright (C) 2022 BlueWave Projects and Services  <licence@blue-wave.net>
 | 
			
		||||
#
 | 
			
		||||
 | 
			
		||||
include $(TOPDIR)/rules.mk
 | 
			
		||||
 | 
			
		||||
PKG_NAME:=morse_mesh11sd
 | 
			
		||||
PKG_VERSION:=1.2.0
 | 
			
		||||
PKG_RELEASE:=$(AUTORELEASE)
 | 
			
		||||
 | 
			
		||||
PKG_MAINTAINER:=Rob White <rob@blue-wave.net>
 | 
			
		||||
PKG_LICENSE:=GPL-2.0-or-later
 | 
			
		||||
PKG_LICENSE_FILES:=LICENSE
 | 
			
		||||
 | 
			
		||||
PKG_SOURCE:=$(PKG_NAME)-$(PKG_VERSION).tar.gz
 | 
			
		||||
PKG_SOURCE_URL:=https://codeload.github.com/opennds/mesh11sd/tar.gz/v$(PKG_VERSION)?
 | 
			
		||||
PKG_HASH:=b719eaacf63eb3684d0cd6a026f4357a4f400f2339f5d5a6cf74ba3744fe30d8
 | 
			
		||||
PKG_BUILD_DIR:=$(BUILD_DIR)/mesh11sd-$(PKG_VERSION)
 | 
			
		||||
 | 
			
		||||
include $(INCLUDE_DIR)/package.mk
 | 
			
		||||
 | 
			
		||||
define Package/morse_mesh11sd
 | 
			
		||||
  SUBMENU:=Captive Portals
 | 
			
		||||
  SECTION:=net
 | 
			
		||||
  CATEGORY:=Network
 | 
			
		||||
  TITLE:=Dynamic 802.11s Mesh Configuration Daemon
 | 
			
		||||
  PKGARCH:=all
 | 
			
		||||
  URL:=https://github.com/opennds/mesh11sd
 | 
			
		||||
  PROVIDES:=mesh11sd
 | 
			
		||||
endef
 | 
			
		||||
 | 
			
		||||
define Package/morse_mesh11sd/description
 | 
			
		||||
  Mesh11sd is a dynamic parameter configuration daemon for 802.11s mesh networks.
 | 
			
		||||
  It was originally designed to leverage 802.11s mesh networking at Captive Portal venues.
 | 
			
		||||
  This is the open source version and it enables easy and automated mesh network operation with multiple mesh nodes.
 | 
			
		||||
  It allows all mesh parameters supported by the wireless driver to be set in the uci config file.
 | 
			
		||||
  Settings take effect immediately without having to restart the wireless network.
 | 
			
		||||
  Default settings give rapid and reliable layer 2 mesh convergence.
 | 
			
		||||
  Without mesh11sd, many mesh parameters cannot be set in the uci wireless config file as the mesh interface must be up before the parameters can be set.
 | 
			
		||||
  Some of those that are supported, would fail to be implemented when the network is (re)started resulting in errors or dropped nodes.
 | 
			
		||||
  The mesh11sd daemon dynamically checks configured parameters and sets them as required.
 | 
			
		||||
  This version does not require a Captive Portal to be running.
 | 
			
		||||
  The modified morse_mesh11sd would allow reconfiguring the wpa supplicant everytime there is 11sMesh config modification.
 | 
			
		||||
endef
 | 
			
		||||
 | 
			
		||||
define Package/morse_mesh11sd/install
 | 
			
		||||
	$(INSTALL_DIR) $(1)/usr/sbin
 | 
			
		||||
	$(INSTALL_DIR) $(1)/etc/config
 | 
			
		||||
	$(INSTALL_DIR) $(1)/etc/init.d
 | 
			
		||||
	$(INSTALL_BIN) $(PKG_BUILD_DIR)/src/mesh11sd $(1)/usr/sbin
 | 
			
		||||
	$(INSTALL_CONF) ./files/etc/config/mesh11sd $(1)/etc/config/
 | 
			
		||||
	$(INSTALL_BIN) $(PKG_BUILD_DIR)/linux_openwrt/mesh11sd/files/etc/init.d/mesh11sd $(1)/etc/init.d/
 | 
			
		||||
endef
 | 
			
		||||
 | 
			
		||||
define Package/morse_mesh11sd/conffiles
 | 
			
		||||
/etc/config/mesh11sd
 | 
			
		||||
endef
 | 
			
		||||
 | 
			
		||||
define Build/Compile
 | 
			
		||||
endef
 | 
			
		||||
 | 
			
		||||
$(eval $(call BuildPackage,morse_mesh11sd))
 | 
			
		||||
Some files were not shown because too many files have changed in this diff Show More
		Reference in New Issue
	
	Block a user