Skip site navigation (1)Skip section navigation (2)
Date:      Wed, 2 Jan 2013 00:38:01 +0000 (UTC)
From:      Adrian Chadd <adrian@FreeBSD.org>
To:        src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-head@freebsd.org
Subject:   svn commit: r244943 - in head/sys/dev/ath/ath_hal: ar5416 ar9002
Message-ID:  <201301020038.r020c1fN074342@svn.freebsd.org>

next in thread | raw e-mail | index | archive | help
Author: adrian
Date: Wed Jan  2 00:38:01 2013
New Revision: 244943
URL: http://svnweb.freebsd.org/changeset/base/244943

Log:
  Bring over the basic spectral scan framework code from Qualcomm Atheros.
  
  This includes the HAL routines to setup, enable/activate/disable spectral
  scan and configure the relevant registers.
  
  This still requires driver interaction to enable spectral scan reporting.
  Specifically:
  
  * call ah_spectralConfigure() to configure and enable spectral scan;
  * .. there's currently no way to disable spectral scan... that will have
    to follow.
  * call ah_spectralStart() to force start a spectral report;
  * call ah_spectralStop() to force stop an active spectral report.
  
  The spectral scan results appear as PHY errors (type 0x5 on the AR9280,
  same as radar) but with the spectral scan bit set (0x10 in the last byte
  of the frame) identifying it as a spectral report rather than a radar
  FFT report.
  
  Caveats:
  
  * It's likely quite difficult to run spectral _and_ radar at the same
    time.  Enabling spectral scan disables the radar thresholds but
    leaves radar enabled.  Thus, the driver (for now) needs to ensure
    that only one or the other is enabled.
  
  * .. it needs testing on HT40 mode.
  
  Tested:
  
  * AR9280 in STA mode, HT/20 only
  
  TODO:
  
  * Test on AR9285, AR9287;
  * Test in both HT20 and HT40 modes;
  * .. all the driver glue.
  
  Obtained from:	Qualcomm Atheros

Added:
  head/sys/dev/ath/ath_hal/ar5416/ar5416_spectral.c   (contents, props changed)
Modified:
  head/sys/dev/ath/ath_hal/ar5416/ar5416.h
  head/sys/dev/ath/ath_hal/ar5416/ar5416_attach.c
  head/sys/dev/ath/ath_hal/ar5416/ar5416phy.h
  head/sys/dev/ath/ath_hal/ar5416/ar5416reg.h
  head/sys/dev/ath/ath_hal/ar9002/ar9280_attach.c
  head/sys/dev/ath/ath_hal/ar9002/ar9285_attach.c
  head/sys/dev/ath/ath_hal/ar9002/ar9287_attach.c

Modified: head/sys/dev/ath/ath_hal/ar5416/ar5416.h
==============================================================================
--- head/sys/dev/ath/ath_hal/ar5416/ar5416.h	Tue Jan  1 19:42:06 2013	(r244942)
+++ head/sys/dev/ath/ath_hal/ar5416/ar5416.h	Wed Jan  2 00:38:01 2013	(r244943)
@@ -265,6 +265,16 @@ extern	HAL_BOOL ar5416ProcessRadarEvent(
 	    HAL_DFS_EVENT *event);
 extern	HAL_BOOL ar5416IsFastClockEnabled(struct ath_hal *ah);
 
+/* ar9280_spectral.c */
+extern	void ar5416ConfigureSpectralScan(struct ath_hal *ah, HAL_SPECTRAL_PARAM *ss);
+extern	void ar5416GetSpectralParams(struct ath_hal *ah, HAL_SPECTRAL_PARAM *ss);
+extern	HAL_BOOL ar5416IsSpectralActive(struct ath_hal *ah);
+extern	HAL_BOOL ar5416IsSpectralEnabled(struct ath_hal *ah);
+extern	void ar5416StartSpectralScan(struct ath_hal *ah);
+extern	void ar5416StopSpectralScan(struct ath_hal *ah);
+extern	uint32_t ar5416GetSpectralConfig(struct ath_hal *ah);
+extern	void ar5416RestoreSpectralConfig(struct ath_hal *ah, uint32_t restoreval);
+
 extern	HAL_BOOL ar5416SetPowerMode(struct ath_hal *ah, HAL_POWER_MODE mode,
 		int setChip);
 extern	HAL_POWER_MODE ar5416GetPowerMode(struct ath_hal *ah);

