Exemplo n.º 1
0
static int carl9170_led_register_led(struct ar9170 *ar, int i, char *name,
                                     char *trigger)
{
    int err;

    snprintf(ar->leds[i].name, sizeof(ar->leds[i].name),
             "carl9170-%s::%s", wiphy_name(ar->hw->wiphy), name);

    ar->leds[i].ar = ar;
    ar->leds[i].l.name = ar->leds[i].name;
    ar->leds[i].l.brightness_set = carl9170_led_set_brightness;
    ar->leds[i].l.brightness = 0;
    ar->leds[i].l.default_trigger = trigger;

    err = led_classdev_register(wiphy_dev(ar->hw->wiphy),
                                &ar->leds[i].l);
    if (err) {
        wiphy_err(ar->hw->wiphy, "failed to register %s LED (%d).\n",
                  ar->leds[i].name, err);
    } else {
        ar->leds[i].registered = true;
    }

    return err;
}
Exemplo n.º 2
0
static void ieee80211_key_disable_hw_accel(struct ieee80211_key *key)
{
	struct ieee80211_sub_if_data *sdata;
	struct sta_info *sta;
	int ret;

	might_sleep();

	if (!key || !key->local->ops->set_key)
		return;

	assert_key_lock(key->local);

	if (!(key->flags & KEY_FLAG_UPLOADED_TO_HARDWARE))
		return;

	sta = key->sta;
	sdata = key->sdata;

	if (!((key->conf.flags & IEEE80211_KEY_FLAG_GENERATE_MMIC) ||
	      (key->conf.flags & IEEE80211_KEY_FLAG_GENERATE_IV) ||
	      (key->conf.flags & IEEE80211_KEY_FLAG_PUT_IV_SPACE)))
		increment_tailroom_need_count(sdata);

	ret = drv_set_key(key->local, DISABLE_KEY, sdata,
			  sta ? &sta->sta : NULL, &key->conf);

	if (ret)
		wiphy_err(key->local->hw.wiphy,
			  "failed to remove key (%d, %pM) from hardware (%d)\n",
			  key->conf.keyidx,
			  sta ? sta->sta.addr : bcast_addr, ret);

	key->flags &= ~KEY_FLAG_UPLOADED_TO_HARDWARE;
}
Exemplo n.º 3
0
/*
 * precondition: perimeter lock has been acquired
 */
int brcms_ucode_init_buf(struct brcms_info *wl, void **pbuf, u32 idx)
{
	int i, entry;
	const u8 *pdata;
	struct firmware_hdr *hdr;
	for (i = 0; i < wl->fw.fw_cnt; i++) {
		hdr = (struct firmware_hdr *)wl->fw.fw_hdr[i]->data;
		for (entry = 0; entry < wl->fw.hdr_num_entries[i];
		     entry++, hdr++) {
			u32 len = le32_to_cpu(hdr->len);
			if (le32_to_cpu(hdr->idx) == idx) {
				pdata = wl->fw.fw_bin[i]->data +
					le32_to_cpu(hdr->offset);
				*pbuf = kmalloc(len, GFP_ATOMIC);
				if (*pbuf == NULL)
					goto fail;

				memcpy(*pbuf, pdata, len);
				return 0;
			}
		}
	}
	wiphy_err(wl->wiphy, "ERROR: ucode buf tag:%d can not be found!\n",
		  idx);
	*pbuf = NULL;
fail:
	return -ENODATA;
}
Exemplo n.º 4
0
/*
 * CFG802.11 operation handler to join an IBSS.
 *
 * This function does not work in any mode other than Ad-Hoc, or if
 * a join operation is already in progress.
 */
static int
mwifiex_cfg80211_join_ibss(struct wiphy *wiphy, struct net_device *dev,
			   struct cfg80211_ibss_params *params)
{
	struct mwifiex_private *priv = mwifiex_cfg80211_get_priv(wiphy);
	int ret = 0;

	if (priv->ibss_join_request)
		return -EBUSY;

	if (priv->bss_mode != NL80211_IFTYPE_ADHOC) {
		wiphy_err(wiphy, "request to join ibss received "
				"when station is not in ibss mode\n");
		goto done;
	}

	priv->ibss_join_request = -EINPROGRESS;

	wiphy_dbg(wiphy, "info: trying to join to %s and bssid %pM\n",
	       (char *) params->ssid, params->bssid);

