예제 #1
0
/* Returns 1 if the data packet is for us and 0 otherwise. */
static int is_data_packet_for_us(struct ieee80211_device *ieee,
	                         struct ieee80211_hdr_4addr *hdr)
{
	struct net_device *netdev = ieee->dev;
	u16 fc = le16_to_cpu(hdr->frame_ctl);

	ZD_ASSERT(WLAN_FC_GET_TYPE(fc) == IEEE80211_FTYPE_DATA);

	switch (ieee->iw_mode) {
	case IW_MODE_ADHOC:
		if ((fc & (IEEE80211_FCTL_TODS|IEEE80211_FCTL_FROMDS)) != 0 ||
		    memcmp(hdr->addr3, ieee->bssid, ETH_ALEN) != 0)
			return 0;
		break;
	case IW_MODE_AUTO:
	case IW_MODE_INFRA:
		if ((fc & (IEEE80211_FCTL_TODS|IEEE80211_FCTL_FROMDS)) !=
		    IEEE80211_FCTL_FROMDS ||
		    memcmp(hdr->addr2, ieee->bssid, ETH_ALEN) != 0)
			return 0;
		break;
	default:
		ZD_ASSERT(ieee->iw_mode != IW_MODE_MONITOR);
		return 0;
	}

	return memcmp(hdr->addr1, netdev->dev_addr, ETH_ALEN) == 0 ||
	       (is_multicast_ether_addr(hdr->addr1) &&
		memcmp(hdr->addr3, netdev->dev_addr, ETH_ALEN) != 0) ||
	       (netdev->flags & IFF_PROMISC);
}
예제 #2
0
static void rx_urb_complete(struct urb *urb)
{
    struct zd_usb *usb;
    struct zd_usb_rx *rx;
    const u8 *buffer;
    unsigned int length;

    switch (urb->status) {
    case 0:
        break;
    case -ESHUTDOWN:
    case -EINVAL:
    case -ENODEV:
    case -ENOENT:
    case -ECONNRESET:
    case -EPIPE:
        return;
    default:
        dev_dbg_f(urb_dev(urb), "urb %p error %d\n", urb, urb->status);
        goto resubmit;
    }

    buffer = urb->transfer_buffer;
    length = urb->actual_length;
    usb = urb->context;
    rx = &usb->rx;

    if (length%rx->usb_packet_size > rx->usb_packet_size-4) {
        /* If there is an old first fragment, we don't care. */
        dev_dbg_f(urb_dev(urb), "*** first fragment ***\n");
        ZD_ASSERT(length <= ARRAY_SIZE(rx->fragment));
        spin_lock(&rx->lock);
        memcpy(rx->fragment, buffer, length);
        rx->fragment_length = length;
        spin_unlock(&rx->lock);
        goto resubmit;
    }

    spin_lock(&rx->lock);
    if (rx->fragment_length > 0) {
        /* We are on a second fragment, we believe */
        ZD_ASSERT(length + rx->fragment_length <=
                  ARRAY_SIZE(rx->fragment));
        dev_dbg_f(urb_dev(urb), "*** second fragment ***\n");
        memcpy(rx->fragment+rx->fragment_length, buffer, length);
        handle_rx_packet(usb, rx->fragment,
                         rx->fragment_length + length);
        rx->fragment_length = 0;
        spin_unlock(&rx->lock);
    } else {
        spin_unlock(&rx->lock);
        handle_rx_packet(usb, buffer, length);
    }

resubmit:
    usb_submit_urb(urb, GFP_ATOMIC);
}
예제 #3
0
파일: zd_mac.c 프로젝트: maraz/linux-2.6
static int fill_ctrlset(struct zd_mac *mac,
			struct sk_buff *skb,
			struct ieee80211_tx_control *control)
{
	int r;
	struct ieee80211_hdr *hdr = (struct ieee80211_hdr *) skb->data;
	unsigned int frag_len = skb->len + FCS_LEN;
	unsigned int packet_length;
	struct zd_ctrlset *cs = (struct zd_ctrlset *)
		skb_push(skb, sizeof(struct zd_ctrlset));

	ZD_ASSERT(frag_len <= 0xffff);

	cs->modulation = control->tx_rate->hw_value;
	if (control->flags & IEEE80211_TXCTL_SHORT_PREAMBLE)
		cs->modulation = control->tx_rate->hw_value_short;

	cs->tx_length = cpu_to_le16(frag_len);

	cs_set_control(mac, cs, hdr, control->flags);

	packet_length = frag_len + sizeof(struct zd_ctrlset) + 10;
	ZD_ASSERT(packet_length <= 0xffff);
	/* ZD1211B: Computing the length difference this way, gives us
	 * flexibility to compute the packet length.
	 */
	cs->packet_length = cpu_to_le16(zd_chip_is_zd1211b(&mac->chip) ?
			packet_length - frag_len : packet_length);

