提交 cf8d55ae 编写于 作者: M Matt Carlson 提交者: David S. Miller

tg3: Add APE scratchpad read function

for retreiving temperature sensor data.
Signed-off-by: NMatt Carlson <mcarlson@broadcom.com>
Signed-off-by: NNithin Nayak Sujir <nsujir@broadcom.com>
Signed-off-by: NMichael Chan <mchan@broadcom.com>
Signed-off-by: NDavid S. Miller <davem@davemloft.net>
上级 b65a372b
......@@ -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;
......
......@@ -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
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册