Modified: head/sys/dev/ath/ath_hal/ar5416/ar5416_attach.c
==============================================================================
--- head/sys/dev/ath/ath_hal/ar5416/ar5416_attach.c	Tue Jan  1 19:42:06 2013	(r244942)
+++ head/sys/dev/ath/ath_hal/ar5416/ar5416_attach.c	Wed Jan  2 00:38:01 2013	(r244943)
@@ -161,6 +161,14 @@ ar5416InitState(struct ath_hal_5416 *ahp
 	ah->ah_procRadarEvent		= ar5416ProcessRadarEvent;
 	ah->ah_isFastClockEnabled	= ar5416IsFastClockEnabled;
 
+	/* Spectral Scan Functions */
+	ah->ah_spectralConfigure	= ar5416ConfigureSpectralScan;
+	ah->ah_spectralGetConfig	= ar5416GetSpectralParams;
+	ah->ah_spectralStart		= ar5416StartSpectralScan;
+	ah->ah_spectralStop		= ar5416StopSpectralScan;
+	ah->ah_spectralIsEnabled	= ar5416IsSpectralEnabled;
+	ah->ah_spectralIsActive		= ar5416IsSpectralActive;
+
 	/* Power Management Functions */
 	ah->ah_setPowerMode		= ar5416SetPowerMode;
 
@@ -918,6 +926,7 @@ ar5416FillCapabilityInfo(struct ath_hal 
 	pCap->halMcastKeySrchSupport = AH_TRUE;	/* Works on AR5416 and later */
 	pCap->halTsfAddSupport = AH_TRUE;
 	pCap->hal4AddrAggrSupport = AH_FALSE;	/* Broken in Owl */
+	pCap->halSpectralScanSupport = AH_FALSE;	/* AR9280 and later */
 
 	if (ath_hal_eepromGet(ah, AR_EEP_MAXQCU, &val) == HAL_OK)
 		pCap->halTotalQueues = val;

Added: head/sys/dev/ath/ath_hal/ar5416/ar5416_spectral.c
==============================================================================
--- /dev/null	00:00:00 1970	(empty, because file is newly added)
+++ head/sys/dev/ath/ath_hal/ar5416/ar5416_spectral.c	Wed Jan  2 00:38:01 2013	(r244943)
@@ -0,0 +1,244 @@
+/*
+ * Copyright (c) 2012 Qualcomm Atheros, All Rights Reserved.
+ *
+ * Permission to use, copy, modify, and/or distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
+ * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
+ * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
+ * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ *
+ * $FreeBSD$
+ */
+#include "opt_ah.h"
+
+#include "ah.h"
+#include "ah_internal.h"
+#include "ah_devid.h"
+#include "ah_desc.h"                    /* NB: for HAL_PHYERR* */
+
+#include "ar5416/ar5416.h"
+#include "ar5416/ar5416reg.h"
+#include "ar5416/ar5416phy.h"
+
+/*
+ * Default AR9280 spectral scan parameters
+ */
+#define	AR5416_SPECTRAL_SCAN_ENA		0
+#define	AR5416_SPECTRAL_SCAN_ACTIVE		0
+#define	AR5416_SPECTRAL_SCAN_FFT_PERIOD		8
+#define	AR5416_SPECTRAL_SCAN_PERIOD		1
+#define	AR5416_SPECTRAL_SCAN_COUNT		16 //used to be 128
+#define	AR5416_SPECTRAL_SCAN_SHORT_REPEAT	1
+
+/* constants */
+#define	MAX_RADAR_RSSI_THRESH	0x3f
+#define	MAX_RADAR_HEIGHT	0x3f
+#define	ENABLE_ALL_PHYERR	0xffffffff
+
+static void ar5416DisableRadar(struct ath_hal *ah);
+static void ar5416PrepSpectralScan(struct ath_hal *ah);
+
+static void
+ar5416DisableRadar(struct ath_hal *ah)
+{
+	uint32_t val;
+
+	// Enable radar FFT
+	val = OS_REG_READ(ah, AR_PHY_RADAR_0);
+	val |= AR_PHY_RADAR_0_FFT_ENA;
+
+	// set radar detect thresholds to max to effectively disable radar
+	val &= ~AR_PHY_RADAR_0_RRSSI;
+	val |= SM(MAX_RADAR_RSSI_THRESH, AR_PHY_RADAR_0_RRSSI);
+
+	val &= ~AR_PHY_RADAR_0_HEIGHT;
+	val |= SM(MAX_RADAR_HEIGHT, AR_PHY_RADAR_0_HEIGHT);
+
+	val &= ~(AR_PHY_RADAR_0_ENA);
+	OS_REG_WRITE(ah, AR_PHY_RADAR_0, val);
+
+	// disable extension radar detect
+	val = OS_REG_READ(ah, AR_PHY_RADAR_EXT);
+	OS_REG_WRITE(ah, AR_PHY_RADAR_EXT, val & ~AR_PHY_RADAR_EXT_ENA);
+
+	val = OS_REG_READ(ah, AR_RX_FILTER);
+	val |= (1<<13);
+	OS_REG_WRITE(ah, AR_RX_FILTER, val);
+}
+
+static void
+ar5416PrepSpectralScan(struct ath_hal *ah)
+{
+
+	ar5416DisableRadar(ah);
+	OS_REG_WRITE(ah, AR_PHY_ERR, ENABLE_ALL_PHYERR);
+}
+
+void
+ar5416ConfigureSpectralScan(struct ath_hal *ah, HAL_SPECTRAL_PARAM *ss)
+{
+	uint32_t val;
+
+	ar5416PrepSpectralScan(ah);
+
+	val = OS_REG_READ(ah, AR_PHY_SPECTRAL_SCAN);
+
+	if (ss->ss_fft_period != HAL_SPECTRAL_PARAM_NOVAL) {
+		val &= ~AR_PHY_SPECTRAL_SCAN_FFT_PERIOD;
+		val |= SM(ss->ss_fft_period, AR_PHY_SPECTRAL_SCAN_FFT_PERIOD);
+	}
+
+	if (ss->ss_period != HAL_SPECTRAL_PARAM_NOVAL) {
+		val &= ~AR_PHY_SPECTRAL_SCAN_PERIOD;
+		val |= SM(ss->ss_period, AR_PHY_SPECTRAL_SCAN_PERIOD);
+	}
+
+	if (ss->ss_period != HAL_SPECTRAL_PARAM_NOVAL) {
+		val &= ~AR_PHY_SPECTRAL_SCAN_PERIOD;
+		val |= SM(ss->ss_period, AR_PHY_SPECTRAL_SCAN_PERIOD);
+	}
+
+	/* This section is different for Kiwi and Merlin */
+	if (AR_SREV_MERLIN(ah) ) {
+		if (ss->ss_count != HAL_SPECTRAL_PARAM_NOVAL) {
+			val &= ~AR_PHY_SPECTRAL_SCAN_COUNT;
+			val |= SM(ss->ss_count, AR_PHY_SPECTRAL_SCAN_COUNT);
+		}
+
+		if (ss->ss_short_report == AH_TRUE) {
+			val |= AR_PHY_SPECTRAL_SCAN_SHORT_REPEAT;
+		} else {
+			val &= ~AR_PHY_SPECTRAL_SCAN_SHORT_REPEAT;
+		}
+	} else {
+		if (ss->ss_count != HAL_SPECTRAL_PARAM_NOVAL) {
+			/*
+			 * In Merlin, for continous scan, scan_count = 128.
+			 * In case of Kiwi, this value should be 0
+			 */
+			if (ss->ss_count == 128)
+				ss->ss_count = 0;
+			val &= ~AR_PHY_SPECTRAL_SCAN_COUNT_KIWI;
+			val |= SM(ss->ss_count, AR_PHY_SPECTRAL_SCAN_COUNT_KIWI);
+		}
+
+		if (ss->ss_short_report == AH_TRUE) {
+			val |= AR_PHY_SPECTRAL_SCAN_SHORT_REPEAT_KIWI;
+		} else {
+			val &= ~AR_PHY_SPECTRAL_SCAN_SHORT_REPEAT_KIWI;
+		}
+
+		//Select the mask to be same as before
+		val |= AR_PHY_SPECTRAL_SCAN_PHYERR_MASK_SELECT_KIWI;
+	}
+	// Enable spectral scan
+	OS_REG_WRITE(ah, AR_PHY_SPECTRAL_SCAN, val | AR_PHY_SPECTRAL_SCAN_ENA);
+
+	ar5416GetSpectralParams(ah, ss);
+}
+
+/*
+ * Get the spectral parameter values and return them in the pe
+ * structure
+ */
+void
+ar5416GetSpectralParams(struct ath_hal *ah, HAL_SPECTRAL_PARAM *ss)
+{
+	uint32_t val;
+
+	val = OS_REG_READ(ah, AR_PHY_SPECTRAL_SCAN);
+
+	ss->ss_fft_period = MS(val, AR_PHY_SPECTRAL_SCAN_FFT_PERIOD);
+	ss->ss_period = MS(val, AR_PHY_SPECTRAL_SCAN_PERIOD);
+	if (AR_SREV_MERLIN(ah) ) {
+		ss->ss_count = MS(val, AR_PHY_SPECTRAL_SCAN_COUNT);
+		ss->ss_short_report = MS(val, AR_PHY_SPECTRAL_SCAN_SHORT_REPEAT);
+	} else {
+		ss->ss_count = MS(val, AR_PHY_SPECTRAL_SCAN_COUNT_KIWI);
+		ss->ss_short_report = MS(val, AR_PHY_SPECTRAL_SCAN_SHORT_REPEAT_KIWI);
+	}
+	val = OS_REG_READ(ah, AR_PHY_RADAR_1);
+	ss->radar_bin_thresh_sel = MS(val, AR_PHY_RADAR_1_BIN_THRESH_SELECT);
+}
+
+HAL_BOOL
+ar5416IsSpectralActive(struct ath_hal *ah)
+{
+	uint32_t val;
+
+	val = OS_REG_READ(ah, AR_PHY_SPECTRAL_SCAN);
+	return MS(val, AR_PHY_SPECTRAL_SCAN_ACTIVE);
+}
+
+HAL_BOOL
+ar5416IsSpectralEnabled(struct ath_hal *ah)
+{
+	uint32_t val;
+
+	val = OS_REG_READ(ah, AR_PHY_SPECTRAL_SCAN);
+	return MS(val,AR_PHY_SPECTRAL_SCAN_ENA);
+}
+
+void
+ar5416StartSpectralScan(struct ath_hal *ah)
+{
+	uint32_t val;
+
+	ar5416PrepSpectralScan(ah);
+
+	// Activate spectral scan
+	val = OS_REG_READ(ah, AR_PHY_SPECTRAL_SCAN);
+	val |= AR_PHY_SPECTRAL_SCAN_ENA;
+	val |= AR_PHY_SPECTRAL_SCAN_ACTIVE;
+	OS_REG_WRITE(ah, AR_PHY_SPECTRAL_SCAN, val);
+	val = OS_REG_READ(ah, AR_PHY_SPECTRAL_SCAN);
+	val = OS_REG_READ(ah, AR_PHY_ERR_MASK_REG);
+	OS_REG_WRITE(ah, AR_PHY_ERR_MASK_REG, val | AR_PHY_ERR_RADAR);
+}
+
+void
+ar5416StopSpectralScan(struct ath_hal *ah)
+{
+	uint32_t val;
+	val = OS_REG_READ(ah, AR_PHY_SPECTRAL_SCAN);
+
+	// Deactivate spectral scan
+	val &= ~AR_PHY_SPECTRAL_SCAN_ENA;
+	val &= ~AR_PHY_SPECTRAL_SCAN_ACTIVE;
+	OS_REG_WRITE(ah, AR_PHY_SPECTRAL_SCAN, val);
+	val = OS_REG_READ(ah, AR_PHY_SPECTRAL_SCAN);
+	val = OS_REG_READ(ah, AR_PHY_ERR_MASK_REG) & (~AR_PHY_ERR_RADAR);
+	OS_REG_WRITE(ah, AR_PHY_ERR_MASK_REG, val);
+}
+
+uint32_t
+ar5416GetSpectralConfig(struct ath_hal *ah)
+{
+	uint32_t val;
+
+	val = OS_REG_READ(ah, AR_PHY_SPECTRAL_SCAN);
+	return val;
+}
+
+void
+ar5416RestoreSpectralConfig(struct ath_hal *ah, uint32_t restoreval)
+{
+	uint32_t curval;
+
+	ar5416PrepSpectralScan(ah);
+
+	curval = OS_REG_READ(ah, AR_PHY_SPECTRAL_SCAN);
+
+	if (restoreval != curval) {
+		restoreval |= AR_PHY_SPECTRAL_SCAN_SHORT_REPEAT;
+		OS_REG_WRITE(ah, AR_PHY_SPECTRAL_SCAN, restoreval);
+	}
+	return;
+}
+

Modified: head/sys/dev/ath/ath_hal/ar5416/ar5416phy.h
==============================================================================
--- head/sys/dev/ath/ath_hal/ar5416/ar5416phy.h	Tue Jan  1 19:42:06 2013	(r244942)
+++ head/sys/dev/ath/ath_hal/ar5416/ar5416phy.h	Wed Jan  2 00:38:01 2013	(r244943)
@@ -66,10 +66,27 @@
 #define	AR_PHY_SPECTRAL_SCAN_FFT_PERIOD_S	4
 #define	AR_PHY_SPECTRAL_SCAN_PERIOD	0x0000FF00
 #define	AR_PHY_SPECTRAL_SCAN_PERIOD_S	8
+
+/* Scan count and Short repeat flags are different for Kiwi and Merlin */
 #define	AR_PHY_SPECTRAL_SCAN_COUNT	0x00FF0000
 #define	AR_PHY_SPECTRAL_SCAN_COUNT_S	16
+#define	AR_PHY_SPECTRAL_SCAN_COUNT_KIWI	0x0FFF0000
+#define	AR_PHY_SPECTRAL_SCAN_COUNT_KIWI_S	16
+
 #define	AR_PHY_SPECTRAL_SCAN_SHORT_REPEAT	0x01000000
 #define	AR_PHY_SPECTRAL_SCAN_SHORT_REPEAT_S	24
+#define	AR_PHY_SPECTRAL_SCAN_SHORT_REPEAT_KIWI	0x10000000
+#define	AR_PHY_SPECTRAL_SCAN_SHORT_REPEAT_KIWI_S	28
+
+/*
+ * Kiwi only, bit 30 is used to set the error type, if set it is 0x5 (HAL_PHYERR_RADAR)
+ * Else it is 38 (new error type)
+ */
+#define	AR_PHY_SPECTRAL_SCAN_PHYERR_MASK_SELECT_KIWI	0x40000000  /* Spectral Error select bit mask */
+#define	AR_PHY_SPECTRAL_SCAN_PHYERR_MASK_SELECT_KIWI_S	30  /* Spectral Error select bit 30 */
+
+#define	AR_PHY_SPECTRAL_SCAN_PRIORITY_SELECT_KIWI	0x20000000  /* Spectral Error select bit mask */
+#define	AR_PHY_SPECTRAL_SCAN_PRIORITY_SELECT_SELECT_KIWI_S	29  /* Spectral Error select bit 30 */
 
 /* For AR_PHY_RADAR0 */
 #define	AR_PHY_RADAR_0_FFT_ENA		0x80000000
@@ -78,8 +95,8 @@
 #define	AR_PHY_RADAR_EXT_ENA		0x00004000
 
 #define	AR_PHY_RADAR_1			0x9958
-#define	AR_PHY_RADAR_1_BIN_THRESH_SEL	0x07000000
-#define	AR_PHY_RADAR_1_BIN_THRESH_SEL_S	24
+#define	AR_PHY_RADAR_1_BIN_THRESH_SELECT	0x07000000
+#define	AR_PHY_RADAR_1_BIN_THRESH_SELECT_S	24
 #define	AR_PHY_RADAR_1_RELPWR_ENA	0x00800000
 #define	AR_PHY_RADAR_1_USE_FIR128	0x00400000
 #define	AR_PHY_RADAR_1_RELPWR_THRESH	0x003F0000

Modified: head/sys/dev/ath/ath_hal/ar5416/ar5416reg.h
==============================================================================
--- head/sys/dev/ath/ath_hal/ar5416/ar5416reg.h	Tue Jan  1 19:42:06 2013	(r244942)
+++ head/sys/dev/ath/ath_hal/ar5416/ar5416reg.h	Wed Jan  2 00:38:01 2013	(r244943)
@@ -179,6 +179,7 @@
 #define	AR_2040_MODE		0x8318
 #define	AR_EXTRCCNT		0x8328	/* extension channel rx clear count */
 #define	AR_SELFGEN_MASK		0x832c	/* rx and cal chain masks */
+#define	AR_PHY_ERR_MASK_REG	0x8338
 #define	AR_PCU_TXBUF_CTRL	0x8340
 #define	AR_PCU_MISC_MODE2	0x8344
 

Modified: head/sys/dev/ath/ath_hal/ar9002/ar9280_attach.c
==============================================================================
--- head/sys/dev/ath/ath_hal/ar9002/ar9280_attach.c	Tue Jan  1 19:42:06 2013	(r244942)
+++ head/sys/dev/ath/ath_hal/ar9002/ar9280_attach.c	Wed Jan  2 00:38:01 2013	(r244943)
@@ -900,6 +900,7 @@ ar9280FillCapabilityInfo(struct ath_hal 
 	pCap->halHasRxSelfLinkedTail = AH_FALSE;
 	pCap->halMbssidAggrSupport = AH_TRUE;
 	pCap->hal4AddrAggrSupport = AH_TRUE;
+	pCap->halSpectralScanSupport = AH_TRUE;
 
 	if (AR_SREV_MERLIN_20(ah)) {
 		pCap->halPSPollBroken = AH_FALSE;

Modified: head/sys/dev/ath/ath_hal/ar9002/ar9285_attach.c
==============================================================================
--- head/sys/dev/ath/ath_hal/ar9002/ar9285_attach.c	Tue Jan  1 19:42:06 2013	(r244942)
+++ head/sys/dev/ath/ath_hal/ar9002/ar9285_attach.c	Wed Jan  2 00:38:01 2013	(r244943)
@@ -524,6 +524,7 @@ ar9285FillCapabilityInfo(struct ath_hal 
 	pCap->halHasRxSelfLinkedTail = AH_FALSE;
 	pCap->halMbssidAggrSupport = AH_TRUE;  
 	pCap->hal4AddrAggrSupport = AH_TRUE;
+	pCap->halSpectralScanSupport = AH_TRUE;
 
 	if (AR_SREV_KITE_12_OR_LATER(ah))
 		pCap->halPSPollBroken = AH_FALSE;

Modified: head/sys/dev/ath/ath_hal/ar9002/ar9287_attach.c
==============================================================================
--- head/sys/dev/ath/ath_hal/ar9002/ar9287_attach.c	Tue Jan  1 19:42:06 2013	(r244942)
+++ head/sys/dev/ath/ath_hal/ar9002/ar9287_attach.c	Wed Jan  2 00:38:01 2013	(r244943)
@@ -453,6 +453,7 @@ ar9287FillCapabilityInfo(struct ath_hal 
 	/* Disable this so Block-ACK works correctly */
 	pCap->halHasRxSelfLinkedTail = AH_FALSE;
 	pCap->halPSPollBroken = AH_FALSE;
+	pCap->halSpectralScanSupport = AH_TRUE;
 
 	/* Hardware supports (at least) single-stream STBC TX/RX */
 	pCap->halRxStbcSupport = 1;



Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?201301020038.r020c1fN074342>