diff --git a/.github/workflows/build-dev.yml b/.github/workflows/build-dev.yml index d848f777a..cc2cc2495 100755 --- a/.github/workflows/build-dev.yml +++ b/.github/workflows/build-dev.yml @@ -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_rap650c', 'sonicfi_rap7110c-341x', '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' ] + 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_rap650c', 'sonicfi_rap7110c-341x', 'sonicfi_rap750e-h', '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' ] steps: - uses: actions/checkout@v3 diff --git a/feeds/mediatek-sdk/mac80211/files/lib/wifi/mac80211.sh b/feeds/mediatek-sdk/mac80211/files/lib/wifi/mac80211.sh index e24a2a634..36958d86c 100644 --- a/feeds/mediatek-sdk/mac80211/files/lib/wifi/mac80211.sh +++ b/feeds/mediatek-sdk/mac80211/files/lib/wifi/mac80211.sh @@ -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 } diff --git a/feeds/mediatek-sdk/mac80211/patches/subsys/999-9031-morse-mac80211-disable-robust-management-frame-without-sta-check.patch b/feeds/mediatek-sdk/mac80211/patches/subsys/999-9031-morse-mac80211-disable-robust-management-frame-without-sta-check.patch new file mode 100644 index 000000000..526b0e178 --- /dev/null +++ b/feeds/mediatek-sdk/mac80211/patches/subsys/999-9031-morse-mac80211-disable-robust-management-frame-without-sta-check.patch @@ -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); diff --git a/feeds/mediatek-sdk/mac80211/patches/subsys/999-9046-morse-mac80211_ndp_block_ack.patch b/feeds/mediatek-sdk/mac80211/patches/subsys/999-9046-morse-mac80211_ndp_block_ack.patch new file mode 100644 index 000000000..261326137 --- /dev/null +++ b/feeds/mediatek-sdk/mac80211/patches/subsys/999-9046-morse-mac80211_ndp_block_ack.patch @@ -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; + }; + + /** diff --git a/feeds/mediatek-sdk/mediatek/files-5.4/arch/arm64/boot/dts/mediatek/mt7981-edgecore-eap111.dts b/feeds/mediatek-sdk/mediatek/files-5.4/arch/arm64/boot/dts/mediatek/mt7981-edgecore-eap111.dts index 60cf5ec58..45305d119 100755 --- a/feeds/mediatek-sdk/mediatek/files-5.4/arch/arm64/boot/dts/mediatek/mt7981-edgecore-eap111.dts +++ b/feeds/mediatek-sdk/mediatek/files-5.4/arch/arm64/boot/dts/mediatek/mt7981-edgecore-eap111.dts @@ -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 { diff --git a/feeds/mediatek-sdk/mediatek/files-5.4/arch/arm64/boot/dts/mediatek/mt7981-edgecore-eap112.dts b/feeds/mediatek-sdk/mediatek/files-5.4/arch/arm64/boot/dts/mediatek/mt7981-edgecore-eap112.dts index e7a15ca82..d728eab55 100755 --- a/feeds/mediatek-sdk/mediatek/files-5.4/arch/arm64/boot/dts/mediatek/mt7981-edgecore-eap112.dts +++ b/feeds/mediatek-sdk/mediatek/files-5.4/arch/arm64/boot/dts/mediatek/mt7981-edgecore-eap112.dts @@ -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 { diff --git a/feeds/mediatek-sdk/mediatek/files-5.4/arch/arm64/boot/dts/mediatek/mt7981-emplus-wap588m.dts b/feeds/mediatek-sdk/mediatek/files-5.4/arch/arm64/boot/dts/mediatek/mt7981-emplus-wap588m.dts new file mode 100644 index 000000000..407ec5b12 --- /dev/null +++ b/feeds/mediatek-sdk/mediatek/files-5.4/arch/arm64/boot/dts/mediatek/mt7981-emplus-wap588m.dts @@ -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 = ; + 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 = ; + bias-pull-up = ; + }; + + conf-pd { + pins = "SPI0_CLK", "SPI0_MOSI", "SPI0_MISO"; + drive-strength = ; + bias-pull-down = ; + }; + }; + + 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 = ; + }; + }; +}; + +&xhci { + mediatek,u3p-dis-msk = <0x0>; + phys = <&u2port0 PHY_TYPE_USB2>, + <&u3port0 PHY_TYPE_USB3>; + status = "disabled"; +}; diff --git a/feeds/mediatek-sdk/mediatek/files-5.4/drivers/net/phy/an8801.c b/feeds/mediatek-sdk/mediatek/files-5.4/drivers/net/phy/an8801.c index a366d23bf..3089a1012 100644 --- a/feeds/mediatek-sdk/mediatek/files-5.4/drivers/net/phy/an8801.c +++ b/feeds/mediatek-sdk/mediatek/files-5.4/drivers/net/phy/an8801.c @@ -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<>\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 } }; diff --git a/feeds/mediatek-sdk/mediatek/files-5.4/drivers/net/phy/an8801.h b/feeds/mediatek-sdk/mediatek/files-5.4/drivers/net/phy/an8801.h index c98c9e098..06234a256 100644 --- a/feeds/mediatek-sdk/mediatek/files-5.4/drivers/net/phy/an8801.h +++ b/feeds/mediatek-sdk/mediatek/files-5.4/drivers/net/phy/an8801.h @@ -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 { diff --git a/feeds/mediatek-sdk/mediatek/files-5.4/drivers/net/phy/en8801sc.c b/feeds/mediatek-sdk/mediatek/files-5.4/drivers/net/phy/en8801sc.c index 2cbea7229..12c8a0f86 100644 --- a/feeds/mediatek-sdk/mediatek/files-5.4/drivers/net/phy/en8801sc.c +++ b/feeds/mediatek-sdk/mediatek/files-5.4/drivers/net/phy/en8801sc.c @@ -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; diff --git a/feeds/mediatek-sdk/mediatek/image/mt7981.mk b/feeds/mediatek-sdk/mediatek/image/mt7981.mk index bcc720db4..44cce6e5f 100755 --- a/feeds/mediatek-sdk/mediatek/image/mt7981.mk +++ b/feeds/mediatek-sdk/mediatek/image/mt7981.mk @@ -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 diff --git a/feeds/mediatek-sdk/mediatek/mt7981/base-files/etc/board.d/02_network b/feeds/mediatek-sdk/mediatek/mt7981/base-files/etc/board.d/02_network index fd19693eb..736309eda 100644 --- a/feeds/mediatek-sdk/mediatek/mt7981/base-files/etc/board.d/02_network +++ b/feeds/mediatek-sdk/mediatek/mt7981/base-files/etc/board.d/02_network @@ -31,7 +31,10 @@ 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" ;; diff --git a/feeds/mediatek-sdk/mediatek/mt7981/base-files/etc/uci-defaults/30_uboot-envtools b/feeds/mediatek-sdk/mediatek/mt7981/base-files/etc/uci-defaults/30_uboot-envtools index addad6664..b4b248037 100644 --- a/feeds/mediatek-sdk/mediatek/mt7981/base-files/etc/uci-defaults/30_uboot-envtools +++ b/feeds/mediatek-sdk/mediatek/mt7981/base-files/etc/uci-defaults/30_uboot-envtools @@ -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" ;; diff --git a/feeds/mediatek-sdk/mediatek/mt7981/base-files/lib/upgrade/platform.sh b/feeds/mediatek-sdk/mediatek/mt7981/base-files/lib/upgrade/platform.sh index 1059c7f55..3e5d58a41 100644 --- a/feeds/mediatek-sdk/mediatek/mt7981/base-files/lib/upgrade/platform.sh +++ b/feeds/mediatek-sdk/mediatek/mt7981/base-files/lib/upgrade/platform.sh @@ -2,13 +2,13 @@ REQUIRE_IMAGE_METADATA=1 senao_swap_active_fw() { echo "Doing swap active_fw" > /dev/console - tmp_active_fw=$(fw_printenv -n active_fw) + 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\),112640k\(ubi_1\),112640k\(ubi\),384k\(cert\),640k\(userconfig\),384k\(crashdump\) + 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\),112640k\(ubi\),112640k\(ubi_1\),384k\(cert\),640k\(userconfig\),384k\(crashdump\) + 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 } @@ -47,6 +47,7 @@ platform_do_upgrade() { nand_do_upgrade "$1" ;; senao,iap2300m|\ + emplus,wap588m|\ senao,jeap6500) CI_UBIPART="ubi_1" nand_do_upgrade "$1" @@ -68,6 +69,7 @@ platform_check_image() { edgecore,eap111|\ edgecore,eap112|\ senao,iap2300m|\ + emplus,wap588m|\ senao,jeap6500) nand_do_platform_check "$board" "$1" return $? diff --git a/feeds/mediatek-sdk/mediatek/mt7981/config-5.4 b/feeds/mediatek-sdk/mediatek/mt7981/config-5.4 index aa0f6ee88..2cc5dc41d 100644 --- a/feeds/mediatek-sdk/mediatek/mt7981/config-5.4 +++ b/feeds/mediatek-sdk/mediatek/mt7981/config-5.4 @@ -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 diff --git a/feeds/mediatek-sdk/mediatek/patches-5.4/999-2738-an8801sb-gphy-support.patch b/feeds/mediatek-sdk/mediatek/patches-5.4/999-2738-an8801sb-gphy-support.patch index 1a7fbf15e..0419cbafb 100644 --- a/feeds/mediatek-sdk/mediatek/patches-5.4/999-2738-an8801sb-gphy-support.patch +++ b/feeds/mediatek-sdk/mediatek/patches-5.4/999-2738-an8801sb-gphy-support.patch @@ -1,15 +1,3 @@ -From 535fdc6dfce7def996a5188819ffc96231c36f98 Mon Sep 17 00:00:00 2001 -From: Bo-Cun Chen -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); + diff --git a/feeds/morse/kernel/mm-board-config/LICENSE.binaries b/feeds/morse/kernel/mm-board-config/LICENSE.binaries new file mode 100644 index 000000000..adf90750d --- /dev/null +++ b/feeds/morse/kernel/mm-board-config/LICENSE.binaries @@ -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 diff --git a/feeds/morse/kernel/mm-board-config/Makefile b/feeds/morse/kernel/mm-board-config/Makefile new file mode 100644 index 000000000..5698f48c8 --- /dev/null +++ b/feeds/morse/kernel/mm-board-config/Makefile @@ -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 +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)) diff --git a/feeds/morse/kernel/mm-board-config/files/etc/hotplug.d/ieee80211/20-module-type b/feeds/morse/kernel/mm-board-config/files/etc/hotplug.d/ieee80211/20-module-type new file mode 100644 index 000000000..52e21c1a1 --- /dev/null +++ b/feeds/morse/kernel/mm-board-config/files/etc/hotplug.d/ieee80211/20-module-type @@ -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 +} diff --git a/feeds/morse/kernel/mm-board-config/files/lib/firmware/morse/bcf_edgecore_eap112_fcc.bin b/feeds/morse/kernel/mm-board-config/files/lib/firmware/morse/bcf_edgecore_eap112_fcc.bin new file mode 100644 index 000000000..07af8e1b9 Binary files /dev/null and b/feeds/morse/kernel/mm-board-config/files/lib/firmware/morse/bcf_edgecore_eap112_fcc.bin differ diff --git a/feeds/morse/kernel/mm-board-config/files/lib/firmware/morse/bcf_failsafe.bin b/feeds/morse/kernel/mm-board-config/files/lib/firmware/morse/bcf_failsafe.bin new file mode 100644 index 000000000..b47329187 Binary files /dev/null and b/feeds/morse/kernel/mm-board-config/files/lib/firmware/morse/bcf_failsafe.bin differ diff --git a/feeds/morse/kernel/mm-board-config/files/lib/firmware/morse/bcf_mf08651_us.bin b/feeds/morse/kernel/mm-board-config/files/lib/firmware/morse/bcf_mf08651_us.bin new file mode 100755 index 000000000..6aa54e167 Binary files /dev/null and b/feeds/morse/kernel/mm-board-config/files/lib/firmware/morse/bcf_mf08651_us.bin differ diff --git a/feeds/morse/kernel/mm-board-config/files/usr/share/morse-bcf/db.txt b/feeds/morse/kernel/mm-board-config/files/usr/share/morse-bcf/db.txt new file mode 100644 index 000000000..09cbb53ca --- /dev/null +++ b/feeds/morse/kernel/mm-board-config/files/usr/share/morse-bcf/db.txt @@ -0,0 +1 @@ +0801,05us,mf08651_us diff --git a/feeds/morse/kernel/mm61xx/Makefile b/feeds/morse/kernel/mm61xx/Makefile new file mode 100644 index 000000000..02c240577 --- /dev/null +++ b/feeds/morse/kernel/mm61xx/Makefile @@ -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)) diff --git a/feeds/morse/kernel/mm61xx/patches/002-fix-watchdog-interval.patch b/feeds/morse/kernel/mm61xx/patches/002-fix-watchdog-interval.patch new file mode 100644 index 000000000..38037c335 --- /dev/null +++ b/feeds/morse/kernel/mm61xx/patches/002-fix-watchdog-interval.patch @@ -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) diff --git a/feeds/morse/kernel/mm61xx/patches/003-ekh01-spi-fix.patch b/feeds/morse/kernel/mm61xx/patches/003-ekh01-spi-fix.patch new file mode 100644 index 000000000..a3e871511 --- /dev/null +++ b/feeds/morse/kernel/mm61xx/patches/003-ekh01-spi-fix.patch @@ -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 */ diff --git a/feeds/morse/kernel/mm61xx/patches/004-fix-kernel-version-check.patch b/feeds/morse/kernel/mm61xx/patches/004-fix-kernel-version-check.patch new file mode 100644 index 000000000..370558e01 --- /dev/null +++ b/feeds/morse/kernel/mm61xx/patches/004-fix-kernel-version-check.patch @@ -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); diff --git a/feeds/morse/kernel/mm61xx/patches/007-sysfs-add-sysfs-to-export-board-type-as-a-device-att.patch b/feeds/morse/kernel/mm61xx/patches/007-sysfs-add-sysfs-to-export-board-type-as-a-device-att.patch new file mode 100644 index 000000000..e499cf54d --- /dev/null +++ b/feeds/morse/kernel/mm61xx/patches/007-sysfs-add-sysfs-to-export-board-type-as-a-device-att.patch @@ -0,0 +1,160 @@ +From 9ebc9a01e90f65f058ed21d3190800dc130b6ef4 Mon Sep 17 00:00:00 2001 +From: Arien Judge +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 ++#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); diff --git a/feeds/morse/kernel/mm61xx/patches/010-fix-sdio-error.patch b/feeds/morse/kernel/mm61xx/patches/010-fix-sdio-error.patch new file mode 100644 index 000000000..9e8850055 --- /dev/null +++ b/feeds/morse/kernel/mm61xx/patches/010-fix-sdio-error.patch @@ -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); + diff --git a/feeds/morse/kernel/mm61xx/patches/011-update-spi.patch b/feeds/morse/kernel/mm61xx/patches/011-update-spi.patch new file mode 100644 index 000000000..fdfedf953 --- /dev/null +++ b/feeds/morse/kernel/mm61xx/patches/011-update-spi.patch @@ -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; diff --git a/feeds/morse/kernel/morse-fw/LICENSE.binaries b/feeds/morse/kernel/morse-fw/LICENSE.binaries new file mode 100644 index 000000000..adf90750d --- /dev/null +++ b/feeds/morse/kernel/morse-fw/LICENSE.binaries @@ -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 diff --git a/feeds/morse/kernel/morse-fw/Makefile b/feeds/morse/kernel/morse-fw/Makefile new file mode 100644 index 000000000..fbef9b7a6 --- /dev/null +++ b/feeds/morse/kernel/morse-fw/Makefile @@ -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 +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)) diff --git a/feeds/morse/kernel/morse-fw/morsemicro-fw-rel_1_11_4_2024_Jul_09.tar b/feeds/morse/kernel/morse-fw/morsemicro-fw-rel_1_11_4_2024_Jul_09.tar new file mode 100644 index 000000000..43663761e Binary files /dev/null and b/feeds/morse/kernel/morse-fw/morsemicro-fw-rel_1_11_4_2024_Jul_09.tar differ diff --git a/feeds/morse/kernel/morse-fw/morsemicro-fw-rel_1_12_4_2024_Jun_11.tar b/feeds/morse/kernel/morse-fw/morsemicro-fw-rel_1_12_4_2024_Jun_11.tar new file mode 100644 index 000000000..9dc88f9a0 Binary files /dev/null and b/feeds/morse/kernel/morse-fw/morsemicro-fw-rel_1_12_4_2024_Jun_11.tar differ diff --git a/feeds/morse/morse-regdb/Makefile b/feeds/morse/morse-regdb/Makefile new file mode 100644 index 000000000..8222ec02a --- /dev/null +++ b/feeds/morse/morse-regdb/Makefile @@ -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)) diff --git a/feeds/morse/morse-regdb/add_5g_shim_channels.py b/feeds/morse/morse-regdb/add_5g_shim_channels.py new file mode 100755 index 000000000..5c64cad23 --- /dev/null +++ b/feeds/morse/morse-regdb/add_5g_shim_channels.py @@ -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) diff --git a/feeds/morse/morse-regdb/artefacts/repo_channels.csv b/feeds/morse/morse-regdb/artefacts/repo_channels.csv new file mode 100644 index 000000000..0b8d4167b --- /dev/null +++ b/feeds/morse/morse-regdb/artefacts/repo_channels.csv @@ -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 diff --git a/feeds/morse/morse-regdb/patches/001-add_column_usable_bannf_c.patch b/feeds/morse/morse-regdb/patches/001-add_column_usable_bannf_c.patch new file mode 100644 index 000000000..0f97524d5 --- /dev/null +++ b/feeds/morse/morse-regdb/patches/001-add_column_usable_bannf_c.patch @@ -0,0 +1,36 @@ +From 6c0733b125434b846bec2a744a812c890c82518d Mon Sep 17 00:00:00 2001 +From: Takura Mapani +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 + diff --git a/feeds/morse/netifd-morse/Makefile b/feeds/morse/netifd-morse/Makefile new file mode 100644 index 000000000..6a13c0fad --- /dev/null +++ b/feeds/morse/netifd-morse/Makefile @@ -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 + +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)) diff --git a/feeds/morse/netifd-morse/etc/init.d/halow-gpio-reset b/feeds/morse/netifd-morse/etc/init.d/halow-gpio-reset new file mode 100755 index 000000000..08d1b48f9 --- /dev/null +++ b/feeds/morse/netifd-morse/etc/init.d/halow-gpio-reset @@ -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 +} diff --git a/feeds/morse/netifd-morse/lib/netifd/morse/morse_overrides.sh b/feeds/morse/netifd-morse/lib/netifd/morse/morse_overrides.sh new file mode 100644 index 000000000..f284c8a7f --- /dev/null +++ b/feeds/morse/netifd-morse/lib/netifd/morse/morse_overrides.sh @@ -0,0 +1,1170 @@ +# netifd wireless implements _wdev_prepare_channel +# which parses the band and hwmode config options before a drv_* function is called +# for now, we override these with desired vals to avoid modifying netifd-wireless +morse_band_override(){ + band=s1g + hwmode=a +} + +# Unlike the other morse functions, this doesn't override but instead +# just adds some extra config options before the network definition. +morse_wpa_supplicant_prepare_interface() { + local _ifname=$1 + _wpa_supplicant_common $_ifname + + json_get_vars sae_pwe multi_ap + json_get_values sae_group_list sae_group + + [ "${multi_ap:=0}" -lt 1 ] && set_default sae_pwe 1 + + local pmf= + [ "${multi_ap:=0}" -eq 1 ] && pmf=2 + + cat >> "$_config" <