	/*
	 * CURRENT LENGTH:
	 * - transmit frame length in microseconds
	 * - seems to be derived from frame length
	 * - see Cal_Us_Service() in zdinlinef.h
	 * - if macp->bTxBurstEnable is enabled, then multiply by 4
	 *  - bTxBurstEnable is never set in the vendor driver
	 *
	 * SERVICE:
	 * - "for PLCP configuration"
	 * - always 0 except in some situations at 802.11b 11M
	 * - see line 53 of zdinlinef.h
	 */
	cs->service = 0;
	r = zd_calc_tx_length_us(&cs->service, ZD_RATE(cs->modulation),
		                 le16_to_cpu(cs->tx_length));
	if (r < 0)
		return r;
	cs->current_length = cpu_to_le16(r);
	cs->next_frame_length = 0;

	return 0;
}
예제 #4
0
int zd_mac_set_regdomain(struct zd_mac *mac, u8 regdomain)
{
	int r;
	u8 channel;

	ZD_ASSERT(!irqs_disabled());
	spin_lock_irq(&mac->lock);
	if (regdomain == 0) {
		regdomain = mac->default_regdomain;
	}
	if (!zd_regdomain_supported(regdomain)) {
		spin_unlock_irq(&mac->lock);
		return -EINVAL;
	}
	mac->regdomain = regdomain;
	channel = mac->requested_channel;
	spin_unlock_irq(&mac->lock);

	r = zd_geo_init(zd_mac_to_ieee80211(mac), regdomain);
	if (r)
		return r;
	if (!zd_regdomain_supports_channel(regdomain, channel)) {
		r = reset_channel(mac);
		if (r)
			return r;
	}

	return 0;
}
예제 #5
0
파일: zd_mac.c 프로젝트: Tigrouzen/k1099
void zd_mac_clear(struct zd_mac *mac)
{
	flush_workqueue(zd_workqueue);
	zd_chip_clear(&mac->chip);
	ZD_ASSERT(!spin_is_locked(&mac->lock));
	ZD_MEMCLEAR(mac, sizeof(struct zd_mac));
}
예제 #6
0
static inline void handle_regs_int(struct urb *urb)
{
	struct zd_usb *usb = urb->context;
	struct zd_usb_interrupt *intr = &usb->intr;
	int len;
	u16 int_num;

	ZD_ASSERT(in_interrupt());
	spin_lock(&intr->lock);

	int_num = le16_to_cpu(*(__le16 *)(urb->transfer_buffer+2));
	if (int_num == CR_INTERRUPT) {
		struct zd_mac *mac = zd_hw_mac(zd_usb_to_hw(urb->context));
		spin_lock(&mac->lock);
		memcpy(&mac->intr_buffer, urb->transfer_buffer,
				USB_MAX_EP_INT_BUFFER);
		spin_unlock(&mac->lock);
		schedule_work(&mac->process_intr);
	} else if (intr->read_regs_enabled) {
		intr->read_regs.length = len = urb->actual_length;

		if (len > sizeof(intr->read_regs.buffer))
			len = sizeof(intr->read_regs.buffer);
		memcpy(intr->read_regs.buffer, urb->transfer_buffer, len);
		intr->read_regs_enabled = 0;
		complete(&intr->read_regs.completion);
		goto out;
	}

out:
	spin_unlock(&intr->lock);
}
예제 #7
0
static int read_e2p_mac_addr(struct zd_chip *chip)
{
	static const zd_addr_t addr[2] = { E2P_MAC_ADDR_P1, E2P_MAC_ADDR_P2 };

	ZD_ASSERT(mutex_is_locked(&chip->mutex));
	return _read_mac_addr(chip, chip->e2p_mac, (const zd_addr_t *)addr);
}
예제 #8
0
int zd_mac_set_mode(struct zd_mac *mac, u32 mode)
{
	struct ieee80211_device *ieee;

	switch (mode) {
	case IW_MODE_AUTO:
	case IW_MODE_ADHOC:
	case IW_MODE_INFRA:
		mac->netdev->type = ARPHRD_ETHER;
		break;
	case IW_MODE_MONITOR:
		mac->netdev->type = ARPHRD_IEEE80211_RADIOTAP;
		break;
	default:
		dev_dbg_f(zd_mac_dev(mac), "wrong mode %u\n", mode);
		return -EINVAL;
	}

	ieee = zd_mac_to_ieee80211(mac);
	ZD_ASSERT(!irqs_disabled());
	spin_lock_irq(&ieee->lock);
	ieee->iw_mode = mode;
	spin_unlock_irq(&ieee->lock);

	if (netif_running(mac->netdev))
		return reset_mode(mac);

	return 0;
}
예제 #9
0
int zd_iowrite16a_locked(struct zd_chip *chip,
                  const struct zd_ioreq16 *ioreqs, unsigned int count)
{
	int r;
	unsigned int i, j, t, max;

	ZD_ASSERT(mutex_is_locked(&chip->mutex));
	for (i = 0; i < count; i += j + t) {
		t = 0;
		max = count-i;
		if (max > USB_MAX_IOWRITE16_COUNT)
			max = USB_MAX_IOWRITE16_COUNT;
		for (j = 0; j < max; j++) {
			if (!ioreqs[i+j].addr) {
				t = 1;
				break;
			}
		}

		r = zd_usb_iowrite16v(&chip->usb, &ioreqs[i], j);
		if (r) {
			dev_dbg_f(zd_chip_dev(chip),
				  "error zd_usb_iowrite16v. Error number %d\n",
				  r);
			return r;
		}
	}

	return 0;
}
예제 #10
0
void zd_chip_clear(struct zd_chip *chip)
{
	ZD_ASSERT(!mutex_is_locked(&chip->mutex));
	zd_usb_clear(&chip->usb);
	zd_rf_clear(&chip->rf);
	mutex_destroy(&chip->mutex);
	ZD_MEMCLEAR(chip, sizeof(*chip));
}
예제 #11
0
int zd_mac_get_range(struct zd_mac *mac, struct iw_range *range)
{
	int i;
	const struct channel_range *channel_range;
	u8 regdomain;

	memset(range, 0, sizeof(*range));

	/* FIXME: Not so important and depends on the mode. For 802.11g
	 * usually this value is used. It seems to be that Bit/s number is
	 * given here.
	 */
	range->throughput = 27 * 1000 * 1000;

	range->max_qual.qual = 100;
	range->max_qual.level = 100;

	/* FIXME: Needs still to be tuned. */
	range->avg_qual.qual = 71;
	range->avg_qual.level = 80;

	/* FIXME: depends on standard? */
	range->min_rts = 256;
	range->max_rts = 2346;

	range->min_frag = MIN_FRAG_THRESHOLD;
	range->max_frag = MAX_FRAG_THRESHOLD;

	range->max_encoding_tokens = WEP_KEYS;
	range->num_encoding_sizes = 2;
	range->encoding_size[0] = 5;
	range->encoding_size[1] = WEP_KEY_LEN;

	range->we_version_compiled = WIRELESS_EXT;
	range->we_version_source = 20;

	range->enc_capa = IW_ENC_CAPA_WPA |  IW_ENC_CAPA_WPA2 |
			  IW_ENC_CAPA_CIPHER_TKIP | IW_ENC_CAPA_CIPHER_CCMP;

	ZD_ASSERT(!irqs_disabled());
	spin_lock_irq(&mac->lock);
	regdomain = mac->regdomain;
	spin_unlock_irq(&mac->lock);
	channel_range = zd_channel_range(regdomain);

	range->num_channels = channel_range->end - channel_range->start;
	range->old_num_channels = range->num_channels;
	range->num_frequency = range->num_channels;
	range->old_num_frequency = range->num_frequency;

	for (i = 0; i < range->num_frequency; i++) {
		struct iw_freq *freq = &range->freq[i];
		freq->i = channel_range->start + i;
		zd_channel_to_freq(freq, freq->i);
	}

	return 0;
}
예제 #12
0
void zd_mac_clear(struct zd_mac *mac)
{
	flush_workqueue(zd_workqueue);
	skb_queue_purge(&mac->rx_queue);
	tasklet_kill(&mac->rx_tasklet);
	zd_chip_clear(&mac->chip);
	ZD_ASSERT(!spin_is_locked(&mac->lock));
	ZD_MEMCLEAR(mac, sizeof(struct zd_mac));
}
예제 #13
0
int zd_mac_init_hw(struct zd_mac *mac, u8 device_type)
{
	int r;
	struct zd_chip *chip = &mac->chip;
	u8 addr[ETH_ALEN];
	u8 default_regdomain;

	r = zd_chip_enable_int(chip);
	if (r)
		goto out;
	r = zd_chip_init_hw(chip, device_type);
	if (r)
		goto disable_int;

	zd_get_e2p_mac_addr(chip, addr);
	r = zd_write_mac_addr(chip, addr);
	if (r)
		goto disable_int;
	ZD_ASSERT(!irqs_disabled());
	spin_lock_irq(&mac->lock);
	memcpy(mac->netdev->dev_addr, addr, ETH_ALEN);
	spin_unlock_irq(&mac->lock);

	r = zd_read_regdomain(chip, &default_regdomain);
	if (r)
		goto disable_int;
	if (!zd_regdomain_supported(default_regdomain)) {
		dev_dbg_f(zd_mac_dev(mac),
			  "Regulatory Domain %#04x is not supported.\n",
		          default_regdomain);
		r = -EINVAL;
		goto disable_int;
	}
	spin_lock_irq(&mac->lock);
	mac->regdomain = mac->default_regdomain = default_regdomain;
	spin_unlock_irq(&mac->lock);
	r = reset_channel(mac);
	if (r)
		goto disable_int;

	/* We must inform the device that we are doing encryption/decryption in
	 * software at the moment. */
	r = zd_set_encryption_type(chip, ENC_SNIFFER);
	if (r)
		goto disable_int;

	r = zd_geo_init(zd_mac_to_ieee80211(mac), mac->regdomain);
	if (r)
		goto disable_int;

	r = 0;
disable_int:
	zd_chip_disable_int(chip);
out:
	return r;
}
예제 #14
0
static inline void init_usb_rx(struct zd_usb *usb)
{
    struct zd_usb_rx *rx = &usb->rx;
    spin_lock_init(&rx->lock);
    if (interface_to_usbdev(usb->intf)->speed == USB_SPEED_HIGH) {
        rx->usb_packet_size = 512;
    } else {
        rx->usb_packet_size = 64;
    }
    ZD_ASSERT(rx->fragment_length == 0);
}
예제 #15
0
static int __zd_usb_enable_rx(struct zd_usb *usb)
{
	int i, r;
	struct zd_usb_rx *rx = &usb->rx;
	struct urb **urbs;

	dev_dbg_f(zd_usb_dev(usb), "\n");

	r = -ENOMEM;
	urbs = kcalloc(RX_URBS_COUNT, sizeof(struct urb *), GFP_KERNEL);
	if (!urbs)
		goto error;
	for (i = 0; i < RX_URBS_COUNT; i++) {
		urbs[i] = alloc_rx_urb(usb);
		if (!urbs[i])
			goto error;
	}

	ZD_ASSERT(!irqs_disabled());
	spin_lock_irq(&rx->lock);
	if (rx->urbs) {
		spin_unlock_irq(&rx->lock);
		r = 0;
		goto error;
	}
	rx->urbs = urbs;
	rx->urbs_count = RX_URBS_COUNT;
	spin_unlock_irq(&rx->lock);

	for (i = 0; i < RX_URBS_COUNT; i++) {
		r = usb_submit_urb(urbs[i], GFP_KERNEL);
		if (r)
			goto error_submit;
	}

	return 0;
error_submit:
	for (i = 0; i < RX_URBS_COUNT; i++) {
		usb_kill_urb(urbs[i]);
	}
	spin_lock_irq(&rx->lock);
	rx->urbs = NULL;
	rx->urbs_count = 0;
	spin_unlock_irq(&rx->lock);
error:
	if (urbs) {
		for (i = 0; i < RX_URBS_COUNT; i++)
			free_rx_urb(urbs[i]);
	}
	return r;
}
예제 #16
0
파일: zd_mac.c 프로젝트: Tigrouzen/k1099
/**
 * tx_status - reports tx status of a packet if required
 * @hw - a &struct ieee80211_hw pointer
 * @skb - a sk-buffer
 * @status - the tx status of the packet without control information
 * @success - True for successfull transmission of the frame
 *
 * This information calls ieee80211_tx_status_irqsafe() if required by the
 * control information. It copies the control information into the status
 * information.
 *
 * If no status information has been requested, the skb is freed.
 */
