Message ID | 20170923003518.GA1583@felix-thinkpad.cavium.com |
---|---|
State | Changes Requested, archived |
Delegated to: | David Miller |
Headers | show |
Series | [net-next] liquidio: pass date and time info to NIC firmware | expand |
On Fri, Sep 22, 2017 at 05:35:18PM -0700, Felix Manlunas wrote:
> From: Veerasenareddy Burru <veerasenareddy.burru@cavium.com>
This is kind of interesting. So you do this once. It could be before
the RTC driver has probed, so it is 1970. It could be before the NTP
daemon has started, and so the host clock will later jump, or stretch
time to gain synchronisation.
It seems like you should be periodically giving the time to the
firmware, not just once.
Andrew
From: Andrew Lunn <andrew@lunn.ch> Date: Sat, 23 Sep 2017 17:16:54 +0200 > On Fri, Sep 22, 2017 at 05:35:18PM -0700, Felix Manlunas wrote: >> From: Veerasenareddy Burru <veerasenareddy.burru@cavium.com> > > This is kind of interesting. So you do this once. It could be before > the RTC driver has probed, so it is 1970. It could be before the NTP > daemon has started, and so the host clock will later jump, or stretch > time to gain synchronisation. > > It seems like you should be periodically giving the time to the > firmware, not just once. Specifically, you really need to send the time/date to the firmware anytime the system time is updated.
diff --git a/drivers/net/ethernet/cavium/liquidio/octeon_console.c b/drivers/net/ethernet/cavium/liquidio/octeon_console.c index ec3dd69..eda799b 100644 --- a/drivers/net/ethernet/cavium/liquidio/octeon_console.c +++ b/drivers/net/ethernet/cavium/liquidio/octeon_console.c @@ -803,15 +803,19 @@ static int octeon_console_read(struct octeon_device *oct, u32 console_num, } #define FBUF_SIZE (4 * 1024 * 1024) +#define MAX_DATE_SIZE 30 int octeon_download_firmware(struct octeon_device *oct, const u8 *data, size_t size) { - int ret = 0; + struct octeon_firmware_file_header *h; + char date[MAX_DATE_SIZE]; + struct timeval time; u32 crc32_result; + struct tm tm_val; u64 load_addr; u32 image_len; - struct octeon_firmware_file_header *h; + int ret = 0; u32 i, rem; if (size < sizeof(struct octeon_firmware_file_header)) { @@ -890,11 +894,29 @@ int octeon_download_firmware(struct octeon_device *oct, const u8 *data, load_addr += size; } } + + /* Get time of the day */ + do_gettimeofday(&time); + time_to_tm(time.tv_sec, (-sys_tz.tz_minuteswest) * 60, &tm_val); + ret = snprintf(date, MAX_DATE_SIZE, + " date=%04ld.%02d.%02d-%02d:%02d:%02d", + tm_val.tm_year + 1900, tm_val.tm_mon + 1, tm_val.tm_mday, + tm_val.tm_hour, tm_val.tm_min, tm_val.tm_sec); + if ((sizeof(h->bootcmd) - strnlen(h->bootcmd, sizeof(h->bootcmd))) < + ret) { + dev_err(&oct->pci_dev->dev, "Boot command buffer too small\n"); + return -EINVAL; + } + strncat(h->bootcmd, date, + sizeof(h->bootcmd) - strnlen(h->bootcmd, sizeof(h->bootcmd))); + dev_info(&oct->pci_dev->dev, "Writing boot command: %s\n", h->bootcmd); /* Invoke the bootcmd */ ret = octeon_console_send_cmd(oct, h->bootcmd, 50); + if (ret) + dev_info(&oct->pci_dev->dev, "Boot command send failed\n"); - return 0; + return ret; }