Exemplo n.º 1
0
/* key must be 32 bytes, including the tx and rx MIC keys.
 * rsc must be 8 bytes
 * tsc must be 8 bytes or NULL
 */
int __orinoco_hw_set_tkip_key(hermes_t *hw, int key_idx, int set_tx,
			      u8 *key, u8 *rsc, u8 *tsc)
{
	struct {
		__le16 idx;
		u8 rsc[IW_ENCODE_SEQ_MAX_SIZE];
		u8 key[TKIP_KEYLEN];
		u8 tx_mic[MIC_KEYLEN];
		u8 rx_mic[MIC_KEYLEN];
		u8 tsc[IW_ENCODE_SEQ_MAX_SIZE];
	} __attribute__ ((packed)) buf;
	int ret;
	int err;
	int k;
	u16 xmitting;

	key_idx &= 0x3;

	if (set_tx)
		key_idx |= 0x8000;

	buf.idx = cpu_to_le16(key_idx);
	memcpy(buf.key, key,
	       sizeof(buf.key) + sizeof(buf.tx_mic) + sizeof(buf.rx_mic));

	if (rsc == NULL)
		memset(buf.rsc, 0, sizeof(buf.rsc));
	else
		memcpy(buf.rsc, rsc, sizeof(buf.rsc));

	if (tsc == NULL) {
		memset(buf.tsc, 0, sizeof(buf.tsc));
		buf.tsc[4] = 0x10;
	} else {
		memcpy(buf.tsc, tsc, sizeof(buf.tsc));
	}

	/* Wait upto 100ms for tx queue to empty */
	for (k = 100; k > 0; k--) {
		udelay(1000);
		ret = hermes_read_wordrec(hw, USER_BAP, HERMES_RID_TXQUEUEEMPTY,
					  &xmitting);
		if (ret || !xmitting)
			break;
	}

	if (k == 0)
		ret = -ETIMEDOUT;

	err = HERMES_WRITE_RECORD(hw, USER_BAP,
				  HERMES_RID_CNFADDDEFAULTTKIPKEY_AGERE,
				  &buf);

	return ret ? ret : err;
}
Exemplo n.º 2
0
Arquivo: wext.c Projeto: Addision/LVS
static int orinoco_ioctl_getfrag(struct net_device *dev,
				 struct iw_request_info *info,
				 struct iw_param *frq,
				 char *extra)
{
	struct orinoco_private *priv = ndev_priv(dev);
	hermes_t *hw = &priv->hw;
	int err;
	u16 val;
	unsigned long flags;

	if (orinoco_lock(priv, &flags) != 0)
		return -EBUSY;

	if (priv->has_mwo) {
		err = hermes_read_wordrec(hw, USER_BAP,
					  HERMES_RID_CNFMWOROBUST_AGERE,
					  &val);
		if (err)
			val = 0;

		frq->value = val ? 2347 : 0;
		frq->disabled = !val;
		frq->fixed = 0;
	} else {
		err = hermes_read_wordrec(hw, USER_BAP,
					  HERMES_RID_CNFFRAGMENTATIONTHRESHOLD,
					  &val);
		if (err)
			val = 0;

		frq->value = val;
		frq->disabled = (val >= 2346);
		frq->fixed = 1;
	}

	orinoco_unlock(priv, &flags);

	return err;
}
Exemplo n.º 3
0
Arquivo: hw.c Projeto: 020gzh/linux
int orinoco_hw_get_act_bitrate(struct orinoco_private *priv, int *bitrate)
{
	struct hermes *hw = &priv->hw;
	int i;
	int err = 0;
	u16 val;

	err = hermes_read_wordrec(hw, USER_BAP,
				  HERMES_RID_CURRENTTXRATE, &val);
	if (err)
		return err;

	switch (priv->firmware_type) {
	case FIRMWARE_TYPE_AGERE: /* Lucent style rate */
		/* Note : in Lucent firmware, the return value of
		 * HERMES_RID_CURRENTTXRATE is the bitrate in Mb/s,
		 * and therefore is totally different from the
		 * encoding of HERMES_RID_CNFTXRATECONTROL.
		 * Don't forget that 6Mb/s is really 5.5Mb/s */
		if (val == 6)
			*bitrate = 5500000;
		else
			*bitrate = val * 1000000;
		break;
	case FIRMWARE_TYPE_INTERSIL: /* Intersil style rate */
	case FIRMWARE_TYPE_SYMBOL: /* Symbol style rate */
		for (i = 0; i < BITRATE_TABLE_SIZE; i++)
			if (bitrate_table[i].intersil_txratectrl == val) {
				*bitrate = bitrate_table[i].bitrate * 100000;
				break;
			}

		if (i >= BITRATE_TABLE_SIZE) {
			printk(KERN_INFO "%s: Unable to determine current bitrate (0x%04hx)\n",
			       priv->ndev->name, val);
			err = -EIO;
		}

		break;
	default:
		BUG();
	}

	return err;
}
Exemplo n.º 4
0
int orinoco_hw_get_act_bitrate(struct orinoco_private *priv, int *bitrate)
{
	struct hermes *hw = &priv->hw;
	int i;
	int err = 0;
	u16 val;

	err = hermes_read_wordrec(hw, USER_BAP,
				  HERMES_RID_CURRENTTXRATE, &val);
	if (err)
		return err;

	switch (priv->firmware_type) {
	case FIRMWARE_TYPE_AGERE: /*                   */
		/*                                               
                                                     
                                                
                                             
                                               */
		if (val == 6)
			*bitrate = 5500000;
		else
			*bitrate = val * 1000000;
		break;
	case FIRMWARE_TYPE_INTERSIL: /*                     */
	case FIRMWARE_TYPE_SYMBOL: /*                   */
		for (i = 0; i < BITRATE_TABLE_SIZE; i++)
			if (bitrate_table[i].intersil_txratectrl == val) {
				*bitrate = bitrate_table[i].bitrate * 100000;
				break;
			}

		if (i >= BITRATE_TABLE_SIZE) {
			printk(KERN_INFO "%s: Unable to determine current bitrate (0x%04hx)\n",
			       priv->ndev->name, val);
			err = -EIO;
		}

		break;
	default:
		BUG();
	}

	return err;
}
Exemplo n.º 5
0
Arquivo: hw.c Projeto: 020gzh/linux
int orinoco_hw_get_freq(struct orinoco_private *priv)
{
	struct hermes *hw = &priv->hw;
	int err = 0;
	u16 channel;
	int freq = 0;
	unsigned long flags;

	if (orinoco_lock(priv, &flags) != 0)
		return -EBUSY;

	err = hermes_read_wordrec(hw, USER_BAP, HERMES_RID_CURRENTCHANNEL,
				  &channel);
	if (err)
		goto out;

	/* Intersil firmware 1.3.5 returns 0 when the interface is down */
	if (channel == 0) {
		err = -EBUSY;
		goto out;
	}

	if ((channel < 1) || (channel > NUM_CHANNELS)) {
		printk(KERN_WARNING "%s: Channel out of range (%d)!\n",
		       priv->ndev->name, channel);
		err = -EBUSY;
		goto out;

	}
	freq = ieee80211_channel_to_frequency(channel, IEEE80211_BAND_2GHZ);

 out:
	orinoco_unlock(priv, &flags);

	if (err > 0)
		err = -EBUSY;
	return err ? err : freq;
}
Exemplo n.º 6
0
Arquivo: hw.c Projeto: 020gzh/linux
/* key must be 32 bytes, including the tx and rx MIC keys.
 * rsc must be NULL or up to 8 bytes
 * tsc must be NULL or up to 8 bytes
 */