static void tx_status(struct ieee80211_hw *hw, struct sk_buff *skb,
	              struct ieee80211_tx_status *status,
		      bool success)
{
	struct zd_tx_skb_control_block *cb = (struct zd_tx_skb_control_block *)
		skb->cb;

	ZD_ASSERT(cb->control != NULL);
	memcpy(&status->control, cb->control, sizeof(status->control));
	if (!success)
		status->excessive_retries = 1;
	clear_tx_skb_control_block(skb);
	ieee80211_tx_status_irqsafe(hw, skb, status);
}
예제 #17
0
int zd_switch_radio_on(struct zd_rf *rf)
{
	int r, t;
	struct zd_chip *chip = zd_rf_to_chip(rf);

	ZD_ASSERT(mutex_is_locked(&chip->mutex));
	r = zd_chip_lock_phy_regs(chip);
	if (r)
		return r;
	t = rf->switch_radio_on(rf);
	r = zd_chip_unlock_phy_regs(chip);
	if (t)
		r = t;
	return r;
}
예제 #18
0
int zd_rf_set_channel(struct zd_rf *rf, u8 channel)
{
	int r;

	ZD_ASSERT(mutex_is_locked(&zd_rf_to_chip(rf)->mutex));
	if (channel < MIN_CHANNEL24)
		return -EINVAL;
	if (channel > MAX_CHANNEL24)
		return -EINVAL;
	dev_dbg_f(zd_chip_dev(zd_rf_to_chip(rf)), "channel: %d\n", channel);

	r = rf->set_channel(rf, channel);
	if (r >= 0)
		rf->channel = channel;
	return r;
}
예제 #19
0
int zd_switch_radio_off(struct zd_rf *rf)
{
	int r, t;
	struct zd_chip *chip = zd_rf_to_chip(rf);

	/* TODO: move phy regs handling to zd_chip */
	ZD_ASSERT(mutex_is_locked(&chip->mutex));
	r = zd_chip_lock_phy_regs(chip);
	if (r)
		return r;
	t = rf->switch_radio_off(rf);
	r = zd_chip_unlock_phy_regs(chip);
	if (t)
		r = t;
	return r;
}
예제 #20
0
파일: zd_mac.c 프로젝트: Tigrouzen/k1099
/**
 * init_tx_skb_control_block - initializes skb control block
 * @skb: a &sk_buff pointer
 * @dev: pointer to the mac80221 device
 * @control: mac80211 tx control applying for the frame in @skb
 *
 * Initializes the control block of the skbuff to be transmitted.
 */
