2011-07-23 13:28:58

by Pavel Roskin

[permalink] [raw]
Subject: [PATCH 2 1/3] ath5k: remove unused and write-only structures and fields

struct ath5k_avg_val is unused.

In struct ath5k_hw, lladdr, ah_radar and ah_mac_revision are write-only,
rxbufsize is unused, ah_phy is write-only and referenced by unused
macros.

In struct ath5k_vif, lladdr is write-only.

Remove AR5K_TUNE_RADAR_ALERT, which has no effect.

Signed-off-by: Pavel Roskin <[email protected]>
Tested-by: Sedat Dilek <[email protected]>
---
drivers/net/wireless/ath/ath5k/ath5k.h | 28 -------------------------
drivers/net/wireless/ath/ath5k/attach.c | 5 +---
drivers/net/wireless/ath/ath5k/base.c | 1 -
drivers/net/wireless/ath/ath5k/base.h | 1 -
drivers/net/wireless/ath/ath5k/mac80211-ops.c | 3 ---
5 files changed, 1 insertions(+), 37 deletions(-)

diff --git a/drivers/net/wireless/ath/ath5k/ath5k.h b/drivers/net/wireless/ath/ath5k/ath5k.h
index 277d5cb..be7b8c0 100644
--- a/drivers/net/wireless/ath/ath5k/ath5k.h
+++ b/drivers/net/wireless/ath/ath5k/ath5k.h
@@ -131,13 +131,6 @@
#define AR5K_REG_DISABLE_BITS(ah, _reg, _flags) \
ath5k_hw_reg_write(ah, ath5k_hw_reg_read(ah, _reg) & ~(_flags), _reg)

-/* Access to PHY registers */
-#define AR5K_PHY_READ(ah, _reg) \
- ath5k_hw_reg_read(ah, (ah)->ah_phy + ((_reg) << 2))
-
-#define AR5K_PHY_WRITE(ah, _reg, _val) \
- ath5k_hw_reg_write(ah, _val, (ah)->ah_phy + ((_reg) << 2))
-
/* Access QCU registers per queue */
#define AR5K_REG_READ_Q(ah, _reg, _queue) \
(ath5k_hw_reg_read(ah, _reg) & (1 << _queue)) \
@@ -166,7 +159,6 @@
#define AR5K_TUNE_DMA_BEACON_RESP 2
#define AR5K_TUNE_SW_BEACON_RESP 10
#define AR5K_TUNE_ADDITIONAL_SWBA_BACKOFF 0
-#define AR5K_TUNE_RADAR_ALERT false
#define AR5K_TUNE_MIN_TX_FIFO_THRES 1
#define AR5K_TUNE_MAX_TX_FIFO_THRES ((IEEE80211_MAX_FRAME_LEN / 64) + 1)
#define AR5K_TUNE_REGISTER_TIMEOUT 20000
@@ -1013,16 +1005,6 @@ struct ath5k_nfcal_hist {
s16 nfval[ATH5K_NF_CAL_HIST_MAX]; /* last few noise floors */
};

-/**
- * struct avg_val - Helper structure for average calculation
- * @avg: contains the actual average value
- * @avg_weight: is used internally during calculation to prevent rounding errors
- */
-struct ath5k_avg_val {
- int avg;
- int avg_weight;
-};
-
#define ATH5K_LED_MAX_NAME_LEN 31

/*
@@ -1148,7 +1130,6 @@ struct ath5k_hw {
bool rx_pending; /* rx tasklet pending */
bool tx_pending; /* tx tasklet pending */

- u8 lladdr[ETH_ALEN];
u8 bssidmask[ETH_ALEN];

