Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit cf8d55ae authored by Matt Carlson's avatar Matt Carlson Committed by David S. Miller
Browse files

tg3: Add APE scratchpad read function



for retreiving temperature sensor data.

Signed-off-by: default avatarMatt Carlson <mcarlson@broadcom.com>
Signed-off-by: default avatarNithin Nayak Sujir <nsujir@broadcom.com>
Signed-off-by: default avatarMichael Chan <mchan@broadcom.com>
Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
parent b65a372b
Loading
Loading
Loading
Loading
+79 −0
Original line number Diff line number Diff line
@@ -752,6 +752,85 @@ static int tg3_ape_event_lock(struct tg3 *tp, u32 timeout_us)
	return timeout_us ? 0 : -EBUSY;
}

static int tg3_ape_wait_for_event(struct tg3 *tp, u32 timeout_us)
{
	u32 i, apedata;

	for (i = 0; i < timeout_us / 10; i++) {
		apedata = tg3_ape_read32(tp, TG3_APE_EVENT_STATUS);

		if (!(apedata & APE_EVENT_STATUS_EVENT_PENDING))
			break;

		udelay(10);
	}

	return i == timeout_us / 10;
}

int tg3_ape_scratchpad_read(struct tg3 *tp, u32 *data, u32 base_off, u32 len)
{
	int err;
	u32 i, bufoff, msgoff, maxlen, apedata;

	if (!tg3_flag(tp, APE_HAS_NCSI))
		return 0;

	apedata = tg3_ape_read32(tp, TG3_APE_SEG_SIG);
	if (apedata != APE_SEG_SIG_MAGIC)
		return -ENODEV;

	apedata = tg3_ape_read32(tp, TG3_APE_FW_STATUS);
	if (!(apedata & APE_FW_STATUS_READY))
		return -EAGAIN;

	bufoff = tg3_ape_read32(tp, TG3_APE_SEG_MSG_BUF_OFF) +
		 TG3_APE_SHMEM_BASE;
	msgoff = bufoff + 2 * sizeof(u32);
	maxlen = tg3_ape_read32(tp, TG3_APE_SEG_MSG_BUF_LEN);

	while (len) {
		u32 length;

		/* Cap xfer sizes to scratchpad limits. */
		length = (len > maxlen) ? maxlen : len;
		len -= length;

		apedata = tg3_ape_read32(tp, TG3_APE_FW_STATUS);
		if (!(apedata & APE_FW_STATUS_READY))
			return -EAGAIN;

		/* Wait for up to 1 msec for APE to service previous event. */
		err = tg3_ape_event_lock(tp, 1000);
		if (err)
			return err;

		apedata = APE_EVENT_STATUS_DRIVER_EVNT |
			  APE_EVENT_STATUS_SCRTCHPD_READ |
			  APE_EVENT_STATUS_EVENT_PENDING;
		tg3_ape_write32(tp, TG3_APE_EVENT_STATUS, apedata);

		tg3_ape_write32(tp, bufoff, base_off);
		tg3_ape_write32(tp, bufoff + sizeof(u32), length);

		tg3_ape_unlock(tp, TG3_APE_LOCK_MEM);
		tg3_ape_write32(tp, TG3_APE_EVENT, APE_EVENT_1);

		base_off += length;

		if (tg3_ape_wait_for_event(tp, 30000))
			return -EAGAIN;

		for (i = 0; length; i += 4, length -= 4) {
			u32 val = tg3_ape_read32(tp, msgoff + i);
			memcpy(data, &val, sizeof(u32));
			data++;
		}
	}

	return 0;
}

static int tg3_ape_send_event(struct tg3 *tp, u32 event)
{
	int err;
+7 −2
Original line number Diff line number Diff line
@@ -2311,10 +2311,11 @@
#define  APE_LOCK_REQ_DRIVER		 0x00001000
#define TG3_APE_LOCK_GRANT		0x004c
#define  APE_LOCK_GRANT_DRIVER		 0x00001000
#define TG3_APE_SEG_SIG			0x4000
#define  APE_SEG_SIG_MAGIC		 0x41504521

/* APE shared memory.  Accessible through BAR1 */
#define TG3_APE_SHMEM_BASE		0x4000
#define TG3_APE_SEG_SIG			0x4000
#define  APE_SEG_SIG_MAGIC		 0x41504521
#define TG3_APE_FW_STATUS		0x400c
#define  APE_FW_STATUS_READY		 0x00000100
#define TG3_APE_FW_FEATURES		0x4010
@@ -2327,6 +2328,8 @@
#define  APE_FW_VERSION_REVMSK		 0x0000ff00
#define  APE_FW_VERSION_REVSFT		 8
#define  APE_FW_VERSION_BLDMSK		 0x000000ff
#define TG3_APE_SEG_MSG_BUF_OFF		0x401c
#define TG3_APE_SEG_MSG_BUF_LEN		0x4020
#define TG3_APE_HOST_SEG_SIG		0x4200
#define  APE_HOST_SEG_SIG_MAGIC		 0x484f5354
#define TG3_APE_HOST_SEG_LEN		0x4204
@@ -2353,6 +2356,8 @@

#define  APE_EVENT_STATUS_DRIVER_EVNT	 0x00000010
#define  APE_EVENT_STATUS_STATE_CHNGE	 0x00000500
#define  APE_EVENT_STATUS_SCRTCHPD_READ	 0x00001600
#define  APE_EVENT_STATUS_SCRTCHPD_WRITE 0x00001700
#define  APE_EVENT_STATUS_STATE_START	 0x00010000
#define  APE_EVENT_STATUS_STATE_UNLOAD	 0x00020000
#define  APE_EVENT_STATUS_STATE_WOL	 0x00030000