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

Commit 2747e5f7 authored by Hante Meuleman's avatar Hante Meuleman Committed by John W. Linville
Browse files

brcmfmac: Signalling header push and pull on logic places.



Currently suppressed packets get enque-ed with header which
then gets pulled before transmit. It is more logical and clean
to pull the header on return and push it unconditionally on xmit.

Reviewed-by: default avatarArend Van Spriel <arend@broadcom.com>
Signed-off-by: default avatarHante Meuleman <meuleman@broadcom.com>
Signed-off-by: default avatarArend van Spriel <arend@broadcom.com>
Signed-off-by: default avatarJohn W. Linville <linville@tuxdriver.com>
parent 0d24b0ea
Loading
Loading
Loading
Loading
+13 −29
Original line number Original line Diff line number Diff line
@@ -1187,6 +1187,7 @@ static int brcmf_fws_txstatus_suppressed(struct brcmf_fws_info *fws, int fifo,
	struct brcmf_fws_mac_descriptor *entry = brcmf_skbcb(skb)->mac;
	struct brcmf_fws_mac_descriptor *entry = brcmf_skbcb(skb)->mac;
	u32 hslot;
	u32 hslot;
	int ret;
	int ret;
	u8 ifidx;


	hslot = brcmf_skb_htod_tag_get_field(skb, HSLOT);
	hslot = brcmf_skb_htod_tag_get_field(skb, HSLOT);


@@ -1203,9 +1204,12 @@ static int brcmf_fws_txstatus_suppressed(struct brcmf_fws_info *fws, int fifo,


	entry->generation = genbit;
	entry->generation = genbit;


	ret = brcmf_fws_enq(fws, BRCMF_FWS_SKBSTATE_SUPPRESSED, fifo, skb);
	ret = brcmf_proto_hdrpull(fws->drvr, false, &ifidx, skb);
	if (ret == 0)
		ret = brcmf_fws_enq(fws, BRCMF_FWS_SKBSTATE_SUPPRESSED, fifo,
				    skb);
	if (ret != 0) {
	if (ret != 0) {
		/* suppress q is full, drop this packet */
		/* suppress q is full or hdrpull failed, drop this packet */
		brcmf_fws_hanger_poppkt(&fws->hanger, hslot, &skb,
		brcmf_fws_hanger_poppkt(&fws->hanger, hslot, &skb,
					true);
					true);
	} else {
	} else {
@@ -1550,18 +1554,10 @@ static int brcmf_fws_precommit_skb(struct brcmf_fws_info *fws, int fifo,
	bool first_time;
	bool first_time;
	int hslot = BRCMF_FWS_HANGER_MAXITEMS;
	int hslot = BRCMF_FWS_HANGER_MAXITEMS;
	u8 free_ctr;
	u8 free_ctr;
	u8 ifidx;
	u8 flags;
	u8 flags;


	first_time = skcb->state != BRCMF_FWS_SKBSTATE_SUPPRESSED;
	first_time = skcb->state != BRCMF_FWS_SKBSTATE_SUPPRESSED;


	if (!first_time) {
		rc = brcmf_proto_hdrpull(fws->drvr, false, &ifidx, p);
		if (rc) {
			brcmf_err("hdrpull failed\n");
			return rc;
		}
	}
	brcmf_skb_if_flags_set_field(p, TRANSMIT, 1);
	brcmf_skb_if_flags_set_field(p, TRANSMIT, 1);
	brcmf_skb_htod_tag_set_field(p, FIFO, fifo);
	brcmf_skb_htod_tag_set_field(p, FIFO, fifo);
	brcmf_skb_htod_tag_set_field(p, GENERATION, entry->generation);
	brcmf_skb_htod_tag_set_field(p, GENERATION, entry->generation);
@@ -1584,15 +1580,14 @@ static int brcmf_fws_precommit_skb(struct brcmf_fws_info *fws, int fifo,
		brcmf_skb_htod_tag_set_field(p, HSLOT, hslot);
		brcmf_skb_htod_tag_set_field(p, HSLOT, hslot);
		brcmf_skb_htod_tag_set_field(p, FREERUN, free_ctr);
		brcmf_skb_htod_tag_set_field(p, FREERUN, free_ctr);
		entry->transit_count++;
		entry->transit_count++;
	}

	brcmf_fws_hdrpush(fws, p);
	if (first_time) {
		rc = brcmf_fws_hanger_pushpkt(&fws->hanger, p, hslot);
		rc = brcmf_fws_hanger_pushpkt(&fws->hanger, p, hslot);
		if (rc)
		if (rc)
			brcmf_err("hanger push failed: rc=%d\n", rc);
			brcmf_err("hanger push failed: rc=%d\n", rc);
	}
	}


	if (rc == 0)
		brcmf_fws_hdrpush(fws, p);

	return rc;
	return rc;
}
}


@@ -1613,7 +1608,6 @@ brcmf_fws_rollback_toq(struct brcmf_fws_info *fws,
	struct sk_buff *pktout;
	struct sk_buff *pktout;
	int rc = 0;
	int rc = 0;
	int hslot;
	int hslot;
	u8 ifidx;


	state = brcmf_skbcb(skb)->state;
	state = brcmf_skbcb(skb)->state;
	entry = brcmf_skbcb(skb)->mac;
	entry = brcmf_skbcb(skb)->mac;
@@ -1630,17 +1624,6 @@ brcmf_fws_rollback_toq(struct brcmf_fws_info *fws,
		} else {
		} else {
			hslot = brcmf_skb_htod_tag_get_field(skb, HSLOT);
			hslot = brcmf_skb_htod_tag_get_field(skb, HSLOT);


			/* remove header first */
			rc = brcmf_proto_hdrpull(fws->drvr, false, &ifidx, skb);
			if (rc) {
				brcmf_err("header removal failed\n");
				/* free the hanger slot */
				brcmf_fws_hanger_poppkt(&fws->hanger, hslot,
							&pktout, true);
				rc = -EINVAL;
				goto fail;
			}

			/* delay-q packets are going to delay-q */
			/* delay-q packets are going to delay-q */
			pktout = brcmu_pktq_penq_head(&entry->psq,
			pktout = brcmu_pktq_penq_head(&entry->psq,
						      2 * fifo, skb);
						      2 * fifo, skb);
@@ -1661,8 +1644,6 @@ brcmf_fws_rollback_toq(struct brcmf_fws_info *fws,
		rc = -ENOENT;
		rc = -ENOENT;
	}
	}



fail:
	if (rc) {
	if (rc) {
		brcmf_fws_bustxfail(fws, skb);
		brcmf_fws_bustxfail(fws, skb);
		fws->stats.rollback_failed++;
		fws->stats.rollback_failed++;
@@ -1732,6 +1713,7 @@ static int brcmf_fws_commit_skb(struct brcmf_fws_info *fws, int fifo,
	struct brcmf_fws_mac_descriptor *entry;
	struct brcmf_fws_mac_descriptor *entry;
	struct brcmf_bus *bus = fws->drvr->bus_if;
	struct brcmf_bus *bus = fws->drvr->bus_if;
	int rc;
	int rc;
	u8 ifidx;


	entry = skcb->mac;
	entry = skcb->mac;
	if (IS_ERR(entry))
	if (IS_ERR(entry))
@@ -1746,8 +1728,10 @@ static int brcmf_fws_commit_skb(struct brcmf_fws_info *fws, int fifo,
	brcmf_dbg(DATA, "%s flags %X htod %X\n", entry->name, skcb->if_flags,
	brcmf_dbg(DATA, "%s flags %X htod %X\n", entry->name, skcb->if_flags,
		  skcb->htod);
		  skcb->htod);
	rc = brcmf_bus_txdata(bus, skb);
	rc = brcmf_bus_txdata(bus, skb);
	if (rc < 0)
	if (rc < 0) {
		brcmf_proto_hdrpull(fws->drvr, false, &ifidx, skb);
		goto rollback;
		goto rollback;
	}


	entry->seq[fifo]++;
	entry->seq[fifo]++;
	fws->stats.pkt2bus++;
	fws->stats.pkt2bus++;