On Mon, 2016-08-08 at 11:57 +0300, Guy Mishol wrote: > Add zone time sync support for mesh role. > This allows to configure the mesh peer > master of each zone for time synchronization. What is this? mac80211 already tries to maintain TSF sync with mesh peers if get/set TSF ops are supported by the driver. > Signed-off-by: Guy Mishol <guym@xxxxxx> > --- > drivers/net/wireless/ti/wl18xx/acx.c | 29 ++++++++++++++++ > drivers/net/wireless/ti/wl18xx/acx.h | 13 +++++++ > drivers/net/wireless/ti/wl18xx/debugfs.c | 59 ++++++++++++++++++++++++++++++++ > drivers/net/wireless/ti/wl18xx/event.c | 1 + > drivers/net/wireless/ti/wlcore/wlcore.h | 3 ++ > 5 files changed, 105 insertions(+) > > diff --git a/drivers/net/wireless/ti/wl18xx/acx.c b/drivers/net/wireless/ti/wl18xx/acx.c > index 4be0409..b5525a3 100644 > --- a/drivers/net/wireless/ti/wl18xx/acx.c > +++ b/drivers/net/wireless/ti/wl18xx/acx.c > @@ -309,3 +309,32 @@ out: > kfree(acx); > return ret; > } > + > +int wl18xx_acx_time_sync_cfg(struct wl1271 *wl) > +{ > + struct acx_time_sync_cfg *acx; > + int ret; > + > + wl1271_debug(DEBUG_ACX, "acx time sync cfg: mode %d, addr: %pM", > + wl->conf.sg.params[WL18XX_CONF_SG_TIME_SYNC], > + wl->zone_master_mac_addr); > + > + acx = kzalloc(sizeof(*acx), GFP_KERNEL); > + if (!acx) { > + ret = -ENOMEM; > + goto out; > + } > + > + acx->sync_mode = wl->conf.sg.params[WL18XX_CONF_SG_TIME_SYNC]; > + memcpy(acx->zone_mac_addr, wl->zone_master_mac_addr, ETH_ALEN); > + > + ret = wl1271_cmd_configure(wl, ACX_TIME_SYNC_CFG, > + acx, sizeof(*acx)); > + if (ret < 0) { > + wl1271_warning("acx time sync cfg failed: %d", ret); > + goto out; > + } > +out: > + kfree(acx); > + return ret; > +} > diff --git a/drivers/net/wireless/ti/wl18xx/acx.h b/drivers/net/wireless/ti/wl18xx/acx.h > index 342a299..2edbbbf 100644 > --- a/drivers/net/wireless/ti/wl18xx/acx.h > +++ b/drivers/net/wireless/ti/wl18xx/acx.h > @@ -37,6 +37,7 @@ enum { > ACX_RX_BA_FILTER = 0x0058, > ACX_AP_SLEEP_CFG = 0x0059, > ACX_DYNAMIC_TRACES_CFG = 0x005A, > + ACX_TIME_SYNC_CFG = 0x005B, > }; > > /* numbers of bits the length field takes (add 1 for the actual number) */ > @@ -388,6 +389,17 @@ struct acx_dynamic_fw_traces_cfg { > __le32 dynamic_fw_traces; > } __packed; > > +/* > + * ACX_TIME_SYNC_CFG > + * configure the time sync parameters > + */ > +struct acx_time_sync_cfg { > + struct acx_header header; > + u8 sync_mode; > + u8 zone_mac_addr[ETH_ALEN]; > + u8 padding[1]; > +} __packed; > + > int wl18xx_acx_host_if_cfg_bitmap(struct wl1271 *wl, u32 host_cfg_bitmap, > u32 sdio_blk_size, u32 extra_mem_blks, > u32 len_field_size); > @@ -402,5 +414,6 @@ int wl18xx_acx_interrupt_notify_config(struct wl1271 *wl, bool action); > int wl18xx_acx_rx_ba_filter(struct wl1271 *wl, bool action); > int wl18xx_acx_ap_sleep(struct wl1271 *wl); > int wl18xx_acx_dynamic_fw_traces(struct wl1271 *wl); > +int wl18xx_acx_time_sync_cfg(struct wl1271 *wl); > > #endif /* __WL18XX_ACX_H__ */ > diff --git a/drivers/net/wireless/ti/wl18xx/debugfs.c b/drivers/net/wireless/ti/wl18xx/debugfs.c > index 86ccf84..9e28748 100644 > --- a/drivers/net/wireless/ti/wl18xx/debugfs.c > +++ b/drivers/net/wireless/ti/wl18xx/debugfs.c > @@ -408,6 +408,64 @@ static const struct file_operations radar_debug_mode_ops = { > }; > #endif /* CFG80211_CERTIFICATION_ONUS */ > > +static ssize_t time_sync_zone_addr_write(struct file *file, > + const char __user *user_buf, > + size_t count, loff_t *ppos) { > + struct wl1271 *wl = file->private_data; > + char buf[(ETH_ALEN * 2)]; > + int ret; > + > + if (count < (ETH_ALEN * 2 + 1)) { > + wl1271_warning("Illegal MAC address: wrong size"); > + return -EINVAL; > + } > + > + ret = copy_from_user(buf, user_buf, (ETH_ALEN * 2)); > + if (ret < 0) > + return ret; > + > + ret = hex2bin(wl->zone_master_mac_addr, buf, ETH_ALEN); > + if (ret < 0) { > + wl1271_warning("Illegal MAC address: invalid characters"); > + return ret; > + } > + > + mutex_lock(&wl->mutex); > + > + if (unlikely(wl->state != WLCORE_STATE_ON)) > + goto out; > + > + ret = wl1271_ps_elp_wakeup(wl); > + if (ret < 0) > + goto out; > + > + ret = wl18xx_acx_time_sync_cfg(wl); > + if (ret < 0) > + count = ret; > + > + wl1271_ps_elp_sleep(wl); > +out: > + mutex_unlock(&wl->mutex); > + return count; > +} > + > +static ssize_t time_sync_zone_addr_read(struct file *file, > + char __user *userbuf, > + size_t count, loff_t *ppos) > +{ > + struct wl1271 *wl = file->private_data; > + > + return wl1271_format_buffer(userbuf, count, ppos, > + "%pM\n", wl->zone_master_mac_addr); > +} > + > +static const struct file_operations time_sync_zone_addr_ops = { > + .write = time_sync_zone_addr_write, > + .read = time_sync_zone_addr_read, > + .open = simple_open, > + .llseek = default_llseek, > +}; > + > int wl18xx_debugfs_add_files(struct wl1271 *wl, > struct dentry *rootdir) > { > @@ -576,6 +634,7 @@ int wl18xx_debugfs_add_files(struct wl1271 *wl, > #ifdef CONFIG_CFG80211_CERTIFICATION_ONUS > DEBUGFS_ADD(radar_debug_mode, moddir); > #endif > + DEBUGFS_ADD(time_sync_zone_addr, moddir); > DEBUGFS_ADD(dynamic_fw_traces, moddir); > > return 0; > diff --git a/drivers/net/wireless/ti/wl18xx/event.c b/drivers/net/wireless/ti/wl18xx/event.c > index 2c5df43..b36ce18 100644 > --- a/drivers/net/wireless/ti/wl18xx/event.c > +++ b/drivers/net/wireless/ti/wl18xx/event.c > @@ -22,6 +22,7 @@ > #include <net/genetlink.h> > #include "event.h" > #include "scan.h" > +#include "conf.h" > #include "../wlcore/cmd.h" > #include "../wlcore/debug.h" > #include "../wlcore/vendor_cmd.h" > diff --git a/drivers/net/wireless/ti/wlcore/wlcore.h b/drivers/net/wireless/ti/wlcore/wlcore.h > index 8f28aa0..1827546 100644 > --- a/drivers/net/wireless/ti/wlcore/wlcore.h > +++ b/drivers/net/wireless/ti/wlcore/wlcore.h > @@ -501,6 +501,9 @@ struct wl1271 { > > /* dynamic fw traces */ > u32 dynamic_fw_traces; > + > + /* time sync zone master */ > + u8 zone_master_mac_addr[ETH_ALEN]; > }; > > int wlcore_probe(struct wl1271 *wl, struct platform_device *pdev);