Here are a couple of ways to reproduce the behavior:
Example 1: CTS frames occur every 120 seconds even without data transfer
1. Configure the device as an access point. Our host environment is Linux, so we can run an access point using hostapd. We see the behavior when running 802.11n at 2.4 or 5 Ghz, for example.
2. I next connect to the device's WiFi network from my Mac. I start a capture in Wireshark with the interface set to capture in monitor mode (Capture->Options, double-click the WiFi interface, then check "capture packets in monitor mode").
3. Start a capture. After 5 minutes, look for Clear-to-send frames (perhaps after filtering on the mac address of the device to make life easier). We see Clear-to-send frames every 120 seconds. They have a duration of 10000 microseconds and are addressed to the device. They do not follow a Request-to-send (perhaps they are CTS-to-self?).
Example 2: Data transfer is delayed approximately 70 milliseconds after each periodic CTS frame
1. Start with two devices, each with the Linux host and the Broadcom WiFi chip.
2. We can use iPerf to push some data between the devices. Download and install it on each device with
o-check-certificate; chmod +x iperf_2.0.5-2_i386 ; mv iperf_2.0.5-2_i386 /usr/bi
3. Start one device (Device1) as an access point. Connect the other device (Device2) to Device1's network.
4. I connect my Mac to Device1's network and start Wireshark in monitor mode.
5. Device1 will send data to Device2. Start an iPerf server on Device2 with
> iperf -s -u -i 1
6. On Device1, start sending 300 seconds of UDP traffic with
> iperf -c 192.168.42.31 -u -b 250k -l 250 -t 300
7. After 5 minutes, stop the test. Find CTS frames that specify duration=10000 microseconds using a Wireshark filter like: "(wlan.addr == <mac address Device1> or wlan.addr == <mac address Device2>) and wlan.duration == 10000". When I do this, I see CTS frames from each device, where the frames at each device are separated by 120 seconds.
8. Now, select one of the CTS frames in Wireshark and then clear the filter. This brings back the surrounding data frames. We notice that data packets are usually separated by about 8 ms; after one of these CTS frames, however, there's a 60 to 80 ms delay before the next data frame.
Could these delays be due to power save, or some sort of periodic off-channel scan?
From your description it looks like internal calibration is taking place.
I will check this issue with our firmware developers.