	ret = mwifiex_cfg80211_assoc(priv, params->ssid_len, params->ssid,
				params->bssid, priv->bss_mode,
				params->channel, NULL, params->privacy);

	priv->ibss_join_request = 1;
done:
	priv->ibss_join_result = ret;
	queue_work(priv->workqueue, &priv->cfg_workqueue);
	return ret;
}
Exemplo n.º 5
0
/*
 * CFG802.11 operation handler for association request.
 *
 * This function does not work when the current mode is set to Ad-Hoc, or
 * when there is already an association procedure going on. The given BSS
 * information is used to associate.
 */
static int
mwifiex_cfg80211_connect(struct wiphy *wiphy, struct net_device *dev,
			 struct cfg80211_connect_params *sme)
{
	struct mwifiex_private *priv = mwifiex_netdev_get_priv(dev);
	int ret = 0;

	if (priv->assoc_request)
		return -EBUSY;

	if (priv->bss_mode == NL80211_IFTYPE_ADHOC) {
		wiphy_err(wiphy, "received infra assoc request "
				"when station is in ibss mode\n");
		goto done;
	}

	priv->assoc_request = -EINPROGRESS;

	wiphy_dbg(wiphy, "info: Trying to associate to %s and bssid %pM\n",
	       (char *) sme->ssid, sme->bssid);

	ret = mwifiex_cfg80211_assoc(priv, sme->ssid_len, sme->ssid, sme->bssid,
				     priv->bss_mode, sme->channel, sme, 0);

