Message ID | 20160808085706.22668-1-guym@ti.com (mailing list archive) |
---|---|
State | Rejected |
Delegated to: | Kalle Valo |
Headers | show |
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@ti.com> > --- > 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);
"Pedersen, Thomas" <twp@qca.qualcomm.com> writes: > 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. Yeah, and why use debugfs?
Kalle/Thomas, Thanks for your feedback. This time sync support is different from the one that mac80211 maintains with mesh peers. This time sync is mostly used by upper layers for several applications (like audio). In this case we allow the user to configure for each zone who will be the synchronizer. You can refer to the following Application Report (chapter 6) for more information: http://www.ti.com/lit/an/swaa166/swaa166.pdf BR, Guy Mishol (+972) 9-7906726 guym@ti.com -----Original Message----- From: Kalle Valo [mailto:kvalo@codeaurora.org] Sent: Friday, August 19, 2016 12:57 To: Pedersen, Thomas Cc: Mishol, Guy; linux-wireless@vger.kernel.org Subject: Re: [PATCH] wlcore: mesh: add zone time sync support "Pedersen, Thomas" <twp@qca.qualcomm.com> writes: > 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. Yeah, and why use debugfs? -- Kalle Valo
"Mishol, Guy" <guym@ti.com> writes: > Kalle/Thomas, > Thanks for your feedback. Please don't top most, it makes using patchwork difficult and is annoying to the readers. > This time sync support is different from the one that mac80211 > maintains with mesh peers. This time sync is mostly used by upper > layers for several applications (like audio). In this case we allow > the user to configure for each zone who will be the synchronizer. You > can refer to the following Application Report (chapter 6) for more > information: http://www.ti.com/lit/an/swaa166/swaa166.pdf I didn't fully understand what this does, but debugfs doesn't sound (no pun intended) like a suitable interface for something like this. nl80211 is more likely candidate.
On Mon, Aug 22, 2016 at 18:56:01, Kalle Valo wrote: > Subject: Re: [PATCH] wlcore: mesh: add zone time sync support > > "Mishol, Guy" <guym@ti.com> writes: > > > Kalle/Thomas, > > Thanks for your feedback. > > Please don't top most, it makes using patchwork difficult and is > annoying to the readers. OK. Understood. > > This time sync support is different from the one that mac80211 > > maintains with mesh peers. This time sync is mostly used by upper > > layers for several applications (like audio). In this case we allow > > the user to configure for each zone who will be the synchronizer. > > You can refer to the following Application Report (chapter 6) for > > more > > information: http://www.ti.com/lit/an/swaa166/swaa166.pdf > > I didn't fully understand what this does, but debugfs doesn't sound > (no pun > intended) like a suitable interface for something like this. nl80211 > is more likely candidate. Agree. The debugfs part was mainly meant for demo and can be omitted. I will submit instead a different patch that only adds the necessary APIs in the wlcore. Guy
On Sun, 2016-08-21 at 10:13 +0000, Mishol, Guy wrote: > Kalle/Thomas, > Thanks for your feedback. > > This time sync support is different from the one that mac80211 maintains with mesh peers. > This time sync is mostly used by upper layers for several applications (like audio). > In this case we allow the user to configure for each zone who will be the synchronizer. > You can refer to the following Application Report (chapter 6) for more information: http://www.ti.com/lit/an/swaa166/swaa166.pdf So it breaks regular mesh synchronization? Power Save, and in the future possibly DFS and MCCA rely on this to work. It sounds like you want some absolute TSF time synchronized within 20us. Mesh TSF synchronization can provide this, it's just a little more complicated as you'll need to compute at the application level using the per-sta offsets. Mesh synchronization accuracy was pretty good IIRC, unfortunately I don't have any test data to share :( thomas
On Thu, Aug 25, 2016 at 21:50:59, Pedersen, Thomas wrote: > Subject: Re: [PATCH] wlcore: mesh: add zone time sync support > > On Sun, 2016-08-21 at 10:13 +0000, Mishol, Guy wrote: > > Kalle/Thomas, > > Thanks for your feedback. > > > > This time sync support is different from the one that mac80211 > > maintains > with mesh peers. > > This time sync is mostly used by upper layers for several > > applications (like > audio). > > In this case we allow the user to configure for each zone who will > > be the > synchronizer. > > You can refer to the following Application Report (chapter 6) for > > more > > information: http://www.ti.com/lit/an/swaa166/swaa166.pdf > > So it breaks regular mesh synchronization? Power Save, and in the > future possibly DFS and MCCA rely on this to work. > > It sounds like you want some absolute TSF time synchronized within 20us. > Mesh TSF synchronization can provide this, it's just a little more > complicated as you'll need to compute at the application level using the per-sta offsets. > Mesh synchronization accuracy was pretty good IIRC, unfortunately I > don't have any test data to share :( Yes. This feature can hit time accuracy of less than 20us when using wl18xx devices. It is not built for mesh role specifically but for STA and AP as well. Unlike STA and AP modes where the topology is well defined when running mesh you have several zones that can be treated as STA-AP topology. This patch just add the API for configuring which mesh peer will act as AP on its zone For the time synchronization matter. It has nothing to do with Mesh TSF synchronization specifically so it shouldn’t break anything. Guy
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);
Add zone time sync support for mesh role. This allows to configure the mesh peer master of each zone for time synchronization. Signed-off-by: Guy Mishol <guym@ti.com> --- 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(+)