unsigned int led_pin, /* GPIO pin for driving LED */
@@ -1156,7 +1137,6 @@ struct ath5k_hw {

struct work_struct reset_work; /* deferred chip reset */

- unsigned int rxbufsize; /* rx size based on mtu */
struct list_head rxbuf; /* receive buffer */
spinlock_t rxbuflock;
u32 *rxlink; /* link ptr in last RX desc */
@@ -1208,10 +1188,8 @@ struct ath5k_hw {

enum ath5k_version ah_version;
enum ath5k_radio ah_radio;
- u32 ah_phy;
u32 ah_mac_srev;
u16 ah_mac_version;
- u16 ah_mac_revision;
u16 ah_phy_revision;
u16 ah_radio_5ghz_revision;
u16 ah_radio_2ghz_revision;
@@ -1279,12 +1257,6 @@ struct ath5k_hw {
bool txp_setup;
} ah_txpower;

- struct {
- bool r_enabled;
- int r_last_alert;
- struct ieee80211_channel r_last_channel;
- } ah_radar;
-
struct ath5k_nfcal_hist ah_nfcal_hist;

/* average beacon RSSI in our BSS (used by ANI) */
diff --git a/drivers/net/wireless/ath/ath5k/attach.c b/drivers/net/wireless/ath/ath5k/attach.c
index f8a6b38..b0df2f6 100644
--- a/drivers/net/wireless/ath/ath5k/attach.c
+++ b/drivers/net/wireless/ath/ath5k/attach.c
@@ -114,7 +114,6 @@ int ath5k_hw_init(struct ath5k_hw *ah)
/*
* HW information
*/
- ah->ah_radar.r_enabled = AR5K_TUNE_RADAR_ALERT;
ah->ah_bwmode = AR5K_BWMODE_DEFAULT;
ah->ah_txpower.txp_tpc = AR5K_TUNE_TPC_TXPOWER;
ah->ah_imr = 0;
@@ -137,9 +136,8 @@ int ath5k_hw_init(struct ath5k_hw *ah)
else
ah->ah_version = AR5K_AR5212;

- /* Get the MAC revision */
+ /* Get the MAC version */
ah->ah_mac_version = AR5K_REG_MS(srev, AR5K_SREV_VER);
- ah->ah_mac_revision = AR5K_REG_MS(srev, AR5K_SREV_REV);

/* Fill the ath5k_hw struct with the needed functions */
ret = ath5k_hw_init_desc_functions(ah);
@@ -156,7 +154,6 @@ int ath5k_hw_init(struct ath5k_hw *ah)
0xffffffff;
ah->ah_radio_5ghz_revision = ath5k_hw_radio_revision(ah,
CHANNEL_5GHZ);
- ah->ah_phy = AR5K_PHY(0);

/* Try to identify radio chip based on its srev */
switch (ah->ah_radio_5ghz_revision & 0xf0) {
diff --git a/drivers/net/wireless/ath/ath5k/base.c b/drivers/net/wireless/ath/ath5k/base.c
index a74d286..ee06e34 100644
--- a/drivers/net/wireless/ath/ath5k/base.c
+++ b/drivers/net/wireless/ath/ath5k/base.c
@@ -2861,7 +2861,6 @@ ath5k_init(struct ieee80211_hw *hw)
}

SET_IEEE80211_PERM_ADDR(hw, mac);
- memcpy(&ah->lladdr, mac, ETH_ALEN);
/* All MAC address bits matter for ACKs */
ath5k_update_bssid_mask_and_opmode(ah, NULL);

diff --git a/drivers/net/wireless/ath/ath5k/base.h b/drivers/net/wireless/ath/ath5k/base.h
index a81f28d..5501bcb 100644
--- a/drivers/net/wireless/ath/ath5k/base.h
+++ b/drivers/net/wireless/ath/ath5k/base.h
@@ -65,7 +65,6 @@ struct ath5k_vif {
enum nl80211_iftype opmode;
int bslot;
struct ath5k_buf *bbuf; /* beacon buffer */
- u8 lladdr[ETH_ALEN];
};

struct ath5k_vif_iter_data {
diff --git a/drivers/net/wireless/ath/ath5k/mac80211-ops.c b/drivers/net/wireless/ath/ath5k/mac80211-ops.c
index 2a715ca..53d3af9 100644
--- a/drivers/net/wireless/ath/ath5k/mac80211-ops.c
+++ b/drivers/net/wireless/ath/ath5k/mac80211-ops.c
@@ -137,11 +137,8 @@ ath5k_add_interface(struct ieee80211_hw *hw, struct ieee80211_vif *vif)
/* Any MAC address is fine, all others are included through the
* filter.
*/
- memcpy(&ah->lladdr, vif->addr, ETH_ALEN);
ath5k_hw_set_lladdr(ah, vif->addr);

- memcpy(&avf->lladdr, vif->addr, ETH_ALEN);
-
ath5k_update_bssid_mask_and_opmode(ah, vif);
ret = 0;
end:


2011-07-23 13:29:04

by Pavel Roskin

[permalink] [raw]
Subject: [PATCH 2 2/3] ath5k: remove most references to XR

XR is a proprietary feature of the chipset. It's not supported and
should not be supported.

Signed-off-by: Pavel Roskin <[email protected]>
Tested-by: Sedat Dilek <[email protected]>
---
drivers/net/wireless/ath/ath5k/ath5k.h | 4 ----
drivers/net/wireless/ath/ath5k/eeprom.c | 1 -
drivers/net/wireless/ath/ath5k/phy.c | 2 --
drivers/net/wireless/ath/ath5k/qcu.c | 7 -------
drivers/net/wireless/ath/ath5k/reset.c | 8 --------
5 files changed, 0 insertions(+), 22 deletions(-)

diff --git a/drivers/net/wireless/ath/ath5k/ath5k.h b/drivers/net/wireless/ath/ath5k/ath5k.h
index be7b8c0..a8a7db4 100644
--- a/drivers/net/wireless/ath/ath5k/ath5k.h
+++ b/drivers/net/wireless/ath/ath5k/ath5k.h
@@ -416,7 +416,6 @@ enum ath5k_driver_mode {
AR5K_MODE_11A = 0,
AR5K_MODE_11B = 1,
AR5K_MODE_11G = 2,
- AR5K_MODE_XR = 0,
AR5K_MODE_MAX = 3
};

@@ -694,12 +693,10 @@ struct ath5k_gain {
#define CHANNEL_5GHZ 0x0100 /* 5GHz channel */
#define CHANNEL_PASSIVE 0x0200 /* Only passive scan allowed */
#define CHANNEL_DYN 0x0400 /* Dynamic CCK-OFDM channel (for g operation) */
-#define CHANNEL_XR 0x0800 /* XR channel */

#define CHANNEL_A (CHANNEL_5GHZ | CHANNEL_OFDM)
#define CHANNEL_B (CHANNEL_2GHZ | CHANNEL_CCK)
#define CHANNEL_G (CHANNEL_2GHZ | CHANNEL_OFDM)
-#define CHANNEL_X (CHANNEL_5GHZ | CHANNEL_OFDM | CHANNEL_XR)

#define CHANNEL_ALL (CHANNEL_OFDM | CHANNEL_CCK | \
CHANNEL_2GHZ | CHANNEL_5GHZ)
@@ -710,7 +707,6 @@ struct ath5k_gain {
* Used internally for ath5k_hw_reset_tx_queue().
* Also see struct struct ieee80211_channel.
*/
-#define IS_CHAN_XR(_c) ((_c->hw_value & CHANNEL_XR) != 0)
#define IS_CHAN_B(_c) ((_c->hw_value & CHANNEL_B) != 0)

/*
diff --git a/drivers/net/wireless/ath/ath5k/eeprom.c b/drivers/net/wireless/ath/ath5k/eeprom.c
index 9068b91..56cb9d4 100644
--- a/drivers/net/wireless/ath/ath5k/eeprom.c
+++ b/drivers/net/wireless/ath/ath5k/eeprom.c
@@ -1782,7 +1782,6 @@ ath5k_eeprom_mode_from_channel(struct ieee80211_channel *channel)
{
switch (channel->hw_value & CHANNEL_MODES) {
case CHANNEL_A:
- case CHANNEL_XR:
return AR5K_EEPROM_MODE_11A;
case CHANNEL_G:
return AR5K_EEPROM_MODE_11G;
diff --git a/drivers/net/wireless/ath/ath5k/phy.c b/drivers/net/wireless/ath/ath5k/phy.c
index 81e465e..b9ada88 100644
--- a/drivers/net/wireless/ath/ath5k/phy.c
+++ b/drivers/net/wireless/ath/ath5k/phy.c
@@ -2408,8 +2408,6 @@ ath5k_get_max_ctl_power(struct ath5k_hw *ah,
case CHANNEL_B:
ctl_mode |= AR5K_CTL_11B;
break;
- case CHANNEL_XR:
- /* Fall through */
default:
return;
}
diff --git a/drivers/net/wireless/ath/ath5k/qcu.c b/drivers/net/wireless/ath/ath5k/qcu.c
index 65f1039..1d37675 100644
--- a/drivers/net/wireless/ath/ath5k/qcu.c
+++ b/drivers/net/wireless/ath/ath5k/qcu.c
@@ -185,13 +185,6 @@ int ath5k_hw_setup_tx_queue(struct ath5k_hw *ah, enum ath5k_tx_queue queue_type,
case AR5K_TX_QUEUE_CAB:
queue = AR5K_TX_QUEUE_ID_CAB;
break;
- case AR5K_TX_QUEUE_XR_DATA:
- if (ah->ah_version != AR5K_AR5212)
- ATH5K_ERR(ah,
- "XR data queues only supported in"
- " 5212!\n");
- queue = AR5K_TX_QUEUE_ID_XR_DATA;
- break;
default:
return -EINVAL;
}
diff --git a/drivers/net/wireless/ath/ath5k/reset.c b/drivers/net/wireless/ath/ath5k/reset.c
index 0686c5d..5d6d3bd 100644
--- a/drivers/net/wireless/ath/ath5k/reset.c
+++ b/drivers/net/wireless/ath/ath5k/reset.c
@@ -1108,14 +1108,6 @@ int ath5k_hw_reset(struct ath5k_hw *ah, enum nl80211_iftype op_mode,

mode = AR5K_MODE_11B;
break;
- case CHANNEL_XR:
- if (ah->ah_version == AR5K_AR5211) {
- ATH5K_ERR(ah,
- "XR mode not available on 5211");
- return -EINVAL;
- }
- mode = AR5K_MODE_XR;
- break;
default:
ATH5K_ERR(ah,
"invalid channel: %d\n", channel->center_freq);

2011-07-23 13:29:11

by Pavel Roskin

[permalink] [raw]
Subject: [PATCH 2 3/3] ath5k: eliminate CHANNEL_* macros, use AR5K_MODE_* in channel->hw_value

When checking for the band, use channel->band.

Change ath5k_hw_nic_wakeup() and ath5k_channel_ok() to take
ieee80211_channel. Change ath5k_hw_radio_revision() to take
ieee80211_band.

Signed-off-by: Pavel Roskin <[email protected]>
Tested-by: Sedat Dilek <[email protected]>
---
drivers/net/wireless/ath/ath5k/ath5k.h | 32 +----------
drivers/net/wireless/ath/ath5k/attach.c | 10 ++--
drivers/net/wireless/ath/ath5k/base.c | 23 ++------
drivers/net/wireless/ath/ath5k/eeprom.c | 8 +--
drivers/net/wireless/ath/ath5k/pcu.c | 4 +
drivers/net/wireless/ath/ath5k/phy.c | 87 +++++++++++++++++--------------
drivers/net/wireless/ath/ath5k/qcu.c | 2 -
drivers/net/wireless/ath/ath5k/reset.c | 70 +++++++++++--------------
8 files changed, 102 insertions(+), 134 deletions(-)

diff --git a/drivers/net/wireless/ath/ath5k/ath5k.h b/drivers/net/wireless/ath/ath5k/ath5k.h
index a8a7db4..0d413be 100644
--- a/drivers/net/wireless/ath/ath5k/ath5k.h
+++ b/drivers/net/wireless/ath/ath5k/ath5k.h
@@ -685,30 +685,6 @@ struct ath5k_gain {
#define AR5K_SLOT_TIME_20 880
#define AR5K_SLOT_TIME_MAX 0xffff

-/* channel_flags */
-#define CHANNEL_CW_INT 0x0008 /* Contention Window interference detected */
-#define CHANNEL_CCK 0x0020 /* CCK channel */
-#define CHANNEL_OFDM 0x0040 /* OFDM channel */
-#define CHANNEL_2GHZ 0x0080 /* 2GHz channel. */
-#define CHANNEL_5GHZ 0x0100 /* 5GHz channel */
-#define CHANNEL_PASSIVE 0x0200 /* Only passive scan allowed */
-#define CHANNEL_DYN 0x0400 /* Dynamic CCK-OFDM channel (for g operation) */
-
-#define CHANNEL_A (CHANNEL_5GHZ | CHANNEL_OFDM)
-#define CHANNEL_B (CHANNEL_2GHZ | CHANNEL_CCK)
-#define CHANNEL_G (CHANNEL_2GHZ | CHANNEL_OFDM)
-
-#define CHANNEL_ALL (CHANNEL_OFDM | CHANNEL_CCK | \
- CHANNEL_2GHZ | CHANNEL_5GHZ)
-
-#define CHANNEL_MODES CHANNEL_ALL
-
-/*
- * Used internally for ath5k_hw_reset_tx_queue().
- * Also see struct struct ieee80211_channel.
- */
-#define IS_CHAN_B(_c) ((_c->hw_value & CHANNEL_B) != 0)
-
/*
* The following structure is used to map 2GHz channels to
* 5GHz Atheros channels.
@@ -965,7 +941,7 @@ enum ath5k_power_mode {
struct ath5k_capabilities {
/*
* Supported PHY modes
- * (ie. CHANNEL_A, CHANNEL_B, ...)
+ * (ie. AR5K_MODE_11A, AR5K_MODE_11B, ...)
*/
DECLARE_BITMAP(cap_mode, AR5K_MODE_MAX);

@@ -1335,7 +1311,7 @@ void ath5k_unregister_leds(struct ath5k_hw *ah);


/* Reset Functions */
-int ath5k_hw_nic_wakeup(struct ath5k_hw *ah, int flags, bool initial);
+int ath5k_hw_nic_wakeup(struct ath5k_hw *ah, struct ieee80211_channel *channel);
int ath5k_hw_on_hold(struct ath5k_hw *ah);
int ath5k_hw_reset(struct ath5k_hw *ah, enum nl80211_iftype op_mode,
struct ieee80211_channel *channel, bool fast, bool skip_pcu);
@@ -1455,13 +1431,13 @@ int ath5k_hw_write_initvals(struct ath5k_hw *ah, u8 mode, bool change_channel);

/* PHY functions */
/* Misc PHY functions */
-u16 ath5k_hw_radio_revision(struct ath5k_hw *ah, unsigned int chan);
+u16 ath5k_hw_radio_revision(struct ath5k_hw *ah, enum ieee80211_band band);
int ath5k_hw_phy_disable(struct ath5k_hw *ah);
/* Gain_F optimization */
enum ath5k_rfgain ath5k_hw_gainf_calibrate(struct ath5k_hw *ah);
int ath5k_hw_rfgain_opt_init(struct ath5k_hw *ah);
/* PHY/RF channel functions */
-bool ath5k_channel_ok(struct ath5k_hw *ah, u16 freq, unsigned int flags);
+bool ath5k_channel_ok(struct ath5k_hw *ah, struct ieee80211_channel *channel);
/* PHY calibration */
void ath5k_hw_init_nfcal_hist(struct ath5k_hw *ah);
int ath5k_hw_phy_calibrate(struct ath5k_hw *ah,
diff --git a/drivers/net/wireless/ath/ath5k/attach.c b/drivers/net/wireless/ath/ath5k/attach.c
index b0df2f6..5606259 100644
--- a/drivers/net/wireless/ath/ath5k/attach.c
+++ b/drivers/net/wireless/ath/ath5k/attach.c
@@ -145,7 +145,7 @@ int ath5k_hw_init(struct ath5k_hw *ah)
goto err;

/* Bring device out of sleep and reset its units */
- ret = ath5k_hw_nic_wakeup(ah, 0, true);
+ ret = ath5k_hw_nic_wakeup(ah, NULL);
if (ret)
goto err;

@@ -153,7 +153,7 @@ int ath5k_hw_init(struct ath5k_hw *ah)
ah->ah_phy_revision = ath5k_hw_reg_read(ah, AR5K_PHY_CHIP_ID) &
0xffffffff;
ah->ah_radio_5ghz_revision = ath5k_hw_radio_revision(ah,
- CHANNEL_5GHZ);
+ IEEE80211_BAND_5GHZ);

/* Try to identify radio chip based on its srev */
switch (ah->ah_radio_5ghz_revision & 0xf0) {
@@ -161,14 +161,14 @@ int ath5k_hw_init(struct ath5k_hw *ah)
ah->ah_radio = AR5K_RF5111;
ah->ah_single_chip = false;
ah->ah_radio_2ghz_revision = ath5k_hw_radio_revision(ah,
- CHANNEL_2GHZ);
+ IEEE80211_BAND_2GHZ);
break;
case AR5K_SREV_RAD_5112:
case AR5K_SREV_RAD_2112:
ah->ah_radio = AR5K_RF5112;
ah->ah_single_chip = false;
ah->ah_radio_2ghz_revision = ath5k_hw_radio_revision(ah,
- CHANNEL_2GHZ);
+ IEEE80211_BAND_2GHZ);
break;
case AR5K_SREV_RAD_2413:
ah->ah_radio = AR5K_RF2413;
@@ -205,7 +205,7 @@ int ath5k_hw_init(struct ath5k_hw *ah)
ah->ah_radio = AR5K_RF5111;
ah->ah_single_chip = false;
ah->ah_radio_2ghz_revision = ath5k_hw_radio_revision(ah,
- CHANNEL_2GHZ);
+ IEEE80211_BAND_2GHZ);
} else if (ah->ah_mac_version == (AR5K_SREV_AR2425 >> 4) ||
ah->ah_mac_version == (AR5K_SREV_AR2417 >> 4) ||
ah->ah_phy_revision == AR5K_SREV_PHY_2425) {
diff --git a/drivers/net/wireless/ath/ath5k/base.c b/drivers/net/wireless/ath/ath5k/base.c
index ee06e34..dfbbd16 100644
--- a/drivers/net/wireless/ath/ath5k/base.c
+++ b/drivers/net/wireless/ath/ath5k/base.c
@@ -271,20 +271,18 @@ static unsigned int
ath5k_setup_channels(struct ath5k_hw *ah, struct ieee80211_channel *channels,
unsigned int mode, unsigned int max)
{
- unsigned int count, size, chfreq, freq, ch;
+ unsigned int count, size, freq, ch;
enum ieee80211_band band;

switch (mode) {
case AR5K_MODE_11A:
/* 1..220, but 2GHz frequencies are filtered by check_channel */
size = 220;
- chfreq = CHANNEL_5GHZ;
band = IEEE80211_BAND_5GHZ;
break;
case AR5K_MODE_11B:
case AR5K_MODE_11G:
size = 26;
- chfreq = CHANNEL_2GHZ;
band = IEEE80211_BAND_2GHZ;
break;
default:
@@ -299,26 +297,19 @@ ath5k_setup_channels(struct ath5k_hw *ah, struct ieee80211_channel *channels,
if (freq == 0) /* mapping failed - not a standard channel */
continue;

+ /* Write channel info, needed for ath5k_channel_ok() */
+ channels[count].center_freq = freq;
+ channels[count].band = band;
+ channels[count].hw_value = mode;
+
/* Check if channel is supported by the chipset */
- if (!ath5k_channel_ok(ah, freq, chfreq))
+ if (!ath5k_channel_ok(ah, &channels[count]))
continue;

if (!modparam_all_channels &&
!ath5k_is_standard_channel(ch, band))
continue;

- /* Write channel info and increment counter */
- channels[count].center_freq = freq;
- channels[count].band = band;
- switch (mode) {
- case AR5K_MODE_11A:
- case AR5K_MODE_11G:
- channels[count].hw_value = chfreq | CHANNEL_OFDM;
- break;
- case AR5K_MODE_11B:
- channels[count].hw_value = CHANNEL_B;
- }
-
count++;
}

diff --git a/drivers/net/wireless/ath/ath5k/eeprom.c b/drivers/net/wireless/ath/ath5k/eeprom.c
index 56cb9d4..7c9c2ab 100644
--- a/drivers/net/wireless/ath/ath5k/eeprom.c
+++ b/drivers/net/wireless/ath/ath5k/eeprom.c
@@ -1780,12 +1780,12 @@ ath5k_eeprom_detach(struct ath5k_hw *ah)
int
ath5k_eeprom_mode_from_channel(struct ieee80211_channel *channel)
{
- switch (channel->hw_value & CHANNEL_MODES) {
- case CHANNEL_A:
+ switch (channel->hw_value) {
+ case AR5K_MODE_11A:
return AR5K_EEPROM_MODE_11A;
- case CHANNEL_G:
+ case AR5K_MODE_11G:
return AR5K_EEPROM_MODE_11G;
- case CHANNEL_B:
+ case AR5K_MODE_11B:
return AR5K_EEPROM_MODE_11B;
default:
return -1;
diff --git a/drivers/net/wireless/ath/ath5k/pcu.c b/drivers/net/wireless/ath/ath5k/pcu.c
index 0673138..733d46c 100644
--- a/drivers/net/wireless/ath/ath5k/pcu.c
+++ b/drivers/net/wireless/ath/ath5k/pcu.c
@@ -152,7 +152,7 @@ unsigned int ath5k_hw_get_default_slottime(struct ath5k_hw *ah)
case AR5K_BWMODE_DEFAULT:
default:
slot_time = AR5K_INIT_SLOT_TIME_DEFAULT;
- if ((channel->hw_value & CHANNEL_CCK) && !ah->ah_short_slot)
+ if ((channel->hw_value == AR5K_MODE_11B) && !ah->ah_short_slot)
slot_time = AR5K_INIT_SLOT_TIME_B;
break;
}
@@ -183,7 +183,7 @@ unsigned int ath5k_hw_get_default_sifs(struct ath5k_hw *ah)
case AR5K_BWMODE_DEFAULT:
sifs = AR5K_INIT_SIFS_DEFAULT_BG;
default:
- if (channel->hw_value & CHANNEL_5GHZ)
+ if (channel->band == IEEE80211_BAND_5GHZ)
sifs = AR5K_INIT_SIFS_DEFAULT_A;
break;
}
diff --git a/drivers/net/wireless/ath/ath5k/phy.c b/drivers/net/wireless/ath/ath5k/phy.c
index b9ada88..227c914 100644
--- a/drivers/net/wireless/ath/ath5k/phy.c
+++ b/drivers/net/wireless/ath/ath5k/phy.c
@@ -38,7 +38,7 @@
/*
* Get the PHY Chip revision
*/
-u16 ath5k_hw_radio_revision(struct ath5k_hw *ah, unsigned int chan)
+u16 ath5k_hw_radio_revision(struct ath5k_hw *ah, enum ieee80211_band band)
{
unsigned int i;
u32 srev;
@@ -47,11 +47,11 @@ u16 ath5k_hw_radio_revision(struct ath5k_hw *ah, unsigned int chan)
/*
* Set the radio chip access register
*/
- switch (chan) {
- case CHANNEL_2GHZ:
+ switch (band) {
+ case IEEE80211_BAND_2GHZ:
ath5k_hw_reg_write(ah, AR5K_PHY_SHIFT_2GHZ, AR5K_PHY(0));
break;
- case CHANNEL_5GHZ:
+ case IEEE80211_BAND_5GHZ:
ath5k_hw_reg_write(ah, AR5K_PHY_SHIFT_5GHZ, AR5K_PHY(0));
break;
default:
@@ -84,14 +84,16 @@ u16 ath5k_hw_radio_revision(struct ath5k_hw *ah, unsigned int chan)
/*
* Check if a channel is supported
*/
-bool ath5k_channel_ok(struct ath5k_hw *ah, u16 freq, unsigned int flags)
+bool ath5k_channel_ok(struct ath5k_hw *ah, struct ieee80211_channel *channel)
{
+ u16 freq = channel->center_freq;
+
/* Check if the channel is in our supported range */
- if (flags & CHANNEL_2GHZ) {
+ if (channel->band == IEEE80211_BAND_2GHZ) {
if ((freq >= ah->ah_capabilities.cap_range.range_2ghz_min) &&
(freq <= ah->ah_capabilities.cap_range.range_2ghz_max))
return true;
- } else if (flags & CHANNEL_5GHZ)
+ } else if (channel->band == IEEE80211_BAND_5GHZ)
if ((freq >= ah->ah_capabilities.cap_range.range_5ghz_min) &&
(freq <= ah->ah_capabilities.cap_range.range_5ghz_max))
return true;
@@ -224,7 +226,7 @@ static inline int ath5k_hw_write_ofdm_timings(struct ath5k_hw *ah,
ds_coef_exp, ds_coef_man, clock;

BUG_ON(!(ah->ah_version == AR5K_AR5212) ||
- !(channel->hw_value & CHANNEL_OFDM));
+ (channel->hw_value == AR5K_MODE_11B));

/* Get coefficient
* ALGO: coef = (5 * clock / carrier_freq) / 2
@@ -298,7 +300,7 @@ static void ath5k_hw_wait_for_synth(struct ath5k_hw *ah,
u32 delay;
delay = ath5k_hw_reg_read(ah, AR5K_PHY_RX_DELAY) &
AR5K_PHY_RX_DELAY_M;
- delay = (channel->hw_value & CHANNEL_CCK) ?
+ delay = (channel->hw_value == AR5K_MODE_11B) ?
((delay << 2) / 22) : (delay / 10);
if (ah->ah_bwmode == AR5K_BWMODE_10MHZ)
delay = delay << 1;
@@ -798,9 +800,9 @@ static int ath5k_hw_rfregs_init(struct ath5k_hw *ah,
}

/* Set Output and Driver bias current (OB/DB) */
- if (channel->hw_value & CHANNEL_2GHZ) {
+ if (channel->band == IEEE80211_BAND_2GHZ) {

- if (channel->hw_value & CHANNEL_CCK)
+ if (channel->hw_value == AR5K_MODE_11B)
ee_mode = AR5K_EEPROM_MODE_11B;
else
ee_mode = AR5K_EEPROM_MODE_11G;
@@ -825,7 +827,7 @@ static int ath5k_hw_rfregs_init(struct ath5k_hw *ah,
AR5K_RF_DB_2GHZ, true);

/* RF5111 always needs OB/DB for 5GHz, even if we use 2GHz */
- } else if ((channel->hw_value & CHANNEL_5GHZ) ||
+ } else if ((channel->band == IEEE80211_BAND_5GHZ) ||
(ah->ah_radio == AR5K_RF5111)) {

/* For 11a, Turbo and XR we need to choose
@@ -857,7 +859,7 @@ static int ath5k_hw_rfregs_init(struct ath5k_hw *ah,
if (ah->ah_radio == AR5K_RF5111) {

/* Set gain_F settings according to current step */
- if (channel->hw_value & CHANNEL_OFDM) {
+ if (channel->hw_value != AR5K_MODE_11B) {

AR5K_REG_WRITE_BITS(ah, AR5K_PHY_FRAME_CTL,
AR5K_PHY_FRAME_CTL_TX_CLIP,
@@ -914,7 +916,7 @@ static int ath5k_hw_rfregs_init(struct ath5k_hw *ah,
if (ah->ah_radio == AR5K_RF5112) {

/* Set gain_F settings according to current step */
- if (channel->hw_value & CHANNEL_OFDM) {
+ if (channel->hw_value != AR5K_MODE_11B) {

ath5k_hw_rfb_op(ah, rf_regs, g_step->gos_param[0],
AR5K_RF_MIXGAIN_OVR, true);
@@ -1026,7 +1028,7 @@ static int ath5k_hw_rfregs_init(struct ath5k_hw *ah,
}

if (ah->ah_radio == AR5K_RF5413 &&
- channel->hw_value & CHANNEL_2GHZ) {
+ channel->band == IEEE80211_BAND_2GHZ) {

ath5k_hw_rfb_op(ah, rf_regs, 1, AR5K_RF_DERBY_CHAN_SEL_MODE,
true);
@@ -1138,7 +1140,7 @@ static int ath5k_hw_rf5111_channel(struct ath5k_hw *ah,
*/
data0 = data1 = 0;

- if (channel->hw_value & CHANNEL_2GHZ) {
+ if (channel->band == IEEE80211_BAND_2GHZ) {
/* Map 2GHz channel to 5GHz Atheros channel ID */
ret = ath5k_hw_rf5111_chan2athchan(
ieee80211_frequency_to_channel(channel->center_freq),
@@ -1265,10 +1267,9 @@ static int ath5k_hw_channel(struct ath5k_hw *ah,
int ret;
/*
* Check bounds supported by the PHY (we don't care about regulatory
- * restrictions at this point). Note: hw_value already has the band
- * (CHANNEL_2GHZ, or CHANNEL_5GHZ) so we inform ath5k_channel_ok()
- * of the band by that */
- if (!ath5k_channel_ok(ah, channel->center_freq, channel->hw_value)) {
+ * restrictions at this point).
+ */
+ if (!ath5k_channel_ok(ah, channel)) {
ATH5K_ERR(ah,
"channel frequency (%u MHz) out of supported "
"band range\n",
@@ -1614,7 +1615,7 @@ int ath5k_hw_phy_calibrate(struct ath5k_hw *ah,
ret = ath5k_hw_rf511x_iq_calibrate(ah);

if ((ah->ah_radio == AR5K_RF5111 || ah->ah_radio == AR5K_RF5112) &&
- (channel->hw_value & CHANNEL_OFDM))
+ (channel->hw_value != AR5K_MODE_11B))
ath5k_hw_request_rfgain_probe(ah);

return ret;
@@ -1641,7 +1642,7 @@ ath5k_hw_set_spur_mitigation_filter(struct ath5k_hw *ah,
/* Convert current frequency to fbin value (the same way channels
* are stored on EEPROM, check out ath5k_eeprom_bin2freq) and scale
* up by 2 so we can compare it later */
- if (channel->hw_value & CHANNEL_2GHZ) {
+ if (channel->band == IEEE80211_BAND_2GHZ) {
chan_fbin = (channel->center_freq - 2300) * 10;
freq_band = AR5K_EEPROM_BAND_2GHZ;
} else {
@@ -1703,7 +1704,7 @@ ath5k_hw_set_spur_mitigation_filter(struct ath5k_hw *ah,
spur_freq_sigma_delta = (spur_delta_phase >> 10);
symbol_width = AR5K_SPUR_SYMBOL_WIDTH_BASE_100Hz / 4;
default:
- if (channel->hw_value == CHANNEL_A) {
+ if (channel->band == IEEE80211_BAND_5GHZ) {
/* Both sample_freq and chip_freq are 40MHz */
spur_delta_phase = (spur_offset << 17) / 25;
spur_freq_sigma_delta =
@@ -2226,15 +2227,20 @@ ath5k_get_chan_pcal_surrounding_piers(struct ath5k_hw *ah,
idx_l = 0;
idx_r = 0;

- if (!(channel->hw_value & CHANNEL_OFDM)) {
+ switch (channel->hw_value) {
+ case AR5K_EEPROM_MODE_11A:
+ pcinfo = ee->ee_pwr_cal_a;
+ mode = AR5K_EEPROM_MODE_11A;
+ break;
+ case AR5K_EEPROM_MODE_11B:
pcinfo = ee->ee_pwr_cal_b;
mode = AR5K_EEPROM_MODE_11B;
- } else if (channel->hw_value & CHANNEL_2GHZ) {
+ break;
+ case AR5K_EEPROM_MODE_11G:
+ default:
pcinfo = ee->ee_pwr_cal_g;
mode = AR5K_EEPROM_MODE_11G;
- } else {
- pcinfo = ee->ee_pwr_cal_a;
- mode = AR5K_EEPROM_MODE_11A;
+ break;
}
max = ee->ee_n_piers[mode] - 1;

@@ -2303,15 +2309,20 @@ ath5k_get_rate_pcal_data(struct ath5k_hw *ah,
idx_l = 0;
idx_r = 0;

- if (!(channel->hw_value & CHANNEL_OFDM)) {
+ switch (channel->hw_value) {
+ case AR5K_MODE_11A:
+ rpinfo = ee->ee_rate_tpwr_a;
+ mode = AR5K_EEPROM_MODE_11A;
+ break;
+ case AR5K_MODE_11B:
rpinfo = ee->ee_rate_tpwr_b;
mode = AR5K_EEPROM_MODE_11B;
- } else if (channel->hw_value & CHANNEL_2GHZ) {
+ break;
+ case AR5K_MODE_11G:
+ default:
rpinfo = ee->ee_rate_tpwr_g;
mode = AR5K_EEPROM_MODE_11G;
- } else {
- rpinfo = ee->ee_rate_tpwr_a;
- mode = AR5K_EEPROM_MODE_11A;
+ break;
}
max = ee->ee_rate_target_pwr_num[mode] - 1;

@@ -2392,20 +2403,20 @@ ath5k_get_max_ctl_power(struct ath5k_hw *ah,

ctl_mode = ath_regd_get_band_ctl(regulatory, channel->band);

- switch (channel->hw_value & CHANNEL_MODES) {
- case CHANNEL_A:
+ switch (channel->hw_value) {
+ case AR5K_MODE_11A:
if (ah->ah_bwmode == AR5K_BWMODE_40MHZ)
ctl_mode |= AR5K_CTL_TURBO;
else
ctl_mode |= AR5K_CTL_11A;
break;
- case CHANNEL_G:
+ case AR5K_MODE_11G:
if (ah->ah_bwmode == AR5K_BWMODE_40MHZ)
ctl_mode |= AR5K_CTL_TURBOG;
else
ctl_mode |= AR5K_CTL_11G;
break;
- case CHANNEL_B:
+ case AR5K_MODE_11B:
ctl_mode |= AR5K_CTL_11B;
break;
default:
@@ -3290,7 +3301,7 @@ int ath5k_hw_phy_init(struct ath5k_hw *ah, struct ieee80211_channel *channel,

/* Write OFDM timings on 5212*/
if (ah->ah_version == AR5K_AR5212 &&
- channel->hw_value & CHANNEL_OFDM) {
+ channel->hw_value != AR5K_MODE_11B) {

ret = ath5k_hw_write_ofdm_timings(ah, channel);
if (ret)
diff --git a/drivers/net/wireless/ath/ath5k/qcu.c b/drivers/net/wireless/ath/ath5k/qcu.c
index 1d37675..a8b8ffa 100644
--- a/drivers/net/wireless/ath/ath5k/qcu.c
+++ b/drivers/net/wireless/ath/ath5k/qcu.c
@@ -537,7 +537,7 @@ int ath5k_hw_set_ifs_intervals(struct ath5k_hw *ah, unsigned int slot_time)
*
* Also we have different lowest rate for 802.11a
*/
- if (channel->hw_value & CHANNEL_5GHZ)
+ if (channel->band == IEEE80211_BAND_5GHZ)
rate = &ah->sbands[IEEE80211_BAND_5GHZ].bitrates[0];
else
rate = &ah->sbands[IEEE80211_BAND_2GHZ].bitrates[0];
diff --git a/drivers/net/wireless/ath/ath5k/reset.c b/drivers/net/wireless/ath/ath5k/reset.c
index 5d6d3bd..8bc57e4 100644
--- a/drivers/net/wireless/ath/ath5k/reset.c
+++ b/drivers/net/wireless/ath/ath5k/reset.c
@@ -102,12 +102,18 @@ static void ath5k_hw_init_core_clock(struct ath5k_hw *ah)
/*
* Set core clock frequency
*/
- if (channel->hw_value & CHANNEL_5GHZ)
- clock = 40; /* 802.11a */
- else if (channel->hw_value & CHANNEL_CCK)
- clock = 22; /* 802.11b */
- else
- clock = 44; /* 802.11g */
+ switch (channel->hw_value) {
+ case AR5K_MODE_11A:
+ clock = 40;
+ break;
+ case AR5K_MODE_11B:
+ clock = 22;
+ break;
+ case AR5K_MODE_11G:
+ default:
+ clock = 44;
+ break;
+ }

/* Use clock multiplier for non-default
* bwmode */
@@ -581,8 +587,9 @@ int ath5k_hw_on_hold(struct ath5k_hw *ah)

/*
* Bring up MAC + PHY Chips and program PLL
+ * Channel is NULL for the initial wakeup.
*/
-int ath5k_hw_nic_wakeup(struct ath5k_hw *ah, int flags, bool initial)
+int ath5k_hw_nic_wakeup(struct ath5k_hw *ah, struct ieee80211_channel *channel)
{
struct pci_dev *pdev = ah->pdev;
u32 turbo, mode, clock, bus_flags;
@@ -592,7 +599,7 @@ int ath5k_hw_nic_wakeup(struct ath5k_hw *ah, int flags, bool initial)
mode = 0;
clock = 0;

- if ((ath5k_get_bus_type(ah) != ATH_AHB) || !initial) {
+ if ((ath5k_get_bus_type(ah) != ATH_AHB) || channel) {
/* Wakeup the device */
ret = ath5k_hw_set_power(ah, AR5K_PM_AWAKE, true, 0);
if (ret) {
@@ -652,7 +659,7 @@ int ath5k_hw_nic_wakeup(struct ath5k_hw *ah, int flags, bool initial)

/* On initialization skip PLL programming since we don't have
* a channel / mode set yet */
- if (initial)
+ if (!channel)
return 0;

if (ah->ah_version != AR5K_AR5210) {
@@ -668,13 +675,13 @@ int ath5k_hw_nic_wakeup(struct ath5k_hw *ah, int flags, bool initial)
clock = AR5K_PHY_PLL_RF5111; /*Zero*/
}

- if (flags & CHANNEL_2GHZ) {
+ if (channel->band == IEEE80211_BAND_2GHZ) {
mode |= AR5K_PHY_MODE_FREQ_2GHZ;
clock |= AR5K_PHY_PLL_44MHZ;

- if (flags & CHANNEL_CCK) {
+ if (channel->hw_value == AR5K_MODE_11B) {
mode |= AR5K_PHY_MODE_MOD_CCK;
- } else if (flags & CHANNEL_OFDM) {
+ } else {
/* XXX Dynamic OFDM/CCK is not supported by the
* AR5211 so we set MOD_OFDM for plain g (no
* CCK headers) operation. We need to test
@@ -686,27 +693,16 @@ int ath5k_hw_nic_wakeup(struct ath5k_hw *ah, int flags, bool initial)
mode |= AR5K_PHY_MODE_MOD_OFDM;
else
mode |= AR5K_PHY_MODE_MOD_DYN;
- } else {
- ATH5K_ERR(ah,
- "invalid radio modulation mode\n");
- return -EINVAL;
}
- } else if (flags & CHANNEL_5GHZ) {
- mode |= AR5K_PHY_MODE_FREQ_5GHZ;
+ } else if (channel->band == IEEE80211_BAND_5GHZ) {
+ mode |= (AR5K_PHY_MODE_FREQ_5GHZ |
+ AR5K_PHY_MODE_MOD_OFDM);

/* Different PLL setting for 5413 */
if (ah->ah_radio == AR5K_RF5413)
clock = AR5K_PHY_PLL_40MHZ_5413;
else
clock |= AR5K_PHY_PLL_40MHZ;
-
- if (flags & CHANNEL_OFDM)
- mode |= AR5K_PHY_MODE_MOD_OFDM;
- else {
- ATH5K_ERR(ah,
- "invalid radio modulation mode\n");
- return -EINVAL;
- }
} else {
ATH5K_ERR(ah, "invalid radio frequency mode\n");
return -EINVAL;
@@ -822,7 +818,7 @@ static void ath5k_hw_tweak_initval_settings(struct ath5k_hw *ah,
u32 data;
ath5k_hw_reg_write(ah, AR5K_PHY_CCKTXCTL_WORLD,
AR5K_PHY_CCKTXCTL);
- if (channel->hw_value & CHANNEL_5GHZ)
+ if (channel->band == IEEE80211_BAND_5GHZ)
data = 0xffb81020;
else
data = 0xffb80d20;
@@ -905,7 +901,7 @@ static void ath5k_hw_commit_eeprom_settings(struct ath5k_hw *ah,
/* Set CCK to OFDM power delta on tx power
* adjustment register */
if (ah->ah_phy_revision >= AR5K_SREV_PHY_5212A) {
- if (channel->hw_value == CHANNEL_G)
+ if (channel->hw_value == AR5K_MODE_11G)
ath5k_hw_reg_write(ah,
AR5K_REG_SM((ee->ee_cck_ofdm_gain_delta * -1),
AR5K_PHY_TX_PWR_ADJ_CCK_GAIN_DELTA) |
@@ -1084,29 +1080,23 @@ int ath5k_hw_reset(struct ath5k_hw *ah, enum nl80211_iftype op_mode,
ret = 0;
}

- switch (channel->hw_value & CHANNEL_MODES) {
- case CHANNEL_A:
- mode = AR5K_MODE_11A;
+ mode = channel->hw_value;
+ switch (mode) {
+ case AR5K_MODE_11A:
break;
- case CHANNEL_G:
-
+ case AR5K_MODE_11G:
if (ah->ah_version <= AR5K_AR5211) {
ATH5K_ERR(ah,
"G mode not available on 5210/5211");
return -EINVAL;
}
-
- mode = AR5K_MODE_11G;
break;
- case CHANNEL_B:
-
+ case AR5K_MODE_11B:
if (ah->ah_version < AR5K_AR5211) {
ATH5K_ERR(ah,
"B mode not available on 5210");
return -EINVAL;
}
-
- mode = AR5K_MODE_11B;
break;
default:
ATH5K_ERR(ah,
@@ -1192,7 +1182,7 @@ int ath5k_hw_reset(struct ath5k_hw *ah, enum nl80211_iftype op_mode,
}

/* Wakeup the device */
- ret = ath5k_hw_nic_wakeup(ah, channel->hw_value, false);
+ ret = ath5k_hw_nic_wakeup(ah, channel);
if (ret)
return ret;


2011-07-23 17:19:30

by Nick Kossifidis

[permalink] [raw]
Subject: Re: [PATCH 2 2/3] ath5k: remove most references to XR

2011/7/23 Pavel Roskin <[email protected]>:
> XR is a proprietary feature of the chipset.  It's not supported and
> should not be supported.
>
> Signed-off-by: Pavel Roskin <[email protected]>
> Tested-by: Sedat Dilek <[email protected]>
> ---
>  drivers/net/wireless/ath/ath5k/ath5k.h  |    4 ----
>  drivers/net/wireless/ath/ath5k/eeprom.c |    1 -
>  drivers/net/wireless/ath/ath5k/phy.c    |    2 --
>  drivers/net/wireless/ath/ath5k/qcu.c    |    7 -------
>  drivers/net/wireless/ath/ath5k/reset.c  |    8 --------
>  5 files changed, 0 insertions(+), 22 deletions(-)
>
> diff --git a/drivers/net/wireless/ath/ath5k/ath5k.h b/drivers/net/wireless/ath/ath5k/ath5k.h
> index be7b8c0..a8a7db4 100644
> --- a/drivers/net/wireless/ath/ath5k/ath5k.h
> +++ b/drivers/net/wireless/ath/ath5k/ath5k.h
> @@ -416,7 +416,6 @@ enum ath5k_driver_mode {
>        AR5K_MODE_11A           =       0,
>        AR5K_MODE_11B           =       1,
>        AR5K_MODE_11G           =       2,
> -       AR5K_MODE_XR            =       0,
>        AR5K_MODE_MAX           =       3
>  };
>
> @@ -694,12 +693,10 @@ struct ath5k_gain {
>  #define        CHANNEL_5GHZ    0x0100  /* 5GHz channel */
>  #define        CHANNEL_PASSIVE 0x0200  /* Only passive scan allowed */
>  #define        CHANNEL_DYN     0x0400  /* Dynamic CCK-OFDM channel (for g operation) */
> -#define        CHANNEL_XR      0x0800  /* XR channel */
>
>  #define        CHANNEL_A       (CHANNEL_5GHZ | CHANNEL_OFDM)
>  #define        CHANNEL_B       (CHANNEL_2GHZ | CHANNEL_CCK)
>  #define        CHANNEL_G       (CHANNEL_2GHZ | CHANNEL_OFDM)
> -#define        CHANNEL_X       (CHANNEL_5GHZ | CHANNEL_OFDM | CHANNEL_XR)
>
>  #define        CHANNEL_ALL     (CHANNEL_OFDM | CHANNEL_CCK | \
>                         CHANNEL_2GHZ | CHANNEL_5GHZ)
> @@ -710,7 +707,6 @@ struct ath5k_gain {
>  * Used internally for ath5k_hw_reset_tx_queue().
>  * Also see struct struct ieee80211_channel.
>  */
> -#define IS_CHAN_XR(_c) ((_c->hw_value & CHANNEL_XR) != 0)
>  #define IS_CHAN_B(_c)  ((_c->hw_value & CHANNEL_B) != 0)
>
>  /*
> diff --git a/drivers/net/wireless/ath/ath5k/eeprom.c b/drivers/net/wireless/ath/ath5k/eeprom.c
> index 9068b91..56cb9d4 100644
> --- a/drivers/net/wireless/ath/ath5k/eeprom.c
> +++ b/drivers/net/wireless/ath/ath5k/eeprom.c
> @@ -1782,7 +1782,6 @@ ath5k_eeprom_mode_from_channel(struct ieee80211_channel *channel)
>  {
>        switch (channel->hw_value & CHANNEL_MODES) {
>        case CHANNEL_A:
> -       case CHANNEL_XR:
>                return AR5K_EEPROM_MODE_11A;
>        case CHANNEL_G:
>                return AR5K_EEPROM_MODE_11G;
> diff --git a/drivers/net/wireless/ath/ath5k/phy.c b/drivers/net/wireless/ath/ath5k/phy.c
> index 81e465e..b9ada88 100644
> --- a/drivers/net/wireless/ath/ath5k/phy.c
> +++ b/drivers/net/wireless/ath/ath5k/phy.c
> @@ -2408,8 +2408,6 @@ ath5k_get_max_ctl_power(struct ath5k_hw *ah,
>        case CHANNEL_B:
>                ctl_mode |= AR5K_CTL_11B;
>                break;
> -       case CHANNEL_XR:
> -               /* Fall through */
>        default:
>                return;
>        }
> diff --git a/drivers/net/wireless/ath/ath5k/qcu.c b/drivers/net/wireless/ath/ath5k/qcu.c
> index 65f1039..1d37675 100644
> --- a/drivers/net/wireless/ath/ath5k/qcu.c
> +++ b/drivers/net/wireless/ath/ath5k/qcu.c
> @@ -185,13 +185,6 @@ int ath5k_hw_setup_tx_queue(struct ath5k_hw *ah, enum ath5k_tx_queue queue_type,
>                case AR5K_TX_QUEUE_CAB:
>                        queue = AR5K_TX_QUEUE_ID_CAB;
>                        break;
> -               case AR5K_TX_QUEUE_XR_DATA:
> -                       if (ah->ah_version != AR5K_AR5212)
> -                               ATH5K_ERR(ah,
> -                                       "XR data queues only supported in"
> -                                       " 5212!\n");
> -                       queue = AR5K_TX_QUEUE_ID_XR_DATA;
> -                       break;
>                default:
>                        return -EINVAL;
>                }
> diff --git a/drivers/net/wireless/ath/ath5k/reset.c b/drivers/net/wireless/ath/ath5k/reset.c
> index 0686c5d..5d6d3bd 100644
> --- a/drivers/net/wireless/ath/ath5k/reset.c
> +++ b/drivers/net/wireless/ath/ath5k/reset.c
> @@ -1108,14 +1108,6 @@ int ath5k_hw_reset(struct ath5k_hw *ah, enum nl80211_iftype op_mode,
>
>                mode = AR5K_MODE_11B;
>                break;
> -       case CHANNEL_XR:
> -               if (ah->ah_version == AR5K_AR5211) {
> -                       ATH5K_ERR(ah,
> -                               "XR mode not available on 5211");
> -                       return -EINVAL;
> -               }
> -               mode = AR5K_MODE_XR;
> -               break;
>        default:
>                ATH5K_ERR(ah,
>                        "invalid channel: %d\n", channel->center_freq);
> --
> To unsubscribe from this list: send the line "unsubscribe linux-wireless" in
> the body of a message to [email protected]
> More majordomo info at  http://vger.kernel.org/majordomo-info.html
>

Acked-by: Nick Kossifidis <[email protected]>

--
GPG ID: 0xD21DB2DB
As you read this post global entropy rises. Have Fun ;-)
Nick

2011-07-23 17:20:28

by Nick Kossifidis

[permalink] [raw]
Subject: Re: [PATCH 2 1/3] ath5k: remove unused and write-only structures and fields

2011/7/23 Pavel Roskin <[email protected]>:
> struct ath5k_avg_val is unused.
>
> In struct ath5k_hw, lladdr, ah_radar and ah_mac_revision are write-only,
> rxbufsize is unused, ah_phy is write-only and referenced by unused
> macros.
>
> In struct ath5k_vif, lladdr is write-only.
>
> Remove AR5K_TUNE_RADAR_ALERT, which has no effect.
>
> Signed-off-by: Pavel Roskin <[email protected]>
> Tested-by: Sedat Dilek <[email protected]>
> ---
>  drivers/net/wireless/ath/ath5k/ath5k.h        |   28 -------------------------
>  drivers/net/wireless/ath/ath5k/attach.c       |    5 +---
>  drivers/net/wireless/ath/ath5k/base.c         |    1 -
>  drivers/net/wireless/ath/ath5k/base.h         |    1 -
>  drivers/net/wireless/ath/ath5k/mac80211-ops.c |    3 ---
>  5 files changed, 1 insertions(+), 37 deletions(-)
>
> diff --git a/drivers/net/wireless/ath/ath5k/ath5k.h b/drivers/net/wireless/ath/ath5k/ath5k.h
> index 277d5cb..be7b8c0 100644
> --- a/drivers/net/wireless/ath/ath5k/ath5k.h
> +++ b/drivers/net/wireless/ath/ath5k/ath5k.h
> @@ -131,13 +131,6 @@
>  #define AR5K_REG_DISABLE_BITS(ah, _reg, _flags)                        \
>        ath5k_hw_reg_write(ah, ath5k_hw_reg_read(ah, _reg) & ~(_flags), _reg)
>
> -/* Access to PHY registers */
> -#define AR5K_PHY_READ(ah, _reg)                                        \
> -       ath5k_hw_reg_read(ah, (ah)->ah_phy + ((_reg) << 2))
> -
> -#define AR5K_PHY_WRITE(ah, _reg, _val)                                 \
> -       ath5k_hw_reg_write(ah, _val, (ah)->ah_phy + ((_reg) << 2))
> -
>  /* Access QCU registers per queue */
>  #define AR5K_REG_READ_Q(ah, _reg, _queue)                              \
>        (ath5k_hw_reg_read(ah, _reg) & (1 << _queue))                   \
> @@ -166,7 +159,6 @@
>  #define AR5K_TUNE_DMA_BEACON_RESP              2
>  #define AR5K_TUNE_SW_BEACON_RESP               10
>  #define AR5K_TUNE_ADDITIONAL_SWBA_BACKOFF      0
> -#define AR5K_TUNE_RADAR_ALERT                  false
>  #define AR5K_TUNE_MIN_TX_FIFO_THRES            1
>  #define AR5K_TUNE_MAX_TX_FIFO_THRES    ((IEEE80211_MAX_FRAME_LEN / 64) + 1)
>  #define AR5K_TUNE_REGISTER_TIMEOUT             20000
> @@ -1013,16 +1005,6 @@ struct ath5k_nfcal_hist {
>        s16 nfval[ATH5K_NF_CAL_HIST_MAX];       /* last few noise floors */
>  };
>
> -/**
> - * struct avg_val - Helper structure for average calculation
> - * @avg: contains the actual average value
> - * @avg_weight: is used internally during calculation to prevent rounding errors
> - */
> -struct ath5k_avg_val {
> -       int avg;
> -       int avg_weight;
> -};
> -
>  #define ATH5K_LED_MAX_NAME_LEN 31
>
>  /*
> @@ -1148,7 +1130,6 @@ struct ath5k_hw {
>        bool                    rx_pending;     /* rx tasklet pending */
>        bool                    tx_pending;     /* tx tasklet pending */
>
> -       u8                      lladdr[ETH_ALEN];
>        u8                      bssidmask[ETH_ALEN];
>
>        unsigned int            led_pin,        /* GPIO pin for driving LED */
> @@ -1156,7 +1137,6 @@ struct ath5k_hw {
>
>        struct work_struct      reset_work;     /* deferred chip reset */
>
> -       unsigned int            rxbufsize;      /* rx size based on mtu */
>        struct list_head        rxbuf;          /* receive buffer */
>        spinlock_t              rxbuflock;
>        u32                     *rxlink;        /* link ptr in last RX desc */
> @@ -1208,10 +1188,8 @@ struct ath5k_hw {
>
>        enum ath5k_version      ah_version;
>        enum ath5k_radio        ah_radio;
> -       u32                     ah_phy;
>        u32                     ah_mac_srev;
>        u16                     ah_mac_version;
> -       u16                     ah_mac_revision;
>        u16                     ah_phy_revision;
>        u16                     ah_radio_5ghz_revision;
>        u16                     ah_radio_2ghz_revision;
> @@ -1279,12 +1257,6 @@ struct ath5k_hw {
>                bool            txp_setup;
>        } ah_txpower;
>
> -       struct {
> -               bool            r_enabled;
> -               int             r_last_alert;
> -               struct ieee80211_channel r_last_channel;
> -       } ah_radar;
> -
>        struct ath5k_nfcal_hist ah_nfcal_hist;
>
>        /* average beacon RSSI in our BSS (used by ANI) */
> diff --git a/drivers/net/wireless/ath/ath5k/attach.c b/drivers/net/wireless/ath/ath5k/attach.c
> index f8a6b38..b0df2f6 100644
> --- a/drivers/net/wireless/ath/ath5k/attach.c
> +++ b/drivers/net/wireless/ath/ath5k/attach.c
> @@ -114,7 +114,6 @@ int ath5k_hw_init(struct ath5k_hw *ah)
>        /*
>         * HW information
>         */
> -       ah->ah_radar.r_enabled = AR5K_TUNE_RADAR_ALERT;
>        ah->ah_bwmode = AR5K_BWMODE_DEFAULT;
>        ah->ah_txpower.txp_tpc = AR5K_TUNE_TPC_TXPOWER;
>        ah->ah_imr = 0;
> @@ -137,9 +136,8 @@ int ath5k_hw_init(struct ath5k_hw *ah)
>        else
>                ah->ah_version = AR5K_AR5212;
>
> -       /* Get the MAC revision */
> +       /* Get the MAC version */
>        ah->ah_mac_version = AR5K_REG_MS(srev, AR5K_SREV_VER);
> -       ah->ah_mac_revision = AR5K_REG_MS(srev, AR5K_SREV_REV);
>
>        /* Fill the ath5k_hw struct with the needed functions */
>        ret = ath5k_hw_init_desc_functions(ah);
> @@ -156,7 +154,6 @@ int ath5k_hw_init(struct ath5k_hw *ah)
>                        0xffffffff;
>        ah->ah_radio_5ghz_revision = ath5k_hw_radio_revision(ah,
>                        CHANNEL_5GHZ);
> -       ah->ah_phy = AR5K_PHY(0);
>
>        /* Try to identify radio chip based on its srev */
>        switch (ah->ah_radio_5ghz_revision & 0xf0) {
> diff --git a/drivers/net/wireless/ath/ath5k/base.c b/drivers/net/wireless/ath/ath5k/base.c
> index a74d286..ee06e34 100644
> --- a/drivers/net/wireless/ath/ath5k/base.c
> +++ b/drivers/net/wireless/ath/ath5k/base.c
> @@ -2861,7 +2861,6 @@ ath5k_init(struct ieee80211_hw *hw)
>        }
>
>        SET_IEEE80211_PERM_ADDR(hw, mac);
> -       memcpy(&ah->lladdr, mac, ETH_ALEN);
>        /* All MAC address bits matter for ACKs */
>        ath5k_update_bssid_mask_and_opmode(ah, NULL);
>
> diff --git a/drivers/net/wireless/ath/ath5k/base.h b/drivers/net/wireless/ath/ath5k/base.h
> index a81f28d..5501bcb 100644
> --- a/drivers/net/wireless/ath/ath5k/base.h
> +++ b/drivers/net/wireless/ath/ath5k/base.h
> @@ -65,7 +65,6 @@ struct ath5k_vif {
>        enum nl80211_iftype     opmode;
>        int                     bslot;
>        struct ath5k_buf        *bbuf; /* beacon buffer */
> -       u8                      lladdr[ETH_ALEN];
>  };
>
>  struct ath5k_vif_iter_data {
> diff --git a/drivers/net/wireless/ath/ath5k/mac80211-ops.c b/drivers/net/wireless/ath/ath5k/mac80211-ops.c
> index 2a715ca..53d3af9 100644
> --- a/drivers/net/wireless/ath/ath5k/mac80211-ops.c
> +++ b/drivers/net/wireless/ath/ath5k/mac80211-ops.c
> @@ -137,11 +137,8 @@ ath5k_add_interface(struct ieee80211_hw *hw, struct ieee80211_vif *vif)
>        /* Any MAC address is fine, all others are included through the
>         * filter.
>         */
> -       memcpy(&ah->lladdr, vif->addr, ETH_ALEN);
>        ath5k_hw_set_lladdr(ah, vif->addr);
>
> -       memcpy(&avf->lladdr, vif->addr, ETH_ALEN);
> -
>        ath5k_update_bssid_mask_and_opmode(ah, vif);
>        ret = 0;
>  end:
> --
> To unsubscribe from this list: send the line "unsubscribe linux-wireless" in
> the body of a message to [email protected]
> More majordomo info at  http://vger.kernel.org/majordomo-info.html
>

Acked-by: Nick Kossifidis <[email protected]>

--
GPG ID: 0xD21DB2DB
As you read this post global entropy rises. Have Fun ;-)
Nick

2011-07-23 17:21:18

by Nick Kossifidis

[permalink] [raw]
Subject: Re: [PATCH 2 3/3] ath5k: eliminate CHANNEL_* macros, use AR5K_MODE_* in channel->hw_value

MjAxMS83LzIzIFBhdmVsIFJvc2tpbiA8cHJvc2tpQGdudS5vcmc+Ogo+IFdoZW4gY2hlY2tpbmcg
Zm9yIHRoZSBiYW5kLCB1c2UgY2hhbm5lbC0+YmFuZC4KPgo+IENoYW5nZSBhdGg1a19od19uaWNf
d2FrZXVwKCkgYW5kIGF0aDVrX2NoYW5uZWxfb2soKSB0byB0YWtlCj4gaWVlZTgwMjExX2NoYW5u
ZWwuIMKgQ2hhbmdlIGF0aDVrX2h3X3JhZGlvX3JldmlzaW9uKCkgdG8gdGFrZQo+IGllZWU4MDIx
MV9iYW5kLgo+Cj4gU2lnbmVkLW9mZi1ieTogUGF2ZWwgUm9za2luIDxwcm9za2lAZ251Lm9yZz4K
PiBUZXN0ZWQtYnk6IFNlZGF0IERpbGVrIDxzZWRhdC5kaWxla0BnbWFpbC5jb20+Cj4gLS0tCj4g
wqBkcml2ZXJzL25ldC93aXJlbGVzcy9hdGgvYXRoNWsvYXRoNWsuaCDCoHwgwqAgMzIgKy0tLS0t
LS0tLS0KPiDCoGRyaXZlcnMvbmV0L3dpcmVsZXNzL2F0aC9hdGg1ay9hdHRhY2guYyB8IMKgIDEw
ICsrLS0KPiDCoGRyaXZlcnMvbmV0L3dpcmVsZXNzL2F0aC9hdGg1ay9iYXNlLmMgwqAgfCDCoCAy
MyArKy0tLS0tLQo+IMKgZHJpdmVycy9uZXQvd2lyZWxlc3MvYXRoL2F0aDVrL2VlcHJvbS5jIHwg
wqAgwqA4ICstLQo+IMKgZHJpdmVycy9uZXQvd2lyZWxlc3MvYXRoL2F0aDVrL3BjdS5jIMKgIMKg
fCDCoCDCoDQgKwo+IMKgZHJpdmVycy9uZXQvd2lyZWxlc3MvYXRoL2F0aDVrL3BoeS5jIMKgIMKg
fCDCoCA4NyArKysrKysrKysrKysrKysrKy0tLS0tLS0tLS0tLS0tCj4gwqBkcml2ZXJzL25ldC93
aXJlbGVzcy9hdGgvYXRoNWsvcWN1LmMgwqAgwqB8IMKgIMKgMiAtCj4gwqBkcml2ZXJzL25ldC93
aXJlbGVzcy9hdGgvYXRoNWsvcmVzZXQuYyDCoHwgwqAgNzAgKysrKysrKysrKystLS0tLS0tLS0t
LS0tLQo+IMKgOCBmaWxlcyBjaGFuZ2VkLCAxMDIgaW5zZXJ0aW9ucygrKSwgMTM0IGRlbGV0aW9u
cygtKQo+Cj4gZGlmZiAtLWdpdCBhL2RyaXZlcnMvbmV0L3dpcmVsZXNzL2F0aC9hdGg1ay9hdGg1
ay5oIGIvZHJpdmVycy9uZXQvd2lyZWxlc3MvYXRoL2F0aDVrL2F0aDVrLmgKPiBpbmRleCBhOGE3
ZGI0Li4wZDQxM2JlIDEwMDY0NAo+IC0tLSBhL2RyaXZlcnMvbmV0L3dpcmVsZXNzL2F0aC9hdGg1
ay9hdGg1ay5oCj4gKysrIGIvZHJpdmVycy9uZXQvd2lyZWxlc3MvYXRoL2F0aDVrL2F0aDVrLmgK
PiBAQCAtNjg1LDMwICs2ODUsNiBAQCBzdHJ1Y3QgYXRoNWtfZ2FpbiB7Cj4gwqAjZGVmaW5lIEFS
NUtfU0xPVF9USU1FXzIwIMKgIMKgIMKgODgwCj4gwqAjZGVmaW5lIEFSNUtfU0xPVF9USU1FX01B
WCDCoCDCoCAweGZmZmYKPgo+IC0vKiBjaGFubmVsX2ZsYWdzICovCj4gLSNkZWZpbmUgwqAgwqAg
wqAgwqBDSEFOTkVMX0NXX0lOVCDCoDB4MDAwOCDCoC8qIENvbnRlbnRpb24gV2luZG93IGludGVy
ZmVyZW5jZSBkZXRlY3RlZCAqLwo+IC0jZGVmaW5lIMKgIMKgIMKgIMKgQ0hBTk5FTF9DQ0sgwqAg
wqAgMHgwMDIwIMKgLyogQ0NLIGNoYW5uZWwgKi8KPiAtI2RlZmluZSDCoCDCoCDCoCDCoENIQU5O
RUxfT0ZETSDCoCDCoDB4MDA0MCDCoC8qIE9GRE0gY2hhbm5lbCAqLwo+IC0jZGVmaW5lIMKgIMKg
IMKgIMKgQ0hBTk5FTF8yR0haIMKgIMKgMHgwMDgwIMKgLyogMkdIeiBjaGFubmVsLiAqLwo+IC0j
ZGVmaW5lIMKgIMKgIMKgIMKgQ0hBTk5FTF81R0haIMKgIMKgMHgwMTAwIMKgLyogNUdIeiBjaGFu
bmVsICovCj4gLSNkZWZpbmUgwqAgwqAgwqAgwqBDSEFOTkVMX1BBU1NJVkUgMHgwMjAwIMKgLyog
T25seSBwYXNzaXZlIHNjYW4gYWxsb3dlZCAqLwo+IC0jZGVmaW5lIMKgIMKgIMKgIMKgQ0hBTk5F
TF9EWU4gwqAgwqAgMHgwNDAwIMKgLyogRHluYW1pYyBDQ0stT0ZETSBjaGFubmVsIChmb3IgZyBv
cGVyYXRpb24pICovCj4gLQo+IC0jZGVmaW5lIMKgIMKgIMKgIMKgQ0hBTk5FTF9BIMKgIMKgIMKg
IChDSEFOTkVMXzVHSFogfCBDSEFOTkVMX09GRE0pCj4gLSNkZWZpbmUgwqAgwqAgwqAgwqBDSEFO
TkVMX0IgwqAgwqAgwqAgKENIQU5ORUxfMkdIWiB8IENIQU5ORUxfQ0NLKQo+IC0jZGVmaW5lIMKg
IMKgIMKgIMKgQ0hBTk5FTF9HIMKgIMKgIMKgIChDSEFOTkVMXzJHSFogfCBDSEFOTkVMX09GRE0p
Cj4gLQo+IC0jZGVmaW5lIMKgIMKgIMKgIMKgQ0hBTk5FTF9BTEwgwqAgwqAgKENIQU5ORUxfT0ZE
TSB8IENIQU5ORUxfQ0NLIHwgXAo+IC0gwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAg
wqBDSEFOTkVMXzJHSFogfCBDSEFOTkVMXzVHSFopCj4gLQo+IC0jZGVmaW5lIENIQU5ORUxfTU9E
RVMgwqAgwqAgwqAgwqAgwqBDSEFOTkVMX0FMTAo+IC0KPiAtLyoKPiAtICogVXNlZCBpbnRlcm5h
bGx5IGZvciBhdGg1a19od19yZXNldF90eF9xdWV1ZSgpLgo+IC0gKiBBbHNvIHNlZSBzdHJ1Y3Qg
c3RydWN0IGllZWU4MDIxMV9jaGFubmVsLgo+IC0gKi8KPiAtI2RlZmluZSBJU19DSEFOX0IoX2Mp
IMKgKChfYy0+aHdfdmFsdWUgJiBDSEFOTkVMX0IpICE9IDApCj4gLQo+IMKgLyoKPiDCoCogVGhl
IGZvbGxvd2luZyBzdHJ1Y3R1cmUgaXMgdXNlZCB0byBtYXAgMkdIeiBjaGFubmVscyB0bwo+IMKg
KiA1R0h6IEF0aGVyb3MgY2hhbm5lbHMuCj4gQEAgLTk2NSw3ICs5NDEsNyBAQCBlbnVtIGF0aDVr
X3Bvd2VyX21vZGUgewo+IMKgc3RydWN0IGF0aDVrX2NhcGFiaWxpdGllcyB7Cj4gwqAgwqAgwqAg
wqAvKgo+IMKgIMKgIMKgIMKgICogU3VwcG9ydGVkIFBIWSBtb2Rlcwo+IC0gwqAgwqAgwqAgwqAq
IChpZS4gQ0hBTk5FTF9BLCBDSEFOTkVMX0IsIC4uLikKPiArIMKgIMKgIMKgIMKgKiAoaWUuIEFS
NUtfTU9ERV8xMUEsIEFSNUtfTU9ERV8xMUIsIC4uLikKPiDCoCDCoCDCoCDCoCAqLwo+IMKgIMKg
IMKgIMKgREVDTEFSRV9CSVRNQVAoY2FwX21vZGUsIEFSNUtfTU9ERV9NQVgpOwo+Cj4gQEAgLTEz
MzUsNyArMTMxMSw3IEBAIHZvaWQgYXRoNWtfdW5yZWdpc3Rlcl9sZWRzKHN0cnVjdCBhdGg1a19o
dyAqYWgpOwo+Cj4KPiDCoC8qIFJlc2V0IEZ1bmN0aW9ucyAqLwo+IC1pbnQgYXRoNWtfaHdfbmlj
X3dha2V1cChzdHJ1Y3QgYXRoNWtfaHcgKmFoLCBpbnQgZmxhZ3MsIGJvb2wgaW5pdGlhbCk7Cj4g
K2ludCBhdGg1a19od19uaWNfd2FrZXVwKHN0cnVjdCBhdGg1a19odyAqYWgsIHN0cnVjdCBpZWVl
ODAyMTFfY2hhbm5lbCAqY2hhbm5lbCk7Cj4gwqBpbnQgYXRoNWtfaHdfb25faG9sZChzdHJ1Y3Qg
YXRoNWtfaHcgKmFoKTsKPiDCoGludCBhdGg1a19od19yZXNldChzdHJ1Y3QgYXRoNWtfaHcgKmFo
LCBlbnVtIG5sODAyMTFfaWZ0eXBlIG9wX21vZGUsCj4gwqAgwqAgwqAgwqAgwqAgc3RydWN0IGll
ZWU4MDIxMV9jaGFubmVsICpjaGFubmVsLCBib29sIGZhc3QsIGJvb2wgc2tpcF9wY3UpOwo+IEBA
IC0xNDU1LDEzICsxNDMxLDEzIEBAIGludCBhdGg1a19od193cml0ZV9pbml0dmFscyhzdHJ1Y3Qg
YXRoNWtfaHcgKmFoLCB1OCBtb2RlLCBib29sIGNoYW5nZV9jaGFubmVsKTsKPgo+IMKgLyogUEhZ
IGZ1bmN0aW9ucyAqLwo+IMKgLyogTWlzYyBQSFkgZnVuY3Rpb25zICovCj4gLXUxNiBhdGg1a19o
d19yYWRpb19yZXZpc2lvbihzdHJ1Y3QgYXRoNWtfaHcgKmFoLCB1bnNpZ25lZCBpbnQgY2hhbik7
Cj4gK3UxNiBhdGg1a19od19yYWRpb19yZXZpc2lvbihzdHJ1Y3QgYXRoNWtfaHcgKmFoLCBlbnVt
IGllZWU4MDIxMV9iYW5kIGJhbmQpOwo+IMKgaW50IGF0aDVrX2h3X3BoeV9kaXNhYmxlKHN0cnVj
dCBhdGg1a19odyAqYWgpOwo+IMKgLyogR2Fpbl9GIG9wdGltaXphdGlvbiAqLwo+IMKgZW51bSBh
dGg1a19yZmdhaW4gYXRoNWtfaHdfZ2FpbmZfY2FsaWJyYXRlKHN0cnVjdCBhdGg1a19odyAqYWgp
Owo+IMKgaW50IGF0aDVrX2h3X3JmZ2Fpbl9vcHRfaW5pdChzdHJ1Y3QgYXRoNWtfaHcgKmFoKTsK
PiDCoC8qIFBIWS9SRiBjaGFubmVsIGZ1bmN0aW9ucyAqLwo+IC1ib29sIGF0aDVrX2NoYW5uZWxf
b2soc3RydWN0IGF0aDVrX2h3ICphaCwgdTE2IGZyZXEsIHVuc2lnbmVkIGludCBmbGFncyk7Cj4g
K2Jvb2wgYXRoNWtfY2hhbm5lbF9vayhzdHJ1Y3QgYXRoNWtfaHcgKmFoLCBzdHJ1Y3QgaWVlZTgw
MjExX2NoYW5uZWwgKmNoYW5uZWwpOwo+IMKgLyogUEhZIGNhbGlicmF0aW9uICovCj4gwqB2b2lk
IGF0aDVrX2h3X2luaXRfbmZjYWxfaGlzdChzdHJ1Y3QgYXRoNWtfaHcgKmFoKTsKPiDCoGludCBh
dGg1a19od19waHlfY2FsaWJyYXRlKHN0cnVjdCBhdGg1a19odyAqYWgsCj4gZGlmZiAtLWdpdCBh
L2RyaXZlcnMvbmV0L3dpcmVsZXNzL2F0aC9hdGg1ay9hdHRhY2guYyBiL2RyaXZlcnMvbmV0L3dp
cmVsZXNzL2F0aC9hdGg1ay9hdHRhY2guYwo+IGluZGV4IGIwZGYyZjYuLjU2MDYyNTkgMTAwNjQ0
Cj4gLS0tIGEvZHJpdmVycy9uZXQvd2lyZWxlc3MvYXRoL2F0aDVrL2F0dGFjaC5jCj4gKysrIGIv
ZHJpdmVycy9uZXQvd2lyZWxlc3MvYXRoL2F0aDVrL2F0dGFjaC5jCj4gQEAgLTE0NSw3ICsxNDUs
NyBAQCBpbnQgYXRoNWtfaHdfaW5pdChzdHJ1Y3QgYXRoNWtfaHcgKmFoKQo+IMKgIMKgIMKgIMKg
IMKgIMKgIMKgIMKgZ290byBlcnI7Cj4KPiDCoCDCoCDCoCDCoC8qIEJyaW5nIGRldmljZSBvdXQg
b2Ygc2xlZXAgYW5kIHJlc2V0IGl0cyB1bml0cyAqLwo+IC0gwqAgwqAgwqAgcmV0ID0gYXRoNWtf
aHdfbmljX3dha2V1cChhaCwgMCwgdHJ1ZSk7Cj4gKyDCoCDCoCDCoCByZXQgPSBhdGg1a19od19u
aWNfd2FrZXVwKGFoLCBOVUxMKTsKPiDCoCDCoCDCoCDCoGlmIChyZXQpCj4gwqAgwqAgwqAgwqAg
wqAgwqAgwqAgwqBnb3RvIGVycjsKPgo+IEBAIC0xNTMsNyArMTUzLDcgQEAgaW50IGF0aDVrX2h3
X2luaXQoc3RydWN0IGF0aDVrX2h3ICphaCkKPiDCoCDCoCDCoCDCoGFoLT5haF9waHlfcmV2aXNp
b24gPSBhdGg1a19od19yZWdfcmVhZChhaCwgQVI1S19QSFlfQ0hJUF9JRCkgJgo+IMKgIMKgIMKg
IMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgMHhmZmZmZmZmZjsKPiDCoCDCoCDCoCDCoGFoLT5h
aF9yYWRpb181Z2h6X3JldmlzaW9uID0gYXRoNWtfaHdfcmFkaW9fcmV2aXNpb24oYWgsCj4gLSDC
oCDCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoCBDSEFOTkVMXzVHSFopOwo+ICsgwqAgwqAg
wqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAgSUVFRTgwMjExX0JBTkRfNUdIWik7Cj4KPiDCoCDC
oCDCoCDCoC8qIFRyeSB0byBpZGVudGlmeSByYWRpbyBjaGlwIGJhc2VkIG9uIGl0cyBzcmV2ICov
Cj4gwqAgwqAgwqAgwqBzd2l0Y2ggKGFoLT5haF9yYWRpb181Z2h6X3JldmlzaW9uICYgMHhmMCkg
ewo+IEBAIC0xNjEsMTQgKzE2MSwxNCBAQCBpbnQgYXRoNWtfaHdfaW5pdChzdHJ1Y3QgYXRoNWtf
aHcgKmFoKQo+IMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgYWgtPmFoX3JhZGlvID0gQVI1S19SRjUx
MTE7Cj4gwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqBhaC0+YWhfc2luZ2xlX2NoaXAgPSBmYWxzZTsK
PiDCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoGFoLT5haF9yYWRpb18yZ2h6X3JldmlzaW9uID0gYXRo
NWtfaHdfcmFkaW9fcmV2aXNpb24oYWgsCj4gLSDCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoCDC
oCDCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoCBDSEFO
TkVMXzJHSFopOwo+ICsgwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAg
wqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAgSUVFRTgwMjExX0JBTkRfMkdI
Wik7Cj4gwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqBicmVhazsKPiDCoCDCoCDCoCDCoGNhc2UgQVI1
S19TUkVWX1JBRF81MTEyOgo+IMKgIMKgIMKgIMKgY2FzZSBBUjVLX1NSRVZfUkFEXzIxMTI6Cj4g
wqAgwqAgwqAgwqAgwqAgwqAgwqAgwqBhaC0+YWhfcmFkaW8gPSBBUjVLX1JGNTExMjsKPiDCoCDC
oCDCoCDCoCDCoCDCoCDCoCDCoGFoLT5haF9zaW5nbGVfY2hpcCA9IGZhbHNlOwo+IMKgIMKgIMKg
IMKgIMKgIMKgIMKgIMKgYWgtPmFoX3JhZGlvXzJnaHpfcmV2aXNpb24gPSBhdGg1a19od19yYWRp
b19yZXZpc2lvbihhaCwKPiAtIMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKg
IMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgIENIQU5ORUxfMkdIWik7
Cj4gKyDCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoCDC
oCDCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoCBJRUVFODAyMTFfQkFORF8yR0haKTsKPiDCoCDC
oCDCoCDCoCDCoCDCoCDCoCDCoGJyZWFrOwo+IMKgIMKgIMKgIMKgY2FzZSBBUjVLX1NSRVZfUkFE
XzI0MTM6Cj4gwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqBhaC0+YWhfcmFkaW8gPSBBUjVLX1JGMjQx
MzsKPiBAQCAtMjA1LDcgKzIwNSw3IEBAIGludCBhdGg1a19od19pbml0KHN0cnVjdCBhdGg1a19o
dyAqYWgpCj4gwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqBhaC0+YWhfcmFkaW8g
PSBBUjVLX1JGNTExMTsKPiDCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoGFoLT5h
aF9zaW5nbGVfY2hpcCA9IGZhbHNlOwo+IMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKg
IMKgYWgtPmFoX3JhZGlvXzJnaHpfcmV2aXNpb24gPSBhdGg1a19od19yYWRpb19yZXZpc2lvbihh
aCwKPiAtIMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKg
IMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgIENIQU5ORUxfMkdIWik7
Cj4gKyDCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoCDC
oCDCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoCBJRUVFODAyMTFfQkFORF8yR0haKTsKPiDCoCDC
oCDCoCDCoCDCoCDCoCDCoCDCoH0gZWxzZSBpZiAoYWgtPmFoX21hY192ZXJzaW9uID09IChBUjVL
X1NSRVZfQVIyNDI1ID4+IDQpIHx8Cj4gwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAg
wqAgwqAgYWgtPmFoX21hY192ZXJzaW9uID09IChBUjVLX1NSRVZfQVIyNDE3ID4+IDQpIHx8Cj4g
wqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAgYWgtPmFoX3BoeV9yZXZpc2lv
biA9PSBBUjVLX1NSRVZfUEhZXzI0MjUpIHsKPiBkaWZmIC0tZ2l0IGEvZHJpdmVycy9uZXQvd2ly
ZWxlc3MvYXRoL2F0aDVrL2Jhc2UuYyBiL2RyaXZlcnMvbmV0L3dpcmVsZXNzL2F0aC9hdGg1ay9i
YXNlLmMKPiBpbmRleCBlZTA2ZTM0Li5kZmJiZDE2IDEwMDY0NAo+IC0tLSBhL2RyaXZlcnMvbmV0
L3dpcmVsZXNzL2F0aC9hdGg1ay9iYXNlLmMKPiArKysgYi9kcml2ZXJzL25ldC93aXJlbGVzcy9h
dGgvYXRoNWsvYmFzZS5jCj4gQEAgLTI3MSwyMCArMjcxLDE4IEBAIHN0YXRpYyB1bnNpZ25lZCBp
bnQKPiDCoGF0aDVrX3NldHVwX2NoYW5uZWxzKHN0cnVjdCBhdGg1a19odyAqYWgsIHN0cnVjdCBp
ZWVlODAyMTFfY2hhbm5lbCAqY2hhbm5lbHMsCj4gwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqB1bnNp
Z25lZCBpbnQgbW9kZSwgdW5zaWduZWQgaW50IG1heCkKPiDCoHsKPiAtIMKgIMKgIMKgIHVuc2ln
bmVkIGludCBjb3VudCwgc2l6ZSwgY2hmcmVxLCBmcmVxLCBjaDsKPiArIMKgIMKgIMKgIHVuc2ln
bmVkIGludCBjb3VudCwgc2l6ZSwgZnJlcSwgY2g7Cj4gwqAgwqAgwqAgwqBlbnVtIGllZWU4MDIx
MV9iYW5kIGJhbmQ7Cj4KPiDCoCDCoCDCoCDCoHN3aXRjaCAobW9kZSkgewo+IMKgIMKgIMKgIMKg
Y2FzZSBBUjVLX01PREVfMTFBOgo+IMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgLyogMS4uMjIwLCBi
dXQgMkdIeiBmcmVxdWVuY2llcyBhcmUgZmlsdGVyZWQgYnkgY2hlY2tfY2hhbm5lbCAqLwo+IMKg
IMKgIMKgIMKgIMKgIMKgIMKgIMKgc2l6ZSA9IDIyMDsKPiAtIMKgIMKgIMKgIMKgIMKgIMKgIMKg
IGNoZnJlcSA9IENIQU5ORUxfNUdIWjsKPiDCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoGJhbmQgPSBJ
RUVFODAyMTFfQkFORF81R0haOwo+IMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgYnJlYWs7Cj4gwqAg
wqAgwqAgwqBjYXNlIEFSNUtfTU9ERV8xMUI6Cj4gwqAgwqAgwqAgwqBjYXNlIEFSNUtfTU9ERV8x
MUc6Cj4gwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqBzaXplID0gMjY7Cj4gLSDCoCDCoCDCoCDCoCDC
oCDCoCDCoCBjaGZyZXEgPSBDSEFOTkVMXzJHSFo7Cj4gwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqBi
YW5kID0gSUVFRTgwMjExX0JBTkRfMkdIWjsKPiDCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoGJyZWFr
Owo+IMKgIMKgIMKgIMKgZGVmYXVsdDoKPiBAQCAtMjk5LDI2ICsyOTcsMTkgQEAgYXRoNWtfc2V0
dXBfY2hhbm5lbHMoc3RydWN0IGF0aDVrX2h3ICphaCwgc3RydWN0IGllZWU4MDIxMV9jaGFubmVs
ICpjaGFubmVscywKPiDCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoGlmIChmcmVxID09IDApIC8qIG1h
cHBpbmcgZmFpbGVkIC0gbm90IGEgc3RhbmRhcmQgY2hhbm5lbCAqLwo+IMKgIMKgIMKgIMKgIMKg
IMKgIMKgIMKgIMKgIMKgIMKgIMKgY29udGludWU7Cj4KPiArIMKgIMKgIMKgIMKgIMKgIMKgIMKg
IC8qIFdyaXRlIGNoYW5uZWwgaW5mbywgbmVlZGVkIGZvciBhdGg1a19jaGFubmVsX29rKCkgKi8K
PiArIMKgIMKgIMKgIMKgIMKgIMKgIMKgIGNoYW5uZWxzW2NvdW50XS5jZW50ZXJfZnJlcSA9IGZy
ZXE7Cj4gKyDCoCDCoCDCoCDCoCDCoCDCoCDCoCBjaGFubmVsc1tjb3VudF0uYmFuZCA9IGJhbmQ7
Cj4gKyDCoCDCoCDCoCDCoCDCoCDCoCDCoCBjaGFubmVsc1tjb3VudF0uaHdfdmFsdWUgPSBtb2Rl
Owo+ICsKPiDCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoC8qIENoZWNrIGlmIGNoYW5uZWwgaXMgc3Vw
cG9ydGVkIGJ5IHRoZSBjaGlwc2V0ICovCj4gLSDCoCDCoCDCoCDCoCDCoCDCoCDCoCBpZiAoIWF0
aDVrX2NoYW5uZWxfb2soYWgsIGZyZXEsIGNoZnJlcSkpCj4gKyDCoCDCoCDCoCDCoCDCoCDCoCDC
oCBpZiAoIWF0aDVrX2NoYW5uZWxfb2soYWgsICZjaGFubmVsc1tjb3VudF0pKQo+IMKgIMKgIMKg
IMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgY29udGludWU7Cj4KPiDCoCDCoCDCoCDCoCDCoCDC
oCDCoCDCoGlmICghbW9kcGFyYW1fYWxsX2NoYW5uZWxzICYmCj4gwqAgwqAgwqAgwqAgwqAgwqAg
wqAgwqAgwqAgwqAhYXRoNWtfaXNfc3RhbmRhcmRfY2hhbm5lbChjaCwgYmFuZCkpCj4gwqAgwqAg
wqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqBjb250aW51ZTsKPgo+IC0gwqAgwqAgwqAgwqAg
wqAgwqAgwqAgLyogV3JpdGUgY2hhbm5lbCBpbmZvIGFuZCBpbmNyZW1lbnQgY291bnRlciAqLwo+
IC0gwqAgwqAgwqAgwqAgwqAgwqAgwqAgY2hhbm5lbHNbY291bnRdLmNlbnRlcl9mcmVxID0gZnJl
cTsKPiAtIMKgIMKgIMKgIMKgIMKgIMKgIMKgIGNoYW5uZWxzW2NvdW50XS5iYW5kID0gYmFuZDsK
PiAtIMKgIMKgIMKgIMKgIMKgIMKgIMKgIHN3aXRjaCAobW9kZSkgewo+IC0gwqAgwqAgwqAgwqAg
wqAgwqAgwqAgY2FzZSBBUjVLX01PREVfMTFBOgo+IC0gwqAgwqAgwqAgwqAgwqAgwqAgwqAgY2Fz
ZSBBUjVLX01PREVfMTFHOgo+IC0gwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAgY2hh
bm5lbHNbY291bnRdLmh3X3ZhbHVlID0gY2hmcmVxIHwgQ0hBTk5FTF9PRkRNOwo+IC0gwqAgwqAg
wqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAgYnJlYWs7Cj4gLSDCoCDCoCDCoCDCoCDCoCDCoCDC
oCBjYXNlIEFSNUtfTU9ERV8xMUI6Cj4gLSDCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoCDC
oCBjaGFubmVsc1tjb3VudF0uaHdfdmFsdWUgPSBDSEFOTkVMX0I7Cj4gLSDCoCDCoCDCoCDCoCDC
oCDCoCDCoCB9Cj4gLQo+IMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgY291bnQrKzsKPiDCoCDCoCDC
oCDCoH0KPgo+IGRpZmYgLS1naXQgYS9kcml2ZXJzL25ldC93aXJlbGVzcy9hdGgvYXRoNWsvZWVw
cm9tLmMgYi9kcml2ZXJzL25ldC93aXJlbGVzcy9hdGgvYXRoNWsvZWVwcm9tLmMKPiBpbmRleCA1
NmNiOWQ0Li43YzljMmFiIDEwMDY0NAo+IC0tLSBhL2RyaXZlcnMvbmV0L3dpcmVsZXNzL2F0aC9h
dGg1ay9lZXByb20uYwo+ICsrKyBiL2RyaXZlcnMvbmV0L3dpcmVsZXNzL2F0aC9hdGg1ay9lZXBy
b20uYwo+IEBAIC0xNzgwLDEyICsxNzgwLDEyIEBAIGF0aDVrX2VlcHJvbV9kZXRhY2goc3RydWN0
IGF0aDVrX2h3ICphaCkKPiDCoGludAo+IMKgYXRoNWtfZWVwcm9tX21vZGVfZnJvbV9jaGFubmVs
KHN0cnVjdCBpZWVlODAyMTFfY2hhbm5lbCAqY2hhbm5lbCkKPiDCoHsKPiAtIMKgIMKgIMKgIHN3
aXRjaCAoY2hhbm5lbC0+aHdfdmFsdWUgJiBDSEFOTkVMX01PREVTKSB7Cj4gLSDCoCDCoCDCoCBj
YXNlIENIQU5ORUxfQToKPiArIMKgIMKgIMKgIHN3aXRjaCAoY2hhbm5lbC0+aHdfdmFsdWUpIHsK
PiArIMKgIMKgIMKgIGNhc2UgQVI1S19NT0RFXzExQToKPiDCoCDCoCDCoCDCoCDCoCDCoCDCoCDC
oHJldHVybiBBUjVLX0VFUFJPTV9NT0RFXzExQTsKPiAtIMKgIMKgIMKgIGNhc2UgQ0hBTk5FTF9H
Ogo+ICsgwqAgwqAgwqAgY2FzZSBBUjVLX01PREVfMTFHOgo+IMKgIMKgIMKgIMKgIMKgIMKgIMKg
IMKgcmV0dXJuIEFSNUtfRUVQUk9NX01PREVfMTFHOwo+IC0gwqAgwqAgwqAgY2FzZSBDSEFOTkVM
X0I6Cj4gKyDCoCDCoCDCoCBjYXNlIEFSNUtfTU9ERV8xMUI6Cj4gwqAgwqAgwqAgwqAgwqAgwqAg
wqAgwqByZXR1cm4gQVI1S19FRVBST01fTU9ERV8xMUI7Cj4gwqAgwqAgwqAgwqBkZWZhdWx0Ogo+
IMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgcmV0dXJuIC0xOwo+IGRpZmYgLS1naXQgYS9kcml2ZXJz
L25ldC93aXJlbGVzcy9hdGgvYXRoNWsvcGN1LmMgYi9kcml2ZXJzL25ldC93aXJlbGVzcy9hdGgv
YXRoNWsvcGN1LmMKPiBpbmRleCAwNjczMTM4Li43MzNkNDZjIDEwMDY0NAo+IC0tLSBhL2RyaXZl
cnMvbmV0L3dpcmVsZXNzL2F0aC9hdGg1ay9wY3UuYwo+ICsrKyBiL2RyaXZlcnMvbmV0L3dpcmVs
ZXNzL2F0aC9hdGg1ay9wY3UuYwo+IEBAIC0xNTIsNyArMTUyLDcgQEAgdW5zaWduZWQgaW50IGF0
aDVrX2h3X2dldF9kZWZhdWx0X3Nsb3R0aW1lKHN0cnVjdCBhdGg1a19odyAqYWgpCj4gwqAgwqAg
wqAgwqBjYXNlIEFSNUtfQldNT0RFX0RFRkFVTFQ6Cj4gwqAgwqAgwqAgwqBkZWZhdWx0Ogo+IMKg
IMKgIMKgIMKgIMKgIMKgIMKgIMKgc2xvdF90aW1lID0gQVI1S19JTklUX1NMT1RfVElNRV9ERUZB
VUxUOwo+IC0gwqAgwqAgwqAgwqAgwqAgwqAgwqAgaWYgKChjaGFubmVsLT5od192YWx1ZSAmIENI
QU5ORUxfQ0NLKSAmJiAhYWgtPmFoX3Nob3J0X3Nsb3QpCj4gKyDCoCDCoCDCoCDCoCDCoCDCoCDC
oCBpZiAoKGNoYW5uZWwtPmh3X3ZhbHVlID09IEFSNUtfTU9ERV8xMUIpICYmICFhaC0+YWhfc2hv
cnRfc2xvdCkKPiDCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoHNsb3RfdGltZSA9
IEFSNUtfSU5JVF9TTE9UX1RJTUVfQjsKPiDCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoGJyZWFrOwo+
IMKgIMKgIMKgIMKgfQo+IEBAIC0xODMsNyArMTgzLDcgQEAgdW5zaWduZWQgaW50IGF0aDVrX2h3
X2dldF9kZWZhdWx0X3NpZnMoc3RydWN0IGF0aDVrX2h3ICphaCkKPiDCoCDCoCDCoCDCoGNhc2Ug
QVI1S19CV01PREVfREVGQVVMVDoKPiDCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoHNpZnMgPSBBUjVL
X0lOSVRfU0lGU19ERUZBVUxUX0JHOwo+IMKgIMKgIMKgIMKgZGVmYXVsdDoKPiAtIMKgIMKgIMKg
IMKgIMKgIMKgIMKgIGlmIChjaGFubmVsLT5od192YWx1ZSAmIENIQU5ORUxfNUdIWikKPiArIMKg
IMKgIMKgIMKgIMKgIMKgIMKgIGlmIChjaGFubmVsLT5iYW5kID09IElFRUU4MDIxMV9CQU5EXzVH
SFopCj4gwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqBzaWZzID0gQVI1S19JTklU
X1NJRlNfREVGQVVMVF9BOwo+IMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgYnJlYWs7Cj4gwqAgwqAg
wqAgwqB9Cj4gZGlmZiAtLWdpdCBhL2RyaXZlcnMvbmV0L3dpcmVsZXNzL2F0aC9hdGg1ay9waHku
YyBiL2RyaXZlcnMvbmV0L3dpcmVsZXNzL2F0aC9hdGg1ay9waHkuYwo+IGluZGV4IGI5YWRhODgu
LjIyN2M5MTQgMTAwNjQ0Cj4gLS0tIGEvZHJpdmVycy9uZXQvd2lyZWxlc3MvYXRoL2F0aDVrL3Bo
eS5jCj4gKysrIGIvZHJpdmVycy9uZXQvd2lyZWxlc3MvYXRoL2F0aDVrL3BoeS5jCj4gQEAgLTM4
LDcgKzM4LDcgQEAKPiDCoC8qCj4gwqAqIEdldCB0aGUgUEhZIENoaXAgcmV2aXNpb24KPiDCoCov
Cj4gLXUxNiBhdGg1a19od19yYWRpb19yZXZpc2lvbihzdHJ1Y3QgYXRoNWtfaHcgKmFoLCB1bnNp
Z25lZCBpbnQgY2hhbikKPiArdTE2IGF0aDVrX2h3X3JhZGlvX3JldmlzaW9uKHN0cnVjdCBhdGg1
a19odyAqYWgsIGVudW0gaWVlZTgwMjExX2JhbmQgYmFuZCkKPiDCoHsKPiDCoCDCoCDCoCDCoHVu
c2lnbmVkIGludCBpOwo+IMKgIMKgIMKgIMKgdTMyIHNyZXY7Cj4gQEAgLTQ3LDExICs0NywxMSBA
QCB1MTYgYXRoNWtfaHdfcmFkaW9fcmV2aXNpb24oc3RydWN0IGF0aDVrX2h3ICphaCwgdW5zaWdu
ZWQgaW50IGNoYW4pCj4gwqAgwqAgwqAgwqAvKgo+IMKgIMKgIMKgIMKgICogU2V0IHRoZSByYWRp
byBjaGlwIGFjY2VzcyByZWdpc3Rlcgo+IMKgIMKgIMKgIMKgICovCj4gLSDCoCDCoCDCoCBzd2l0
Y2ggKGNoYW4pIHsKPiAtIMKgIMKgIMKgIGNhc2UgQ0hBTk5FTF8yR0haOgo+ICsgwqAgwqAgwqAg
c3dpdGNoIChiYW5kKSB7Cj4gKyDCoCDCoCDCoCBjYXNlIElFRUU4MDIxMV9CQU5EXzJHSFo6Cj4g
wqAgwqAgwqAgwqAgwqAgwqAgwqAgwqBhdGg1a19od19yZWdfd3JpdGUoYWgsIEFSNUtfUEhZX1NI
SUZUXzJHSFosIEFSNUtfUEhZKDApKTsKPiDCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoGJyZWFrOwo+
IC0gwqAgwqAgwqAgY2FzZSBDSEFOTkVMXzVHSFo6Cj4gKyDCoCDCoCDCoCBjYXNlIElFRUU4MDIx
MV9CQU5EXzVHSFo6Cj4gwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqBhdGg1a19od19yZWdfd3JpdGUo
YWgsIEFSNUtfUEhZX1NISUZUXzVHSFosIEFSNUtfUEhZKDApKTsKPiDCoCDCoCDCoCDCoCDCoCDC
oCDCoCDCoGJyZWFrOwo+IMKgIMKgIMKgIMKgZGVmYXVsdDoKPiBAQCAtODQsMTQgKzg0LDE2IEBA
IHUxNiBhdGg1a19od19yYWRpb19yZXZpc2lvbihzdHJ1Y3QgYXRoNWtfaHcgKmFoLCB1bnNpZ25l
ZCBpbnQgY2hhbikKPiDCoC8qCj4gwqAqIENoZWNrIGlmIGEgY2hhbm5lbCBpcyBzdXBwb3J0ZWQK
PiDCoCovCj4gLWJvb2wgYXRoNWtfY2hhbm5lbF9vayhzdHJ1Y3QgYXRoNWtfaHcgKmFoLCB1MTYg
ZnJlcSwgdW5zaWduZWQgaW50IGZsYWdzKQo+ICtib29sIGF0aDVrX2NoYW5uZWxfb2soc3RydWN0
IGF0aDVrX2h3ICphaCwgc3RydWN0IGllZWU4MDIxMV9jaGFubmVsICpjaGFubmVsKQo+IMKgewo+
ICsgwqAgwqAgwqAgdTE2IGZyZXEgPSBjaGFubmVsLT5jZW50ZXJfZnJlcTsKPiArCj4gwqAgwqAg
wqAgwqAvKiBDaGVjayBpZiB0aGUgY2hhbm5lbCBpcyBpbiBvdXIgc3VwcG9ydGVkIHJhbmdlICov
Cj4gLSDCoCDCoCDCoCBpZiAoZmxhZ3MgJiBDSEFOTkVMXzJHSFopIHsKPiArIMKgIMKgIMKgIGlm
IChjaGFubmVsLT5iYW5kID09IElFRUU4MDIxMV9CQU5EXzJHSFopIHsKPiDCoCDCoCDCoCDCoCDC
oCDCoCDCoCDCoGlmICgoZnJlcSA+PSBhaC0+YWhfY2FwYWJpbGl0aWVzLmNhcF9yYW5nZS5yYW5n
ZV8yZ2h6X21pbikgJiYKPiDCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoChmcmVxIDw9IGFo
LT5haF9jYXBhYmlsaXRpZXMuY2FwX3JhbmdlLnJhbmdlXzJnaHpfbWF4KSkKPiDCoCDCoCDCoCDC
oCDCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoHJldHVybiB0cnVlOwo+IC0gwqAgwqAgwqAgfSBlbHNl
IGlmIChmbGFncyAmIENIQU5ORUxfNUdIWikKPiArIMKgIMKgIMKgIH0gZWxzZSBpZiAoY2hhbm5l
bC0+YmFuZCA9PSBJRUVFODAyMTFfQkFORF81R0haKQo+IMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKg
aWYgKChmcmVxID49IGFoLT5haF9jYXBhYmlsaXRpZXMuY2FwX3JhbmdlLnJhbmdlXzVnaHpfbWlu
KSAmJgo+IMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgKGZyZXEgPD0gYWgtPmFoX2NhcGFi
aWxpdGllcy5jYXBfcmFuZ2UucmFuZ2VfNWdoel9tYXgpKQo+IMKgIMKgIMKgIMKgIMKgIMKgIMKg
IMKgIMKgIMKgIMKgIMKgcmV0dXJuIHRydWU7Cj4gQEAgLTIyNCw3ICsyMjYsNyBAQCBzdGF0aWMg
aW5saW5lIGludCBhdGg1a19od193cml0ZV9vZmRtX3RpbWluZ3Moc3RydWN0IGF0aDVrX2h3ICph
aCwKPiDCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoGRzX2NvZWZfZXhwLCBkc19jb2VmX21hbiwgY2xv
Y2s7Cj4KPiDCoCDCoCDCoCDCoEJVR19PTighKGFoLT5haF92ZXJzaW9uID09IEFSNUtfQVI1MjEy
KSB8fAo+IC0gwqAgwqAgwqAgwqAgwqAgwqAgwqAgIShjaGFubmVsLT5od192YWx1ZSAmIENIQU5O
RUxfT0ZETSkpOwo+ICsgwqAgwqAgwqAgwqAgwqAgwqAgwqAgKGNoYW5uZWwtPmh3X3ZhbHVlID09
IEFSNUtfTU9ERV8xMUIpKTsKPgo+IMKgIMKgIMKgIMKgLyogR2V0IGNvZWZmaWNpZW50Cj4gwqAg
wqAgwqAgwqAgKiBBTEdPOiBjb2VmID0gKDUgKiBjbG9jayAvIGNhcnJpZXJfZnJlcSkgLyAyCj4g
QEAgLTI5OCw3ICszMDAsNyBAQCBzdGF0aWMgdm9pZCBhdGg1a19od193YWl0X2Zvcl9zeW50aChz
dHJ1Y3QgYXRoNWtfaHcgKmFoLAo+IMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgdTMyIGRlbGF5Owo+
IMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgZGVsYXkgPSBhdGg1a19od19yZWdfcmVhZChhaCwgQVI1
S19QSFlfUlhfREVMQVkpICYKPiDCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoEFS
NUtfUEhZX1JYX0RFTEFZX007Cj4gLSDCoCDCoCDCoCDCoCDCoCDCoCDCoCBkZWxheSA9IChjaGFu
bmVsLT5od192YWx1ZSAmIENIQU5ORUxfQ0NLKSA/Cj4gKyDCoCDCoCDCoCDCoCDCoCDCoCDCoCBk
ZWxheSA9IChjaGFubmVsLT5od192YWx1ZSA9PSBBUjVLX01PREVfMTFCKSA/Cj4gwqAgwqAgwqAg
wqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAoKGRlbGF5IDw8IDIpIC8gMjIpIDogKGRlbGF5IC8g
MTApOwo+IMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgaWYgKGFoLT5haF9id21vZGUgPT0gQVI1S19C
V01PREVfMTBNSFopCj4gwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqBkZWxheSA9
IGRlbGF5IDw8IDE7Cj4gQEAgLTc5OCw5ICs4MDAsOSBAQCBzdGF0aWMgaW50IGF0aDVrX2h3X3Jm
cmVnc19pbml0KHN0cnVjdCBhdGg1a19odyAqYWgsCj4gwqAgwqAgwqAgwqB9Cj4KPiDCoCDCoCDC
oCDCoC8qIFNldCBPdXRwdXQgYW5kIERyaXZlciBiaWFzIGN1cnJlbnQgKE9CL0RCKSAqLwo+IC0g
wqAgwqAgwqAgaWYgKGNoYW5uZWwtPmh3X3ZhbHVlICYgQ0hBTk5FTF8yR0haKSB7Cj4gKyDCoCDC
oCDCoCBpZiAoY2hhbm5lbC0+YmFuZCA9PSBJRUVFODAyMTFfQkFORF8yR0haKSB7Cj4KPiAtIMKg
IMKgIMKgIMKgIMKgIMKgIMKgIGlmIChjaGFubmVsLT5od192YWx1ZSAmIENIQU5ORUxfQ0NLKQo+
ICsgwqAgwqAgwqAgwqAgwqAgwqAgwqAgaWYgKGNoYW5uZWwtPmh3X3ZhbHVlID09IEFSNUtfTU9E
RV8xMUIpCj4gwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqBlZV9tb2RlID0gQVI1
S19FRVBST01fTU9ERV8xMUI7Cj4gwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqBlbHNlCj4gwqAgwqAg
wqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqBlZV9tb2RlID0gQVI1S19FRVBST01fTU9ERV8x
MUc7Cj4gQEAgLTgyNSw3ICs4MjcsNyBAQCBzdGF0aWMgaW50IGF0aDVrX2h3X3JmcmVnc19pbml0
KHN0cnVjdCBhdGg1a19odyAqYWgsCj4gwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAg
wqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqBBUjVLX1JGX0RCXzJHSFosIHRy
dWUpOwo+Cj4gwqAgwqAgwqAgwqAvKiBSRjUxMTEgYWx3YXlzIG5lZWRzIE9CL0RCIGZvciA1R0h6
LCBldmVuIGlmIHdlIHVzZSAyR0h6ICovCj4gLSDCoCDCoCDCoCB9IGVsc2UgaWYgKChjaGFubmVs
LT5od192YWx1ZSAmIENIQU5ORUxfNUdIWikgfHwKPiArIMKgIMKgIMKgIH0gZWxzZSBpZiAoKGNo
YW5uZWwtPmJhbmQgPT0gSUVFRTgwMjExX0JBTkRfNUdIWikgfHwKPiDCoCDCoCDCoCDCoCDCoCDC
oCDCoCDCoCDCoCDCoCDCoCDCoChhaC0+YWhfcmFkaW8gPT0gQVI1S19SRjUxMTEpKSB7Cj4KPiDC
oCDCoCDCoCDCoCDCoCDCoCDCoCDCoC8qIEZvciAxMWEsIFR1cmJvIGFuZCBYUiB3ZSBuZWVkIHRv
IGNob29zZQo+IEBAIC04NTcsNyArODU5LDcgQEAgc3RhdGljIGludCBhdGg1a19od19yZnJlZ3Nf
aW5pdChzdHJ1Y3QgYXRoNWtfaHcgKmFoLAo+IMKgIMKgIMKgIMKgaWYgKGFoLT5haF9yYWRpbyA9
PSBBUjVLX1JGNTExMSkgewo+Cj4gwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAvKiBTZXQgZ2Fpbl9G
IHNldHRpbmdzIGFjY29yZGluZyB0byBjdXJyZW50IHN0ZXAgKi8KPiAtIMKgIMKgIMKgIMKgIMKg
IMKgIMKgIGlmIChjaGFubmVsLT5od192YWx1ZSAmIENIQU5ORUxfT0ZETSkgewo+ICsgwqAgwqAg
wqAgwqAgwqAgwqAgwqAgaWYgKGNoYW5uZWwtPmh3X3ZhbHVlICE9IEFSNUtfTU9ERV8xMUIpIHsK
Pgo+IMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgQVI1S19SRUdfV1JJVEVfQklU
UyhhaCwgQVI1S19QSFlfRlJBTUVfQ1RMLAo+IMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKg
IMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgQVI1S19QSFlfRlJBTUVfQ1RMX1RYX0NMSVAs
Cj4gQEAgLTkxNCw3ICs5MTYsNyBAQCBzdGF0aWMgaW50IGF0aDVrX2h3X3JmcmVnc19pbml0KHN0
cnVjdCBhdGg1a19odyAqYWgsCj4gwqAgwqAgwqAgwqBpZiAoYWgtPmFoX3JhZGlvID09IEFSNUtf
UkY1MTEyKSB7Cj4KPiDCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoC8qIFNldCBnYWluX0Ygc2V0dGlu
Z3MgYWNjb3JkaW5nIHRvIGN1cnJlbnQgc3RlcCAqLwo+IC0gwqAgwqAgwqAgwqAgwqAgwqAgwqAg
aWYgKGNoYW5uZWwtPmh3X3ZhbHVlICYgQ0hBTk5FTF9PRkRNKSB7Cj4gKyDCoCDCoCDCoCDCoCDC
oCDCoCDCoCBpZiAoY2hhbm5lbC0+aHdfdmFsdWUgIT0gQVI1S19NT0RFXzExQikgewo+Cj4gwqAg
wqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqBhdGg1a19od19yZmJfb3AoYWgsIHJmX3Jl
Z3MsIGdfc3RlcC0+Z29zX3BhcmFtWzBdLAo+IMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKg
IMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgQVI1S19SRl9NSVhHQUlO
X09WUiwgdHJ1ZSk7Cj4gQEAgLTEwMjYsNyArMTAyOCw3IEBAIHN0YXRpYyBpbnQgYXRoNWtfaHdf
cmZyZWdzX2luaXQoc3RydWN0IGF0aDVrX2h3ICphaCwKPiDCoCDCoCDCoCDCoH0KPgo+IMKgIMKg
IMKgIMKgaWYgKGFoLT5haF9yYWRpbyA9PSBBUjVLX1JGNTQxMyAmJgo+IC0gwqAgwqAgwqAgY2hh
bm5lbC0+aHdfdmFsdWUgJiBDSEFOTkVMXzJHSFopIHsKPiArIMKgIMKgIMKgIGNoYW5uZWwtPmJh
bmQgPT0gSUVFRTgwMjExX0JBTkRfMkdIWikgewo+Cj4gwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqBh
dGg1a19od19yZmJfb3AoYWgsIHJmX3JlZ3MsIDEsIEFSNUtfUkZfREVSQllfQ0hBTl9TRUxfTU9E
RSwKPiDCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoCDC
oCDCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoHRy
dWUpOwo+IEBAIC0xMTM4LDcgKzExNDAsNyBAQCBzdGF0aWMgaW50IGF0aDVrX2h3X3JmNTExMV9j
aGFubmVsKHN0cnVjdCBhdGg1a19odyAqYWgsCj4gwqAgwqAgwqAgwqAgKi8KPiDCoCDCoCDCoCDC
oGRhdGEwID0gZGF0YTEgPSAwOwo+Cj4gLSDCoCDCoCDCoCBpZiAoY2hhbm5lbC0+aHdfdmFsdWUg
JiBDSEFOTkVMXzJHSFopIHsKPiArIMKgIMKgIMKgIGlmIChjaGFubmVsLT5iYW5kID09IElFRUU4
MDIxMV9CQU5EXzJHSFopIHsKPiDCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoC8qIE1hcCAyR0h6IGNo
YW5uZWwgdG8gNUdIeiBBdGhlcm9zIGNoYW5uZWwgSUQgKi8KPiDCoCDCoCDCoCDCoCDCoCDCoCDC
oCDCoHJldCA9IGF0aDVrX2h3X3JmNTExMV9jaGFuMmF0aGNoYW4oCj4gwqAgwqAgwqAgwqAgwqAg
wqAgwqAgwqAgwqAgwqAgwqAgwqBpZWVlODAyMTFfZnJlcXVlbmN5X3RvX2NoYW5uZWwoY2hhbm5l
bC0+Y2VudGVyX2ZyZXEpLAo+IEBAIC0xMjY1LDEwICsxMjY3LDkgQEAgc3RhdGljIGludCBhdGg1
a19od19jaGFubmVsKHN0cnVjdCBhdGg1a19odyAqYWgsCj4gwqAgwqAgwqAgwqBpbnQgcmV0Owo+
IMKgIMKgIMKgIMKgLyoKPiDCoCDCoCDCoCDCoCAqIENoZWNrIGJvdW5kcyBzdXBwb3J0ZWQgYnkg
dGhlIFBIWSAod2UgZG9uJ3QgY2FyZSBhYm91dCByZWd1bGF0b3J5Cj4gLSDCoCDCoCDCoCDCoCog
cmVzdHJpY3Rpb25zIGF0IHRoaXMgcG9pbnQpLiBOb3RlOiBod192YWx1ZSBhbHJlYWR5IGhhcyB0
aGUgYmFuZAo+IC0gwqAgwqAgwqAgwqAqIChDSEFOTkVMXzJHSFosIG9yIENIQU5ORUxfNUdIWikg
c28gd2UgaW5mb3JtIGF0aDVrX2NoYW5uZWxfb2soKQo+IC0gwqAgwqAgwqAgwqAqIG9mIHRoZSBi
YW5kIGJ5IHRoYXQgKi8KPiAtIMKgIMKgIMKgIGlmICghYXRoNWtfY2hhbm5lbF9vayhhaCwgY2hh
bm5lbC0+Y2VudGVyX2ZyZXEsIGNoYW5uZWwtPmh3X3ZhbHVlKSkgewo+ICsgwqAgwqAgwqAgwqAq
IHJlc3RyaWN0aW9ucyBhdCB0aGlzIHBvaW50KS4KPiArIMKgIMKgIMKgIMKgKi8KPiArIMKgIMKg
IMKgIGlmICghYXRoNWtfY2hhbm5lbF9vayhhaCwgY2hhbm5lbCkpIHsKPiDCoCDCoCDCoCDCoCDC
oCDCoCDCoCDCoEFUSDVLX0VSUihhaCwKPiDCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoCDC
oCDCoCJjaGFubmVsIGZyZXF1ZW5jeSAoJXUgTUh6KSBvdXQgb2Ygc3VwcG9ydGVkICIKPiDCoCDC
oCDCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoCJiYW5kIHJhbmdlXG4iLAo+IEBAIC0xNjE0
LDcgKzE2MTUsNyBAQCBpbnQgYXRoNWtfaHdfcGh5X2NhbGlicmF0ZShzdHJ1Y3QgYXRoNWtfaHcg
KmFoLAo+IMKgIMKgIMKgIMKgcmV0ID0gYXRoNWtfaHdfcmY1MTF4X2lxX2NhbGlicmF0ZShhaCk7
Cj4KPiDCoCDCoCDCoCDCoGlmICgoYWgtPmFoX3JhZGlvID09IEFSNUtfUkY1MTExIHx8IGFoLT5h
aF9yYWRpbyA9PSBBUjVLX1JGNTExMikgJiYKPiAtIMKgIMKgIMKgIMKgIMKgIChjaGFubmVsLT5o
d192YWx1ZSAmIENIQU5ORUxfT0ZETSkpCj4gKyDCoCDCoCDCoCDCoCDCoCAoY2hhbm5lbC0+aHdf
dmFsdWUgIT0gQVI1S19NT0RFXzExQikpCj4gwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqBhdGg1a19o
d19yZXF1ZXN0X3JmZ2Fpbl9wcm9iZShhaCk7Cj4KPiDCoCDCoCDCoCDCoHJldHVybiByZXQ7Cj4g
QEAgLTE2NDEsNyArMTY0Miw3IEBAIGF0aDVrX2h3X3NldF9zcHVyX21pdGlnYXRpb25fZmlsdGVy
KHN0cnVjdCBhdGg1a19odyAqYWgsCj4gwqAgwqAgwqAgwqAvKiBDb252ZXJ0IGN1cnJlbnQgZnJl
cXVlbmN5IHRvIGZiaW4gdmFsdWUgKHRoZSBzYW1lIHdheSBjaGFubmVscwo+IMKgIMKgIMKgIMKg
ICogYXJlIHN0b3JlZCBvbiBFRVBST00sIGNoZWNrIG91dCBhdGg1a19lZXByb21fYmluMmZyZXEp
IGFuZCBzY2FsZQo+IMKgIMKgIMKgIMKgICogdXAgYnkgMiBzbyB3ZSBjYW4gY29tcGFyZSBpdCBs
YXRlciAqLwo+IC0gwqAgwqAgwqAgaWYgKGNoYW5uZWwtPmh3X3ZhbHVlICYgQ0hBTk5FTF8yR0ha
KSB7Cj4gKyDCoCDCoCDCoCBpZiAoY2hhbm5lbC0+YmFuZCA9PSBJRUVFODAyMTFfQkFORF8yR0ha
KSB7Cj4gwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqBjaGFuX2ZiaW4gPSAoY2hhbm5lbC0+Y2VudGVy
X2ZyZXEgLSAyMzAwKSAqIDEwOwo+IMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgZnJlcV9iYW5kID0g
QVI1S19FRVBST01fQkFORF8yR0haOwo+IMKgIMKgIMKgIMKgfSBlbHNlIHsKPiBAQCAtMTcwMyw3
ICsxNzA0LDcgQEAgYXRoNWtfaHdfc2V0X3NwdXJfbWl0aWdhdGlvbl9maWx0ZXIoc3RydWN0IGF0
aDVrX2h3ICphaCwKPiDCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoHNwdXJfZnJl
cV9zaWdtYV9kZWx0YSA9IChzcHVyX2RlbHRhX3BoYXNlID4+IDEwKTsKPiDCoCDCoCDCoCDCoCDC
oCDCoCDCoCDCoCDCoCDCoCDCoCDCoHN5bWJvbF93aWR0aCA9IEFSNUtfU1BVUl9TWU1CT0xfV0lE
VEhfQkFTRV8xMDBIeiAvIDQ7Cj4gwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqBkZWZhdWx0Ogo+IC0g
wqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAgaWYgKGNoYW5uZWwtPmh3X3ZhbHVlID09
IENIQU5ORUxfQSkgewo+ICsgwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAgaWYgKGNo
YW5uZWwtPmJhbmQgPT0gSUVFRTgwMjExX0JBTkRfNUdIWikgewo+IMKgIMKgIMKgIMKgIMKgIMKg
IMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgLyogQm90aCBzYW1wbGVfZnJlcSBhbmQgY2hp
cF9mcmVxIGFyZSA0ME1IeiAqLwo+IMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKg
IMKgIMKgIMKgIMKgc3B1cl9kZWx0YV9waGFzZSA9IChzcHVyX29mZnNldCA8PCAxNykgLyAyNTsK
PiDCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoHNwdXJfZnJl
cV9zaWdtYV9kZWx0YSA9Cj4gQEAgLTIyMjYsMTUgKzIyMjcsMjAgQEAgYXRoNWtfZ2V0X2NoYW5f
cGNhbF9zdXJyb3VuZGluZ19waWVycyhzdHJ1Y3QgYXRoNWtfaHcgKmFoLAo+IMKgIMKgIMKgIMKg
aWR4X2wgPSAwOwo+IMKgIMKgIMKgIMKgaWR4X3IgPSAwOwo+Cj4gLSDCoCDCoCDCoCBpZiAoIShj
aGFubmVsLT5od192YWx1ZSAmIENIQU5ORUxfT0ZETSkpIHsKPiArIMKgIMKgIMKgIHN3aXRjaCAo
Y2hhbm5lbC0+aHdfdmFsdWUpIHsKPiArIMKgIMKgIMKgIGNhc2UgQVI1S19FRVBST01fTU9ERV8x
MUE6Cj4gKyDCoCDCoCDCoCDCoCDCoCDCoCDCoCBwY2luZm8gPSBlZS0+ZWVfcHdyX2NhbF9hOwo+
ICsgwqAgwqAgwqAgwqAgwqAgwqAgwqAgbW9kZSA9IEFSNUtfRUVQUk9NX01PREVfMTFBOwo+ICsg
wqAgwqAgwqAgwqAgwqAgwqAgwqAgYnJlYWs7Cj4gKyDCoCDCoCDCoCBjYXNlIEFSNUtfRUVQUk9N
X01PREVfMTFCOgo+IMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgcGNpbmZvID0gZWUtPmVlX3B3cl9j
YWxfYjsKPiDCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoG1vZGUgPSBBUjVLX0VFUFJPTV9NT0RFXzEx
QjsKPiAtIMKgIMKgIMKgIH0gZWxzZSBpZiAoY2hhbm5lbC0+aHdfdmFsdWUgJiBDSEFOTkVMXzJH
SFopIHsKPiArIMKgIMKgIMKgIMKgIMKgIMKgIMKgIGJyZWFrOwo+ICsgwqAgwqAgwqAgY2FzZSBB
UjVLX0VFUFJPTV9NT0RFXzExRzoKPiArIMKgIMKgIMKgIGRlZmF1bHQ6Cj4gwqAgwqAgwqAgwqAg
wqAgwqAgwqAgwqBwY2luZm8gPSBlZS0+ZWVfcHdyX2NhbF9nOwo+IMKgIMKgIMKgIMKgIMKgIMKg
IMKgIMKgbW9kZSA9IEFSNUtfRUVQUk9NX01PREVfMTFHOwo+IC0gwqAgwqAgwqAgfSBlbHNlIHsK
PiAtIMKgIMKgIMKgIMKgIMKgIMKgIMKgIHBjaW5mbyA9IGVlLT5lZV9wd3JfY2FsX2E7Cj4gLSDC
oCDCoCDCoCDCoCDCoCDCoCDCoCBtb2RlID0gQVI1S19FRVBST01fTU9ERV8xMUE7Cj4gKyDCoCDC
oCDCoCDCoCDCoCDCoCDCoCBicmVhazsKPiDCoCDCoCDCoCDCoH0KPiDCoCDCoCDCoCDCoG1heCA9
IGVlLT5lZV9uX3BpZXJzW21vZGVdIC0gMTsKPgo+IEBAIC0yMzAzLDE1ICsyMzA5LDIwIEBAIGF0
aDVrX2dldF9yYXRlX3BjYWxfZGF0YShzdHJ1Y3QgYXRoNWtfaHcgKmFoLAo+IMKgIMKgIMKgIMKg
aWR4X2wgPSAwOwo+IMKgIMKgIMKgIMKgaWR4X3IgPSAwOwo+Cj4gLSDCoCDCoCDCoCBpZiAoIShj
aGFubmVsLT5od192YWx1ZSAmIENIQU5ORUxfT0ZETSkpIHsKPiArIMKgIMKgIMKgIHN3aXRjaCAo
Y2hhbm5lbC0+aHdfdmFsdWUpIHsKPiArIMKgIMKgIMKgIGNhc2UgQVI1S19NT0RFXzExQToKPiAr
IMKgIMKgIMKgIMKgIMKgIMKgIMKgIHJwaW5mbyA9IGVlLT5lZV9yYXRlX3Rwd3JfYTsKPiArIMKg
IMKgIMKgIMKgIMKgIMKgIMKgIG1vZGUgPSBBUjVLX0VFUFJPTV9NT0RFXzExQTsKPiArIMKgIMKg
IMKgIMKgIMKgIMKgIMKgIGJyZWFrOwo+ICsgwqAgwqAgwqAgY2FzZSBBUjVLX01PREVfMTFCOgo+
IMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgcnBpbmZvID0gZWUtPmVlX3JhdGVfdHB3cl9iOwo+IMKg
IMKgIMKgIMKgIMKgIMKgIMKgIMKgbW9kZSA9IEFSNUtfRUVQUk9NX01PREVfMTFCOwo+IC0gwqAg
wqAgwqAgfSBlbHNlIGlmIChjaGFubmVsLT5od192YWx1ZSAmIENIQU5ORUxfMkdIWikgewo+ICsg
wqAgwqAgwqAgwqAgwqAgwqAgwqAgYnJlYWs7Cj4gKyDCoCDCoCDCoCBjYXNlIEFSNUtfTU9ERV8x
MUc6Cj4gKyDCoCDCoCDCoCBkZWZhdWx0Ogo+IMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgcnBpbmZv
ID0gZWUtPmVlX3JhdGVfdHB3cl9nOwo+IMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgbW9kZSA9IEFS
NUtfRUVQUk9NX01PREVfMTFHOwo+IC0gwqAgwqAgwqAgfSBlbHNlIHsKPiAtIMKgIMKgIMKgIMKg
IMKgIMKgIMKgIHJwaW5mbyA9IGVlLT5lZV9yYXRlX3Rwd3JfYTsKPiAtIMKgIMKgIMKgIMKgIMKg
IMKgIMKgIG1vZGUgPSBBUjVLX0VFUFJPTV9NT0RFXzExQTsKPiArIMKgIMKgIMKgIMKgIMKgIMKg
IMKgIGJyZWFrOwo+IMKgIMKgIMKgIMKgfQo+IMKgIMKgIMKgIMKgbWF4ID0gZWUtPmVlX3JhdGVf
dGFyZ2V0X3B3cl9udW1bbW9kZV0gLSAxOwo+Cj4gQEAgLTIzOTIsMjAgKzI0MDMsMjAgQEAgYXRo
NWtfZ2V0X21heF9jdGxfcG93ZXIoc3RydWN0IGF0aDVrX2h3ICphaCwKPgo+IMKgIMKgIMKgIMKg
Y3RsX21vZGUgPSBhdGhfcmVnZF9nZXRfYmFuZF9jdGwocmVndWxhdG9yeSwgY2hhbm5lbC0+YmFu
ZCk7Cj4KPiAtIMKgIMKgIMKgIHN3aXRjaCAoY2hhbm5lbC0+aHdfdmFsdWUgJiBDSEFOTkVMX01P
REVTKSB7Cj4gLSDCoCDCoCDCoCBjYXNlIENIQU5ORUxfQToKPiArIMKgIMKgIMKgIHN3aXRjaCAo
Y2hhbm5lbC0+aHdfdmFsdWUpIHsKPiArIMKgIMKgIMKgIGNhc2UgQVI1S19NT0RFXzExQToKPiDC
oCDCoCDCoCDCoCDCoCDCoCDCoCDCoGlmIChhaC0+YWhfYndtb2RlID09IEFSNUtfQldNT0RFXzQw
TUhaKQo+IMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgY3RsX21vZGUgfD0gQVI1
S19DVExfVFVSQk87Cj4gwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqBlbHNlCj4gwqAgwqAgwqAgwqAg
wqAgwqAgwqAgwqAgwqAgwqAgwqAgwqBjdGxfbW9kZSB8PSBBUjVLX0NUTF8xMUE7Cj4gwqAgwqAg
wqAgwqAgwqAgwqAgwqAgwqBicmVhazsKPiAtIMKgIMKgIMKgIGNhc2UgQ0hBTk5FTF9HOgo+ICsg
wqAgwqAgwqAgY2FzZSBBUjVLX01PREVfMTFHOgo+IMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgaWYg
KGFoLT5haF9id21vZGUgPT0gQVI1S19CV01PREVfNDBNSFopCj4gwqAgwqAgwqAgwqAgwqAgwqAg
wqAgwqAgwqAgwqAgwqAgwqBjdGxfbW9kZSB8PSBBUjVLX0NUTF9UVVJCT0c7Cj4gwqAgwqAgwqAg
wqAgwqAgwqAgwqAgwqBlbHNlCj4gwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqBj
dGxfbW9kZSB8PSBBUjVLX0NUTF8xMUc7Cj4gwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqBicmVhazsK
PiAtIMKgIMKgIMKgIGNhc2UgQ0hBTk5FTF9COgo+ICsgwqAgwqAgwqAgY2FzZSBBUjVLX01PREVf
MTFCOgo+IMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgY3RsX21vZGUgfD0gQVI1S19DVExfMTFCOwo+
IMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgYnJlYWs7Cj4gwqAgwqAgwqAgwqBkZWZhdWx0Ogo+IEBA
IC0zMjkwLDcgKzMzMDEsNyBAQCBpbnQgYXRoNWtfaHdfcGh5X2luaXQoc3RydWN0IGF0aDVrX2h3
ICphaCwgc3RydWN0IGllZWU4MDIxMV9jaGFubmVsICpjaGFubmVsLAo+Cj4gwqAgwqAgwqAgwqAv
KiBXcml0ZSBPRkRNIHRpbWluZ3Mgb24gNTIxMiovCj4gwqAgwqAgwqAgwqBpZiAoYWgtPmFoX3Zl
cnNpb24gPT0gQVI1S19BUjUyMTIgJiYKPiAtIMKgIMKgIMKgIMKgIMKgIMKgIMKgIGNoYW5uZWwt
Pmh3X3ZhbHVlICYgQ0hBTk5FTF9PRkRNKSB7Cj4gKyDCoCDCoCDCoCDCoCDCoCDCoCDCoCBjaGFu
bmVsLT5od192YWx1ZSAhPSBBUjVLX01PREVfMTFCKSB7Cj4KPiDCoCDCoCDCoCDCoCDCoCDCoCDC
oCDCoHJldCA9IGF0aDVrX2h3X3dyaXRlX29mZG1fdGltaW5ncyhhaCwgY2hhbm5lbCk7Cj4gwqAg
wqAgwqAgwqAgwqAgwqAgwqAgwqBpZiAocmV0KQo+IGRpZmYgLS1naXQgYS9kcml2ZXJzL25ldC93
aXJlbGVzcy9hdGgvYXRoNWsvcWN1LmMgYi9kcml2ZXJzL25ldC93aXJlbGVzcy9hdGgvYXRoNWsv
cWN1LmMKPiBpbmRleCAxZDM3Njc1Li5hOGI4ZmZhIDEwMDY0NAo+IC0tLSBhL2RyaXZlcnMvbmV0
L3dpcmVsZXNzL2F0aC9hdGg1ay9xY3UuYwo+ICsrKyBiL2RyaXZlcnMvbmV0L3dpcmVsZXNzL2F0
aC9hdGg1ay9xY3UuYwo+IEBAIC01MzcsNyArNTM3LDcgQEAgaW50IGF0aDVrX2h3X3NldF9pZnNf
aW50ZXJ2YWxzKHN0cnVjdCBhdGg1a19odyAqYWgsIHVuc2lnbmVkIGludCBzbG90X3RpbWUpCj4g
wqAgwqAgwqAgwqAgKgo+IMKgIMKgIMKgIMKgICogQWxzbyB3ZSBoYXZlIGRpZmZlcmVudCBsb3dl
c3QgcmF0ZSBmb3IgODAyLjExYQo+IMKgIMKgIMKgIMKgICovCj4gLSDCoCDCoCDCoCBpZiAoY2hh
bm5lbC0+aHdfdmFsdWUgJiBDSEFOTkVMXzVHSFopCj4gKyDCoCDCoCDCoCBpZiAoY2hhbm5lbC0+
YmFuZCA9PSBJRUVFODAyMTFfQkFORF81R0haKQo+IMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgcmF0
ZSA9ICZhaC0+c2JhbmRzW0lFRUU4MDIxMV9CQU5EXzVHSFpdLmJpdHJhdGVzWzBdOwo+IMKgIMKg
IMKgIMKgZWxzZQo+IMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgcmF0ZSA9ICZhaC0+c2JhbmRzW0lF
RUU4MDIxMV9CQU5EXzJHSFpdLmJpdHJhdGVzWzBdOwo+IGRpZmYgLS1naXQgYS9kcml2ZXJzL25l
dC93aXJlbGVzcy9hdGgvYXRoNWsvcmVzZXQuYyBiL2RyaXZlcnMvbmV0L3dpcmVsZXNzL2F0aC9h
dGg1ay9yZXNldC5jCj4gaW5kZXggNWQ2ZDNiZC4uOGJjNTdlNCAxMDA2NDQKPiAtLS0gYS9kcml2
ZXJzL25ldC93aXJlbGVzcy9hdGgvYXRoNWsvcmVzZXQuYwo+ICsrKyBiL2RyaXZlcnMvbmV0L3dp
cmVsZXNzL2F0aC9hdGg1ay9yZXNldC5jCj4gQEAgLTEwMiwxMiArMTAyLDE4IEBAIHN0YXRpYyB2
b2lkIGF0aDVrX2h3X2luaXRfY29yZV9jbG9jayhzdHJ1Y3QgYXRoNWtfaHcgKmFoKQo+IMKgIMKg
IMKgIMKgLyoKPiDCoCDCoCDCoCDCoCAqIFNldCBjb3JlIGNsb2NrIGZyZXF1ZW5jeQo+IMKgIMKg
IMKgIMKgICovCj4gLSDCoCDCoCDCoCBpZiAoY2hhbm5lbC0+aHdfdmFsdWUgJiBDSEFOTkVMXzVH
SFopCj4gLSDCoCDCoCDCoCDCoCDCoCDCoCDCoCBjbG9jayA9IDQwOyAvKiA4MDIuMTFhICovCj4g
LSDCoCDCoCDCoCBlbHNlIGlmIChjaGFubmVsLT5od192YWx1ZSAmIENIQU5ORUxfQ0NLKQo+IC0g
wqAgwqAgwqAgwqAgwqAgwqAgwqAgY2xvY2sgPSAyMjsgLyogODAyLjExYiAqLwo+IC0gwqAgwqAg
wqAgZWxzZQo+IC0gwqAgwqAgwqAgwqAgwqAgwqAgwqAgY2xvY2sgPSA0NDsgLyogODAyLjExZyAq
Lwo+ICsgwqAgwqAgwqAgc3dpdGNoIChjaGFubmVsLT5od192YWx1ZSkgewo+ICsgwqAgwqAgwqAg
Y2FzZSBBUjVLX01PREVfMTFBOgo+ICsgwqAgwqAgwqAgwqAgwqAgwqAgwqAgY2xvY2sgPSA0MDsK
PiArIMKgIMKgIMKgIMKgIMKgIMKgIMKgIGJyZWFrOwo+ICsgwqAgwqAgwqAgY2FzZSBBUjVLX01P
REVfMTFCOgo+ICsgwqAgwqAgwqAgwqAgwqAgwqAgwqAgY2xvY2sgPSAyMjsKPiArIMKgIMKgIMKg
IMKgIMKgIMKgIMKgIGJyZWFrOwo+ICsgwqAgwqAgwqAgY2FzZSBBUjVLX01PREVfMTFHOgo+ICsg
wqAgwqAgwqAgZGVmYXVsdDoKPiArIMKgIMKgIMKgIMKgIMKgIMKgIMKgIGNsb2NrID0gNDQ7Cj4g
KyDCoCDCoCDCoCDCoCDCoCDCoCDCoCBicmVhazsKPiArIMKgIMKgIMKgIH0KPgo+IMKgIMKgIMKg
IMKgLyogVXNlIGNsb2NrIG11bHRpcGxpZXIgZm9yIG5vbi1kZWZhdWx0Cj4gwqAgwqAgwqAgwqAg
KiBid21vZGUgKi8KPiBAQCAtNTgxLDggKzU4Nyw5IEBAIGludCBhdGg1a19od19vbl9ob2xkKHN0
cnVjdCBhdGg1a19odyAqYWgpCj4KPiDCoC8qCj4gwqAqIEJyaW5nIHVwIE1BQyArIFBIWSBDaGlw
cyBhbmQgcHJvZ3JhbSBQTEwKPiArICogQ2hhbm5lbCBpcyBOVUxMIGZvciB0aGUgaW5pdGlhbCB3
YWtldXAuCj4gwqAqLwo+IC1pbnQgYXRoNWtfaHdfbmljX3dha2V1cChzdHJ1Y3QgYXRoNWtfaHcg
KmFoLCBpbnQgZmxhZ3MsIGJvb2wgaW5pdGlhbCkKPiAraW50IGF0aDVrX2h3X25pY193YWtldXAo
c3RydWN0IGF0aDVrX2h3ICphaCwgc3RydWN0IGllZWU4MDIxMV9jaGFubmVsICpjaGFubmVsKQo+
IMKgewo+IMKgIMKgIMKgIMKgc3RydWN0IHBjaV9kZXYgKnBkZXYgPSBhaC0+cGRldjsKPiDCoCDC
oCDCoCDCoHUzMiB0dXJibywgbW9kZSwgY2xvY2ssIGJ1c19mbGFnczsKPiBAQCAtNTkyLDcgKzU5
OSw3IEBAIGludCBhdGg1a19od19uaWNfd2FrZXVwKHN0cnVjdCBhdGg1a19odyAqYWgsIGludCBm
bGFncywgYm9vbCBpbml0aWFsKQo+IMKgIMKgIMKgIMKgbW9kZSA9IDA7Cj4gwqAgwqAgwqAgwqBj
bG9jayA9IDA7Cj4KPiAtIMKgIMKgIMKgIGlmICgoYXRoNWtfZ2V0X2J1c190eXBlKGFoKSAhPSBB
VEhfQUhCKSB8fCAhaW5pdGlhbCkgewo+ICsgwqAgwqAgwqAgaWYgKChhdGg1a19nZXRfYnVzX3R5
cGUoYWgpICE9IEFUSF9BSEIpIHx8IGNoYW5uZWwpIHsKPiDCoCDCoCDCoCDCoCDCoCDCoCDCoCDC
oC8qIFdha2V1cCB0aGUgZGV2aWNlICovCj4gwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqByZXQgPSBh
dGg1a19od19zZXRfcG93ZXIoYWgsIEFSNUtfUE1fQVdBS0UsIHRydWUsIDApOwo+IMKgIMKgIMKg
IMKgIMKgIMKgIMKgIMKgaWYgKHJldCkgewo+IEBAIC02NTIsNyArNjU5LDcgQEAgaW50IGF0aDVr
X2h3X25pY193YWtldXAoc3RydWN0IGF0aDVrX2h3ICphaCwgaW50IGZsYWdzLCBib29sIGluaXRp
YWwpCj4KPiDCoCDCoCDCoCDCoC8qIE9uIGluaXRpYWxpemF0aW9uIHNraXAgUExMIHByb2dyYW1t
aW5nIHNpbmNlIHdlIGRvbid0IGhhdmUKPiDCoCDCoCDCoCDCoCAqIGEgY2hhbm5lbCAvIG1vZGUg
c2V0IHlldCAqLwo+IC0gwqAgwqAgwqAgaWYgKGluaXRpYWwpCj4gKyDCoCDCoCDCoCBpZiAoIWNo
YW5uZWwpCj4gwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqByZXR1cm4gMDsKPgo+IMKgIMKgIMKgIMKg
aWYgKGFoLT5haF92ZXJzaW9uICE9IEFSNUtfQVI1MjEwKSB7Cj4gQEAgLTY2OCwxMyArNjc1LDEz
IEBAIGludCBhdGg1a19od19uaWNfd2FrZXVwKHN0cnVjdCBhdGg1a19odyAqYWgsIGludCBmbGFn
cywgYm9vbCBpbml0aWFsKQo+IMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgY2xv
Y2sgPSBBUjVLX1BIWV9QTExfUkY1MTExOyDCoCDCoCDCoCDCoCDCoCDCoC8qWmVybyovCj4gwqAg
wqAgwqAgwqAgwqAgwqAgwqAgwqB9Cj4KPiAtIMKgIMKgIMKgIMKgIMKgIMKgIMKgIGlmIChmbGFn
cyAmIENIQU5ORUxfMkdIWikgewo+ICsgwqAgwqAgwqAgwqAgwqAgwqAgwqAgaWYgKGNoYW5uZWwt
PmJhbmQgPT0gSUVFRTgwMjExX0JBTkRfMkdIWikgewo+IMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKg
IMKgIMKgIMKgIMKgbW9kZSB8PSBBUjVLX1BIWV9NT0RFX0ZSRVFfMkdIWjsKPiDCoCDCoCDCoCDC
oCDCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoGNsb2NrIHw9IEFSNUtfUEhZX1BMTF80NE1IWjsKPgo+
IC0gwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAgaWYgKGZsYWdzICYgQ0hBTk5FTF9D
Q0spIHsKPiArIMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgIGlmIChjaGFubmVsLT5o
d192YWx1ZSA9PSBBUjVLX01PREVfMTFCKSB7Cj4gwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAg
wqAgwqAgwqAgwqAgwqAgwqAgwqBtb2RlIHw9IEFSNUtfUEhZX01PREVfTU9EX0NDSzsKPiAtIMKg
IMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgIH0gZWxzZSBpZiAoZmxhZ3MgJiBDSEFOTkVM
X09GRE0pIHsKPiArIMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgIH0gZWxzZSB7Cj4g
wqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAvKiBYWFggRHlu
YW1pYyBPRkRNL0NDSyBpcyBub3Qgc3VwcG9ydGVkIGJ5IHRoZQo+IMKgIMKgIMKgIMKgIMKgIMKg
IMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgICogQVI1MjExIHNvIHdlIHNldCBNT0RfT0ZE
TSBmb3IgcGxhaW4gZyAobm8KPiDCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoCDC
oCDCoCDCoCDCoCAqIENDSyBoZWFkZXJzKSBvcGVyYXRpb24uIFdlIG5lZWQgdG8gdGVzdAo+IEBA
IC02ODYsMjcgKzY5MywxNiBAQCBpbnQgYXRoNWtfaHdfbmljX3dha2V1cChzdHJ1Y3QgYXRoNWtf
aHcgKmFoLCBpbnQgZmxhZ3MsIGJvb2wgaW5pdGlhbCkKPiDCoCDCoCDCoCDCoCDCoCDCoCDCoCDC
oCDCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoG1vZGUgfD0gQVI1S19QSFlfTU9E
RV9NT0RfT0ZETTsKPiDCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoCDC
oCDCoGVsc2UKPiDCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoCDC
oCDCoCDCoCDCoCDCoG1vZGUgfD0gQVI1S19QSFlfTU9ERV9NT0RfRFlOOwo+IC0gwqAgwqAgwqAg
wqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAgfSBlbHNlIHsKPiAtIMKgIMKgIMKgIMKgIMKgIMKgIMKg
IMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgIEFUSDVLX0VSUihhaCwKPiAtIMKgIMKgIMKgIMKgIMKg
IMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgICJpbnZhbGlkIHJhZGlv
IG1vZHVsYXRpb24gbW9kZVxuIik7Cj4gLSDCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoCDC
oCDCoCDCoCDCoCDCoCByZXR1cm4gLUVJTlZBTDsKPiDCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoCDC
oCDCoCDCoCDCoH0KPiAtIMKgIMKgIMKgIMKgIMKgIMKgIMKgIH0gZWxzZSBpZiAoZmxhZ3MgJiBD
SEFOTkVMXzVHSFopIHsKPiAtIMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgIG1vZGUg
fD0gQVI1S19QSFlfTU9ERV9GUkVRXzVHSFo7Cj4gKyDCoCDCoCDCoCDCoCDCoCDCoCDCoCB9IGVs
c2UgaWYgKGNoYW5uZWwtPmJhbmQgPT0gSUVFRTgwMjExX0JBTkRfNUdIWikgewo+ICsgwqAgwqAg
wqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAgbW9kZSB8PSAoQVI1S19QSFlfTU9ERV9GUkVRXzVH
SFogfAo+ICsgwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqBB
UjVLX1BIWV9NT0RFX01PRF9PRkRNKTsKPgo+IMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKg
IMKgIMKgLyogRGlmZmVyZW50IFBMTCBzZXR0aW5nIGZvciA1NDEzICovCj4gwqAgwqAgwqAgwqAg
wqAgwqAgwqAgwqAgwqAgwqAgwqAgwqBpZiAoYWgtPmFoX3JhZGlvID09IEFSNUtfUkY1NDEzKQo+
IMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgY2xvY2sgPSBB
UjVLX1BIWV9QTExfNDBNSFpfNTQxMzsKPiDCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoCDC
oCDCoGVsc2UKPiDCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoCDC
oGNsb2NrIHw9IEFSNUtfUEhZX1BMTF80ME1IWjsKPiAtCj4gLSDCoCDCoCDCoCDCoCDCoCDCoCDC
oCDCoCDCoCDCoCDCoCBpZiAoZmxhZ3MgJiBDSEFOTkVMX09GRE0pCj4gLSDCoCDCoCDCoCDCoCDC
oCDCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoCBtb2RlIHw9IEFSNUtfUEhZX01PREVfTU9E
X09GRE07Cj4gLSDCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoCBlbHNlIHsKPiAtIMKg
IMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgIEFUSDVLX0VSUihhaCwK
PiAtIMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKg
IMKgICJpbnZhbGlkIHJhZGlvIG1vZHVsYXRpb24gbW9kZVxuIik7Cj4gLSDCoCDCoCDCoCDCoCDC
oCDCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoCByZXR1cm4gLUVJTlZBTDsKPiAtIMKgIMKg
IMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgIH0KPiDCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoH0g
ZWxzZSB7Cj4gwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqBBVEg1S19FUlIoYWgs
ICJpbnZhbGlkIHJhZGlvIGZyZXF1ZW5jeSBtb2RlXG4iKTsKPiDCoCDCoCDCoCDCoCDCoCDCoCDC
oCDCoCDCoCDCoCDCoCDCoHJldHVybiAtRUlOVkFMOwo+IEBAIC04MjIsNyArODE4LDcgQEAgc3Rh
dGljIHZvaWQgYXRoNWtfaHdfdHdlYWtfaW5pdHZhbF9zZXR0aW5ncyhzdHJ1Y3QgYXRoNWtfaHcg
KmFoLAo+IMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgdTMyIGRhdGE7Cj4gwqAgwqAgwqAgwqAgwqAg
wqAgwqAgwqBhdGg1a19od19yZWdfd3JpdGUoYWgsIEFSNUtfUEhZX0NDS1RYQ1RMX1dPUkxELAo+
IMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgQVI1S19QSFlf
Q0NLVFhDVEwpOwo+IC0gwqAgwqAgwqAgwqAgwqAgwqAgwqAgaWYgKGNoYW5uZWwtPmh3X3ZhbHVl
ICYgQ0hBTk5FTF81R0haKQo+ICsgwqAgwqAgwqAgwqAgwqAgwqAgwqAgaWYgKGNoYW5uZWwtPmJh
bmQgPT0gSUVFRTgwMjExX0JBTkRfNUdIWikKPiDCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoCDC
oCDCoCDCoGRhdGEgPSAweGZmYjgxMDIwOwo+IMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgZWxzZQo+
IMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgZGF0YSA9IDB4ZmZiODBkMjA7Cj4g
QEAgLTkwNSw3ICs5MDEsNyBAQCBzdGF0aWMgdm9pZCBhdGg1a19od19jb21taXRfZWVwcm9tX3Nl
dHRpbmdzKHN0cnVjdCBhdGg1a19odyAqYWgsCj4gwqAgwqAgwqAgwqAvKiBTZXQgQ0NLIHRvIE9G
RE0gcG93ZXIgZGVsdGEgb24gdHggcG93ZXIKPiDCoCDCoCDCoCDCoCAqIGFkanVzdG1lbnQgcmVn
aXN0ZXIgKi8KPiDCoCDCoCDCoCDCoGlmIChhaC0+YWhfcGh5X3JldmlzaW9uID49IEFSNUtfU1JF
Vl9QSFlfNTIxMkEpIHsKPiAtIMKgIMKgIMKgIMKgIMKgIMKgIMKgIGlmIChjaGFubmVsLT5od192
YWx1ZSA9PSBDSEFOTkVMX0cpCj4gKyDCoCDCoCDCoCDCoCDCoCDCoCDCoCBpZiAoY2hhbm5lbC0+
aHdfdmFsdWUgPT0gQVI1S19NT0RFXzExRykKPiDCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoCDC
oCDCoCDCoGF0aDVrX2h3X3JlZ193cml0ZShhaCwKPiDCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoCDC
oCDCoCDCoCDCoEFSNUtfUkVHX1NNKChlZS0+ZWVfY2NrX29mZG1fZ2Fpbl9kZWx0YSAqIC0xKSwK
PiDCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoEFSNUtfUEhZ
X1RYX1BXUl9BREpfQ0NLX0dBSU5fREVMVEEpIHwKPiBAQCAtMTA4NCwyOSArMTA4MCwyMyBAQCBp
bnQgYXRoNWtfaHdfcmVzZXQoc3RydWN0IGF0aDVrX2h3ICphaCwgZW51bSBubDgwMjExX2lmdHlw
ZSBvcF9tb2RlLAo+IMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgcmV0ID0gMDsKPiDCoCDCoCDCoCDC
oH0KPgo+IC0gwqAgwqAgwqAgc3dpdGNoIChjaGFubmVsLT5od192YWx1ZSAmIENIQU5ORUxfTU9E
RVMpIHsKPiAtIMKgIMKgIMKgIGNhc2UgQ0hBTk5FTF9BOgo+IC0gwqAgwqAgwqAgwqAgwqAgwqAg
wqAgbW9kZSA9IEFSNUtfTU9ERV8xMUE7Cj4gKyDCoCDCoCDCoCBtb2RlID0gY2hhbm5lbC0+aHdf
dmFsdWU7Cj4gKyDCoCDCoCDCoCBzd2l0Y2ggKG1vZGUpIHsKPiArIMKgIMKgIMKgIGNhc2UgQVI1
S19NT0RFXzExQToKPiDCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoGJyZWFrOwo+IC0gwqAgwqAgwqAg
Y2FzZSBDSEFOTkVMX0c6Cj4gLQo+ICsgwqAgwqAgwqAgY2FzZSBBUjVLX01PREVfMTFHOgo+IMKg
IMKgIMKgIMKgIMKgIMKgIMKgIMKgaWYgKGFoLT5haF92ZXJzaW9uIDw9IEFSNUtfQVI1MjExKSB7
Cj4gwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqBBVEg1S19FUlIoYWgsCj4gwqAg
wqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAiRyBtb2RlIG5vdCBh
dmFpbGFibGUgb24gNTIxMC81MjExIik7Cj4gwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAg
wqAgwqByZXR1cm4gLUVJTlZBTDsKPiDCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoH0KPiAtCj4gLSDC
oCDCoCDCoCDCoCDCoCDCoCDCoCBtb2RlID0gQVI1S19NT0RFXzExRzsKPiDCoCDCoCDCoCDCoCDC
oCDCoCDCoCDCoGJyZWFrOwo+IC0gwqAgwqAgwqAgY2FzZSBDSEFOTkVMX0I6Cj4gLQo+ICsgwqAg
wqAgwqAgY2FzZSBBUjVLX01PREVfMTFCOgo+IMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgaWYgKGFo
LT5haF92ZXJzaW9uIDwgQVI1S19BUjUyMTEpIHsKPiDCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoCDC
oCDCoCDCoCDCoEFUSDVLX0VSUihhaCwKPiDCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoCDC
oCDCoCDCoCDCoCDCoCDCoCJCIG1vZGUgbm90IGF2YWlsYWJsZSBvbiA1MjEwIik7Cj4gwqAgwqAg
wqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqByZXR1cm4gLUVJTlZBTDsKPiDCoCDCoCDCoCDC
oCDCoCDCoCDCoCDCoH0KPiAtCj4gLSDCoCDCoCDCoCDCoCDCoCDCoCDCoCBtb2RlID0gQVI1S19N
T0RFXzExQjsKPiDCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoGJyZWFrOwo+IMKgIMKgIMKgIMKgZGVm
YXVsdDoKPiDCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoEFUSDVLX0VSUihhaCwKPiBAQCAtMTE5Miw3
ICsxMTgyLDcgQEAgaW50IGF0aDVrX2h3X3Jlc2V0KHN0cnVjdCBhdGg1a19odyAqYWgsIGVudW0g
bmw4MDIxMV9pZnR5cGUgb3BfbW9kZSwKPiDCoCDCoCDCoCDCoH0KPgo+IMKgIMKgIMKgIMKgLyog
V2FrZXVwIHRoZSBkZXZpY2UgKi8KPiAtIMKgIMKgIMKgIHJldCA9IGF0aDVrX2h3X25pY193YWtl
dXAoYWgsIGNoYW5uZWwtPmh3X3ZhbHVlLCBmYWxzZSk7Cj4gKyDCoCDCoCDCoCByZXQgPSBhdGg1
a19od19uaWNfd2FrZXVwKGFoLCBjaGFubmVsKTsKPiDCoCDCoCDCoCDCoGlmIChyZXQpCj4gwqAg
wqAgwqAgwqAgwqAgwqAgwqAgwqByZXR1cm4gcmV0Owo+CgpBY2tlZC1ieTogTmljayBLb3NzaWZp
ZGlzIDxtaWNrZmxlbW1AZ21haWwuY29tPgoKCgotLSAKR1BHIElEOiAweEQyMURCMkRCCkFzIHlv
dSByZWFkIHRoaXMgcG9zdCBnbG9iYWwgZW50cm9weSByaXNlcy4gSGF2ZSBGdW4gOy0pCk5pY2sK