	priv->assoc_request = 1;
done:
	priv->assoc_result = ret;
	queue_work(priv->workqueue, &priv->cfg_workqueue);
	return ret;
}
Exemplo n.º 6
0
Arquivo: cmd.c Projeto: 03199618/linux
int carl9170_read_mreg(struct ar9170 *ar, const int nregs,
		       const u32 *regs, u32 *out)
{
	int i, err;
	__le32 *offs, *res;

	/* abuse "out" for the register offsets, must be same length */
	offs = (__le32 *)out;
	for (i = 0; i < nregs; i++)
		offs[i] = cpu_to_le32(regs[i]);

	/* also use the same buffer for the input */
	res = (__le32 *)out;

	err = carl9170_exec_cmd(ar, CARL9170_CMD_RREG,
				4 * nregs, (u8 *)offs,
				4 * nregs, (u8 *)res);
	if (err) {
		if (net_ratelimit()) {
			wiphy_err(ar->hw->wiphy, "reading regs failed (%d)\n",
				  err);
		}
		return err;
	}

	/* convert result to cpu endian */
	for (i = 0; i < nregs; i++)
		out[i] = le32_to_cpu(res[i]);

	return 0;
}
Exemplo n.º 7
0
static const struct country_info *
brcms_c_countrycode_map(struct brcms_cm_info *wlc_cm, const char *ccode,
			char *mapped_ccode, uint *mapped_regrev)
{
	struct brcms_c_info *wlc = wlc_cm->wlc;
	const struct country_info *country;
	uint srom_regrev = wlc_cm->srom_regrev;
	const char *srom_ccode = wlc_cm->srom_ccode;
	int mapped;

	/* check for currently supported ccode size */
	if (strlen(ccode) > (BRCM_CNTRY_BUF_SZ - 1)) {
		wiphy_err(wlc->wiphy, "wl%d: %s: ccode \"%s\" too long for "
			  "match\n", wlc->pub->unit, __func__, ccode);
		return NULL;
	}

	/* default mapping is the given ccode and regrev 0 */
	strncpy(mapped_ccode, ccode, BRCM_CNTRY_BUF_SZ);
	*mapped_regrev = 0;

	/* If the desired country code matches the srom country code,
	 * then the mapped country is the srom regulatory rev.
	 * Otherwise look for an aggregate mapping.
	 */
	if (!strcmp(srom_ccode, ccode)) {
		*mapped_regrev = srom_regrev;
		mapped = 0;
		wiphy_err(wlc->wiphy, "srom_code == ccode %s\n", __func__);
	} else {
		mapped =
		    brcms_c_country_aggregate_map(wlc_cm, ccode, mapped_ccode,
					      mapped_regrev);
	}

	/* find the matching built-in country definition */
	country = brcms_c_country_lookup_direct(mapped_ccode, *mapped_regrev);

	/* if there is not an exact rev match, default to rev zero */
	if (country == NULL && *mapped_regrev != 0) {
		*mapped_regrev = 0;
		country =
		    brcms_c_country_lookup_direct(mapped_ccode, *mapped_regrev);
	}

	return country;
}
Exemplo n.º 8
0
static int p54p_open(struct ieee80211_hw *dev)
{
	struct p54p_priv *priv = dev->priv;
	int err;

	init_completion(&priv->boot_comp);
	err = request_irq(priv->pdev->irq, p54p_interrupt,
			  IRQF_SHARED, "p54pci", dev);
	if (err) {
		dev_err(&priv->pdev->dev, "failed to register IRQ handler\n");
		return err;
	}

	memset(priv->ring_control, 0, sizeof(*priv->ring_control));
	err = p54p_upload_firmware(dev);
	if (err) {
		free_irq(priv->pdev->irq, dev);
		return err;
	}
	priv->rx_idx_data = priv->tx_idx_data = 0;
	priv->rx_idx_mgmt = priv->tx_idx_mgmt = 0;

	p54p_refill_rx_ring(dev, 0, priv->ring_control->rx_data,
		ARRAY_SIZE(priv->ring_control->rx_data), priv->rx_buf_data, 0);

	p54p_refill_rx_ring(dev, 2, priv->ring_control->rx_mgmt,
		ARRAY_SIZE(priv->ring_control->rx_mgmt), priv->rx_buf_mgmt, 0);

	P54P_WRITE(ring_control_base, cpu_to_le32(priv->ring_control_dma));
	P54P_READ(ring_control_base);
	wmb();
	udelay(10);

	P54P_WRITE(int_enable, cpu_to_le32(ISL38XX_INT_IDENT_INIT));
	P54P_READ(int_enable);
	wmb();
	udelay(10);

	P54P_WRITE(dev_int, cpu_to_le32(ISL38XX_DEV_INT_RESET));
	P54P_READ(dev_int);

	if (!wait_for_completion_interruptible_timeout(&priv->boot_comp, HZ)) {
		wiphy_err(dev->wiphy, "Cannot boot firmware!\n");
		p54p_stop(dev);
		return -ETIMEDOUT;
	}

	P54P_WRITE(int_enable, cpu_to_le32(ISL38XX_INT_IDENT_UPDATE));
	P54P_READ(int_enable);
	wmb();
	udelay(10);

	P54P_WRITE(dev_int, cpu_to_le32(ISL38XX_DEV_INT_UPDATE));
	P54P_READ(dev_int);
	wmb();
	udelay(10);

	return 0;
}
Exemplo n.º 9
0
static int mwifiex_process_country_ie(struct mwifiex_private *priv,
				      struct cfg80211_bss *bss)
{
	const u8 *country_ie;
	u8 country_ie_len;
	struct mwifiex_802_11d_domain_reg *domain_info =
					&priv->adapter->domain_reg;

	rcu_read_lock();
	country_ie = ieee80211_bss_get_ie(bss, WLAN_EID_COUNTRY);
	if (!country_ie) {
		rcu_read_unlock();
		return 0;
	}

	country_ie_len = country_ie[1];
	if (country_ie_len < IEEE80211_COUNTRY_IE_MIN_LEN) {
		rcu_read_unlock();
		return 0;
	}

	if (!strncmp(priv->adapter->country_code, &country_ie[2], 2)) {
		rcu_read_unlock();
		wiphy_dbg(priv->wdev->wiphy,
			  "11D: skip setting domain info in FW\n");
		return 0;
	}
	memcpy(priv->adapter->country_code, &country_ie[2], 2);

	domain_info->country_code[0] = country_ie[2];
	domain_info->country_code[1] = country_ie[3];
	domain_info->country_code[2] = ' ';

	country_ie_len -= IEEE80211_COUNTRY_STRING_LEN;

	domain_info->no_of_triplet =
		country_ie_len / sizeof(struct ieee80211_country_ie_triplet);

	memcpy((u8 *)domain_info->triplet,
	       &country_ie[2] + IEEE80211_COUNTRY_STRING_LEN, country_ie_len);

	rcu_read_unlock();

	if (mwifiex_send_cmd(priv, HostCmd_CMD_802_11D_DOMAIN_INFO,
			     HostCmd_ACT_GEN_SET, 0, NULL, false)) {
		wiphy_err(priv->adapter->wiphy,
			  "11D: setting domain info in FW\n");
		return -1;
	}