int __orinoco_hw_set_tkip_key(struct orinoco_private *priv, int key_idx,
			      int set_tx, const u8 *key, const u8 *rsc,
			      size_t rsc_len, const u8 *tsc, size_t tsc_len)
{
	struct {
		__le16 idx;
		u8 rsc[ORINOCO_SEQ_LEN];
		u8 key[TKIP_KEYLEN];
		u8 tx_mic[MIC_KEYLEN];
		u8 rx_mic[MIC_KEYLEN];
		u8 tsc[ORINOCO_SEQ_LEN];
	} __packed buf;
	struct hermes *hw = &priv->hw;
	int ret;
	int err;
	int k;
	u16 xmitting;

	key_idx &= 0x3;

	if (set_tx)
		key_idx |= 0x8000;

	buf.idx = cpu_to_le16(key_idx);
	memcpy(buf.key, key,
	       sizeof(buf.key) + sizeof(buf.tx_mic) + sizeof(buf.rx_mic));

	if (rsc_len > sizeof(buf.rsc))
		rsc_len = sizeof(buf.rsc);

	if (tsc_len > sizeof(buf.tsc))
		tsc_len = sizeof(buf.tsc);

	memset(buf.rsc, 0, sizeof(buf.rsc));
	memset(buf.tsc, 0, sizeof(buf.tsc));

	if (rsc != NULL)
		memcpy(buf.rsc, rsc, rsc_len);

	if (tsc != NULL)
		memcpy(buf.tsc, tsc, tsc_len);
	else
		buf.tsc[4] = 0x10;

	/* Wait up to 100ms for tx queue to empty */
	for (k = 100; k > 0; k--) {
		udelay(1000);
		ret = hermes_read_wordrec(hw, USER_BAP, HERMES_RID_TXQUEUEEMPTY,
					  &xmitting);
		if (ret || !xmitting)
			break;
	}

	if (k == 0)
		ret = -ETIMEDOUT;

	err = HERMES_WRITE_RECORD(hw, USER_BAP,
				  HERMES_RID_CNFADDDEFAULTTKIPKEY_AGERE,
				  &buf);

	return ret ? ret : err;
}
Exemplo n.º 7
0
Arquivo: hw.c Projeto: 020gzh/linux
/* Read settings from EEPROM into our private structure.
 * MAC address gets dropped into callers buffer
 * Can be called before netdev registration.
 */