static int init_tx_skb_control_block(struct sk_buff *skb,
				     struct ieee80211_hw *hw,
	                             struct ieee80211_tx_control *control)
{
	struct zd_tx_skb_control_block *cb =
		(struct zd_tx_skb_control_block *)skb->cb;

	ZD_ASSERT(sizeof(*cb) <= sizeof(skb->cb));
	memset(cb, 0, sizeof(*cb));
	cb->hw= hw;
	cb->control = kmalloc(sizeof(*control), GFP_ATOMIC);
	if (cb->control == NULL)
		return -ENOMEM;
	memcpy(cb->control, control, sizeof(*control));

	return 0;
}
예제 #21
0
static int read_pod(struct zd_chip *chip, u8 *rf_type)
{
	int r;
	u32 value;

	ZD_ASSERT(mutex_is_locked(&chip->mutex));
	r = zd_ioread32_locked(chip, &value, E2P_POD);
	if (r)
		goto error;
	dev_dbg_f(zd_chip_dev(chip), "E2P_POD %#010x\n", value);

	/* FIXME: AL2230 handling (Bit 7 in POD) */
	*rf_type = value & 0x0f;
	chip->pa_type = (value >> 16) & 0x0f;
	chip->patch_cck_gain = (value >> 8) & 0x1;
	chip->patch_cr157 = (value >> 13) & 0x1;
	chip->patch_6m_band_edge = (value >> 21) & 0x1;
	chip->new_phy_layout = (value >> 31) & 0x1;
	chip->al2230s_bit = (value >> 7) & 0x1;
	chip->link_led = ((value >> 4) & 1) ? LED1 : LED2;
	chip->supports_tx_led = 1;
	if (value & (1 << 24)) { /* LED scenario */
		if (value & (1 << 29))
			chip->supports_tx_led = 0;
	}

	dev_dbg_f(zd_chip_dev(chip),
		"RF %s %#01x PA type %#01x patch CCK %d patch CR157 %d "
		"patch 6M %d new PHY %d link LED%d tx led %d\n",
		zd_rf_name(*rf_type), *rf_type,
		chip->pa_type, chip->patch_cck_gain,
		chip->patch_cr157, chip->patch_6m_band_edge,
		chip->new_phy_layout,
		chip->link_led == LED1 ? 1 : 2,
		chip->supports_tx_led);
	return 0;
error:
	*rf_type = 0;
	chip->pa_type = 0;
	chip->patch_cck_gain = 0;
	chip->patch_cr157 = 0;
	chip->patch_6m_band_edge = 0;
	chip->new_phy_layout = 0;
	return r;
}
예제 #22
0
int _zd_iowrite32v_locked(struct zd_chip *chip, const struct zd_ioreq32 *ioreqs,
	           unsigned int count)
{
	int i, j, r;
	struct zd_ioreq16 *ioreqs16;
	unsigned int count16;

	ZD_ASSERT(mutex_is_locked(&chip->mutex));

	if (count == 0)
		return 0;
	if (count > USB_MAX_IOWRITE32_COUNT)
		return -EINVAL;

	/* Allocate a single memory block for values and addresses. */
	count16 = 2*count;
	ioreqs16 = kmalloc(count16 * sizeof(struct zd_ioreq16), GFP_KERNEL);
	if (!ioreqs16) {
		r = -ENOMEM;
		dev_dbg_f(zd_chip_dev(chip),
			  "error %d in ioreqs16 allocation\n", r);
		goto out;
	}

	for (i = 0; i < count; i++) {
		j = 2*i;
		/* We write the high word always first. */
		ioreqs16[j].value   = ioreqs[i].value >> 16;
		ioreqs16[j].addr    = inc_addr(ioreqs[i].addr);
		ioreqs16[j+1].value = ioreqs[i].value;
		ioreqs16[j+1].addr  = ioreqs[i].addr;
	}

	r = zd_usb_iowrite16v(&chip->usb, ioreqs16, count16);
#ifdef DEBUG
	if (r) {
		dev_dbg_f(zd_chip_dev(chip),
			  "error %d in zd_usb_write16v\n", r);
	}
#endif /* DEBUG */
out:
	kfree(ioreqs16);
	return r;
}
예제 #23
0
int zd_rf_init_hw(struct zd_rf *rf, u8 type)
{
	int r = 0;
	int t;
	struct zd_chip *chip = zd_rf_to_chip(rf);

	ZD_ASSERT(mutex_is_locked(&chip->mutex));
	switch (type) {
	case RF2959_RF:
		r = zd_rf_init_rf2959(rf);
		break;
	case AL2230_RF:
	case AL2230S_RF:
		r = zd_rf_init_al2230(rf);
		break;
	case AL7230B_RF:
		r = zd_rf_init_al7230b(rf);
		break;
	case MAXIM_NEW_RF:
	case UW2453_RF:
		r = zd_rf_init_uw2453(rf);
		break;
	default:
		dev_err(zd_chip_dev(chip),
			"RF %s %#x is not supported\n", zd_rf_name(type), type);
		rf->type = 0;
		return -ENODEV;
	}

	if (r)
		return r;

	rf->type = type;

	r = zd_chip_lock_phy_regs(chip);
	if (r)
		return r;
	t = rf->init_hw(rf);
	r = zd_chip_unlock_phy_regs(chip);
	if (t)
		r = t;
	return r;
}
예제 #24
0
/* If wrong rate is given, we are falling back to the slowest rate: 1MBit/s */
static u8 zd_rate_typed(u8 zd_rate)
{
	static const u8 typed_rates[16] = {
		[ZD_CCK_RATE_1M]	= ZD_CS_CCK|ZD_CCK_RATE_1M,
		[ZD_CCK_RATE_2M]	= ZD_CS_CCK|ZD_CCK_RATE_2M,
		[ZD_CCK_RATE_5_5M]	= ZD_CS_CCK|ZD_CCK_RATE_5_5M,
		[ZD_CCK_RATE_11M]	= ZD_CS_CCK|ZD_CCK_RATE_11M,
		[ZD_OFDM_RATE_6M]	= ZD_CS_OFDM|ZD_OFDM_RATE_6M,
		[ZD_OFDM_RATE_9M]	= ZD_CS_OFDM|ZD_OFDM_RATE_9M,
		[ZD_OFDM_RATE_12M]	= ZD_CS_OFDM|ZD_OFDM_RATE_12M,
		[ZD_OFDM_RATE_18M]	= ZD_CS_OFDM|ZD_OFDM_RATE_18M,
		[ZD_OFDM_RATE_24M]	= ZD_CS_OFDM|ZD_OFDM_RATE_24M,
		[ZD_OFDM_RATE_36M]	= ZD_CS_OFDM|ZD_OFDM_RATE_36M,
		[ZD_OFDM_RATE_48M]	= ZD_CS_OFDM|ZD_OFDM_RATE_48M,
		[ZD_OFDM_RATE_54M]	= ZD_CS_OFDM|ZD_OFDM_RATE_54M,
	};

	ZD_ASSERT(ZD_CS_RATE_MASK == 0x0f);
	return typed_rates[zd_rate & ZD_CS_RATE_MASK];
}
예제 #25
0
파일: zd_chip.c 프로젝트: 020gzh/linux
static int _zd_iowrite32v_async_locked(struct zd_chip *chip,
				       const struct zd_ioreq32 *ioreqs,
				       unsigned int count)
{
	int i, j, r;
	struct zd_ioreq16 ioreqs16[USB_MAX_IOWRITE32_COUNT * 2];
	unsigned int count16;

	/* Use stack for values and addresses. */

	ZD_ASSERT(mutex_is_locked(&chip->mutex));

	if (count == 0)
		return 0;
	if (count > USB_MAX_IOWRITE32_COUNT)
		return -EINVAL;

	count16 = 2 * count;
	BUG_ON(count16 * sizeof(struct zd_ioreq16) > sizeof(ioreqs16));

	for (i = 0; i < count; i++) {
		j = 2*i;
		/* We write the high word always first. */
		ioreqs16[j].value   = ioreqs[i].value >> 16;
		ioreqs16[j].addr    = inc_addr(ioreqs[i].addr);
		ioreqs16[j+1].value = ioreqs[i].value;
		ioreqs16[j+1].addr  = ioreqs[i].addr;
	}

	r = zd_usb_iowrite16v_async(&chip->usb, ioreqs16, count16);
#ifdef DEBUG
	if (r) {
		dev_dbg_f(zd_chip_dev(chip),
			  "error %d in zd_usb_write16v\n", r);
	}
#endif /* DEBUG */
	return r;
}
예제 #26
0
파일: zd_mac.c 프로젝트: Tigrouzen/k1099
int zd_mac_init_hw(struct ieee80211_hw *hw)
{
	int r;
	struct zd_mac *mac = zd_hw_mac(hw);
	struct zd_chip *chip = &mac->chip;
	u8 default_regdomain;

	r = zd_chip_enable_int(chip);
	if (r)
		goto out;
	r = zd_chip_init_hw(chip);
	if (r)
		goto disable_int;

	ZD_ASSERT(!irqs_disabled());

	r = zd_read_regdomain(chip, &default_regdomain);
	if (r)
		goto disable_int;
	spin_lock_irq(&mac->lock);
	mac->regdomain = mac->default_regdomain = default_regdomain;
	spin_unlock_irq(&mac->lock);

	/* We must inform the device that we are doing encryption/decryption in
	 * software at the moment. */
	r = zd_set_encryption_type(chip, ENC_SNIFFER);
	if (r)
		goto disable_int;

	zd_geo_init(hw, mac->regdomain);

	r = 0;
disable_int:
	zd_chip_disable_int(chip);
out:
	return r;
}
예제 #27
0
static inline void handle_regs_int(struct urb *urb)
{
    struct zd_usb *usb = urb->context;
    struct zd_usb_interrupt *intr = &usb->intr;
    int len;

    ZD_ASSERT(in_interrupt());
    spin_lock(&intr->lock);

    if (intr->read_regs_enabled) {
        intr->read_regs.length = len = urb->actual_length;

        if (len > sizeof(intr->read_regs.buffer))
            len = sizeof(intr->read_regs.buffer);
        memcpy(intr->read_regs.buffer, urb->transfer_buffer, len);
        intr->read_regs_enabled = 0;
        complete(&intr->read_regs.completion);
        goto out;
    }

    dev_dbg_f(urb_dev(urb), "regs interrupt ignored\n");
out:
    spin_unlock(&intr->lock);
}
예제 #28
0
int zd_usb_enable_int(struct zd_usb *usb)
{
    int r;
    struct usb_device *udev;
    struct zd_usb_interrupt *intr = &usb->intr;
    void *transfer_buffer = NULL;
    struct urb *urb;

    dev_dbg_f(zd_usb_dev(usb), "\n");

    urb = usb_alloc_urb(0, GFP_KERNEL);
    if (!urb) {
        r = -ENOMEM;
        goto out;
    }

    ZD_ASSERT(!irqs_disabled());
    spin_lock_irq(&intr->lock);
    if (intr->urb) {
        spin_unlock_irq(&intr->lock);
        r = 0;
        goto error_free_urb;
    }
    intr->urb = urb;
    spin_unlock_irq(&intr->lock);

    /* TODO: make it a DMA buffer */
    r = -ENOMEM;
    transfer_buffer = kmalloc(USB_MAX_EP_INT_BUFFER, GFP_KERNEL);
    if (!transfer_buffer) {
        dev_dbg_f(zd_usb_dev(usb),
                  "couldn't allocate transfer_buffer\n");
        goto error_set_urb_null;
    }

    udev = zd_usb_to_usbdev(usb);
    usb_fill_int_urb(urb, udev, usb_rcvintpipe(udev, EP_INT_IN),
                     transfer_buffer, USB_MAX_EP_INT_BUFFER,
                     int_urb_complete, usb,
                     intr->interval);

    dev_dbg_f(zd_usb_dev(usb), "submit urb %p\n", intr->urb);
    r = usb_submit_urb(urb, GFP_KERNEL);
    if (r) {
        dev_dbg_f(zd_usb_dev(usb),
                  "Couldn't submit urb. Error number %d\n", r);
        goto error;
    }

    return 0;
error:
    kfree(transfer_buffer);
error_set_urb_null:
    spin_lock_irq(&intr->lock);
    intr->urb = NULL;
    spin_unlock_irq(&intr->lock);
error_free_urb:
    usb_free_urb(urb);
out:
    return r;
}
예제 #29
0
static int fill_ctrlset(struct zd_mac *mac,
	                struct ieee80211_txb *txb,
			int frag_num)
{
	int r;
	struct sk_buff *skb = txb->fragments[frag_num];
	struct ieee80211_hdr_4addr *hdr =
		(struct ieee80211_hdr_4addr *) skb->data;
	unsigned int frag_len = skb->len + IEEE80211_FCS_LEN;
	unsigned int next_frag_len;
	unsigned int packet_length;
	struct zd_ctrlset *cs = (struct zd_ctrlset *)
		skb_push(skb, sizeof(struct zd_ctrlset));

	if (frag_num+1  < txb->nr_frags) {
		next_frag_len = txb->fragments[frag_num+1]->len +
			        IEEE80211_FCS_LEN;
	} else {
		next_frag_len = 0;
	}
	ZD_ASSERT(frag_len <= 0xffff);
	ZD_ASSERT(next_frag_len <= 0xffff);

	cs_set_modulation(mac, cs, hdr);

	cs->tx_length = cpu_to_le16(frag_len);

	cs_set_control(mac, cs, hdr);

	packet_length = frag_len + sizeof(struct zd_ctrlset) + 10;
	ZD_ASSERT(packet_length <= 0xffff);
	/* ZD1211B: Computing the length difference this way, gives us
	 * flexibility to compute the packet length.
	 */
	cs->packet_length = cpu_to_le16(mac->chip.is_zd1211b ?
			packet_length - frag_len : packet_length);

	/*
	 * CURRENT LENGTH:
	 * - transmit frame length in microseconds
	 * - seems to be derived from frame length
	 * - see Cal_Us_Service() in zdinlinef.h
	 * - if macp->bTxBurstEnable is enabled, then multiply by 4
	 *  - bTxBurstEnable is never set in the vendor driver
	 *
	 * SERVICE:
	 * - "for PLCP configuration"
	 * - always 0 except in some situations at 802.11b 11M
	 * - see line 53 of zdinlinef.h
	 */
	cs->service = 0;
	r = zd_calc_tx_length_us(&cs->service, ZD_CS_RATE(cs->modulation),
		                 le16_to_cpu(cs->tx_length));
	if (r < 0)
		return r;
	cs->current_length = cpu_to_le16(r);

	if (next_frag_len == 0) {
		cs->next_frame_length = 0;
	} else {
		r = zd_calc_tx_length_us(NULL, ZD_CS_RATE(cs->modulation),
			                 next_frag_len);
		if (r < 0)
			return r;
		cs->next_frame_length = cpu_to_le16(r);
	}

	return 0;
}
예제 #30
0
int zd_usb_enable_int(struct zd_usb *usb)
{
	int r;
	struct usb_device *udev = zd_usb_to_usbdev(usb);
	struct zd_usb_interrupt *intr = &usb->intr;
	struct urb *urb;

	dev_dbg_f(zd_usb_dev(usb), "\n");

	urb = usb_alloc_urb(0, GFP_KERNEL);
	if (!urb) {
		r = -ENOMEM;
		goto out;
	}

	ZD_ASSERT(!irqs_disabled());
	spin_lock_irq(&intr->lock);
	if (intr->urb) {
		spin_unlock_irq(&intr->lock);
		r = 0;
		goto error_free_urb;
	}
	intr->urb = urb;
	spin_unlock_irq(&intr->lock);

	r = -ENOMEM;
	intr->buffer = usb_alloc_coherent(udev, USB_MAX_EP_INT_BUFFER,
					  GFP_KERNEL, &intr->buffer_dma);
	if (!intr->buffer) {
		dev_dbg_f(zd_usb_dev(usb),
			"couldn't allocate transfer_buffer\n");
		goto error_set_urb_null;
	}

	usb_fill_int_urb(urb, udev, usb_rcvintpipe(udev, EP_INT_IN),
			 intr->buffer, USB_MAX_EP_INT_BUFFER,
			 int_urb_complete, usb,
			 intr->interval);
	urb->transfer_dma = intr->buffer_dma;
	urb->transfer_flags |= URB_NO_TRANSFER_DMA_MAP;

	dev_dbg_f(zd_usb_dev(usb), "submit urb %p\n", intr->urb);
	r = usb_submit_urb(urb, GFP_KERNEL);
	if (r) {
		dev_dbg_f(zd_usb_dev(usb),
			 "Couldn't submit urb. Error number %d\n", r);
		goto error;
	}

	return 0;
error:
	usb_free_coherent(udev, USB_MAX_EP_INT_BUFFER,
			  intr->buffer, intr->buffer_dma);
error_set_urb_null:
	spin_lock_irq(&intr->lock);
	intr->urb = NULL;
	spin_unlock_irq(&intr->lock);
error_free_urb:
	usb_free_urb(urb);
out:
	return r;
}