	mwifiex_dnld_txpwr_table(priv);

	return 0;
}
Exemplo n.º 10
0
static void
wl_ops_sta_notify(struct ieee80211_hw *hw, struct ieee80211_vif *vif,
		  enum sta_notify_cmd cmd, struct ieee80211_sta *sta)
{
	switch (cmd) {
	default:
		wiphy_err(hw->wiphy, "%s: Unknown cmd = %d\n", __func__,
			  cmd);
		break;
	}
	return;
}
Exemplo n.º 11
0
/* Update the radio state (enable/disable) and tx power targets
 * based on a new set of channel/regulatory information
 */
static void brcms_c_channels_commit(struct brcms_cm_info *wlc_cm)
{
	struct brcms_c_info *wlc = wlc_cm->wlc;
	uint chan;
	struct txpwr_limits txpwr;

	/* search for the existence of any valid channel */
	for (chan = 0; chan < MAXCHANNEL; chan++) {
		if (brcms_c_valid_channel20_db(wlc->cmi, chan))
			break;
	}
	if (chan == MAXCHANNEL)
		chan = INVCHANNEL;

	/*
	 * based on the channel search above, set or
	 * clear WL_RADIO_COUNTRY_DISABLE.
	 */
	if (chan == INVCHANNEL) {
		/*
		 * country/locale with no valid channels, set
		 * the radio disable bit
		 */
		mboolset(wlc->pub->radio_disabled, WL_RADIO_COUNTRY_DISABLE);
		wiphy_err(wlc->wiphy, "wl%d: %s: no valid channel for \"%s\" "
			  "nbands %d bandlocked %d\n", wlc->pub->unit,
			  __func__, wlc_cm->country_abbrev, wlc->pub->_nbands,
			  wlc->bandlocked);
	} else if (mboolisset(wlc->pub->radio_disabled,
			      WL_RADIO_COUNTRY_DISABLE)) {
		/*
		 * country/locale with valid channel, clear
		 * the radio disable bit
		 */
		mboolclr(wlc->pub->radio_disabled, WL_RADIO_COUNTRY_DISABLE);
	}

	/*
	 * Now that the country abbreviation is set, if the radio supports 2G,
	 * then set channel 14 restrictions based on the new locale.
	 */
	if (wlc->pub->_nbands > 1 || wlc->band->bandtype == BRCM_BAND_2G)
		wlc_phy_chanspec_ch14_widefilter_set(wlc->band->pi,
						     brcms_c_japan(wlc) ? true :
						     false);

	if (wlc->pub->up && chan != INVCHANNEL) {
		brcms_c_channel_reg_limits(wlc_cm, wlc->chanspec, &txpwr);
		brcms_c_channel_min_txpower_limits_with_local_constraint(wlc_cm,
			&txpwr, BRCMS_TXPWR_MAX);
		wlc_phy_txpower_limit_set(wlc->band->pi, &txpwr, wlc->chanspec);
	}
}
Exemplo n.º 12
0
static void
wl_ops_configure_filter(struct ieee80211_hw *hw,
			unsigned int changed_flags,
			unsigned int *total_flags, u64 multicast)
{
	struct wl_info *wl = hw->priv;
	struct wiphy *wiphy = hw->wiphy;

	changed_flags &= MAC_FILTERS;
	*total_flags &= MAC_FILTERS;
	if (changed_flags & FIF_PROMISC_IN_BSS)
		wiphy_err(wiphy, "FIF_PROMISC_IN_BSS\n");
	if (changed_flags & FIF_ALLMULTI)
		wiphy_err(wiphy, "FIF_ALLMULTI\n");
	if (changed_flags & FIF_FCSFAIL)
		wiphy_err(wiphy, "FIF_FCSFAIL\n");
	if (changed_flags & FIF_PLCPFAIL)
		wiphy_err(wiphy, "FIF_PLCPFAIL\n");
	if (changed_flags & FIF_CONTROL)
		wiphy_err(wiphy, "FIF_CONTROL\n");
	if (changed_flags & FIF_OTHER_BSS)
		wiphy_err(wiphy, "FIF_OTHER_BSS\n");
	if (changed_flags & FIF_BCN_PRBRESP_PROMISC) {
		WL_LOCK(wl);
		if (*total_flags & FIF_BCN_PRBRESP_PROMISC) {
			wl->pub->mac80211_state |= MAC80211_PROMISC_BCNS;
			wlc_mac_bcn_promisc_change(wl->wlc, 1);
		} else {
			wlc_mac_bcn_promisc_change(wl->wlc, 0);
			wl->pub->mac80211_state &= ~MAC80211_PROMISC_BCNS;
		}
		WL_UNLOCK(wl);
	}
	return;
}
Exemplo n.º 13
0
/*
 * CFG802.11 operation handler for association request.
 *
 * This function does not work when the current mode is set to Ad-Hoc, or
 * when there is already an association procedure going on. The given BSS
 * information is used to associate.
 */
