static int ipw_send_associate(struct ipw_priv *priv,
struct ipw_associate *associate)
{
- struct ipw_associate tmp_associate;
-
if (!priv || !associate) {
IPW_ERROR("Invalid args\n");
return -1;
}
- memcpy(&tmp_associate, associate, sizeof(*associate));
- tmp_associate.policy_support =
- cpu_to_le16(tmp_associate.policy_support);
- tmp_associate.assoc_tsf_msw = cpu_to_le32(tmp_associate.assoc_tsf_msw);
- tmp_associate.assoc_tsf_lsw = cpu_to_le32(tmp_associate.assoc_tsf_lsw);
- tmp_associate.capability = cpu_to_le16(tmp_associate.capability);
- tmp_associate.listen_interval =
- cpu_to_le16(tmp_associate.listen_interval);
- tmp_associate.beacon_interval =
- cpu_to_le16(tmp_associate.beacon_interval);
- tmp_associate.atim_window = cpu_to_le16(tmp_associate.atim_window);
-
- return ipw_send_cmd_pdu(priv, IPW_CMD_ASSOCIATE, sizeof(tmp_associate),
- &tmp_associate);
+ return ipw_send_cmd_pdu(priv, IPW_CMD_ASSOCIATE, sizeof(*associate),
+ associate);
}
static int ipw_send_supported_rates(struct ipw_priv *priv,
/* Set us so that we have processed and used all buffers, but have
* not restocked the Rx queue with fresh buffers */
rxq->read = rxq->write = 0;
- rxq->processed = RX_QUEUE_SIZE - 1;
rxq->free_count = 0;
spin_unlock_irqrestore(&rxq->lock, flags);
}
* Driver allocates buffers of this size for Rx
*/
-static inline int ipw_queue_space(const struct clx2_queue *q)
+/**
+ * ipw_rx_queue_space - Return number of free slots available in queue.
+ */
+static int ipw_rx_queue_space(const struct ipw_rx_queue *q)
+{
+ int s = q->read - q->write;
+ if (s <= 0)
+ s += RX_QUEUE_SIZE;
+ /* keep some buffer to not confuse full and empty queue */
+ s -= 2;
+ if (s < 0)
+ s = 0;
+ return s;
+}
+
+static inline int ipw_tx_queue_space(const struct clx2_queue *q)
{
int s = q->last_used - q->first_empty;
if (s <= 0)
priv->last_missed_beacons = priv->missed_beacons;
if (priv->assoc_request.beacon_interval) {
missed_beacons_percent = missed_beacons_delta *
- (HZ * priv->assoc_request.beacon_interval) /
+ (HZ * le16_to_cpu(priv->assoc_request.beacon_interval)) /
(IPW_STATS_INTERVAL * 10);
} else {
missed_beacons_percent = 0;
workqueue,
&priv->
adhoc_check,
- priv->
+ le16_to_cpu(priv->
assoc_request.
- beacon_interval);
+ beacon_interval));
break;
}
priv->
essid_len),
print_mac(mac, priv->bssid),
- ntohs(auth->status),
+ le16_to_cpu(auth->status),
ipw_get_status_code
- (ntohs
+ (le16_to_cpu
(auth->status)));
priv->status &=
IPW_DL_STATE |
IPW_DL_ASSOC,
"association failed (0x%04X): %s\n",
- ntohs(resp->status),
+ le16_to_cpu(resp->status),
ipw_get_status_code
- (ntohs
+ (le16_to_cpu
(resp->status)));
}
IPW_DEBUG(IPW_DL_NOTIF | IPW_DL_STATE |
IPW_DL_ASSOC,
"authentication failed (0x%04X): %s\n",
- ntohs(auth->status),
- ipw_get_status_code(ntohs
+ le16_to_cpu(auth->status),
+ ipw_get_status_code(le16_to_cpu
(auth->
status)));
}
priv->tx_packets++;
}
done:
- if ((ipw_queue_space(q) > q->low_mark) &&
+ if ((ipw_tx_queue_space(q) > q->low_mark) &&
(qindex >= 0) &&
(priv->status & STATUS_ASSOCIATED) && netif_running(priv->net_dev))
netif_wake_queue(priv->net_dev);
struct clx2_queue *q = &txq->q;
struct tfd_frame *tfd;
- if (ipw_queue_space(q) < (sync ? 1 : 2)) {
+ if (ipw_tx_queue_space(q) < (sync ? 1 : 2)) {
IPW_ERROR("No space for Tx\n");
return -EBUSY;
}
spin_lock_irqsave(&rxq->lock, flags);
write = rxq->write;
- while ((rxq->write != rxq->processed) && (rxq->free_count)) {
+ while ((ipw_rx_queue_space(rxq) > 0) && (rxq->free_count)) {
element = rxq->rx_free.next;
rxb = list_entry(element, struct ipw_rx_mem_buffer, list);
list_del(element);
/* Set us so that we have processed and used all buffers, but have
* not restocked the Rx queue with fresh buffers */
rxq->read = rxq->write = 0;
- rxq->processed = RX_QUEUE_SIZE - 1;
rxq->free_count = 0;
return rxq;
}
queue_delayed_work(priv->workqueue, &priv->adhoc_check,
- priv->assoc_request.beacon_interval);
+ le16_to_cpu(priv->assoc_request.beacon_interval));
}
static void ipw_bg_adhoc_check(struct work_struct *work)
priv->assoc_request.auth_type = AUTH_OPEN;
if (priv->ieee->wpa_ie_len) {
- priv->assoc_request.policy_support = 0x02; /* RSN active */
+ priv->assoc_request.policy_support = cpu_to_le16(0x02); /* RSN active */
ipw_set_rsn_capa(priv, priv->ieee->wpa_ie,
priv->ieee->wpa_ie_len);
}
else if (network->mode & priv->ieee->mode & IEEE_B)
priv->assoc_request.ieee_mode = IPW_B_MODE;
- priv->assoc_request.capability = network->capability;
+ priv->assoc_request.capability = cpu_to_le16(network->capability);
if ((network->capability & WLAN_CAPABILITY_SHORT_PREAMBLE)
&& !(priv->config & CFG_PREAMBLE_LONG)) {
priv->assoc_request.preamble_length = DCT_FLAG_SHORT_PREAMBLE;
/* Clear the short preamble if we won't be supporting it */
priv->assoc_request.capability &=
- ~WLAN_CAPABILITY_SHORT_PREAMBLE;
+ ~cpu_to_le16(WLAN_CAPABILITY_SHORT_PREAMBLE);
}
/* Clear capability bits that aren't used in Ad Hoc */
if (priv->ieee->iw_mode == IW_MODE_ADHOC)
priv->assoc_request.capability &=
- ~WLAN_CAPABILITY_SHORT_SLOT_TIME;
+ ~cpu_to_le16(WLAN_CAPABILITY_SHORT_SLOT_TIME);
IPW_DEBUG_ASSOC("%sssocation attempt: '%s', channel %d, "
"802.11%c [%d], %s[:%s], enc=%s%s%s%c%c\n",
'1' + priv->ieee->sec.active_key : '.',
priv->capability & CAP_PRIVACY_ON ? '.' : ' ');
- priv->assoc_request.beacon_interval = network->beacon_interval;
+ priv->assoc_request.beacon_interval = cpu_to_le16(network->beacon_interval);
if ((priv->ieee->iw_mode == IW_MODE_ADHOC) &&
(network->time_stamp[0] == 0) && (network->time_stamp[1] == 0)) {
priv->assoc_request.assoc_type = HC_IBSS_START;
priv->assoc_request.assoc_type = HC_REASSOCIATE;
else
priv->assoc_request.assoc_type = HC_ASSOCIATE;
- priv->assoc_request.assoc_tsf_msw = network->time_stamp[1];
- priv->assoc_request.assoc_tsf_lsw = network->time_stamp[0];
+ priv->assoc_request.assoc_tsf_msw = cpu_to_le32(network->time_stamp[1]);
+ priv->assoc_request.assoc_tsf_lsw = cpu_to_le32(network->time_stamp[0]);
}
memcpy(priv->assoc_request.bssid, network->bssid, ETH_ALEN);
if (priv->ieee->iw_mode == IW_MODE_ADHOC) {
memset(&priv->assoc_request.dest, 0xFF, ETH_ALEN);
- priv->assoc_request.atim_window = network->atim_window;
+ priv->assoc_request.atim_window = cpu_to_le16(network->atim_window);
} else {
memcpy(priv->assoc_request.dest, network->bssid, ETH_ALEN);
priv->assoc_request.atim_window = 0;
}
- priv->assoc_request.listen_interval = network->listen_interval;
+ priv->assoc_request.listen_interval = cpu_to_le16(network->listen_interval);
err = ipw_send_ssid(priv, priv->essid, priv->essid_len);
if (err) {
struct ieee80211_hdr_4addr *header;
u32 r, w, i;
u8 network_packet;
+ u8 fill_rx = 0;
DECLARE_MAC_BUF(mac);
DECLARE_MAC_BUF(mac2);
DECLARE_MAC_BUF(mac3);
r = ipw_read32(priv, IPW_RX_READ_INDEX);
w = ipw_read32(priv, IPW_RX_WRITE_INDEX);
- i = (priv->rxq->processed + 1) % RX_QUEUE_SIZE;
+ i = priv->rxq->read;
+
+ if (ipw_rx_queue_space (priv->rxq) > (RX_QUEUE_SIZE / 2))
+ fill_rx = 1;
while (i != r) {
rxb = priv->rxq->queue[i];
list_add_tail(&rxb->list, &priv->rxq->rx_used);
i = (i + 1) % RX_QUEUE_SIZE;
+
+ /* If there are a lot of unsued frames, restock the Rx queue
+ * so the ucode won't assert */
+ if (fill_rx) {
+ priv->rxq->read = i;
+ ipw_rx_queue_replenish(priv);
+ }
}
/* Backtrack one entry */
- priv->rxq->processed = (i ? i : RX_QUEUE_SIZE) - 1;
-
+ priv->rxq->read = i;
ipw_rx_queue_restock(priv);
}
u8 id, hdr_len, unicast;
u16 remaining_bytes;
int fc;
- DECLARE_MAC_BUF(mac);
hdr_len = ieee80211_get_hdrlen(le16_to_cpu(hdr->frame_ctl));
switch (priv->ieee->iw_mode) {
id = ipw_add_station(priv, hdr->addr1);
if (id == IPW_INVALID_STATION) {
IPW_WARNING("Attempt to send data to "
- "invalid cell: %s\n",
- print_mac(mac, hdr->addr1));
+ "invalid cell: " MAC_FMT "\n",
+ hdr->addr1[0], hdr->addr1[1],
+ hdr->addr1[2], hdr->addr1[3],
+ hdr->addr1[4], hdr->addr1[5]);
goto drop;
}
}
remaining_bytes,
PCI_DMA_TODEVICE));
- tfd->u.data.num_chunks =
- cpu_to_le32(le32_to_cpu(tfd->u.data.num_chunks) +
- 1);
+ le32_add_cpu(&tfd->u.data.num_chunks, 1);
}
}
q->first_empty = ipw_queue_inc_wrap(q->first_empty, q->n_bd);
ipw_write32(priv, q->reg_w, q->first_empty);
- if (ipw_queue_space(q) < q->high_mark)
+ if (ipw_tx_queue_space(q) < q->high_mark)
netif_stop_queue(priv->net_dev);
return NETDEV_TX_OK;
struct clx2_tx_queue *txq = &priv->txq[0];
#endif /* CONFIG_IPW2200_QOS */
- if (ipw_queue_space(&txq->q) < txq->q.high_mark)
+ if (ipw_tx_queue_space(&txq->q) < txq->q.high_mark)
return 1;
return 0;
#if 0
if ((priv->status & (STATUS_ASSOCIATED | STATUS_ASSOCIATING)) &&
(((priv->assoc_request.capability &
- WLAN_CAPABILITY_PRIVACY) && !sec->enabled) ||
+ cpu_to_le16(WLAN_CAPABILITY_PRIVACY)) && !sec->enabled) ||
(!(priv->assoc_request.capability &
- WLAN_CAPABILITY_PRIVACY) && sec->enabled))) {
+ cpu_to_le16(WLAN_CAPABILITY_PRIVACY)) && sec->enabled))) {
IPW_DEBUG_ASSOC("Disassociating due to capability "
"change.\n");
ipw_disassociate(priv);
priv->prom_priv->priv = priv;
strcpy(priv->prom_net_dev->name, "rtap%d");
+ memcpy(priv->prom_net_dev->dev_addr, priv->mac_addr, ETH_ALEN);
priv->prom_net_dev->type = ARPHRD_IEEE80211_RADIOTAP;
priv->prom_net_dev->open = ipw_prom_open;