int orinoco_hw_read_card_settings(struct orinoco_private *priv, u8 *dev_addr)
{
	struct device *dev = priv->dev;
	struct hermes_idstring nickbuf;
	struct hermes *hw = &priv->hw;
	int len;
	int err;
	u16 reclen;

	/* Get the MAC address */
	err = hw->ops->read_ltv(hw, USER_BAP, HERMES_RID_CNFOWNMACADDR,
				ETH_ALEN, NULL, dev_addr);
	if (err) {
		dev_warn(dev, "Failed to read MAC address!\n");
		goto out;
	}

	dev_dbg(dev, "MAC address %pM\n", dev_addr);

	/* Get the station name */
	err = hw->ops->read_ltv(hw, USER_BAP, HERMES_RID_CNFOWNNAME,
				sizeof(nickbuf), &reclen, &nickbuf);
	if (err) {
		dev_err(dev, "failed to read station name\n");
		goto out;
	}
	if (nickbuf.len)
		len = min(IW_ESSID_MAX_SIZE, (int)le16_to_cpu(nickbuf.len));
	else
		len = min(IW_ESSID_MAX_SIZE, 2 * reclen);
	memcpy(priv->nick, &nickbuf.val, len);
	priv->nick[len] = '\0';

	dev_dbg(dev, "Station name \"%s\"\n", priv->nick);

	/* Get allowed channels */
	err = hermes_read_wordrec(hw, USER_BAP, HERMES_RID_CHANNELLIST,
				  &priv->channel_mask);
	if (err) {
		dev_err(dev, "Failed to read channel list!\n");
		goto out;
	}

	/* Get initial AP density */
	err = hermes_read_wordrec(hw, USER_BAP, HERMES_RID_CNFSYSTEMSCALE,
				  &priv->ap_density);
	if (err || priv->ap_density < 1 || priv->ap_density > 3)
		priv->has_sensitivity = 0;

	/* Get initial RTS threshold */
	err = hermes_read_wordrec(hw, USER_BAP, HERMES_RID_CNFRTSTHRESHOLD,
				  &priv->rts_thresh);
	if (err) {
		dev_err(dev, "Failed to read RTS threshold!\n");
		goto out;
	}

	/* Get initial fragmentation settings */
	if (priv->has_mwo)
		err = hermes_read_wordrec(hw, USER_BAP,
					  HERMES_RID_CNFMWOROBUST_AGERE,
					  &priv->mwo_robust);
	else
		err = hermes_read_wordrec(hw, USER_BAP,
					  HERMES_RID_CNFFRAGMENTATIONTHRESHOLD,
					  &priv->frag_thresh);
	if (err) {
		dev_err(dev, "Failed to read fragmentation settings!\n");
		goto out;
	}

	/* Power management setup */
	if (priv->has_pm) {
		priv->pm_on = 0;
		priv->pm_mcast = 1;
		err = hermes_read_wordrec(hw, USER_BAP,
					  HERMES_RID_CNFMAXSLEEPDURATION,
					  &priv->pm_period);
		if (err) {
			dev_err(dev, "Failed to read power management "
				"period!\n");
			goto out;
		}
		err = hermes_read_wordrec(hw, USER_BAP,
					  HERMES_RID_CNFPMHOLDOVERDURATION,
					  &priv->pm_timeout);
		if (err) {
			dev_err(dev, "Failed to read power management "
				"timeout!\n");
			goto out;
		}
	}

	/* Preamble setup */
	if (priv->has_preamble) {
		err = hermes_read_wordrec(hw, USER_BAP,
					  HERMES_RID_CNFPREAMBLE_SYMBOL,
					  &priv->preamble);
		if (err) {
			dev_err(dev, "Failed to read preamble setup\n");
			goto out;
		}
	}

	/* Retry settings */
	err = hermes_read_wordrec(hw, USER_BAP, HERMES_RID_SHORTRETRYLIMIT,
				  &priv->short_retry_limit);
	if (err) {
		dev_err(dev, "Failed to read short retry limit\n");
		goto out;
	}

	err = hermes_read_wordrec(hw, USER_BAP, HERMES_RID_LONGRETRYLIMIT,
				  &priv->long_retry_limit);
	if (err) {
		dev_err(dev, "Failed to read long retry limit\n");
		goto out;
	}

	err = hermes_read_wordrec(hw, USER_BAP, HERMES_RID_MAXTRANSMITLIFETIME,
				  &priv->retry_lifetime);
	if (err) {
		dev_err(dev, "Failed to read max retry lifetime\n");
		goto out;
	}

out:
	return err;
}