static int
mwifiex_cfg80211_connect(struct wiphy *wiphy, struct net_device *dev,
			 struct cfg80211_connect_params *sme)
{
	struct mwifiex_private *priv = mwifiex_netdev_get_priv(dev);
	int ret = 0;

	if (priv->bss_mode == NL80211_IFTYPE_ADHOC) {
		wiphy_err(wiphy, "received infra assoc request "
				"when station is in ibss mode\n");
		goto done;
	}

	if (priv->bss_mode == NL80211_IFTYPE_AP) {
		wiphy_err(wiphy, "skip association request for AP interface\n");
		goto done;
	}

	wiphy_dbg(wiphy, "info: Trying to associate to %s and bssid %pM\n",
		  (char *) sme->ssid, sme->bssid);

	ret = mwifiex_cfg80211_assoc(priv, sme->ssid_len, sme->ssid, sme->bssid,
				     priv->bss_mode, sme->channel, sme, 0);
done:
	if (!ret) {
		cfg80211_connect_result(priv->netdev, priv->cfg_bssid, NULL, 0,
					NULL, 0, WLAN_STATUS_SUCCESS,
					GFP_KERNEL);
		dev_dbg(priv->adapter->dev,
			"info: associated to bssid %pM successfully\n",
			priv->cfg_bssid);
	} else {
		dev_dbg(priv->adapter->dev,
			"info: association to bssid %pM failed\n",
			priv->cfg_bssid);
		memset(priv->cfg_bssid, 0, ETH_ALEN);
	}

	return ret;
}
Exemplo n.º 14
0
/*
 * CFG802.11 operation handler to delete a network key.
 */
static int
mwifiex_cfg80211_del_key(struct wiphy *wiphy, struct net_device *netdev,
			 u8 key_index, bool pairwise, const u8 *mac_addr)
{
	struct mwifiex_private *priv = mwifiex_cfg80211_get_priv(wiphy);

	if (mwifiex_set_encode(priv, NULL, 0, key_index, 1)) {
		wiphy_err(wiphy, "deleting the crypto keys\n");
		return -EFAULT;
	}

	wiphy_dbg(wiphy, "info: crypto keys deleted\n");
	return 0;
}
Exemplo n.º 15
0
static void brcms_ops_tx(struct ieee80211_hw *hw, struct sk_buff *skb)
{
	struct brcms_info *wl = hw->priv;

	spin_lock_bh(&wl->lock);
	if (!wl->pub->up) {
		wiphy_err(wl->wiphy, "ops->tx called while down\n");
		kfree_skb(skb);
		goto done;
	}
	brcms_c_sendpkt_mac80211(wl->wlc, skb, hw);
 done:
	spin_unlock_bh(&wl->lock);
}
Exemplo n.º 16
0
static void wl_ops_tx(struct ieee80211_hw *hw, struct sk_buff *skb)
{
	struct wl_info *wl = hw->priv;

	WL_LOCK(wl);
	if (!wl->pub->up) {
		wiphy_err(wl->wiphy, "ops->tx called while down\n");
		kfree_skb(skb);
		goto done;
	}
	wlc_sendpkt_mac80211(wl->wlc, skb, hw);
 done:
	WL_UNLOCK(wl);
}
Exemplo n.º 17
0
/*
 * CFG802.11 operation handler to set channel.
 *
 * This function can only be used when station is not connected.
 */
static int
mwifiex_cfg80211_set_channel(struct wiphy *wiphy, struct net_device *dev,
			     struct ieee80211_channel *chan,
			     enum nl80211_channel_type channel_type)
{
	struct mwifiex_private *priv = mwifiex_cfg80211_get_priv(wiphy);

