2014-06-25 20:15:08

by Malcolm Priestley

[permalink] [raw]
Subject: [PATCH 00/17] staging: vt6656: conversion to mac80211

The patches in this series convert the driver to mac80211.

As well as infrastructure mode the driver now operates in
IBSS and access point modes.

Host access point is now working with hostapd in nl80211 mode.

These patches creates huge amount of dead code.

The driver nolonger supports WEP 256 mode due to no support in
mac80211. The vendors code had removed support for this in their
last version anyway.

Malcolm Priestley (17):
staging: vt6656: mac80211 conversion: create rx function.
staging: vt6656: mac80211 conversion: Create tx functions
staging: vt6656: mac80211 conversion: add key functions
staging: vt6656: mac80211 conversion: main_usb add functions and
change usb_driver functions
staging: vt6656: mac80211 conversion: add channel bands
staging: vt6656: mac80211 conversion: add vnt_init to bScheduleCommand
staging: vt6656: mac80211 conversion: vnt_update_ifs change basic
rates
staging: vt6656: mac80211 conversion: enable power saving
staging: vt6656: mac80211 conversion: vRunCommand change beacon
staging: vt6656: mac80211 conversion: change vnt_next_tbtt_wakeup
staging: vt6656: mac80211 conversion: int.c changes
staging: vt6656: mac80211 conversion: vRunCommand channel changes
staging: vt6656: mac80211 conversion: move data rates to device.h
staging: vt6656: mac80211 conversion: change vnt_rf_set_txpower
staging: vt6656: vnt_mac_set_keyentry remove byLocalID check
staging: vt6656: mac80211 conversion: device_alloc_bufs use dev_err
staging: vt6656: mac80211 conversion: rxtx implement power save poll

drivers/staging/vt6656/Kconfig | 2 +-
drivers/staging/vt6656/card.c | 22 +-
drivers/staging/vt6656/channel.c | 139 +++++++++
drivers/staging/vt6656/channel.h | 2 +
drivers/staging/vt6656/datarate.h | 14 -
drivers/staging/vt6656/device.h | 31 +-
drivers/staging/vt6656/dpc.c | 137 +++++++-
drivers/staging/vt6656/dpc.h | 3 +
drivers/staging/vt6656/int.c | 49 +--
drivers/staging/vt6656/key.c | 143 +++++++++
drivers/staging/vt6656/key.h | 13 +
drivers/staging/vt6656/mac.c | 4 -
drivers/staging/vt6656/main_usb.c | 640 +++++++++++++++++++++++++++++++-------
drivers/staging/vt6656/power.c | 47 +--
drivers/staging/vt6656/rf.c | 23 +-
drivers/staging/vt6656/rxtx.c | 462 +++++++++++++++++++++++++--
drivers/staging/vt6656/rxtx.h | 7 +-
drivers/staging/vt6656/usbpipe.c | 32 +-
drivers/staging/vt6656/wcmd.c | 34 +-
drivers/staging/vt6656/wcmd.h | 2 +
20 files changed, 1506 insertions(+), 300 deletions(-)

--
1.9.1



2014-06-25 20:15:44

by Malcolm Priestley

[permalink] [raw]
Subject: [PATCH 17/17] staging: vt6656: mac80211 conversion: rxtx implement power save poll

Signed-off-by: Malcolm Priestley <[email protected]>
---
drivers/staging/vt6656/rxtx.c | 25 ++++++++++++++++++++++---
1 file changed, 22 insertions(+), 3 deletions(-)

