Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 91c3eeba authored by Pontus Fuchs's avatar Pontus Fuchs Committed by Kalle Valo
Browse files

wcn36xx: Pad TIM PVM if needed



The wcn36xx FW expects a fixed size TIM PVM in the beacon template. If
supplied with a shorter than expected PVM it will overwrite the IE
following the TIM.

Squashed with fix from Jason Mobarak <jam@cozybit.com>:
Patch "wcn36xx: Pad TIM PVM if needed" has caused a regression in mesh
beaconing.  The field tim_off is always 0 for mesh mode, and thus
pvm_len (referring to the TIM length field) and pad are both incorrectly
calculated.  Thus, msg_body.beacon_length is incorrectly calculated for
mesh mode. Fix this.

Signed-off-by: default avatarPontus Fuchs <pontus.fuchs@gmail.com>
Signed-off-by: default avatarJason Mobarak <jam@cozybit.com>
[bjorn: squashed in Jason's fixup]
Signed-off-by: default avatarBjorn Andersson <bjorn.andersson@linaro.org>
Signed-off-by: default avatarKalle Valo <kvalo@qca.qualcomm.com>
parent 25d217d6
Loading
Loading
Loading
Loading
+3 −0
Original line number Diff line number Diff line
@@ -54,6 +54,9 @@
/* Default Beacon template size */
#define BEACON_TEMPLATE_SIZE 0x180

/* Minimum PVM size that the FW expects. See comment in smd.c for details. */
#define TIM_MIN_PVM_SIZE 6

/* Param Change Bitmap sent to HAL */
#define PARAM_BCN_INTERVAL_CHANGED                      (1 << 0)
#define PARAM_SHORT_PREAMBLE_CHANGED                 (1 << 1)
+25 −2
Original line number Diff line number Diff line
@@ -1375,12 +1375,19 @@ int wcn36xx_smd_send_beacon(struct wcn36xx *wcn, struct ieee80211_vif *vif,
			    u16 p2p_off)
{
	struct wcn36xx_hal_send_beacon_req_msg msg_body;
	int ret = 0;
	int ret = 0, pad, pvm_len;

	mutex_lock(&wcn->hal_mutex);
	INIT_HAL_MSG(msg_body, WCN36XX_HAL_SEND_BEACON_REQ);

	msg_body.beacon_length = skb_beacon->len;
	pvm_len = skb_beacon->data[tim_off + 1] - 3;
	pad = TIM_MIN_PVM_SIZE - pvm_len;

	/* Padding is irrelevant to mesh mode since tim_off is always 0. */
	if (vif->type == NL80211_IFTYPE_MESH_POINT)
		pad = 0;

	msg_body.beacon_length = skb_beacon->len + pad;
	/* TODO need to find out why + 6 is needed */
	msg_body.beacon_length6 = msg_body.beacon_length + 6;

@@ -1393,6 +1400,22 @@ int wcn36xx_smd_send_beacon(struct wcn36xx *wcn, struct ieee80211_vif *vif,
	memcpy(msg_body.beacon, skb_beacon->data, skb_beacon->len);
	memcpy(msg_body.bssid, vif->addr, ETH_ALEN);

	if (pad > 0) {
		/*
		 * The wcn36xx FW has a fixed size for the PVM in the TIM. If
		 * given the beacon template from mac80211 with a PVM shorter
		 * than the FW expectes it will overwrite the data after the
		 * TIM.
		 */
		wcn36xx_dbg(WCN36XX_DBG_HAL, "Pad TIM PVM. %d bytes at %d\n",
			    pad, pvm_len);
		memmove(&msg_body.beacon[tim_off + 5 + pvm_len + pad],
			&msg_body.beacon[tim_off + 5 + pvm_len],
			skb_beacon->len - (tim_off + 5 + pvm_len));
		memset(&msg_body.beacon[tim_off + 5 + pvm_len], 0, pad);
		msg_body.beacon[tim_off + 1] += pad;
	}

	/* TODO need to find out why this is needed? */
	if (vif->type == NL80211_IFTYPE_MESH_POINT)
		/* mesh beacon don't need this, so push further down */