	if (priv->media_connected) {
		wiphy_err(wiphy, "This setting is valid only when station "
				"is not connected\n");
		return -EINVAL;
	}

	return mwifiex_set_rf_channel(priv, chan, channel_type);
}
Exemplo n.º 18
0
/*
 * CFG802.11 operation handler to add a network key.
 */
static int
mwifiex_cfg80211_add_key(struct wiphy *wiphy, struct net_device *netdev,
			 u8 key_index, bool pairwise, const u8 *mac_addr,
			 struct key_params *params)
{
	struct mwifiex_private *priv = mwifiex_cfg80211_get_priv(wiphy);

	if (mwifiex_set_encode(priv, params->key, params->key_len,
							key_index, 0)) {
		wiphy_err(wiphy, "crypto keys added\n");
		return -EFAULT;
	}

	return 0;
}
Exemplo n.º 19
0
/*
 * Precondition: Since this function is called in wl_pci_probe() context,
 * no locking is required.
 */
int wl_ucode_init_uint(struct wl_info *wl, u32 *data, u32 idx)
{
	int i, entry;
	const u8 *pdata;
	struct wl_fw_hdr *hdr;
	for (i = 0; i < wl->fw.fw_cnt; i++) {
		hdr = (struct wl_fw_hdr *)wl->fw.fw_hdr[i]->data;
		for (entry = 0; entry < wl->fw.hdr_num_entries[i];
		     entry++, hdr++) {
			if (hdr->idx == idx) {
				pdata = wl->fw.fw_bin[i]->data + hdr->offset;
				if (hdr->len != 4) {
					wiphy_err(wl->wiphy,
						  "ERROR: fw hdr len\n");
					return -ENOMSG;
				}
				*data = *((u32 *) pdata);
				return 0;
			}
		}
	}
	wiphy_err(wl->wiphy, "ERROR: ucode tag:%d can not be found!\n", idx);
	return -ENOMSG;
}
Exemplo n.º 20
0
/* BMAC_NOTE: Add timer adds only the kernel timer since it's going to be more accurate
 * as well as it's easier to make it periodic
 *
 * precondition: perimeter lock has been acquired
 */
void wl_add_timer(struct wl_info *wl, struct wl_timer *t, uint ms, int periodic)
{
#ifdef BCMDBG
	if (t->set) {
		wiphy_err(wl->wiphy, "%s: Already set. Name: %s, per %d\n",
			  __func__, t->name, periodic);
	}
#endif
	t->ms = ms;
	t->periodic = (bool) periodic;
	t->set = true;
	t->timer.expires = jiffies + ms * HZ / 1000;

	atomic_inc(&wl->callbacks);
	add_timer(&t->timer);
}
Exemplo n.º 21
0
struct phy_shim_info *wlc_phy_shim_attach(struct brcms_hardware *wlc_hw,
						       void *wl, void *wlc) {
	struct phy_shim_info *physhim = NULL;

	physhim = kzalloc(sizeof(struct phy_shim_info), GFP_ATOMIC);
	if (!physhim) {
		wiphy_err(wlc_hw->wlc->wiphy,
			  "wl%d: wlc_phy_shim_attach: out of mem\n",
			  wlc_hw->unit);
		return NULL;
	}
	physhim->wlc_hw = wlc_hw;
	physhim->wlc = wlc;
	physhim->wl = wl;

	return physhim;
}
Exemplo n.º 22
0
static int
brcms_ops_add_interface(struct ieee80211_hw *hw, struct ieee80211_vif *vif)
{
	struct brcms_info *wl = hw->priv;

	/* Just STA for now */
	if (vif->type != NL80211_IFTYPE_STATION) {
		wiphy_err(hw->wiphy, "%s: Attempt to add type %d, only"
			  " STA for now\n", __func__, vif->type);
		return -EOPNOTSUPP;
	}

	wl->mute_tx = false;
	brcms_c_mute(wl->wlc, false);

	return 0;
}
Exemplo n.º 23
0
static int pcie_tx_ring_alloc_ndp(struct mwl_priv *priv)
{
	struct pcie_priv *pcie_priv = priv->hif.priv;
	struct pcie_desc_data_ndp *desc = &pcie_priv->desc_data_ndp;
	u8 *mem;

	mem = dma_alloc_coherent(priv->dev,
				 MAX_NUM_TX_RING_BYTES,
				 &desc->pphys_tx_ring,
				 GFP_KERNEL);
	if (!mem)
		goto err_no_mem;
	desc->ptx_ring = (struct pcie_tx_desc_ndp *)mem;
	memset(desc->ptx_ring, 0x00, MAX_NUM_TX_RING_BYTES);

	mem = dma_alloc_coherent(priv->dev,
				 MAX_NUM_TX_RING_DONE_BYTES,
				 &desc->pphys_tx_ring_done,
				 GFP_KERNEL);
	if (!mem)
		goto err_no_mem;
	desc->ptx_ring_done = (struct tx_ring_done *)mem;
	memset(desc->ptx_ring_done, 0x00, MAX_NUM_TX_RING_DONE_BYTES);

	mem = dma_alloc_coherent(priv->dev,
				 DEFAULT_ACNT_RING_SIZE,
				 &desc->pphys_acnt_ring,
				 GFP_KERNEL);
	if (!mem)
		goto err_no_mem;
	desc->pacnt_ring = (u8 *)mem;
	memset(desc->pacnt_ring, 0x00, DEFAULT_ACNT_RING_SIZE);

	desc->pacnt_buf = kzalloc(DEFAULT_ACNT_RING_SIZE, GFP_KERNEL);
	if (!desc->pacnt_buf)
		goto err_no_mem;
	desc->acnt_ring_size = DEFAULT_ACNT_RING_SIZE;

	return 0;

err_no_mem:

	wiphy_err(priv->hw->wiphy, "cannot alloc mem\n");

	return -ENOMEM;
}
Exemplo n.º 24
0
/*
 * adds only the kernel timer since it's going to be more accurate
 * as well as it's easier to make it periodic
 *
 * precondition: perimeter lock has been acquired
 */