diff --git a/drivers/staging/vt6656/rxtx.c b/drivers/staging/vt6656/rxtx.c
index 7f7c13a..c3d4778 100644
--- a/drivers/staging/vt6656/rxtx.c
+++ b/drivers/staging/vt6656/rxtx.c
@@ -492,6 +492,8 @@ static u16 vnt_rxtx_datahead_g(struct vnt_usb_send_context *tx_context,
{

struct vnt_private *priv = tx_context->priv;
+ struct ieee80211_hdr *hdr =
+ (struct ieee80211_hdr *)tx_context->skb->data;

/* Get SignalField,ServiceField,Length */
vnt_get_phy_field(priv, frame_len, rate, pkt_type, &buf->a);
@@ -499,8 +501,16 @@ static u16 vnt_rxtx_datahead_g(struct vnt_usb_send_context *tx_context,
PK_TYPE_11B, &buf->b);

/* Get Duration and TimeStamp */
- buf->duration_a = s_uGetDataDuration(priv, pkt_type, need_ack);
- buf->duration_b = s_uGetDataDuration(priv, PK_TYPE_11B, need_ack);
+ if (ieee80211_is_pspoll(hdr->frame_control)) {
+ __le16 dur = cpu_to_le16(priv->current_aid | BIT(14) | BIT(15));
+
+ buf->duration_a = dur;
+ buf->duration_b = dur;
+ } else {
+ buf->duration_a = s_uGetDataDuration(priv, pkt_type, need_ack);
+ buf->duration_b = s_uGetDataDuration(priv,
+ PK_TYPE_11B, need_ack);
+ }

buf->time_stamp_off_a = vnt_time_stamp_off(priv, rate);
buf->time_stamp_off_b = vnt_time_stamp_off(priv,
@@ -565,11 +575,20 @@ static u16 vnt_rxtx_datahead_ab(struct vnt_usb_send_context *tx_context,
u32 frame_len, int need_ack)
{
struct vnt_private *priv = tx_context->priv;
+ struct ieee80211_hdr *hdr =
+ (struct ieee80211_hdr *)tx_context->skb->data;

/* Get SignalField,ServiceField,Length */
vnt_get_phy_field(priv, frame_len, rate, pkt_type, &buf->ab);
+
/* Get Duration and TimeStampOff */
- buf->duration = s_uGetDataDuration(priv, pkt_type, need_ack);
+ if (ieee80211_is_pspoll(hdr->frame_control)) {
+ __le16 dur = cpu_to_le16(priv->current_aid | BIT(14) | BIT(15));
+
+ buf->duration = dur;
+ } else {
+ buf->duration = s_uGetDataDuration(priv, pkt_type, need_ack);
+ }

buf->time_stamp_off = vnt_time_stamp_off(priv, rate);

--
1.9.1


2014-06-27 04:09:03

by Greg Kroah-Hartman

[permalink] [raw]
Subject: Re: [PATCH 00/17] staging: vt6656: conversion to mac80211

On Thu, Jun 26, 2014 at 08:29:38AM +0200, Johannes Berg wrote:
> On Wed, 2014-06-25 at 21:14 +0100, Malcolm Priestley wrote:
> > The patches in this series convert the driver to mac80211.
>
> Impressive! I didn't think it was actually *possible* to convert a
> driver, I used to think a rewrite with selective copy/pasting would be
> the right approach :-)

I agree, very nice job with all of this, great to see this happen.

greg k-h

2014-06-25 20:15:37

by Malcolm Priestley

[permalink] [raw]
Subject: [PATCH 13/17] staging: vt6656: mac80211 conversion: move data rates to device.h

Move all RATE_* macros to device.h

Signed-off-by: Malcolm Priestley <[email protected]>
---
drivers/staging/vt6656/datarate.h | 14 --------------
drivers/staging/vt6656/device.h | 14 ++++++++++++++
2 files changed, 14 insertions(+), 14 deletions(-)

diff --git a/drivers/staging/vt6656/datarate.h b/drivers/staging/vt6656/datarate.h
index 96252ad..19b2c66 100644
--- a/drivers/staging/vt6656/datarate.h
+++ b/drivers/staging/vt6656/datarate.h
@@ -39,20 +39,6 @@
#define RETRY_TIMES_THRD_H 2 /* times */
#define RETRY_TIMES_THRD_L 1 /* times */

-#define RATE_1M 0
-#define RATE_2M 1
-#define RATE_5M 2
-#define RATE_11M 3
-#define RATE_6M 4
-#define RATE_9M 5
-#define RATE_12M 6
-#define RATE_18M 7
-#define RATE_24M 8
-#define RATE_36M 9
-#define RATE_48M 10
-#define RATE_54M 11
-#define RATE_AUTO 12
-
void RATEvParseMaxRate(struct vnt_private *, PWLAN_IE_SUPP_RATES pItemRates,
PWLAN_IE_SUPP_RATES pItemExtRates, int bUpdateBasicRate,
u16 *pwMaxBasicRate, u16 *pwMaxSuppRate, u16 *pwSuppRate,
diff --git a/drivers/staging/vt6656/device.h b/drivers/staging/vt6656/device.h
index 2bd9830..6696365 100644
--- a/drivers/staging/vt6656/device.h
+++ b/drivers/staging/vt6656/device.h
@@ -53,6 +53,20 @@
#undef DEVICE_ETHTOOL_IOCTL_SUPPORT
#endif

+#define RATE_1M 0
+#define RATE_2M 1
+#define RATE_5M 2
+#define RATE_11M 3
+#define RATE_6M 4
+#define RATE_9M 5
+#define RATE_12M 6
+#define RATE_18M 7
+#define RATE_24M 8
+#define RATE_36M 9
+#define RATE_48M 10
+#define RATE_54M 11
+#define RATE_AUTO 12
+
#define MAX_RATE 12

/*
--
1.9.1


2014-06-25 20:15:13

by Malcolm Priestley

[permalink] [raw]
Subject: [PATCH 02/17] staging: vt6656: mac80211 conversion: Create tx functions

Create vnt_fill_txkey as mac80211 replacement for s_vFillTxKey.

Create vnt_tx_packet which a merger of s_bPacketToWirelessUsb, nsDMA_tx_packet
and csMgmt_xmit using mac80211 signalling.

Create vnt_beacon_xmit as mac80211 replacement for csBeacon_xmit. Changing
header in vnt_beacon_buffer to struct ieee80211_mgmt deleting some of
old code. vnt_beacon_make is needed to make beacon for vnt_beacon_xmit.

Create vnt_beacon_enable as mac80211 call to enable beacon.

vnt_fill_ieee80211_rts is modified to use struct ieee80211_hdr instead of
struct ethhdr and access to tx_context.

In s_nsBulkOutIoCompleteWrite modify context handling

Signed-off-by: Malcolm Priestley <[email protected]>

---
drivers/staging/vt6656/device.h | 3 +-
drivers/staging/vt6656/rxtx.c | 437 ++++++++++++++++++++++++++++++++++++---
drivers/staging/vt6656/rxtx.h | 7 +-
drivers/staging/vt6656/usbpipe.c | 28 +--
4 files changed, 432 insertions(+), 43 deletions(-)

diff --git a/drivers/staging/vt6656/device.h b/drivers/staging/vt6656/device.h
index 631f402..23fc5e2 100644
--- a/drivers/staging/vt6656/device.h
+++ b/drivers/staging/vt6656/device.h
@@ -223,7 +223,8 @@ struct vnt_rsp_card_init {
*/
enum {
CONTEXT_DATA_PACKET = 1,
- CONTEXT_MGMT_PACKET
+ CONTEXT_MGMT_PACKET,
+ CONTEXT_BEACON_PACKET
};

/* RCB (Receive Control Block) */
diff --git a/drivers/staging/vt6656/rxtx.c b/drivers/staging/vt6656/rxtx.c
index 3c19288..7f7c13a 100644
--- a/drivers/staging/vt6656/rxtx.c
+++ b/drivers/staging/vt6656/rxtx.c
@@ -578,24 +578,18 @@ static u16 vnt_rxtx_datahead_ab(struct vnt_usb_send_context *tx_context,
return le16_to_cpu(buf->duration);
}

-static int vnt_fill_ieee80211_rts(struct vnt_private *priv,
- struct ieee80211_rts *rts, struct ethhdr *eth_hdr,
- __le16 duration)
+static int vnt_fill_ieee80211_rts(struct vnt_usb_send_context *tx_context,
+ struct ieee80211_rts *rts, __le16 duration)
{
+ struct ieee80211_hdr *hdr =
+ (struct ieee80211_hdr *)tx_context->skb->data;
+
rts->duration = duration;
rts->frame_control =
cpu_to_le16(IEEE80211_FTYPE_CTL | IEEE80211_STYPE_RTS);

- if (priv->op_mode == NL80211_IFTYPE_ADHOC ||
- priv->op_mode == NL80211_IFTYPE_AP)
- memcpy(rts->ra, eth_hdr->h_dest, ETH_ALEN);
- else
- memcpy(rts->ra, priv->abyBSSID, ETH_ALEN);
-
- if (priv->op_mode == NL80211_IFTYPE_AP)
- memcpy(rts->ta, priv->abyBSSID, ETH_ALEN);
- else
- memcpy(rts->ta, eth_hdr->h_source, ETH_ALEN);
+ memcpy(rts->ra, hdr->addr1, ETH_ALEN);
+ memcpy(rts->ta, hdr->addr2, ETH_ALEN);

return 0;
}
@@ -620,7 +614,7 @@ static u16 vnt_rxtx_rts_g_head(struct vnt_usb_send_context *tx_context,
buf->duration_ba = s_uGetRTSCTSDuration(priv, RTSDUR_BA, frame_len,
pkt_type, current_rate, need_ack, fb_option);

- vnt_fill_ieee80211_rts(priv, &buf->data, eth_hdr, buf->duration_aa);
+ vnt_fill_ieee80211_rts(tx_context, &buf->data, buf->duration_aa);

return vnt_rxtx_datahead_g(tx_context, pkt_type, current_rate,
&buf->data_head, frame_len, need_ack);
@@ -657,7 +651,7 @@ static u16 vnt_rxtx_rts_g_fb_head(struct vnt_usb_send_context *tx_context,
buf->rts_duration_aa_f1 = s_uGetRTSCTSDuration(priv, RTSDUR_AA_F1,
frame_len, pkt_type, priv->tx_rate_fb1, need_ack, fb_option);

- vnt_fill_ieee80211_rts(priv, &buf->data, eth_hdr, buf->duration_aa);
+ vnt_fill_ieee80211_rts(tx_context, &buf->data, buf->duration_aa);

return vnt_rxtx_datahead_g_fb(tx_context, pkt_type, current_rate,
&buf->data_head, frame_len, need_ack);
@@ -677,7 +671,7 @@ static u16 vnt_rxtx_rts_ab_head(struct vnt_usb_send_context *tx_context,
buf->duration = s_uGetRTSCTSDuration(priv, RTSDUR_AA, frame_len,
pkt_type, current_rate, need_ack, fb_option);

- vnt_fill_ieee80211_rts(priv, &buf->data, eth_hdr, buf->duration);
+ vnt_fill_ieee80211_rts(tx_context, &buf->data, buf->duration);

return vnt_rxtx_datahead_ab(tx_context, pkt_type, current_rate,
&buf->data_head, frame_len, need_ack);
@@ -703,7 +697,7 @@ static u16 vnt_rxtx_rts_a_fb_head(struct vnt_usb_send_context *tx_context,
buf->rts_duration_f1 = s_uGetRTSCTSDuration(priv, RTSDUR_AA_F1,
frame_len, pkt_type, priv->tx_rate_fb1, need_ack, fb_option);

- vnt_fill_ieee80211_rts(priv, &buf->data, eth_hdr, buf->duration);
+ vnt_fill_ieee80211_rts(tx_context, &buf->data, buf->duration);

return vnt_rxtx_datahead_a_fb(tx_context, pkt_type, current_rate,
&buf->data_head, frame_len, need_ack);
@@ -1626,7 +1620,6 @@ CMD_STATUS csBeacon_xmit(struct vnt_private *pDevice,
struct vnt_tx_short_buf_head *short_head;
u32 cbFrameSize = pPacket->cbMPDULen + WLAN_FCS_LEN;
u32 cbHeaderSize = 0;
- struct ieee80211_hdr *pMACHeader;
u16 wCurrentRate;
u32 cbFrameBodySize;
u32 cbReqCount;
@@ -1676,12 +1669,6 @@ CMD_STATUS csBeacon_xmit(struct vnt_private *pDevice,


/* Generate Beacon Header */
- pMACHeader = &pTX_Buffer->hdr;
-
- memcpy(pMACHeader, pPacket->p80211Header, pPacket->cbMPDULen);
-
- pMACHeader->duration_id = 0;
- pMACHeader->seq_ctrl = cpu_to_le16(pDevice->wSeqCounter << 4);
pDevice->wSeqCounter++;
if (pDevice->wSeqCounter > 0x0fff)
pDevice->wSeqCounter = 0;
@@ -2067,3 +2054,405 @@ int nsDMA_tx_packet(struct vnt_private *pDevice, struct sk_buff *skb)

return 0;
}
+
+static void vnt_fill_txkey(struct vnt_usb_send_context *tx_context,
+ u8 *key_buffer, struct ieee80211_key_conf *tx_key, struct sk_buff *skb,
+ u16 payload_len, struct vnt_mic_hdr *mic_hdr)
+{
+ struct ieee80211_hdr *hdr = tx_context->hdr;
+ struct ieee80211_key_seq seq;
+ u8 *iv = ((u8 *)hdr + ieee80211_get_hdrlen_from_skb(skb));
+
+ /* strip header and icv len from payload */
+ payload_len -= ieee80211_get_hdrlen_from_skb(skb);
+ payload_len -= tx_key->icv_len;
+
+ switch (tx_key->cipher) {
+ case WLAN_CIPHER_SUITE_WEP40:
+ case WLAN_CIPHER_SUITE_WEP104:
+ memcpy(key_buffer, iv, 3);
+ memcpy(key_buffer + 3, tx_key->key, tx_key->keylen);
+
+ if (tx_key->keylen == WLAN_KEY_LEN_WEP40) {
+ memcpy(key_buffer + 8, iv, 3);
+ memcpy(key_buffer + 11,
+ tx_key->key, WLAN_KEY_LEN_WEP40);
+ }
+
+ break;
+ case WLAN_CIPHER_SUITE_TKIP:
+ ieee80211_get_tkip_p2k(tx_key, skb, key_buffer);
+
+ break;
+ case WLAN_CIPHER_SUITE_CCMP:
+
+ if (!mic_hdr)
+ return;
+
+ mic_hdr->id = 0x59;
+ mic_hdr->payload_len = cpu_to_be16(payload_len);
+ memcpy(mic_hdr->mic_addr2, hdr->addr2, ETH_ALEN);
+
+ ieee80211_get_key_tx_seq(tx_key, &seq);
+
+ mic_hdr->tsc_47_16 = cpu_to_be32((u32)seq.ccmp.pn[3] |
+ ((u32)seq.ccmp.pn[2] << 8) |
+ ((u32)seq.ccmp.pn[1] << 16) |
+ ((u32)seq.ccmp.pn[0] << 24));
+
+ mic_hdr->tsc_15_0 = cpu_to_be16((u16)seq.ccmp.pn[5] |
+ ((u16)seq.ccmp.pn[4] << 8));
+
+ if (ieee80211_has_a4(hdr->frame_control))
+ mic_hdr->hlen = cpu_to_be16(28);
+ else
+ mic_hdr->hlen = cpu_to_be16(22);
+
+ memcpy(mic_hdr->addr1, hdr->addr1, ETH_ALEN);
+ memcpy(mic_hdr->addr2, hdr->addr2, ETH_ALEN);
+ memcpy(mic_hdr->addr3, hdr->addr3, ETH_ALEN);
+
+ mic_hdr->frame_control = cpu_to_le16(
+ le16_to_cpu(hdr->frame_control) & 0xc78f);
+ mic_hdr->seq_ctrl = cpu_to_le16(
+ le16_to_cpu(hdr->seq_ctrl) & 0xf);
+
+ if (ieee80211_has_a4(hdr->frame_control))
+ memcpy(mic_hdr->addr4, hdr->addr4, ETH_ALEN);
+
+
+ memcpy(key_buffer, tx_key->key, WLAN_KEY_LEN_CCMP);
+
+ break;
+ default:
+ break;
+ }
+
+}
+
+int vnt_tx_packet(struct vnt_private *priv, struct sk_buff *skb)
+{
+ struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb);
+ struct ieee80211_tx_rate *tx_rate = &info->control.rates[0];
+ struct ieee80211_rate *rate;
+ struct ieee80211_key_conf *tx_key;
+ struct ieee80211_hdr *hdr;
+ struct vnt_mic_hdr *mic_hdr = NULL;
+ struct vnt_tx_buffer *tx_buffer;
+ struct vnt_tx_fifo_head *tx_buffer_head;
+ struct vnt_usb_send_context *tx_context;
+ unsigned long flags;
+ u32 frame_size = 0;
+ u16 tx_bytes, tx_header_size, tx_body_size, current_rate, duration_id;
+ u8 pkt_type, fb_option = AUTO_FB_NONE;
+ bool need_rts = false, need_ack = false, is_pspoll = false;
+ bool need_mic = false;
+
+ hdr = (struct ieee80211_hdr *)(skb->data);
+
+ rate = ieee80211_get_tx_rate(priv->hw, info);
+
+ current_rate = rate->hw_value;
+ if (priv->wCurrentRate != current_rate) {
+ priv->wCurrentRate = current_rate;
+ bScheduleCommand(priv, WLAN_CMD_SETPOWER, NULL);
+ }
+
+ if (current_rate > RATE_11M)
+ pkt_type = priv->byPacketType;
+ else
+ pkt_type = PK_TYPE_11B;
+
+ spin_lock_irqsave(&priv->lock, flags);
+
+ tx_context = s_vGetFreeContext(priv);
+ if (!tx_context) {
+ dev_dbg(&priv->usb->dev, "%s No free context\n", __func__);
+ spin_unlock_irqrestore(&priv->lock, flags);
+ return -ENOMEM;
+ }
+
+ tx_context->skb = skb;
+
+ spin_unlock_irqrestore(&priv->lock, flags);
+
+ tx_buffer = (struct vnt_tx_buffer *)tx_context->data;
+ tx_buffer_head = &tx_buffer->fifo_head;
+ tx_body_size = skb->len;
+
+ frame_size = tx_body_size + 4;
+
+ /* Set time stamp */
+ tx_buffer_head->time_stamp = cpu_to_le16(DEFAULT_MGN_LIFETIME_RES_64us);
+
+ /*Set fifo controls */
+ if (pkt_type == PK_TYPE_11A)
+ tx_buffer_head->wFIFOCtl = 0;
+ else if (pkt_type == PK_TYPE_11B)
+ tx_buffer_head->wFIFOCtl = FIFOCTL_11B;
+ else if (pkt_type == PK_TYPE_11GB)
+ tx_buffer_head->wFIFOCtl = FIFOCTL_11GB;
+ else if (pkt_type == PK_TYPE_11GA)
+ tx_buffer_head->wFIFOCtl = FIFOCTL_11GA;
+
+ if (!ieee80211_is_data(hdr->frame_control)) {
+ tx_buffer_head->wFIFOCtl |= (FIFOCTL_GENINT |
+ FIFOCTL_ISDMA0);
+ tx_buffer_head->wFIFOCtl |= FIFOCTL_TMOEN;
+
+ tx_buffer_head->time_stamp =
+ cpu_to_le16(DEFAULT_MGN_LIFETIME_RES_64us);
+ } else {
+ tx_buffer_head->time_stamp =
+ cpu_to_le16(DEFAULT_MSDU_LIFETIME_RES_64us);
+ }
+
+ if (!(info->flags & IEEE80211_TX_CTL_NO_ACK)) {
+ tx_buffer_head->wFIFOCtl |= FIFOCTL_NEEDACK;
+ need_ack = true;
+ }
+
+ if (ieee80211_has_retry(hdr->frame_control))
+ tx_buffer_head->wFIFOCtl |= FIFOCTL_LRETRY;
+
+ if (tx_rate->flags & IEEE80211_TX_RC_USE_SHORT_PREAMBLE)
+ priv->byPreambleType = PREAMBLE_SHORT;
+ else
+ priv->byPreambleType = PREAMBLE_LONG;
+
+ if (tx_rate->flags & IEEE80211_TX_RC_USE_RTS_CTS) {
+ need_rts = true;
+ tx_buffer_head->wFIFOCtl |= FIFOCTL_RTS;
+ }
+
+ if (ieee80211_has_a4(hdr->frame_control))
+ tx_buffer_head->wFIFOCtl |= FIFOCTL_LHEAD;
+
+ if (info->flags & IEEE80211_TX_CTL_NO_PS_BUFFER)
+ is_pspoll = true;
+
+ tx_buffer_head->wFragCtl =
+ cpu_to_le16(ieee80211_get_hdrlen_from_skb(skb)) << 10;
+
+ if (info->control.hw_key) {
+ tx_key = info->control.hw_key;
+ switch (info->control.hw_key->cipher) {
+ case WLAN_CIPHER_SUITE_WEP40:
+ case WLAN_CIPHER_SUITE_WEP104:
+ tx_buffer_head->wFragCtl |= FRAGCTL_LEGACY;
+ break;
+ case WLAN_CIPHER_SUITE_TKIP:
+ tx_buffer_head->wFragCtl |= FRAGCTL_TKIP;
+ break;
+ case WLAN_CIPHER_SUITE_CCMP:
+ tx_buffer_head->wFragCtl |= FRAGCTL_AES;
+ need_mic = true;
+ default:
+ break;
+ }
+ frame_size += tx_key->icv_len;
+ }
+
+ /* legacy rates TODO use ieee80211_tx_rate */
+ if (current_rate >= RATE_18M && ieee80211_is_data(hdr->frame_control)) {
+ if (priv->byAutoFBCtrl == AUTO_FB_0) {
+ tx_buffer_head->wFIFOCtl |= FIFOCTL_AUTO_FB_0;
+
+ priv->tx_rate_fb0 =
+ wFB_Opt0[FB_RATE0][current_rate - RATE_18M];
+ priv->tx_rate_fb1 =
+ wFB_Opt0[FB_RATE1][current_rate - RATE_18M];
+
+ fb_option = AUTO_FB_0;
+ } else if (priv->byAutoFBCtrl == AUTO_FB_1) {
+ tx_buffer_head->wFIFOCtl |= FIFOCTL_AUTO_FB_1;
+
+ priv->tx_rate_fb0 =
+ wFB_Opt1[FB_RATE0][current_rate - RATE_18M];
+ priv->tx_rate_fb1 =
+ wFB_Opt1[FB_RATE1][current_rate - RATE_18M];
+
+ fb_option = AUTO_FB_1;
+ }
+ }
+
+ duration_id = s_vGenerateTxParameter(tx_context, pkt_type, current_rate,
+ tx_buffer, &mic_hdr, need_mic, frame_size,
+ need_ack, NULL, need_rts);
+
+ tx_header_size = tx_context->tx_hdr_size;
+ if (!tx_header_size) {
+ tx_context->in_use = false;
+ return -ENOMEM;
+ }
+
+ tx_buffer_head->wFragCtl |= (u16)FRAGCTL_NONFRAG;
+
+ tx_bytes = tx_header_size + tx_body_size;
+
+ memcpy(tx_context->hdr, skb->data, tx_body_size);
+
+ hdr->duration_id = cpu_to_le16(duration_id);
+
+ if (info->control.hw_key) {
+ tx_key = info->control.hw_key;
+ if (tx_key->keylen > 0)
+ vnt_fill_txkey(tx_context, tx_buffer_head->tx_key,
+ tx_key, skb, tx_body_size, mic_hdr);
+ }
+
+ priv->wSeqCounter = (le16_to_cpu(hdr->seq_ctrl) &
+ IEEE80211_SCTL_SEQ) >> 4;
+
+ tx_buffer->tx_byte_count = cpu_to_le16(tx_bytes);
+ tx_buffer->byPKTNO = (u8)(((current_rate << 4) & 0xf0) |
+ (priv->wSeqCounter & 0xf));
+ tx_buffer->byType = 0x00;
+
+ tx_bytes += 4;
+
+ tx_context->type = CONTEXT_DATA_PACKET;
+ tx_context->buf_len = tx_bytes;
+
+ spin_lock_irqsave(&priv->lock, flags);
+
+ if (PIPEnsSendBulkOut(priv, tx_context) != STATUS_PENDING) {
+ spin_unlock_irqrestore(&priv->lock, flags);
+ return -EIO;
+ }
+
+ spin_unlock_irqrestore(&priv->lock, flags);
+
+ return 0;
+}
+
+static int vnt_beacon_xmit(struct vnt_private *priv,
+ struct sk_buff *skb)
+{
+ struct vnt_beacon_buffer *beacon_buffer;
+ struct vnt_tx_short_buf_head *short_head;
+ struct ieee80211_tx_info *info;
+ struct vnt_usb_send_context *context;
+ struct ieee80211_mgmt *mgmt_hdr;
+ unsigned long flags;
+ u32 frame_size = skb->len + 4;
+ u16 current_rate, count;
+
+ spin_lock_irqsave(&priv->lock, flags);
+
+ context = s_vGetFreeContext(priv);
+ if (!context) {
+ dev_dbg(&priv->usb->dev, "%s No free context!\n", __func__);
+ spin_unlock_irqrestore(&priv->lock, flags);
+ return -ENOMEM;
+ }
+
+ context->skb = skb;
+
+ spin_unlock_irqrestore(&priv->lock, flags);
+
+ beacon_buffer = (struct vnt_beacon_buffer *)&context->data[0];
+ short_head = &beacon_buffer->short_head;
+
+ if (priv->byBBType == BB_TYPE_11A) {
+ current_rate = RATE_6M;
+
+ /* Get SignalField,ServiceField,Length */
+ vnt_get_phy_field(priv, frame_size, current_rate,
+ PK_TYPE_11A, &short_head->ab);
+
+ /* Get Duration and TimeStampOff */
+ short_head->duration = s_uGetDataDuration(priv,
+ PK_TYPE_11A, false);
+ short_head->time_stamp_off =
+ vnt_time_stamp_off(priv, current_rate);
+ } else {
+ current_rate = RATE_1M;
+ short_head->fifo_ctl |= FIFOCTL_11B;
+
+ /* Get SignalField,ServiceField,Length */
+ vnt_get_phy_field(priv, frame_size, current_rate,
+ PK_TYPE_11B, &short_head->ab);
+
+ /* Get Duration and TimeStampOff */
+ short_head->duration = s_uGetDataDuration(priv,
+ PK_TYPE_11B, false);
+ short_head->time_stamp_off =
+ vnt_time_stamp_off(priv, current_rate);
+ }
+
+ /* Generate Beacon Header */
+ mgmt_hdr = &beacon_buffer->mgmt_hdr;
+ memcpy(mgmt_hdr, skb->data, skb->len);
+
+ /* time stamp always 0 */
+ mgmt_hdr->u.beacon.timestamp = 0;
+
+ info = IEEE80211_SKB_CB(skb);
+ if (info->flags & IEEE80211_TX_CTL_ASSIGN_SEQ) {
+ struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)mgmt_hdr;
+ hdr->duration_id = 0;
+ hdr->seq_ctrl = cpu_to_le16(priv->wSeqCounter << 4);
+ }
+
+ priv->wSeqCounter++;
+ if (priv->wSeqCounter > 0x0fff)
+ priv->wSeqCounter = 0;
+
+ count = sizeof(struct vnt_tx_short_buf_head) + skb->len;
+
+ beacon_buffer->tx_byte_count = cpu_to_le16(count);
+ beacon_buffer->byPKTNO = (u8)(((current_rate << 4) & 0xf0) |
+ ((priv->wSeqCounter - 1) & 0x000f));
+ beacon_buffer->byType = 0x01;
+
+ context->type = CONTEXT_BEACON_PACKET;
+ context->buf_len = count + 4; /* USB header */
+
+ spin_lock_irqsave(&priv->lock, flags);
+
+ if (PIPEnsSendBulkOut(priv, context) != STATUS_PENDING)
+ ieee80211_free_txskb(priv->hw, context->skb);
+
+ spin_unlock_irqrestore(&priv->lock, flags);
+
+ return 0;
+}
+
+int vnt_beacon_make(struct vnt_private *priv, struct ieee80211_vif *vif)
+{
+ struct sk_buff *beacon;
+
+ beacon = ieee80211_beacon_get(priv->hw, vif);
+ if (!beacon)
+ return -ENOMEM;
+
+ if (vnt_beacon_xmit(priv, beacon)) {
+ ieee80211_free_txskb(priv->hw, beacon);
+ return -ENODEV;
+ }
+
+ return 0;
+}
+
+int vnt_beacon_enable(struct vnt_private *priv, struct ieee80211_vif *vif,
+ struct ieee80211_bss_conf *conf)
+{
+ int ret;
+
+ vnt_mac_reg_bits_off(priv, MAC_REG_TCR, TCR_AUTOBCNTX);
+
+ vnt_mac_reg_bits_off(priv, MAC_REG_TFTCTL, TFTCTL_TSFCNTREN);
+
+ vnt_mac_set_beacon_interval(priv, conf->beacon_int);
+
+ vnt_clear_current_tsf(priv);
+
+ vnt_mac_reg_bits_on(priv, MAC_REG_TFTCTL, TFTCTL_TSFCNTREN);
+
+ vnt_reset_next_tbtt(priv, conf->beacon_int);
+
+ ret = vnt_beacon_make(priv, vif);
+
+ return ret;
+}
diff --git a/drivers/staging/vt6656/rxtx.h b/drivers/staging/vt6656/rxtx.h
index 95a4e2c..65f7e26 100644
--- a/drivers/staging/vt6656/rxtx.h
+++ b/drivers/staging/vt6656/rxtx.h
@@ -247,7 +247,7 @@ struct vnt_beacon_buffer {
u8 byPKTNO;
__le16 tx_byte_count;
struct vnt_tx_short_buf_head short_head;
- struct ieee80211_hdr hdr;
+ struct ieee80211_mgmt mgmt_hdr;
} __packed;

void vDMA0_tx_80211(struct vnt_private *, struct sk_buff *skb);
@@ -255,4 +255,9 @@ int nsDMA_tx_packet(struct vnt_private *, struct sk_buff *skb);
CMD_STATUS csMgmt_xmit(struct vnt_private *, struct vnt_tx_mgmt *);
CMD_STATUS csBeacon_xmit(struct vnt_private *, struct vnt_tx_mgmt *);

+int vnt_tx_packet(struct vnt_private *, struct sk_buff *);
+int vnt_beacon_make(struct vnt_private *, struct ieee80211_vif *);
+int vnt_beacon_enable(struct vnt_private *, struct ieee80211_vif *,
+ struct ieee80211_bss_conf *);
+
#endif /* __RXTX_H__ */
diff --git a/drivers/staging/vt6656/usbpipe.c b/drivers/staging/vt6656/usbpipe.c
index e30150e..fd8776c 100644
--- a/drivers/staging/vt6656/usbpipe.c
+++ b/drivers/staging/vt6656/usbpipe.c
@@ -398,7 +398,7 @@ static void s_nsBulkOutIoCompleteWrite(struct urb *urb)
{
struct vnt_usb_send_context *context = urb->context;
struct vnt_private *priv = context->priv;
- u8 context_type = context->type;
+ struct ieee80211_tx_info *info;

switch (urb->status) {
case 0:
@@ -415,24 +415,18 @@ static void s_nsBulkOutIoCompleteWrite(struct urb *urb)
break;
}

- if (!netif_device_present(priv->dev))
- return;
-
- if (CONTEXT_DATA_PACKET == context_type) {
- if (context->skb != NULL) {
- dev_kfree_skb_irq(context->skb);
- context->skb = NULL;
- dev_dbg(&priv->usb->dev,
- "tx %d bytes\n", context->buf_len);
- }
-
- priv->dev->trans_start = jiffies;
+ if (context->skb) {
+ info = IEEE80211_SKB_CB(context->skb);
+ ieee80211_tx_info_clear_status(info);
+ info->status.rates[0].idx = priv->wCurrentRate;
+ info->status.rates[0].count = 0;
+ if (!urb->status)
+ info->flags |= IEEE80211_TX_STAT_ACK;
+ ieee80211_tx_status_irqsafe(priv->hw, context->skb);
}

- if (priv->bLinkPass == true) {
- if (netif_queue_stopped(priv->dev))
- netif_wake_queue(priv->dev);
- }
+ if (context->type == CONTEXT_DATA_PACKET)
+ ieee80211_wake_queues(priv->hw);

context->in_use = false;

--
1.9.1


2014-06-25 20:15:35

by Malcolm Priestley

[permalink] [raw]
Subject: [PATCH 11/17] staging: vt6656: mac80211 conversion: int.c changes

Remove BSSvUpdateNodeTxCounter which is not used. net_device_stats and wsats
will be removed later.

Change handling of ISR_BNTX to mac80211

Change handling of ISR_TBTT. Use IEEE80211_CONF_PS for WLAN_CMD_TBTT_WAKEUP
disable bChannelSwitch this is yet to be done.

Signed-off-by: Malcolm Priestley <[email protected]>
---
drivers/staging/vt6656/int.c | 49 ++++++--------------------------------------
1 file changed, 6 insertions(+), 43 deletions(-)

diff --git a/drivers/staging/vt6656/int.c b/drivers/staging/vt6656/int.c
index f2a5225..b717ace 100644
--- a/drivers/staging/vt6656/int.c
+++ b/drivers/staging/vt6656/int.c
@@ -80,7 +80,6 @@ void INTvWorkItem(struct vnt_private *pDevice)
void INTnsProcessData(struct vnt_private *priv)
{
struct vnt_interrupt_data *int_data;
- struct vnt_manager *mgmt = &priv->vnt_mgmt;
struct net_device_stats *stats = &priv->stats;

DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"---->s_nsInterruptProcessData\n");
@@ -92,10 +91,6 @@ void INTnsProcessData(struct vnt_private *priv)
priv->wstats.discard.retries++;
else
stats->tx_packets++;
-
- BSSvUpdateNodeTxCounter(priv,
- int_data->tsr0,
- int_data->pkt0);
}

if (int_data->tsr1 & TSR_VALID) {
@@ -103,11 +98,6 @@ void INTnsProcessData(struct vnt_private *priv)
priv->wstats.discard.retries++;
else
stats->tx_packets++;
-
-
- BSSvUpdateNodeTxCounter(priv,
- int_data->tsr1,
- int_data->pkt1);
}

if (int_data->tsr2 & TSR_VALID) {
@@ -115,10 +105,6 @@ void INTnsProcessData(struct vnt_private *priv)
priv->wstats.discard.retries++;
else
stats->tx_packets++;
-
- BSSvUpdateNodeTxCounter(priv,
- int_data->tsr2,
- int_data->pkt2);
}

if (int_data->tsr3 & TSR_VALID) {
@@ -126,43 +112,19 @@ void INTnsProcessData(struct vnt_private *priv)
priv->wstats.discard.retries++;
else
stats->tx_packets++;
-
- BSSvUpdateNodeTxCounter(priv,
- int_data->tsr3,
- int_data->pkt3);
}

if (int_data->isr0 != 0) {
- if (int_data->isr0 & ISR_BNTX) {
- if (priv->op_mode == NL80211_IFTYPE_AP) {
- if (mgmt->byDTIMCount > 0) {
- mgmt->byDTIMCount--;
- mgmt->sNodeDBTable[0].bRxPSPoll =
- false;
- } else if (mgmt->byDTIMCount == 0) {
- /* check if multicast tx buffering */
- mgmt->byDTIMCount =
- mgmt->byDTIMPeriod-1;
- mgmt->sNodeDBTable[0].bRxPSPoll = true;
- if (mgmt->sNodeDBTable[0].bPSEnable)
- bScheduleCommand((void *) priv,
- WLAN_CMD_RX_PSPOLL,
- NULL);
- }
- bScheduleCommand((void *) priv,
- WLAN_CMD_BECON_SEND,
- NULL);
- }
- priv->bBeaconSent = true;
- } else {
- priv->bBeaconSent = false;
- }
+ if (int_data->isr0 & ISR_BNTX &&
+ priv->op_mode == NL80211_IFTYPE_AP)
+ bScheduleCommand(priv, WLAN_CMD_BECON_SEND, NULL);

if (int_data->isr0 & ISR_TBTT) {
- if (priv->bEnablePSMode)
+ if (priv->hw->conf.flags & IEEE80211_CONF_PS)
bScheduleCommand((void *) priv,
WLAN_CMD_TBTT_WAKEUP,
NULL);
+#if 0 /* TODO channel switch */
if (priv->bChannelSwitch) {
priv->byChannelSwitchCount--;
if (priv->byChannelSwitchCount == 0)
@@ -170,6 +132,7 @@ void INTnsProcessData(struct vnt_private *priv)
WLAN_CMD_11H_CHSW,
NULL);
}
+#endif
}
priv->qwCurrTSF = le64_to_cpu(int_data->tsf);
}
--
1.9.1


2014-06-25 20:15:45

by Malcolm Priestley

[permalink] [raw]
Subject: [PATCH 15/17] staging: vt6656: vnt_mac_set_keyentry remove byLocalID check

This is now set in vnt_set_keys.

Signed-off-by: Malcolm Priestley <[email protected]>
---
drivers/staging/vt6656/mac.c | 4 ----
1 file changed, 4 deletions(-)

diff --git a/drivers/staging/vt6656/mac.c b/drivers/staging/vt6656/mac.c
index b06436f..a60240c 100644
--- a/drivers/staging/vt6656/mac.c
+++ b/drivers/staging/vt6656/mac.c
@@ -125,10 +125,6 @@ void vnt_mac_set_keyentry(struct vnt_private *priv, u16 key_ctl, u32 entry_idx,
struct vnt_mac_set_key set_key;
u16 offset;

- if (priv->byLocalID <= MAC_REVISION_A1)
- if (priv->vnt_mgmt.byCSSPK == KEY_CTL_CCMP)
- return;
-
offset = MISCFIFO_KEYETRY0;
offset += (entry_idx * MISCFIFO_KEYENTRYSIZE);

--
1.9.1


2014-06-25 20:15:30

by Malcolm Priestley

[permalink] [raw]
Subject: [PATCH 09/17] staging: vt6656: mac80211 conversion: vRunCommand change beacon

Remove bMgrPrepareBeaconToSend

Check that vif is not null

Call vnt_beacon_make and turn on TCR_AUTOBCNTX.

Signed-off-by: Malcolm Priestley <[email protected]>
---
drivers/staging/vt6656/wcmd.c | 8 +++++++-
1 file changed, 7 insertions(+), 1 deletion(-)

diff --git a/drivers/staging/vt6656/wcmd.c b/drivers/staging/vt6656/wcmd.c
index 85adc1c..3095689 100644
--- a/drivers/staging/vt6656/wcmd.c
+++ b/drivers/staging/vt6656/wcmd.c
@@ -843,7 +843,13 @@ void vRunCommand(struct work_struct *work)
break;

case WLAN_CMD_BECON_SEND_START:
- bMgrPrepareBeaconToSend(pDevice, pMgmt);
+ if (!pDevice->vif)
+ break;
+
+ vnt_beacon_make(pDevice, pDevice->vif);
+
+ vnt_mac_reg_bits_on(pDevice, MAC_REG_TCR, TCR_AUTOBCNTX);
+
break;

case WLAN_CMD_SETPOWER_START:
--
1.9.1


2014-06-25 20:15:23

by Malcolm Priestley

[permalink] [raw]
Subject: [PATCH 04/17] staging: vt6656: mac80211 conversion: main_usb add functions and change usb_driver functions

Create new functions for the operations of mac80211
vnt_tx_80211
vnt_start
vnt_stop
vnt_add_interface
vnt_remove_interface
vnt_config
vnt_bss_info_changed
vnt_prepare_multicast
vnt_configure
vnt_set_key
vnt_sw_scan_start
vnt_sw_scan_complete
vnt_get_tsf
vnt_set_tsf
vnt_reset_tsf

Create vnt_init to call device_init_registers to get permanent mac address.
This will be linked to vt6656_probe via bScheduleCommand in another patch as
firmware needs to be loaded first.

Modify vt6656_probe, vt6656_disconnect for mac80211

Change vt6656_suspend and vt6656_resume, nothing needs to be done here
let mac80211 handle the suspend.

Signed-off-by: Malcolm Priestley <[email protected]>
---
drivers/staging/vt6656/device.h | 3 +
drivers/staging/vt6656/main_usb.c | 619 ++++++++++++++++++++++++++++++++------
2 files changed, 522 insertions(+), 100 deletions(-)

diff --git a/drivers/staging/vt6656/device.h b/drivers/staging/vt6656/device.h
index 112e0b0..46d7704 100644
--- a/drivers/staging/vt6656/device.h
+++ b/drivers/staging/vt6656/device.h
@@ -396,6 +396,7 @@ typedef struct __device_opt {
struct vnt_private {
/* mac80211 */
struct ieee80211_hw *hw;
+ struct ieee80211_vif *vif;
/* netdev */
struct usb_device *usb;
struct net_device *dev;
@@ -410,6 +411,7 @@ struct vnt_private {
u8 rx_rate;

u32 rx_buf_sz;
+ int mc_list_count;
int multicast_limit;
u8 byRxMode;

@@ -574,6 +576,7 @@ struct vnt_private {
int bRadioOff;

/* Power save */
+ u16 current_aid;
int bEnablePSMode;
u16 wListenInterval;
int bPWBitOn;
diff --git a/drivers/staging/vt6656/main_usb.c b/drivers/staging/vt6656/main_usb.c
index ebbb10d..6f66b86 100644
--- a/drivers/staging/vt6656/main_usb.c
+++ b/drivers/staging/vt6656/main_usb.c
@@ -572,36 +572,6 @@ static int device_init_registers(struct vnt_private *pDevice)
return true;
}

-#ifdef CONFIG_PM /* Minimal support for suspend and resume */
-
-static int vt6656_suspend(struct usb_interface *intf, pm_message_t message)
-{
- struct vnt_private *device = usb_get_intfdata(intf);
-
- if (!device || !device->dev)
- return -ENODEV;
-
- if (device->flags & DEVICE_FLAGS_OPENED)
- device_close(device->dev);
-
- return 0;
-}
-
-static int vt6656_resume(struct usb_interface *intf)
-{
- struct vnt_private *device = usb_get_intfdata(intf);
-
- if (!device || !device->dev)
- return -ENODEV;
-
- if (!(device->flags & DEVICE_FLAGS_OPENED))
- device_open(device->dev);
-
- return 0;
-}
-
-#endif /* CONFIG_PM */
-
static const struct net_device_ops device_netdev_ops = {
.ndo_open = device_open,
.ndo_stop = device_close,
@@ -611,69 +581,6 @@ static const struct net_device_ops device_netdev_ops = {
.ndo_set_rx_mode = device_set_multi,
};

-static int
-vt6656_probe(struct usb_interface *intf, const struct usb_device_id *id)
-{
- u8 fake_mac[ETH_ALEN] = {0x00, 0x00, 0x00, 0x00, 0x00, 0x01};
- struct usb_device *udev = interface_to_usbdev(intf);
- int rc = 0;
- struct net_device *netdev = NULL;
- struct vnt_private *pDevice;
-
- printk(KERN_NOTICE "%s Ver. %s\n", DEVICE_FULL_DRV_NAM, DEVICE_VERSION);
- printk(KERN_NOTICE "Copyright (c) 2004 VIA Networking Technologies, Inc.\n");
-
- udev = usb_get_dev(udev);
- netdev = alloc_etherdev(sizeof(struct vnt_private));
- if (!netdev) {
- printk(KERN_ERR DEVICE_NAME ": allocate net device failed\n");
- rc = -ENOMEM;
- goto err_nomem;
- }
-
- pDevice = netdev_priv(netdev);
- memset(pDevice, 0, sizeof(struct vnt_private));
-
- pDevice->dev = netdev;
- pDevice->usb = udev;
-
- device_set_options(pDevice);
- spin_lock_init(&pDevice->lock);
- mutex_init(&pDevice->usb_lock);
-
- INIT_DELAYED_WORK(&pDevice->run_command_work, vRunCommand);
- INIT_DELAYED_WORK(&pDevice->second_callback_work, BSSvSecondCallBack);
- INIT_WORK(&pDevice->read_work_item, RXvWorkItem);
- INIT_WORK(&pDevice->rx_mng_work_item, RXvMngWorkItem);
-
- pDevice->vnt_mgmt.pAdapter = (void *) pDevice;
-
- netdev->netdev_ops = &device_netdev_ops;
- netdev->wireless_handlers =
- (struct iw_handler_def *) &iwctl_handler_def;
-
- usb_set_intfdata(intf, pDevice);
- SET_NETDEV_DEV(netdev, &intf->dev);
- memcpy(pDevice->dev->dev_addr, fake_mac, ETH_ALEN);
-
- usb_device_reset(pDevice);
-
- rc = register_netdev(netdev);
- if (rc) {
- printk(KERN_ERR DEVICE_NAME " Failed to register netdev\n");
- goto err_netdev;
- }
-
- return 0;
-
-err_netdev:
- free_netdev(netdev);
-err_nomem:
- usb_put_dev(udev);
-
- return rc;
-}
-
static void device_free_tx_bufs(struct vnt_private *priv)
{
struct vnt_usb_send_context *tx_context;
@@ -1043,24 +950,536 @@ static int device_close(struct net_device *dev)
return 0;
}

+static void vnt_tx_80211(struct ieee80211_hw *hw,
+ struct ieee80211_tx_control *control, struct sk_buff *skb)
+{
+ struct vnt_private *priv = hw->priv;
+
+ ieee80211_stop_queues(hw);
+
+ if (vnt_tx_packet(priv, skb)) {
+ ieee80211_free_txskb(hw, skb);
+
+ ieee80211_wake_queues(hw);
+ }
+}
+
+static int vnt_start(struct ieee80211_hw *hw)
+{
+ struct vnt_private *priv = hw->priv;
+
+ priv->rx_buf_sz = MAX_TOTAL_SIZE_WITH_ALL_HEADERS;
+
+ if (device_alloc_bufs(priv) == false) {
+ dev_dbg(&priv->usb->dev, "device_alloc_bufs fail...\n");
+ return -ENOMEM;
+ }
+
+ MP_CLEAR_FLAG(priv, fMP_DISCONNECTED);
+ MP_SET_FLAG(priv, fMP_POST_READS);
+ MP_SET_FLAG(priv, fMP_POST_WRITES);
+
+ if (device_init_registers(priv) == false) {
+ dev_dbg(&priv->usb->dev, " init register fail\n");
+ goto free_all;
+ }
+
+ priv->int_interval = 1; /* bInterval is set to 1 */
+
+ schedule_work(&priv->read_work_item);
+ INTvWorkItem(priv);
+
+ priv->flags |= DEVICE_FLAGS_OPENED;
+
+ ieee80211_wake_queues(hw);
+
+ return 0;
+
+free_all:
+ device_free_rx_bufs(priv);
+ device_free_tx_bufs(priv);
+ device_free_int_bufs(priv);
+
+ usb_kill_urb(priv->pInterruptURB);
+ usb_free_urb(priv->pInterruptURB);
+
+ return -ENOMEM;
+}
+
+static void vnt_stop(struct ieee80211_hw *hw)
+{
+ struct vnt_private *priv = hw->priv;
+ int i;
+
+ if (!priv)
+ return;
+
+ for (i = 0; i < MAX_KEY_TABLE; i++)
+ vnt_mac_disable_keyentry(priv, i);
+
+ /* clear all keys */
+ priv->key_entry_inuse = 0;
+
+ if ((priv->flags & DEVICE_FLAGS_UNPLUG) == false)
+ vnt_mac_shutdown(priv);
+
+ ieee80211_stop_queues(hw);
+
+ MP_SET_FLAG(priv, fMP_DISCONNECTED);
+ MP_CLEAR_FLAG(priv, fMP_POST_WRITES);
+ MP_CLEAR_FLAG(priv, fMP_POST_READS);
+
+ cancel_delayed_work_sync(&priv->run_command_work);
+ cancel_work_sync(&priv->read_work_item);
+
+ priv->bCmdRunning = false;
+
+ priv->flags &= ~DEVICE_FLAGS_OPENED;
+
+ device_free_tx_bufs(priv);
+ device_free_rx_bufs(priv);
+ device_free_int_bufs(priv);
+
+ usb_kill_urb(priv->pInterruptURB);
+ usb_free_urb(priv->pInterruptURB);
+
+ return;
+}
+
+static int vnt_add_interface(struct ieee80211_hw *hw, struct ieee80211_vif *vif)
+{
+ struct vnt_private *priv = hw->priv;
+
+ priv->vif = vif;
+
+ switch (vif->type) {
+ case NL80211_IFTYPE_STATION:
+ break;
+ case NL80211_IFTYPE_ADHOC:
+ vnt_mac_reg_bits_off(priv, MAC_REG_RCR, RCR_UNICAST);
+
+ vnt_mac_reg_bits_on(priv, MAC_REG_HOSTCR, HOSTCR_ADHOC);
+
+ break;
+ case NL80211_IFTYPE_AP:
+ vnt_mac_reg_bits_off(priv, MAC_REG_RCR, RCR_UNICAST);
+
+ vnt_mac_reg_bits_on(priv, MAC_REG_HOSTCR, HOSTCR_AP);
+
+ break;
+ default:
+ return -EOPNOTSUPP;
+ }
+
+ priv->op_mode = vif->type;
+
+ /* LED blink on TX */
+ vnt_mac_set_led(priv, LEDSTS_STS, LEDSTS_INTER);
+
+ return 0;
+}
+
+static void vnt_remove_interface(struct ieee80211_hw *hw,
+ struct ieee80211_vif *vif)
+{
+ struct vnt_private *priv = hw->priv;
+
+ switch (vif->type) {
+ case NL80211_IFTYPE_STATION:
+ break;
+ case NL80211_IFTYPE_ADHOC:
+ vnt_mac_reg_bits_off(priv, MAC_REG_TCR, TCR_AUTOBCNTX);
+ vnt_mac_reg_bits_off(priv, MAC_REG_TFTCTL, TFTCTL_TSFCNTREN);
+ vnt_mac_reg_bits_off(priv, MAC_REG_HOSTCR, HOSTCR_ADHOC);
+ break;
+ case NL80211_IFTYPE_AP:
+ vnt_mac_reg_bits_off(priv, MAC_REG_TCR, TCR_AUTOBCNTX);
+ vnt_mac_reg_bits_off(priv, MAC_REG_TFTCTL, TFTCTL_TSFCNTREN);
+ vnt_mac_reg_bits_off(priv, MAC_REG_HOSTCR, HOSTCR_AP);
+ break;
+ default:
+ break;
+ }
+
+ vnt_radio_power_off(priv);
+
+ priv->op_mode = NL80211_IFTYPE_UNSPECIFIED;
+
+ /* LED slow blink */
+ vnt_mac_set_led(priv, LEDSTS_STS, LEDSTS_SLOW);
+
+ return;
+}
+
+static int vnt_config(struct ieee80211_hw *hw, u32 changed)
+{
+ struct vnt_private *priv = hw->priv;
+ struct ieee80211_conf *conf = &hw->conf;
+ u8 bb_type;
+
+ if (changed & IEEE80211_CONF_CHANGE_PS) {
+ if (conf->flags & IEEE80211_CONF_PS)
+ vnt_enable_power_saving(priv, conf->listen_interval);
+ else
+ vnt_disable_power_saving(priv);
+ }
+
+ if ((changed & IEEE80211_CONF_CHANGE_CHANNEL) ||
+ (conf->flags & IEEE80211_CONF_OFFCHANNEL)) {
+ vnt_set_channel(priv, conf->chandef.chan->hw_value);
+
+ if (conf->chandef.chan->band == IEEE80211_BAND_5GHZ)
+ bb_type = BB_TYPE_11A;
+ else
+ bb_type = BB_TYPE_11G;
+
+ if (priv->byBBType != bb_type) {
+ priv->byBBType = bb_type;
+
+ vnt_set_bss_mode(priv);
+ }
+ }
+
+ if (changed & IEEE80211_CONF_CHANGE_POWER) {
+ if (priv->byBBType == BB_TYPE_11B)
+ priv->wCurrentRate = RATE_1M;
+ else
+ priv->wCurrentRate = RATE_54M;
+
+ vnt_rf_setpower(priv, priv->wCurrentRate,
+ conf->chandef.chan->hw_value);
+ }
+
+ return 0;
+}
+
+static void vnt_bss_info_changed(struct ieee80211_hw *hw,
+ struct ieee80211_vif *vif, struct ieee80211_bss_conf *conf,
+ u32 changed)
+{
+ struct vnt_private *priv = hw->priv;
+ priv->current_aid = conf->aid;
+
+ if (changed & BSS_CHANGED_BSSID)
+ vnt_mac_set_bssid_addr(priv, (u8 *)conf->bssid);
+
+
+ if (changed & BSS_CHANGED_BASIC_RATES) {
+ priv->wBasicRate = conf->basic_rates;
+
+ vnt_update_top_rates(priv);
+
+ dev_dbg(&priv->usb->dev, "basic rates %x\n", conf->basic_rates);
+ }
+
+ if (changed & BSS_CHANGED_ERP_PREAMBLE) {
+ if (conf->use_short_preamble) {
+ vnt_mac_enable_barker_preamble_mode(priv);
+ priv->byPreambleType = true;
+ } else {
+ vnt_mac_disable_barker_preamble_mode(priv);
+ priv->byPreambleType = false;
+ }
+ }
+
+ if (changed & BSS_CHANGED_ERP_CTS_PROT) {
+ if (conf->use_cts_prot)
+ vnt_mac_enable_protect_mode(priv);
+ else
+ vnt_mac_disable_protect_mode(priv);
+ }
+
+ if (changed & BSS_CHANGED_ERP_SLOT) {
+ if (conf->use_short_slot)
+ priv->bShortSlotTime = true;
+ else
+ priv->bShortSlotTime = false;
+
+ BBvSetShortSlotTime(priv);
+ BBvSetVGAGainOffset(priv, priv->abyBBVGA[0]);
+ BBvUpdatePreEDThreshold(priv, false);
+ }
+
+ if (changed & BSS_CHANGED_TXPOWER)
+ vnt_rf_setpower(priv, priv->wCurrentRate,
+ conf->chandef.chan->hw_value);
+
+ if (changed & BSS_CHANGED_BEACON_ENABLED) {
+ dev_dbg(&priv->usb->dev,
+ "Beacon enable %d\n", conf->enable_beacon);
+
+ if (conf->enable_beacon) {
+ vnt_beacon_enable(priv, vif, conf);
+
+ vnt_mac_reg_bits_on(priv, MAC_REG_TCR, TCR_AUTOBCNTX);
+ } else {
+ vnt_mac_reg_bits_off(priv, MAC_REG_TCR, TCR_AUTOBCNTX);
+ }
+ }
+}
+
+static u64 vnt_prepare_multicast(struct ieee80211_hw *hw,
+ struct netdev_hw_addr_list *mc_list)
+{
+ struct vnt_private *priv = hw->priv;
+ struct netdev_hw_addr *ha;
+ u64 mc_filter = 0;
+ u32 bit_nr = 0;
+
+ netdev_hw_addr_list_for_each(ha, mc_list) {
+ bit_nr = ether_crc(ETH_ALEN, ha->addr) >> 26;
+
+ mc_filter |= 1ULL << (bit_nr & 0x3f);
+ }
+
+ priv->mc_list_count = mc_list->count;
+
+ return mc_filter;
+}
+
+static void vnt_configure(struct ieee80211_hw *hw,
+ unsigned int changed_flags, unsigned int *total_flags, u64 multicast)
+{
+ struct vnt_private *priv = hw->priv;
+ u8 rx_mode = 0;
+ int rc;
+
+ *total_flags &= FIF_ALLMULTI | FIF_OTHER_BSS | FIF_PROMISC_IN_BSS |
+ FIF_BCN_PRBRESP_PROMISC;
+
+ rc = vnt_control_in(priv, MESSAGE_TYPE_READ, MAC_REG_RCR,
+ MESSAGE_REQUEST_MACREG, sizeof(u8), &rx_mode);
+
+ if (!rc)
+ rx_mode = RCR_MULTICAST | RCR_BROADCAST;
+
+ dev_dbg(&priv->usb->dev, "rx mode in = %x\n", rx_mode);
+
+ if (changed_flags & FIF_PROMISC_IN_BSS) {
+ /* unconditionally log net taps */
+ if (*total_flags & FIF_PROMISC_IN_BSS)
+ rx_mode |= RCR_UNICAST;
+ else
+ rx_mode &= ~RCR_UNICAST;
+ }
+
+ if (changed_flags & FIF_ALLMULTI) {
+ if (*total_flags & FIF_ALLMULTI) {
+ if (priv->mc_list_count > 2)
+ vnt_mac_set_filter(priv, ~0);
+ else
+ vnt_mac_set_filter(priv, multicast);
+
+ rx_mode |= RCR_MULTICAST | RCR_BROADCAST;
+ } else {
+ rx_mode &= ~(RCR_MULTICAST | RCR_BROADCAST);
+ }
+
+ }
+
+ if (changed_flags & (FIF_OTHER_BSS | FIF_BCN_PRBRESP_PROMISC)) {
+ if (*total_flags & (FIF_OTHER_BSS | FIF_BCN_PRBRESP_PROMISC))
+ rx_mode &= ~RCR_BSSID;
+ else
+ rx_mode |= RCR_BSSID;
+ }
+
+ vnt_control_out_u8(priv, MESSAGE_REQUEST_MACREG, MAC_REG_RCR, rx_mode);
+
+ dev_dbg(&priv->usb->dev, "rx mode out= %x\n", rx_mode);
+
+ return;
+}
+
+static int vnt_set_key(struct ieee80211_hw *hw, enum set_key_cmd cmd,
+ struct ieee80211_vif *vif, struct ieee80211_sta *sta,
+ struct ieee80211_key_conf *key)
+{
+ struct vnt_private *priv = hw->priv;
+
+ switch (cmd) {
+ case SET_KEY:
+ if (vnt_set_keys(hw, sta, vif, key))
+ return -EOPNOTSUPP;
+ break;
+ case DISABLE_KEY:
+ if (test_bit(key->hw_key_idx, &priv->key_entry_inuse))
+ clear_bit(key->hw_key_idx, &priv->key_entry_inuse);
+ default:
+ break;
+ }
+
+ return 0;
+}
+
+static void vnt_sw_scan_start(struct ieee80211_hw *hw)
+{
+ struct vnt_private *priv = hw->priv;
+
+ /* Set max sensitivity*/
+ BBvUpdatePreEDThreshold(priv, true);
+}
+
+static void vnt_sw_scan_complete(struct ieee80211_hw *hw)
+{
+ struct vnt_private *priv = hw->priv;
+
+ /* Return sensitivity to channel level*/
+ BBvUpdatePreEDThreshold(priv, false);
+}
+
+static u64 vnt_get_tsf(struct ieee80211_hw *hw, struct ieee80211_vif *vif)
+{
+ struct vnt_private *priv = hw->priv;
+
+ return priv->qwCurrTSF;
+}
+
+static void vnt_set_tsf(struct ieee80211_hw *hw, struct ieee80211_vif *vif,
+ u64 tsf)
+{
+ struct vnt_private *priv = hw->priv;
+
+ vnt_update_next_tbtt(priv, tsf, vif->bss_conf.beacon_int);
+}
+
+static void vnt_reset_tsf(struct ieee80211_hw *hw, struct ieee80211_vif *vif)
+{
+ struct vnt_private *priv = hw->priv;
+
+ vnt_mac_reg_bits_off(priv, MAC_REG_TFTCTL, TFTCTL_TSFCNTREN);
+
+ vnt_clear_current_tsf(priv);
+}
+
+static const struct ieee80211_ops vnt_mac_ops = {
+ .tx = vnt_tx_80211,
+ .start = vnt_start,
+ .stop = vnt_stop,
+ .add_interface = vnt_add_interface,
+ .remove_interface = vnt_remove_interface,
+ .config = vnt_config,
+ .bss_info_changed = vnt_bss_info_changed,
+ .prepare_multicast = vnt_prepare_multicast,
+ .configure_filter = vnt_configure,
+ .set_key = vnt_set_key,
+ .sw_scan_start = vnt_sw_scan_start,
+ .sw_scan_complete = vnt_sw_scan_complete,
+ .get_tsf = vnt_get_tsf,
+ .set_tsf = vnt_set_tsf,
+ .reset_tsf = vnt_reset_tsf,
+};
+
+int vnt_init(struct vnt_private *priv)
+{
+
+ if (!(device_init_registers(priv)))
+ return -EAGAIN;
+
+ SET_IEEE80211_PERM_ADDR(priv->hw, priv->abyPermanentNetAddr);
+
+ if (ieee80211_register_hw(priv->hw))
+ return -ENODEV;
+
+ return 0;
+}
+
+static int
+vt6656_probe(struct usb_interface *intf, const struct usb_device_id *id)
+{
+ struct usb_device *udev;
+ struct vnt_private *priv;
+ struct ieee80211_hw *hw;
+ struct wiphy *wiphy;
+ int rc = 0;
+
+ udev = usb_get_dev(interface_to_usbdev(intf));
+
+ dev_notice(&udev->dev, "%s Ver. %s\n",
+ DEVICE_FULL_DRV_NAM, DEVICE_VERSION);
+ dev_notice(&udev->dev,
+ "Copyright (c) 2004 VIA Networking Technologies, Inc.\n");
+
+ hw = ieee80211_alloc_hw(sizeof(struct vnt_private), &vnt_mac_ops);
+ if (!hw) {
+ dev_err(&udev->dev, "could not register ieee80211_hw\n");
+ goto err_nomem;
+ }
+
+ priv = hw->priv;
+ priv->hw = hw;
+ priv->usb = udev;
+
+ device_set_options(priv);
+
+ spin_lock_init(&priv->lock);
+ mutex_init(&priv->usb_lock);
+
+ INIT_DELAYED_WORK(&priv->run_command_work, vRunCommand);
+ INIT_WORK(&priv->read_work_item, RXvWorkItem);
+
+ priv->vnt_mgmt.pAdapter = priv;
+
+ usb_set_intfdata(intf, priv);
+
+ wiphy = priv->hw->wiphy;
+
+ wiphy->frag_threshold = FRAG_THRESH_DEF;
+ wiphy->rts_threshold = RTS_THRESH_DEF;
+ wiphy->interface_modes = BIT(NL80211_IFTYPE_STATION) |
+ BIT(NL80211_IFTYPE_ADHOC) | BIT(NL80211_IFTYPE_AP);
+
+ priv->hw->flags = IEEE80211_HW_RX_INCLUDES_FCS |
+ IEEE80211_HW_REPORTS_TX_ACK_STATUS |
+ IEEE80211_HW_SIGNAL_DBM |
+ IEEE80211_HW_TIMING_BEACON_ONLY;
+
+ priv->hw->rate_control_algorithm = "pid";
+ priv->hw->max_signal = 100;
+
+ SET_IEEE80211_DEV(priv->hw, &intf->dev);
+
+ usb_device_reset(priv);
+
+ return 0;
+
+err_nomem:
+ usb_put_dev(udev);
+
+ return rc;
+}
+
static void vt6656_disconnect(struct usb_interface *intf)
{
- struct vnt_private *device = usb_get_intfdata(intf);
+ struct vnt_private *priv = usb_get_intfdata(intf);

- if (!device)
+ if (!priv)
return;

+ ieee80211_unregister_hw(priv->hw);
+
usb_set_intfdata(intf, NULL);
usb_put_dev(interface_to_usbdev(intf));

- device->flags |= DEVICE_FLAGS_UNPLUG;
+ priv->flags |= DEVICE_FLAGS_UNPLUG;

- if (device->dev) {
- unregister_netdev(device->dev);
- free_netdev(device->dev);
- }
+ ieee80211_free_hw(priv->hw);
+}
+
+#ifdef CONFIG_PM
+
+static int vt6656_suspend(struct usb_interface *intf, pm_message_t message)
+{
+ return 0;
}

+static int vt6656_resume(struct usb_interface *intf)
+{
+ return 0;
+}
+
+#endif /* CONFIG_PM */
+
static int device_xmit(struct sk_buff *skb, struct net_device *dev)
{
struct vnt_private *pDevice = netdev_priv(dev);
--
1.9.1


2014-06-25 20:15:13

by Malcolm Priestley

[permalink] [raw]
Subject: [PATCH 03/17] staging: vt6656: mac80211 conversion: add key functions

Create vnt_key_init_table to replace KeyvInitTable.

Create vnt_set_keymode to handle key setting operations with five different
modes VNT_KEY_DEFAULTKEY, VNT_KEY_GROUP_ADDRESS, VNT_KEY_ALLGROUP, VNT_KEY_GROUP
and VNT_KEY_PAIRWISE. VNT_KEY_ONFLY and VNT_KEY_ONFLY_ALL are for when
key latching in driver is not required.

Create vnt_set_keys to handle mac80211 key cipher modes, four modes are
supported WLAN_CIPHER_SUITE_WEP40, WLAN_CIPHER_SUITE_WEP104, WLAN_CIPHER_SUITE_TKIP
and WLAN_CIPHER_SUITE_CCMP.

Signed-off-by: Malcolm Priestley <[email protected]>
---
drivers/staging/vt6656/device.h | 1 +
drivers/staging/vt6656/key.c | 143 ++++++++++++++++++++++++++++++++++++++++
drivers/staging/vt6656/key.h | 13 ++++
3 files changed, 157 insertions(+)

diff --git a/drivers/staging/vt6656/device.h b/drivers/staging/vt6656/device.h
index 23fc5e2..112e0b0 100644
--- a/drivers/staging/vt6656/device.h
+++ b/drivers/staging/vt6656/device.h
@@ -631,6 +631,7 @@ struct vnt_private {

u32 uKeyLength;
u8 abyKey[WLAN_WEP232_KEYLEN];
+ unsigned long key_entry_inuse;

/* for AP mode */
u32 uAssocCount;
diff --git a/drivers/staging/vt6656/key.c b/drivers/staging/vt6656/key.c
index 33e3e5a..3513066 100644
--- a/drivers/staging/vt6656/key.c
+++ b/drivers/staging/vt6656/key.c
@@ -728,3 +728,146 @@ int KeybSetAllGroupKey(struct vnt_private *pDevice, PSKeyManagement pTable,
}
return (true);
}
+
+int vnt_key_init_table(struct vnt_private *priv)
+{
+ int ret;
+ u8 i;
+ u8 data[MAX_KEY_TABLE];
+
+ for (i = 0; i < MAX_KEY_TABLE; i++)
+ data[i] = i;
+
+ ret = vnt_control_out(priv, MESSAGE_TYPE_CLRKEYENTRY,
+ 0, 0, ARRAY_SIZE(data), data);
+
+ return ret;
+}
+
+static int vnt_set_keymode(struct ieee80211_hw *hw, u8 *mac_addr,
+ struct ieee80211_key_conf *key, u32 key_type, u32 mode,
+ bool onfly_latch)
+{
+ struct vnt_private *priv = hw->priv;
+ u8 broadcast[6] = {0xff, 0xff, 0xff, 0xff, 0xff, 0xff};
+ u16 key_mode = 0;
+ u32 entry = 0;
+ u8 *bssid;
+ u8 key_inx = key->keyidx;
+ u8 i;
+
+ if (mac_addr)
+ bssid = mac_addr;
+ else
+ bssid = &broadcast[0];
+
+ if (key_type != VNT_KEY_DEFAULTKEY) {
+ for (i = 0; i < (MAX_KEY_TABLE - 1); i++) {
+ if (!test_bit(i, &priv->key_entry_inuse)) {
+ set_bit(i, &priv->key_entry_inuse);
+
+ key->hw_key_idx = i;
+ entry = key->hw_key_idx;
+ break;
+ }
+ }
+ }
+
+ switch (key_type) {
+ /* fallthrough */
+ case VNT_KEY_DEFAULTKEY:
+ /* default key last entry */
+ entry = MAX_KEY_TABLE - 1;
+ key->hw_key_idx = entry;
+ case VNT_KEY_ALLGROUP:
+ key_mode |= VNT_KEY_ALLGROUP;
+ if (onfly_latch)
+ key_mode |= VNT_KEY_ONFLY_ALL;
+ case VNT_KEY_GROUP_ADDRESS:
+ key_mode |= mode;
+ case VNT_KEY_GROUP:
+ key_mode |= (mode << 4);
+ key_mode |= VNT_KEY_GROUP;
+ break;
+ case VNT_KEY_PAIRWISE:
+ key_mode |= mode;
+ key_inx = 4;
+ break;
+ default:
+ return -EINVAL;
+ }
+
+ if (onfly_latch)
+ key_mode |= VNT_KEY_ONFLY;
+
+ if (mode == KEY_CTL_WEP) {
+ if (key->keylen == WLAN_KEY_LEN_WEP40)
+ key->key[15] &= 0x7f;
+ if (key->keylen == WLAN_KEY_LEN_WEP104)
+ key->key[15] |= 0x80;
+ }
+
+ vnt_mac_set_keyentry(priv, key_mode, entry, key_inx, bssid, key->key);
+
+ return 0;
+}
+
+int vnt_set_keys(struct ieee80211_hw *hw, struct ieee80211_sta *sta,
+ struct ieee80211_vif *vif, struct ieee80211_key_conf *key)
+{
+ struct ieee80211_bss_conf *conf = &vif->bss_conf;
+ struct vnt_private *priv = hw->priv;
+ u8 *mac_addr = NULL;
+ u8 key_dec_mode = 0;
+ int ret = 0, u;
+
+ if (sta)
+ mac_addr = &sta->addr[0];
+
+ switch (key->cipher) {
+ case 0:
+ for (u = 0 ; u < MAX_KEY_TABLE; u++)
+ vnt_mac_disable_keyentry(priv, u);
+ return ret;
+
+ case WLAN_CIPHER_SUITE_WEP40:
+ case WLAN_CIPHER_SUITE_WEP104:
+ for (u = 0; u < MAX_KEY_TABLE; u++)
+ vnt_mac_disable_keyentry(priv, u);
+
+ vnt_set_keymode(hw, mac_addr, key, VNT_KEY_DEFAULTKEY,
+ KEY_CTL_WEP, true);
+
+ key->flags |= IEEE80211_KEY_FLAG_GENERATE_IV;
+
+ return ret;
+ case WLAN_CIPHER_SUITE_TKIP:
+ key->flags |= IEEE80211_KEY_FLAG_GENERATE_MMIC;
+ key->flags |= IEEE80211_KEY_FLAG_GENERATE_IV;
+
+ key_dec_mode = KEY_CTL_TKIP;
+
+ break;
+ case WLAN_CIPHER_SUITE_CCMP:
+ if (priv->byLocalID <= MAC_REVISION_A1)
+ return -EINVAL;
+
+ key_dec_mode = KEY_CTL_CCMP;
+
+ key->flags |= IEEE80211_KEY_FLAG_GENERATE_IV;
+ }
+
+
+ if (key->flags & IEEE80211_KEY_FLAG_PAIRWISE) {
+ vnt_set_keymode(hw, mac_addr, key, VNT_KEY_PAIRWISE,
+ key_dec_mode, true);
+ } else {
+ vnt_set_keymode(hw, mac_addr, key, VNT_KEY_DEFAULTKEY,
+ key_dec_mode, true);
+
+ vnt_set_keymode(hw, (u8 *)conf->bssid, key,
+ VNT_KEY_GROUP_ADDRESS, key_dec_mode, true);
+ }
+
+ return 0;
+}
diff --git a/drivers/staging/vt6656/key.h b/drivers/staging/vt6656/key.h
index 23e188d..7b8c960 100644
--- a/drivers/staging/vt6656/key.h
+++ b/drivers/staging/vt6656/key.h
@@ -51,6 +51,14 @@
#define KEY_CTL_CCMP 0x03
#define KEY_CTL_INVALID 0xFF

+#define VNT_KEY_DEFAULTKEY 0x1
+#define VNT_KEY_GROUP_ADDRESS 0x2
+#define VNT_KEY_ALLGROUP 0x4
+#define VNT_KEY_GROUP 0x40
+#define VNT_KEY_PAIRWISE 0x00
+#define VNT_KEY_ONFLY 0x8000
+#define VNT_KEY_ONFLY_ALL 0x4000
+
typedef struct tagSKeyItem
{
bool bKeyValid;
@@ -109,4 +117,9 @@ int KeybSetAllGroupKey(struct vnt_private *, PSKeyManagement pTable,
u32 dwKeyIndex, u32 uKeyLength, u64 *KeyRSC, u8 *pbyKey,
u8 byKeyDecMode);

+int vnt_key_init_table(struct vnt_private *);
+
+int vnt_set_keys(struct ieee80211_hw *hw, struct ieee80211_sta *sta,
+ struct ieee80211_vif *vif, struct ieee80211_key_conf *key);
+
#endif /* __KEY_H__ */
--
1.9.1


2014-06-27 18:50:23

by Malcolm Priestley

[permalink] [raw]
Subject: Re: [PATCH 00/17] staging: vt6656: conversion to mac80211

On 27/06/14 01:20, Greg KH wrote:
> On Thu, Jun 26, 2014 at 08:29:38AM +0200, Johannes Berg wrote:
>> On Wed, 2014-06-25 at 21:14 +0100, Malcolm Priestley wrote:
>>> The patches in this series convert the driver to mac80211.
>>
>> Impressive! I didn't think it was actually *possible* to convert a
>> driver, I used to think a rewrite with selective copy/pasting would be
>> the right approach :-)
>
> I agree, very nice job with all of this, great to see this happen.
>

Thanks all,

It's taken a while to convert to driver but interesting.

Still a little more work needs doing and hopefully get this driver out
of staging.



Malcolm

2014-06-25 20:15:36

by Malcolm Priestley

[permalink] [raw]
Subject: [PATCH 12/17] staging: vt6656: mac80211 conversion: vRunCommand channel changes

pDevice->hw->conf.chandef.chan->hw_value to find current channel

Remove bChannelSwitch, uCurrChannel, byNewChannel and bStopDataPkt

Signed-off-by: Malcolm Priestley <[email protected]>
---
drivers/staging/vt6656/wcmd.c | 7 ++-----
1 file changed, 2 insertions(+), 5 deletions(-)

diff --git a/drivers/staging/vt6656/wcmd.c b/drivers/staging/vt6656/wcmd.c
index 3095689..81a6683 100644
--- a/drivers/staging/vt6656/wcmd.c
+++ b/drivers/staging/vt6656/wcmd.c
@@ -855,7 +855,7 @@ void vRunCommand(struct work_struct *work)
case WLAN_CMD_SETPOWER_START:

vnt_rf_setpower(pDevice, pDevice->wCurrentRate,
- pMgmt->uCurrChannel);
+ pDevice->hw->conf.chandef.chan->hw_value);

break;

@@ -895,10 +895,7 @@ void vRunCommand(struct work_struct *work)
break;

case WLAN_CMD_11H_CHSW_START:
- vnt_set_channel(pDevice, pDevice->byNewChannel);
- pDevice->bChannelSwitch = false;
- pMgmt->uCurrChannel = pDevice->byNewChannel;
- pDevice->bStopDataPkt = false;
+ vnt_set_channel(pDevice, pDevice->hw->conf.chandef.chan->hw_value);
break;

case WLAN_CMD_CONFIGURE_FILTER_START:
--
1.9.1


2014-06-25 20:15:25

by Malcolm Priestley

[permalink] [raw]
Subject: [PATCH 05/17] staging: vt6656: mac80211 conversion: add channel bands

Add rates and channels according to rf type for vnt_init_bands which is
a mac80211 replacement for CHvInitChannelTable.

Signed-off-by: Malcolm Priestley <[email protected]>
---
drivers/staging/vt6656/channel.c | 139 ++++++++++++++++++++++++++++++++++++++
drivers/staging/vt6656/channel.h | 2 +
drivers/staging/vt6656/main_usb.c | 2 +
3 files changed, 143 insertions(+)

diff --git a/drivers/staging/vt6656/channel.c b/drivers/staging/vt6656/channel.c
index 5a4fa0e..29c2ed3 100644
--- a/drivers/staging/vt6656/channel.c
+++ b/drivers/staging/vt6656/channel.c
@@ -36,6 +36,8 @@

#include <linux/kernel.h>
#include "country.h"
+#include "device.h"
+#include "datarate.h"
#include "channel.h"
#include "rf.h"

@@ -471,3 +473,140 @@ void CHvInitChannelTable(struct vnt_private *pDevice)
}*/
}
}
+
+static struct ieee80211_rate vnt_rates_bg[] = {
+ { .bitrate = 10, .hw_value = RATE_1M },
+ { .bitrate = 20, .hw_value = RATE_2M },
+ { .bitrate = 55, .hw_value = RATE_5M },
+ { .bitrate = 110, .hw_value = RATE_11M },
+ { .bitrate = 60, .hw_value = RATE_6M },
+ { .bitrate = 90, .hw_value = RATE_9M },
+ { .bitrate = 120, .hw_value = RATE_12M },
+ { .bitrate = 180, .hw_value = RATE_18M },
+ { .bitrate = 240, .hw_value = RATE_24M },
+ { .bitrate = 360, .hw_value = RATE_36M },
+ { .bitrate = 480, .hw_value = RATE_48M },
+ { .bitrate = 540, .hw_value = RATE_54M },
+};
+
+static struct ieee80211_rate vnt_rates_a[] = {
+ { .bitrate = 60, .hw_value = RATE_6M },
+ { .bitrate = 90, .hw_value = RATE_9M },
+ { .bitrate = 120, .hw_value = RATE_12M },
+ { .bitrate = 180, .hw_value = RATE_18M },
+ { .bitrate = 240, .hw_value = RATE_24M },
+ { .bitrate = 360, .hw_value = RATE_36M },
+ { .bitrate = 480, .hw_value = RATE_48M },
+ { .bitrate = 540, .hw_value = RATE_54M },
+};
+
+static struct ieee80211_channel vnt_channels_2ghz[] = {
+ { .center_freq = 2412, .hw_value = 1 },
+ { .center_freq = 2417, .hw_value = 2 },
+ { .center_freq = 2422, .hw_value = 3 },
+ { .center_freq = 2427, .hw_value = 4 },
+ { .center_freq = 2432, .hw_value = 5 },
+ { .center_freq = 2437, .hw_value = 6 },
+ { .center_freq = 2442, .hw_value = 7 },
+ { .center_freq = 2447, .hw_value = 8 },
+ { .center_freq = 2452, .hw_value = 9 },
+ { .center_freq = 2457, .hw_value = 10 },
+ { .center_freq = 2462, .hw_value = 11 },
+ { .center_freq = 2467, .hw_value = 12 },
+ { .center_freq = 2472, .hw_value = 13 },
+ { .center_freq = 2484, .hw_value = 14 }
+};
+
+static struct ieee80211_channel vnt_channels_5ghz[] = {
+ { .center_freq = 4915, .hw_value = 15 },
+ { .center_freq = 4920, .hw_value = 16 },
+ { .center_freq = 4925, .hw_value = 17 },
+ { .center_freq = 4935, .hw_value = 18 },
+ { .center_freq = 4940, .hw_value = 19 },
+ { .center_freq = 4945, .hw_value = 20 },
+ { .center_freq = 4960, .hw_value = 21 },
+ { .center_freq = 4980, .hw_value = 22 },
+ { .center_freq = 5035, .hw_value = 23 },
+ { .center_freq = 5040, .hw_value = 24 },
+ { .center_freq = 5045, .hw_value = 25 },
+ { .center_freq = 5055, .hw_value = 26 },
+ { .center_freq = 5060, .hw_value = 27 },
+ { .center_freq = 5080, .hw_value = 28 },
+ { .center_freq = 5170, .hw_value = 29 },
+ { .center_freq = 5180, .hw_value = 30 },
+ { .center_freq = 5190, .hw_value = 31 },
+ { .center_freq = 5200, .hw_value = 32 },
+ { .center_freq = 5210, .hw_value = 33 },
+ { .center_freq = 5220, .hw_value = 34 },
+ { .center_freq = 5230, .hw_value = 35 },
+ { .center_freq = 5240, .hw_value = 36 },
+ { .center_freq = 5260, .hw_value = 37 },
+ { .center_freq = 5280, .hw_value = 38 },
+ { .center_freq = 5300, .hw_value = 39 },
+ { .center_freq = 5320, .hw_value = 40 },
+ { .center_freq = 5500, .hw_value = 41 },
+ { .center_freq = 5520, .hw_value = 42 },
+ { .center_freq = 5540, .hw_value = 43 },
+ { .center_freq = 5560, .hw_value = 44 },
+ { .center_freq = 5580, .hw_value = 45 },
+ { .center_freq = 5600, .hw_value = 46 },
+ { .center_freq = 5620, .hw_value = 47 },
+ { .center_freq = 5640, .hw_value = 48 },
+ { .center_freq = 5660, .hw_value = 49 },
+ { .center_freq = 5680, .hw_value = 50 },
+ { .center_freq = 5700, .hw_value = 51 },
+ { .center_freq = 5745, .hw_value = 52 },
+ { .center_freq = 5765, .hw_value = 53 },
+ { .center_freq = 5785, .hw_value = 54 },
+ { .center_freq = 5805, .hw_value = 55 },
+ { .center_freq = 5825, .hw_value = 56 }
+};
+
+static struct ieee80211_supported_band vnt_supported_2ghz_band = {
+ .channels = vnt_channels_2ghz,
+ .n_channels = ARRAY_SIZE(vnt_channels_2ghz),
+ .bitrates = vnt_rates_bg,
+ .n_bitrates = ARRAY_SIZE(vnt_rates_bg),
+};
+
+static struct ieee80211_supported_band vnt_supported_5ghz_band = {
+ .channels = vnt_channels_5ghz,
+ .n_channels = ARRAY_SIZE(vnt_channels_5ghz),
+ .bitrates = vnt_rates_a,
+ .n_bitrates = ARRAY_SIZE(vnt_rates_a),
+};
+
+void vnt_init_bands(struct vnt_private *priv)
+{
+ struct ieee80211_channel *ch;
+ int i;
+
+ switch (priv->byRFType) {
+ case RF_AIROHA7230:
+ case RF_VT3342A0:
+ ch = vnt_channels_5ghz;
+
+ for (i = 0; i < ARRAY_SIZE(vnt_channels_5ghz); i++) {
+ ch[i].max_power = VNT_RF_MAX_POWER;
+ ch[i].flags = IEEE80211_CHAN_NO_HT40;
+ }
+
+ priv->hw->wiphy->bands[IEEE80211_BAND_5GHZ] =
+ &vnt_supported_5ghz_band;
+ /* fallthrough */
+ case RF_AL2230:
+ case RF_AL2230S:
+ case RF_VT3226:
+ case RF_VT3226D0:
+ ch = vnt_channels_2ghz;
+
+ for (i = 0; i < ARRAY_SIZE(vnt_channels_2ghz); i++) {
+ ch[i].max_power = VNT_RF_MAX_POWER;
+ ch[i].flags = IEEE80211_CHAN_NO_HT40;
+ }
+
+ priv->hw->wiphy->bands[IEEE80211_BAND_2GHZ] =
+ &vnt_supported_2ghz_band;
+ break;
+ }
+}
diff --git a/drivers/staging/vt6656/channel.h b/drivers/staging/vt6656/channel.h
index 95701e0..0d52225 100644
--- a/drivers/staging/vt6656/channel.h
+++ b/drivers/staging/vt6656/channel.h
@@ -41,4 +41,6 @@ typedef struct tagSChannelTblElement {
bool ChannelValid(unsigned int CountryCode, unsigned int ChannelNum);
void CHvInitChannelTable(struct vnt_private *pDevice);

+void vnt_init_bands(struct vnt_private *);
+
#endif /* _CHANNEL_H_ */
diff --git a/drivers/staging/vt6656/main_usb.c b/drivers/staging/vt6656/main_usb.c
index 6f66b86..663ea0c 100644
--- a/drivers/staging/vt6656/main_usb.c
+++ b/drivers/staging/vt6656/main_usb.c
@@ -1378,6 +1378,8 @@ int vnt_init(struct vnt_private *priv)

SET_IEEE80211_PERM_ADDR(priv->hw, priv->abyPermanentNetAddr);

+ vnt_init_bands(priv);
+
if (ieee80211_register_hw(priv->hw))
return -ENODEV;

--
1.9.1


2014-06-26 06:29:47

by Johannes Berg

[permalink] [raw]
Subject: Re: [PATCH 00/17] staging: vt6656: conversion to mac80211

On Wed, 2014-06-25 at 21:14 +0100, Malcolm Priestley wrote:
> The patches in this series convert the driver to mac80211.

Impressive! I didn't think it was actually *possible* to convert a
driver, I used to think a rewrite with selective copy/pasting would be
the right approach :-)

johannes


2014-06-25 20:15:26

by Malcolm Priestley

[permalink] [raw]
Subject: [PATCH 06/17] staging: vt6656: mac80211 conversion: add vnt_init to bScheduleCommand

start driver by linking vnt_init to vt6656_probe use bScheduleCommand
to schedule new command WLAN_CMD_INIT_MAC80211

vResetCommandTimer is now used to initiate command timer.

Signed-off-by: Malcolm Priestley <[email protected]>
---
drivers/staging/vt6656/device.h | 2 ++
drivers/staging/vt6656/main_usb.c | 10 +++++++++-
drivers/staging/vt6656/wcmd.c | 19 +++++++++++++++++--
drivers/staging/vt6656/wcmd.h | 2 ++
4 files changed, 30 insertions(+), 3 deletions(-)

diff --git a/drivers/staging/vt6656/device.h b/drivers/staging/vt6656/device.h
index 46d7704..46584c7 100644
--- a/drivers/staging/vt6656/device.h
+++ b/drivers/staging/vt6656/device.h
@@ -397,6 +397,7 @@ struct vnt_private {
/* mac80211 */
struct ieee80211_hw *hw;
struct ieee80211_vif *vif;
+ u8 mac_hw;
/* netdev */
struct usb_device *usb;
struct net_device *dev;
@@ -744,5 +745,6 @@ struct vnt_private {

int device_alloc_frag_buf(struct vnt_private *, PSDeFragControlBlock pDeF);
void vnt_configure_filter(struct vnt_private *);
+int vnt_init(struct vnt_private *priv);

#endif
diff --git a/drivers/staging/vt6656/main_usb.c b/drivers/staging/vt6656/main_usb.c
index 663ea0c..ee63390 100644
--- a/drivers/staging/vt6656/main_usb.c
+++ b/drivers/staging/vt6656/main_usb.c
@@ -1383,6 +1383,8 @@ int vnt_init(struct vnt_private *priv)
if (ieee80211_register_hw(priv->hw))
return -ENODEV;

+ priv->mac_hw = true;
+
return 0;
}

@@ -1443,6 +1445,11 @@ vt6656_probe(struct usb_interface *intf, const struct usb_device_id *id)

usb_device_reset(priv);

+ MP_CLEAR_FLAG(priv, fMP_DISCONNECTED);
+ vResetCommandTimer(priv);
+
+ bScheduleCommand(priv, WLAN_CMD_INIT_MAC80211, NULL);
+
return 0;

err_nomem:
@@ -1458,7 +1465,8 @@ static void vt6656_disconnect(struct usb_interface *intf)
if (!priv)
return;

- ieee80211_unregister_hw(priv->hw);
+ if (priv->mac_hw)
+ ieee80211_unregister_hw(priv->hw);

usb_set_intfdata(intf, NULL);
usb_put_dev(interface_to_usbdev(intf));
diff --git a/drivers/staging/vt6656/wcmd.c b/drivers/staging/vt6656/wcmd.c
index 4c37908..85adc1c 100644
--- a/drivers/staging/vt6656/wcmd.c
+++ b/drivers/staging/vt6656/wcmd.c
@@ -287,7 +287,20 @@ void vRunCommand(struct work_struct *work)
return;

switch (pDevice->eCommandState) {
+ case WLAN_CMD_INIT_MAC80211_START:
+ if (pDevice->mac_hw)
+ break;
+
+ dev_info(&pDevice->usb->dev, "Starting mac80211\n");
+
+ if (vnt_init(pDevice)) {
+ /* If fail all ends TODO retry */
+ dev_err(&pDevice->usb->dev, "failed to start\n");
+ ieee80211_free_hw(pDevice->hw);
+ return;
+ }

+ break;
case WLAN_CMD_SCAN_START:

pDevice->byReAssocCount = 0;
@@ -915,6 +928,10 @@ static int s_bCommandComplete(struct vnt_private *pDevice)
pDevice->cbFreeCmdQueue++;
pDevice->bCmdRunning = true;
switch (pDevice->eCommand) {
+ case WLAN_CMD_INIT_MAC80211:
+ pDevice->eCommandState = WLAN_CMD_INIT_MAC80211_START;
+ break;
+
case WLAN_CMD_BSSID_SCAN:
DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"eCommandState= WLAN_CMD_BSSID_SCAN\n");
pDevice->eCommandState = WLAN_CMD_SCAN_START;
@@ -1083,8 +1100,6 @@ static int s_bClearBSSID_SCAN(struct vnt_private *pDevice)
//mike add:reset command timer
void vResetCommandTimer(struct vnt_private *pDevice)
{
- cancel_delayed_work_sync(&pDevice->run_command_work);
-
pDevice->cbFreeCmdQueue = CMD_Q_SIZE;
pDevice->uCmdDequeueIdx = 0;
pDevice->uCmdEnqueueIdx = 0;
diff --git a/drivers/staging/vt6656/wcmd.h b/drivers/staging/vt6656/wcmd.h
index 7365721..894eea1 100644
--- a/drivers/staging/vt6656/wcmd.h
+++ b/drivers/staging/vt6656/wcmd.h
@@ -37,6 +37,7 @@

// Command code
typedef enum tagCMD_CODE {
+ WLAN_CMD_INIT_MAC80211,
WLAN_CMD_BSSID_SCAN,
WLAN_CMD_SSID,
WLAN_CMD_DISASSOCIATE,
@@ -78,6 +79,7 @@ typedef struct tagCMD_ITEM {

// Command state
typedef enum tagCMD_STATE {
+ WLAN_CMD_INIT_MAC80211_START,
WLAN_CMD_SCAN_START,
WLAN_CMD_SCAN_END,
WLAN_CMD_DISASSOCIATE_START,
--
1.9.1


2014-06-25 20:15:32

by Malcolm Priestley

[permalink] [raw]
Subject: [PATCH 10/17] staging: vt6656: mac80211 conversion: change vnt_next_tbtt_wakeup

Wake up to listen to next beacon when struct ieee80211_conf -> listen_interval == 1

Signed-off-by: Malcolm Priestley <[email protected]>
---
drivers/staging/vt6656/power.c | 24 +++++++-----------------
1 file changed, 7 insertions(+), 17 deletions(-)

diff --git a/drivers/staging/vt6656/power.c b/drivers/staging/vt6656/power.c
index 6c34d36..ace0cba 100644
--- a/drivers/staging/vt6656/power.c
+++ b/drivers/staging/vt6656/power.c
@@ -293,25 +293,15 @@ int PSbSendNullPacket(struct vnt_private *pDevice)

int vnt_next_tbtt_wakeup(struct vnt_private *priv)
{
- struct vnt_manager *mgmt = &priv->vnt_mgmt;
+ struct ieee80211_hw *hw = priv->hw;
+ struct ieee80211_conf *conf = &hw->conf;
int wake_up = false;

- if (mgmt->wListenInterval >= 2) {
- if (mgmt->wCountToWakeUp == 0)
- mgmt->wCountToWakeUp = mgmt->wListenInterval;
-
- mgmt->wCountToWakeUp--;
-
- if (mgmt->wCountToWakeUp == 1) {
- /* Turn on wake up to listen next beacon */
- vnt_mac_reg_bits_on(priv, MAC_REG_PSCTL, PSCTL_LNBCN);
- priv->bPSRxBeacon = false;
- wake_up = true;
- } else if (!priv->bPSRxBeacon) {
- /* Listen until RxBeacon */
- vnt_mac_reg_bits_on(priv, MAC_REG_PSCTL, PSCTL_LNBCN);
- }
+ if (conf->listen_interval == 1) {
+ /* Turn on wake up to listen next beacon */
+ vnt_mac_reg_bits_on(priv, MAC_REG_PSCTL, PSCTL_LNBCN);
+ wake_up = true;
}
+
return wake_up;
}
-
--
1.9.1


2014-06-25 20:15:42

by Malcolm Priestley

[permalink] [raw]
Subject: [PATCH 16/17] staging: vt6656: mac80211 conversion: device_alloc_bufs use dev_err

priv->dev->name is now null change to dev_err

Signed-off-by: Malcolm Priestley <[email protected]>
---
drivers/staging/vt6656/main_usb.c | 9 +++------
1 file changed, 3 insertions(+), 6 deletions(-)

diff --git a/drivers/staging/vt6656/main_usb.c b/drivers/staging/vt6656/main_usb.c
index ee63390..5cc3d42 100644
--- a/drivers/staging/vt6656/main_usb.c
+++ b/drivers/staging/vt6656/main_usb.c
@@ -650,9 +650,8 @@ static bool device_alloc_bufs(struct vnt_private *priv)
tx_context = kmalloc(sizeof(struct vnt_usb_send_context),
GFP_KERNEL);
if (tx_context == NULL) {
- DBG_PRT(MSG_LEVEL_ERR, KERN_ERR
- "%s : allocate tx usb context failed\n",
- priv->dev->name);
+ dev_err(&priv->usb->dev,
+ "allocate tx usb context failed\n");
goto free_tx;
}

@@ -674,9 +673,7 @@ static bool device_alloc_bufs(struct vnt_private *priv)
priv->pRCBMem = kzalloc((sizeof(struct vnt_rcb) * priv->cbRD),
GFP_KERNEL);
if (priv->pRCBMem == NULL) {
- DBG_PRT(MSG_LEVEL_ERR, KERN_ERR
- "%s : alloc rx usb context failed\n",
- priv->dev->name);
+ dev_err(&priv->usb->dev, "alloc rx usb context failed\n");
goto free_tx;
}

--
1.9.1


2014-06-25 20:15:39

by Malcolm Priestley

[permalink] [raw]
Subject: [PATCH 14/17] staging: vt6656: mac80211 conversion: change vnt_rf_set_txpower

Remove old eScanState code and use.

priv->hw->conf.chandef.chan->hw_value to find current channel

Check hw_value for bounds of vt3226d0_lo_current_table

Signed-off-by: Malcolm Priestley <[email protected]>
---
drivers/staging/vt6656/rf.c | 23 +++++++++--------------
1 file changed, 9 insertions(+), 14 deletions(-)

diff --git a/drivers/staging/vt6656/rf.c b/drivers/staging/vt6656/rf.c
index 3f54ae3..6bfd272 100644
--- a/drivers/staging/vt6656/rf.c
+++ b/drivers/staging/vt6656/rf.c
@@ -891,6 +891,8 @@ int vnt_rf_set_txpower(struct vnt_private *priv, u8 power, u32 rate)
return false;

if (rate <= RATE_11M) {
+ u16 hw_value = priv->hw->conf.chandef.chan->hw_value;
+
power_setting = ((0x3f-priv->byCurPwr) << 20) |
(0xe07 << 8) | (BY_VT3226_REG_LEN << 3) |
IFREGCTL_REGW;
@@ -899,21 +901,14 @@ int vnt_rf_set_txpower(struct vnt_private *priv, u8 power, u32 rate)
ret &= vnt_rf_write_embedded(priv, 0x03c6a200 +
(BY_VT3226_REG_LEN<<3)+IFREGCTL_REGW);

- if (priv->vnt_mgmt.eScanState != WMAC_NO_SCANNING) {
- dev_dbg(&priv->usb->dev,
- "vnt_rf_set_txpower> 11B mode uCurrChannel[%d]\n",
- priv->vnt_mgmt.uScanChannel);
- ret &= vnt_rf_write_embedded(priv,
- vt3226d0_lo_current_table[priv->
- vnt_mgmt.uScanChannel - 1]);
- } else {
- dev_dbg(&priv->usb->dev,
- "vnt_rf_set_txpower> 11B mode uCurrChannel[%d]\n",
- priv->vnt_mgmt.uCurrChannel);
+ dev_dbg(&priv->usb->dev,
+ "%s 11b channel [%d]\n", __func__, hw_value);
+
+ hw_value--;
+
+ if (hw_value < ARRAY_SIZE(vt3226d0_lo_current_table))
ret &= vnt_rf_write_embedded(priv,
- vt3226d0_lo_current_table[priv->
- vnt_mgmt.uCurrChannel - 1]);
- }
+ vt3226d0_lo_current_table[hw_value]);

ret &= vnt_rf_write_embedded(priv, 0x015C0800 +
(BY_VT3226_REG_LEN<<3)+IFREGCTL_REGW);
--
1.9.1


2014-06-25 20:15:27

by Malcolm Priestley

[permalink] [raw]
Subject: [PATCH 07/17] staging: vt6656: mac80211 conversion: vnt_update_ifs change basic rates

Use wBasicRate to find ofdm_rate.

wBasicRate is changed to u32 to match struct ieee80211_bss_conf -> basic_rates

Signed-off-by: Malcolm Priestley <[email protected]>
---
drivers/staging/vt6656/card.c | 22 ++--------------------
drivers/staging/vt6656/device.h | 2 +-
2 files changed, 3 insertions(+), 21 deletions(-)

diff --git a/drivers/staging/vt6656/card.c b/drivers/staging/vt6656/card.c
index 8be3a89..1b3e0af 100644
--- a/drivers/staging/vt6656/card.c
+++ b/drivers/staging/vt6656/card.c
@@ -402,10 +402,8 @@ void vnt_update_ifs(struct vnt_private *priv)
priv->uCwMin = C_CWMIN_B;
max_min = 5;
} else {/* PK_TYPE_11GA & PK_TYPE_11GB */
- u8 rate = 0;
bool ofdm_rate = false;
unsigned int ii = 0;
- PWLAN_IE_SUPP_RATES item_rates = NULL;

priv->uSIFS = C_SIFS_BG;

@@ -416,29 +414,13 @@ void vnt_update_ifs(struct vnt_private *priv)

priv->uDIFS = C_SIFS_BG + 2 * priv->uSlot;

- item_rates =
- (PWLAN_IE_SUPP_RATES)priv->vnt_mgmt.abyCurrSuppRates;
-
- for (ii = 0; ii < item_rates->len; ii++) {
- rate = (u8)(item_rates->abyRates[ii] & 0x7f);
- if (RATEwGetRateIdx(rate) > RATE_11M) {
+ for (ii = RATE_54M; ii >= RATE_6M; ii--) {
+ if (priv->wBasicRate & ((u32)(0x1 << ii))) {
ofdm_rate = true;
break;
}
}

- if (ofdm_rate == false) {
- item_rates = (PWLAN_IE_SUPP_RATES)priv->vnt_mgmt
- .abyCurrExtSuppRates;
- for (ii = 0; ii < item_rates->len; ii++) {
- rate = (u8)(item_rates->abyRates[ii] & 0x7f);
- if (RATEwGetRateIdx(rate) > RATE_11M) {
- ofdm_rate = true;
- break;
- }
- }
- }
-
if (ofdm_rate == true) {
priv->uCwMin = C_CWMIN_A;
max_min = 4;
diff --git a/drivers/staging/vt6656/device.h b/drivers/staging/vt6656/device.h
index 46584c7..2bd9830 100644
--- a/drivers/staging/vt6656/device.h
+++ b/drivers/staging/vt6656/device.h
@@ -522,7 +522,7 @@ struct vnt_private {
/* Rate */
u8 byBBType; /* 0: 11A, 1:11B, 2:11G */
u8 byPacketType; /* 0:11a 1:11b 2:11gb 3:11ga */
- u16 wBasicRate;
+ u32 wBasicRate;
u8 byTopOFDMBasicRate;
u8 byTopCCKBasicRate;

--
1.9.1


2014-06-25 20:15:10

by Malcolm Priestley

[permalink] [raw]
Subject: [PATCH 01/17] staging: vt6656: mac80211 conversion: create rx function.

Add mac80211 header and depends.

Create new function vnt_rx_data to receive 80211 packets which is based
on RXbBulkInProcessData and rx them into mac80211

The function also relays dbm, tsf_time(as mactime) and sets byBBPreEDRSSI and
uCurrRSSI.

skb is modified slightly to skb_put the maxium tail room in PIPEnsBulkInUsbRead
and trim back in vnt_rx_data. dev_alloc_skb is used to reallocate the sk_buff.

Signed-off-by: Malcolm Priestley <[email protected]>
---
drivers/staging/vt6656/Kconfig | 2 +-
drivers/staging/vt6656/device.h | 6 ++
drivers/staging/vt6656/dpc.c | 137 +++++++++++++++++++++++++++++++++++++-
drivers/staging/vt6656/dpc.h | 3 +
drivers/staging/vt6656/main_usb.c | 2 +-
drivers/staging/vt6656/usbpipe.c | 4 +-
6 files changed, 149 insertions(+), 5 deletions(-)

diff --git a/drivers/staging/vt6656/Kconfig b/drivers/staging/vt6656/Kconfig
index f89ab20..839db3a 100644
--- a/drivers/staging/vt6656/Kconfig
+++ b/drivers/staging/vt6656/Kconfig
@@ -1,6 +1,6 @@
config VT6656
tristate "VIA Technologies VT6656 support"
- depends on USB && WLAN && m
+ depends on MAC80211 && USB && WLAN && m
select WIRELESS_EXT
select WEXT_PRIV
select FW_LOADER
diff --git a/drivers/staging/vt6656/device.h b/drivers/staging/vt6656/device.h
index 11b863d..631f402 100644
--- a/drivers/staging/vt6656/device.h
+++ b/drivers/staging/vt6656/device.h
@@ -44,6 +44,7 @@
#include <linux/timer.h>
#include <linux/usb.h>
#include <linux/crc32.h>
+#include <net/mac80211.h>

#ifdef SIOCETHTOOL
#define DEVICE_ETHTOOL_IOCTL_SUPPORT
@@ -392,6 +393,8 @@ typedef struct __device_opt {
} OPTIONS, *POPTIONS;

struct vnt_private {
+ /* mac80211 */
+ struct ieee80211_hw *hw;
/* netdev */
struct usb_device *usb;
struct net_device *dev;
@@ -402,6 +405,9 @@ struct vnt_private {
struct work_struct read_work_item;
struct work_struct rx_mng_work_item;

+ u64 tsf_time;
+ u8 rx_rate;
+
u32 rx_buf_sz;
int multicast_limit;
u8 byRxMode;
diff --git a/drivers/staging/vt6656/dpc.c b/drivers/staging/vt6656/dpc.c
index c0ec5b3..0b9c923 100644
--- a/drivers/staging/vt6656/dpc.c
+++ b/drivers/staging/vt6656/dpc.c
@@ -900,7 +900,7 @@ void RXvFreeRCB(struct vnt_rcb *rcb, int re_alloc_skb)
}

if (re_alloc_skb == true) {
- rcb->skb = netdev_alloc_skb(priv->dev, priv->rx_buf_sz);
+ rcb->skb = dev_alloc_skb(priv->rx_buf_sz);
/* TODO error handling */
if (!rcb->skb) {
DBG_PRT(MSG_LEVEL_ERR, KERN_ERR
@@ -969,3 +969,138 @@ void RXvMngWorkItem(struct work_struct *work)
pDevice->bIsRxMngWorkItemQueued = false;
}

+int vnt_rx_data(struct vnt_private *priv, struct vnt_rcb *ptr_rcb,
+ unsigned long bytes_received)
+{
+ struct ieee80211_hw *hw = priv->hw;
+ struct ieee80211_supported_band *sband;
+ struct sk_buff *skb;
+ struct ieee80211_rx_status rx_status = { 0 };
+ struct ieee80211_hdr *hdr;
+ __le16 fc;
+ u8 *rsr, *new_rsr, *rssi, *frame;
+ __le64 *tsf_time;
+ u32 frame_size;
+ int ii, r;
+ u8 *rx_sts, *rx_rate, *sq, *sq_3;
+ u32 wbk_status;
+ u8 *skb_data;
+ u16 *pay_load_len;
+ u16 pay_load_with_padding;
+ u8 rate_idx = 0;
+ u8 rate[MAX_RATE] = {2, 4, 11, 22, 12, 18, 24, 36, 48, 72, 96, 108};
+ long rx_dbm;
+
+ skb = ptr_rcb->skb;
+
+ /* [31:16]RcvByteCount ( not include 4-byte Status ) */
+ wbk_status = *((u32 *)(skb->data));
+ frame_size = wbk_status >> 16;
+ frame_size += 4;
+
+ if (bytes_received != frame_size) {
+ dev_dbg(&priv->usb->dev, "------- WRONG Length 1\n");
+ return false;
+ }
+
+ if ((bytes_received > 2372) || (bytes_received <= 40)) {
+ /* Frame Size error drop this packet.*/
+ dev_dbg(&priv->usb->dev, "------ WRONG Length 2\n");
+ return false;
+ }
+
+ skb_data = (u8 *)skb->data;
+
+ rx_sts = skb_data+4;
+ rx_rate = skb_data+5;
+
+ /* real Frame Size = USBframe_size -4WbkStatus - 4RxStatus */
+ /* -8TSF - 4RSR - 4SQ3 - ?Padding */
+
+ /* if SQ3 the range is 24~27, if no SQ3 the range is 20~23 */
+
+ pay_load_len = (u16 *) (skb_data + 6);
+
+ /*Fix hardware bug => PLCP_Length error */
+ if (((bytes_received - (*pay_load_len)) > 27) ||
+ ((bytes_received - (*pay_load_len)) < 24) ||
+ (bytes_received < (*pay_load_len))) {
+ dev_dbg(&priv->usb->dev, "Wrong PLCP Length %x\n",
+ *pay_load_len);
+ return false;
+ }
+
+ sband = hw->wiphy->bands[hw->conf.chandef.chan->band];
+
+ for (r = RATE_1M; r < MAX_RATE; r++) {
+ if (*rx_rate == rate[r])
+ break;
+ }
+
+ priv->rx_rate = r;
+
+ for (ii = 0; ii < sband->n_bitrates; ii++) {
+ if (sband->bitrates[ii].hw_value == r) {
+ rate_idx = ii;
+ break;
+ }
+ }
+
+ if (ii == sband->n_bitrates) {
+ dev_dbg(&priv->usb->dev, "Wrong RxRate %x\n", *rx_rate);
+ return false;
+ }
+
+ pay_load_with_padding = ((*pay_load_len / 4) +
+ ((*pay_load_len % 4) ? 1 : 0)) * 4;
+
+ tsf_time = (__le64 *)(skb_data + 8 + pay_load_with_padding);
+
+ priv->tsf_time = le64_to_cpu(*tsf_time);
+
+ if (priv->byBBType == BB_TYPE_11G) {
+ sq_3 = skb_data + 8 + pay_load_with_padding + 12;
+ sq = sq_3;
+ } else {
+ sq = skb_data + 8 + pay_load_with_padding + 8;
+ sq_3 = sq;
+ }
+
+ new_rsr = skb_data + 8 + pay_load_with_padding + 9;
+ rssi = skb_data + 8 + pay_load_with_padding + 10;
+ rsr = skb_data + 8 + pay_load_with_padding + 11;
+
+ frame_size = *pay_load_len;
+
+ vnt_rf_rssi_to_dbm(priv, *rssi, &rx_dbm);
+
+ priv->byBBPreEDRSSI = (u8)rx_dbm + 1;
+ priv->uCurrRSSI = priv->byBBPreEDRSSI;
+
+ frame = skb_data + 8;
+
+ skb_pull(skb, 8);
+ skb_trim(skb, frame_size);
+
+ rx_status.mactime = priv->tsf_time;
+ rx_status.band = hw->conf.chandef.chan->band;
+ rx_status.signal = rx_dbm;
+ rx_status.flag = 0;
+ rx_status.freq = hw->conf.chandef.chan->center_freq;
+
+ hdr = (struct ieee80211_hdr *)(skb->data);
+ fc = hdr->frame_control;
+
+ rx_status.rate_idx = rate_idx;
+
+ if (ieee80211_has_protected(fc)) {
+ if (priv->byLocalID > REV_ID_VT3253_A1)
+ rx_status.flag = RX_FLAG_DECRYPTED;
+ }
+
+ memcpy(IEEE80211_SKB_RXCB(skb), &rx_status, sizeof(rx_status));
+
+ ieee80211_rx_irqsafe(priv->hw, skb);
+
+ return true;
+}
diff --git a/drivers/staging/vt6656/dpc.h b/drivers/staging/vt6656/dpc.h
index 8d52434..45da7b2 100644
--- a/drivers/staging/vt6656/dpc.h
+++ b/drivers/staging/vt6656/dpc.h
@@ -41,4 +41,7 @@ void RXvFreeRCB(struct vnt_rcb *pRCB, int bReAllocSkb);
int RXbBulkInProcessData(struct vnt_private *, struct vnt_rcb *pRCB,
unsigned long BytesToIndicate);

+int vnt_rx_data(struct vnt_private *, struct vnt_rcb *,
+ unsigned long bytes_recieved);
+
#endif /* __RXTX_H__ */
diff --git a/drivers/staging/vt6656/main_usb.c b/drivers/staging/vt6656/main_usb.c
index 4662a3e..ebbb10d 100644
--- a/drivers/staging/vt6656/main_usb.c
+++ b/drivers/staging/vt6656/main_usb.c
@@ -793,7 +793,7 @@ static bool device_alloc_bufs(struct vnt_private *priv)
goto free_rx_tx;
}

- rcb->skb = netdev_alloc_skb(priv->dev, priv->rx_buf_sz);
+ rcb->skb = dev_alloc_skb(priv->rx_buf_sz);
if (rcb->skb == NULL) {
DBG_PRT(MSG_LEVEL_ERR, KERN_ERR
" Failed to alloc rx skb\n");
diff --git a/drivers/staging/vt6656/usbpipe.c b/drivers/staging/vt6656/usbpipe.c
index e4751b7..e30150e 100644
--- a/drivers/staging/vt6656/usbpipe.c
+++ b/drivers/staging/vt6656/usbpipe.c
@@ -242,7 +242,7 @@ int PIPEnsBulkInUsbRead(struct vnt_private *priv, struct vnt_rcb *rcb)
usb_fill_bulk_urb(urb,
priv->usb,
usb_rcvbulkpipe(priv->usb, 2),
- (void *) (rcb->skb->data),
+ skb_put(rcb->skb, skb_tailroom(rcb->skb)),
MAX_TOTAL_SIZE_WITH_ALL_HEADERS,
s_nsBulkInUsbIoCompleteRead,
rcb);
@@ -297,7 +297,7 @@ static void s_nsBulkInUsbIoCompleteRead(struct urb *urb)
if (urb->actual_length) {
spin_lock_irqsave(&priv->lock, flags);

- if (RXbBulkInProcessData(priv, rcb, urb->actual_length) == true)
+ if (vnt_rx_data(priv, rcb, urb->actual_length))
re_alloc_skb = true;

spin_unlock_irqrestore(&priv->lock, flags);
--
1.9.1


2014-06-25 20:15:30

by Malcolm Priestley

[permalink] [raw]
Subject: [PATCH 08/17] staging: vt6656: mac80211 conversion: enable power saving

Convert vnt_enable_power_saving and vnt_disable_power_saving

Remove mgmt->wCurrAID and use priv->current_aid

We nolonger send the PSbSendNullPacket from vnt_enable_power_saving

Signed-off-by: Malcolm Priestley <[email protected]>
---
drivers/staging/vt6656/power.c | 23 +----------------------
1 file changed, 1 insertion(+), 22 deletions(-)

diff --git a/drivers/staging/vt6656/power.c b/drivers/staging/vt6656/power.c
index cc28192..6c34d36 100644
--- a/drivers/staging/vt6656/power.c
+++ b/drivers/staging/vt6656/power.c
@@ -60,8 +60,7 @@ static int msglevel = MSG_LEVEL_INFO;

void vnt_enable_power_saving(struct vnt_private *priv, u16 listen_interval)
{
- struct vnt_manager *mgmt = &priv->vnt_mgmt;
- u16 aid = mgmt->wCurrAID | BIT14 | BIT15;
+ u16 aid = priv->current_aid | BIT(14) | BIT(15);

/* set period of power up before TBTT */
vnt_mac_write_word(priv, MAC_REG_PWBT, C_PWBT);
@@ -92,26 +91,12 @@ void vnt_enable_power_saving(struct vnt_private *priv, u16 listen_interval)

/* first time set listen next beacon */
vnt_mac_reg_bits_on(priv, MAC_REG_PSCTL, PSCTL_LNBCN);
-
- mgmt->wCountToWakeUp = listen_interval;
-
} else {

/* always listen beacon */
vnt_mac_reg_bits_on(priv, MAC_REG_PSCTL, PSCTL_ALBCN);
-
- mgmt->wCountToWakeUp = 0;
}

- priv->bEnablePSMode = true;
-
- /* We don't send null pkt in ad hoc mode
- * since beacon will handle this.
- */
- if (priv->op_mode == NL80211_IFTYPE_STATION)
- PSbSendNullPacket(priv);
-
- priv->bPWBitOn = true;
DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "PS:Power Saving Mode Enable...\n");
}

@@ -137,12 +122,6 @@ void vnt_disable_power_saving(struct vnt_private *priv)

/* set always listen beacon */
vnt_mac_reg_bits_on(priv, MAC_REG_PSCTL, PSCTL_ALBCN);
- priv->bEnablePSMode = false;
-
- if (priv->op_mode == NL80211_IFTYPE_STATION)
- PSbSendNullPacket(priv);
-
- priv->bPWBitOn = false;
}

/*
--
1.9.1