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

Commit 6eecad77 authored by David Kilroy's avatar David Kilroy Committed by John W. Linville
Browse files

orinoco: Fix transmit for Agere/Lucent with fw 9.x



The tx control word has moved into the 802.11 header area on these
firmwares.

Signed-off-by: default avatarDavid Kilroy <kilroyd@gmail.com>
Signed-off-by: default avatarJohn W. Linville <linville@tuxdriver.com>
parent 3994d502
Loading
Loading
Loading
Loading
+1 −0
Original line number Diff line number Diff line
@@ -179,6 +179,7 @@
#define HERMES_802_11_OFFSET		(14)
#define HERMES_802_3_OFFSET		(14+32)
#define HERMES_802_2_OFFSET		(14+32+14)
#define HERMES_TXCNTL2_OFFSET		(HERMES_802_3_OFFSET - 2)

#define HERMES_RXSTAT_ERR		(0x0003)
#define	HERMES_RXSTAT_BADCRC		(0x0001)
+44 −15
Original line number Diff line number Diff line
@@ -722,7 +722,7 @@ static int orinoco_xmit(struct sk_buff *skb, struct net_device *dev)
	u16 txfid = priv->txfid;
	struct ethhdr *eh;
	int data_off;
	struct hermes_tx_descriptor desc;
	int tx_control;
	unsigned long flags;

	if (! netif_running(dev)) {
@@ -756,13 +756,39 @@ static int orinoco_xmit(struct sk_buff *skb, struct net_device *dev)

	eh = (struct ethhdr *)skb->data;

	tx_control = HERMES_TXCTRL_TX_OK | HERMES_TXCTRL_TX_EX;

	if (priv->has_alt_txcntl) {
		/* WPA enabled firmwares have tx_cntl at the end of
		 * the 802.11 header.  So write zeroed descriptor and
		 * 802.11 header at the same time
		 */
		char desc[HERMES_802_3_OFFSET];
		__le16 *txcntl = (__le16 *) &desc[HERMES_TXCNTL2_OFFSET];

		memset(&desc, 0, sizeof(desc));
 	desc.tx_control = cpu_to_le16(HERMES_TXCTRL_TX_OK | HERMES_TXCTRL_TX_EX);
	err = hermes_bap_pwrite(hw, USER_BAP, &desc, sizeof(desc), txfid, 0);

		*txcntl = cpu_to_le16(tx_control);
		err = hermes_bap_pwrite(hw, USER_BAP, &desc, sizeof(desc),
					txfid, 0);
		if (err) {
			if (net_ratelimit())
			printk(KERN_ERR "%s: Error %d writing Tx descriptor "
			       "to BAP\n", dev->name, err);
				printk(KERN_ERR "%s: Error %d writing Tx "
				       "descriptor to BAP\n", dev->name, err);
			goto busy;
		}
	} else {
		struct hermes_tx_descriptor desc;

		memset(&desc, 0, sizeof(desc));

		desc.tx_control = cpu_to_le16(tx_control);
		err = hermes_bap_pwrite(hw, USER_BAP, &desc, sizeof(desc),
					txfid, 0);
		if (err) {
			if (net_ratelimit())
				printk(KERN_ERR "%s: Error %d writing Tx "
				       "descriptor to BAP\n", dev->name, err);
			goto busy;
		}

@@ -771,6 +797,7 @@ static int orinoco_xmit(struct sk_buff *skb, struct net_device *dev)
		 * if this isn't done. */
		hermes_clear_words(hw, HERMES_DATA0,
				   HERMES_802_3_OFFSET - HERMES_802_11_OFFSET);
	}

	/* Encapsulate Ethernet-II frames */
	if (ntohs(eh->h_proto) > ETH_DATA_LEN) { /* Ethernet-II frame */
@@ -2528,6 +2555,7 @@ static int determine_firmware(struct net_device *dev)
	priv->has_ibss = 1;
	priv->has_wep = 0;
	priv->has_big_wep = 0;
	priv->has_alt_txcntl = 0;
	priv->do_fw_download = 0;

	/* Determine capabilities from the firmware version */
@@ -2550,6 +2578,7 @@ static int determine_firmware(struct net_device *dev)
		priv->has_hostscan = (firmver >= 0x8000a);
		priv->do_fw_download = 1;
		priv->broken_monitor = (firmver >= 0x80000);
		priv->has_alt_txcntl = (firmver >= 0x90000); /* All 9.x ? */

		/* Tested with Agere firmware :
		 *	1.16 ; 4.08 ; 4.52 ; 6.04 ; 6.16 ; 7.28 => Jean II
+1 −0
Original line number Diff line number Diff line
@@ -85,6 +85,7 @@ struct orinoco_private {
	unsigned int has_preamble:1;
	unsigned int has_sensitivity:1;
	unsigned int has_hostscan:1;
	unsigned int has_alt_txcntl:1;
	unsigned int do_fw_download:1;
	unsigned int broken_disableport:1;
	unsigned int broken_monitor:1;