void brcms_add_timer(struct brcms_timer *t, uint ms, int periodic)
{
	struct ieee80211_hw *hw = t->wl->pub->ieee_hw;

#ifdef DEBUG
	if (t->set)
		wiphy_err(hw->wiphy, "%s: Already set. Name: %s, per %d\n",
			  __func__, t->name, periodic);
#endif
	t->ms = ms;
	t->periodic = (bool) periodic;
	t->set = true;

	atomic_inc(&t->wl->callbacks);

	ieee80211_queue_delayed_work(hw, &t->dly_wrk, msecs_to_jiffies(ms));
}
Exemplo n.º 25
0
/*
 * CFG802.11 operation handler to add a network key.
 */
static int
mwifiex_cfg80211_add_key(struct wiphy *wiphy, struct net_device *netdev,
			 u8 key_index, bool pairwise, const u8 *mac_addr,
			 struct key_params *params)
{
	struct mwifiex_private *priv = mwifiex_netdev_get_priv(netdev);
	const u8 bc_mac[] = {0xff, 0xff, 0xff, 0xff, 0xff, 0xff};
	const u8 *peer_mac = pairwise ? mac_addr : bc_mac;

	if (mwifiex_set_encode(priv, params->key, params->key_len,
			       key_index, peer_mac, 0)) {
		wiphy_err(wiphy, "crypto keys added\n");
		return -EFAULT;
	}

	return 0;
}
Exemplo n.º 26
0
int carl9170_write_reg(struct ar9170 *ar, const u32 reg, const u32 val)
{
	const __le32 buf[2] = {
		cpu_to_le32(reg),
		cpu_to_le32(val),
	};
	int err;

	err = carl9170_exec_cmd(ar, CARL9170_CMD_WREG, sizeof(buf),
				(u8 *) buf, 0, NULL);
	if (err) {
		if (net_ratelimit()) {
			wiphy_err(ar->hw->wiphy, "writing reg %#x "
				"(val %#x) failed (%d)\n", reg, val, err);
		}
	}
	return err;
}
Exemplo n.º 27
0
static void brcms_ops_tx(struct ieee80211_hw *hw,
                         struct ieee80211_tx_control *control,
                         struct sk_buff *skb)
{
    struct brcms_info *wl = hw->priv;
    struct ieee80211_tx_info *tx_info = IEEE80211_SKB_CB(skb);

    spin_lock_bh(&wl->lock);
    if (!wl->pub->up) {
        wiphy_err(wl->wiphy, "ops->tx called while down\n");
        kfree_skb(skb);
        goto done;
    }
    if (brcms_c_sendpkt_mac80211(wl->wlc, skb, hw))
        tx_info->rate_driver_data[0] = control->sta;
done:
    spin_unlock_bh(&wl->lock);
}
Exemplo n.º 28
0
/*
 * CFG802.11 operation handler to set the default network key.
 */
static int
mwifiex_cfg80211_set_default_key(struct wiphy *wiphy, struct net_device *netdev,
				 u8 key_index, bool unicast,
				 bool multicast)
{
	struct mwifiex_private *priv = mwifiex_netdev_get_priv(netdev);

	/* Return if WEP key not configured */
	if (!priv->sec_info.wep_enabled)
		return 0;

	if (mwifiex_set_encode(priv, NULL, 0, key_index, NULL, 0)) {
		wiphy_err(wiphy, "set default Tx key index\n");
		return -EFAULT;
	}

	return 0;
}
Exemplo n.º 29
0
/*
 * CFG802.11 operation handler to change interface type.
 */
static int
mwifiex_cfg80211_change_virtual_intf(struct wiphy *wiphy,
				     struct net_device *dev,
				     enum nl80211_iftype type, u32 *flags,
				     struct vif_params *params)
{
	int ret;
	struct mwifiex_private *priv = mwifiex_netdev_get_priv(dev);

	if (priv->bss_mode == type) {
		wiphy_warn(wiphy, "already set to required type\n");
		return 0;
	}

	priv->bss_mode = type;

	switch (type) {
	case NL80211_IFTYPE_ADHOC:
		dev->ieee80211_ptr->iftype = NL80211_IFTYPE_ADHOC;
		wiphy_dbg(wiphy, "info: setting interface type to adhoc\n");
		break;
	case NL80211_IFTYPE_STATION:
		dev->ieee80211_ptr->iftype = NL80211_IFTYPE_STATION;
		wiphy_dbg(wiphy, "info: setting interface type to managed\n");
		break;
	case NL80211_IFTYPE_UNSPECIFIED:
		dev->ieee80211_ptr->iftype = NL80211_IFTYPE_STATION;
		wiphy_dbg(wiphy, "info: setting interface type to auto\n");
		return 0;
	default:
		wiphy_err(wiphy, "unknown interface type: %d\n", type);
		return -EINVAL;
	}

	mwifiex_deauthenticate(priv, NULL);

	priv->sec_info.authentication_mode = NL80211_AUTHTYPE_OPEN_SYSTEM;

	ret = mwifiex_send_cmd_sync(priv, HostCmd_CMD_SET_BSS_MODE,
				    HostCmd_ACT_GEN_SET, 0, NULL);

	return ret;
}
Exemplo n.º 30
0
static int mwl_tx_ring_init(struct mwl_priv *priv)
{
	int num, i;
	struct mwl_desc_data *desc;

	for (num = 0; num < SYSADPT_NUM_OF_DESC_DATA; num++) {
		skb_queue_head_init(&priv->txq[num]);
		priv->fw_desc_cnt[num] = 0;

		desc = &priv->desc_data[num];

		if (desc->ptx_ring) {
			for (i = 0; i < SYSADPT_MAX_NUM_TX_DESC; i++) {
				desc->ptx_ring[i].status =
					cpu_to_le32(EAGLE_TXD_STATUS_IDLE);
				desc->ptx_ring[i].pphys_next =
					cpu_to_le32((u32)desc->pphys_tx_ring +
					((i + 1) * sizeof(struct mwl_tx_desc)));
				desc->tx_hndl[i].pdesc =
					&desc->ptx_ring[i];
				if (i < SYSADPT_MAX_NUM_TX_DESC - 1)
					desc->tx_hndl[i].pnext =
						&desc->tx_hndl[i + 1];
			}
			desc->ptx_ring[SYSADPT_MAX_NUM_TX_DESC - 1].pphys_next =
				cpu_to_le32((u32)desc->pphys_tx_ring);
			desc->tx_hndl[SYSADPT_MAX_NUM_TX_DESC - 1].pnext =
				&desc->tx_hndl[0];

			desc->pstale_tx_hndl = &desc->tx_hndl[0];
			desc->pnext_tx_hndl  = &desc->tx_hndl[0];
		} else {
			wiphy_err(priv->hw->wiphy, "no valid TX mem\n");
			return -ENOMEM;
		}
	}

	return 0;
}