Skip to content

Commit

Permalink
---
Browse files Browse the repository at this point in the history
yaml
---
r: 194987
b: refs/heads/master
c: c809e86
h: refs/heads/master
i:
  194985: c0ad7fe
  194983: 53c6c55
v: v3
  • Loading branch information
John W. Linville committed May 7, 2010
1 parent faf7803 commit 75f0057
Show file tree
Hide file tree
Showing 3 changed files with 81 additions and 11 deletions.
2 changes: 1 addition & 1 deletion [refs]
Original file line number Diff line number Diff line change
@@ -1,2 +1,2 @@
---
refs/heads/master: 51e080deba57437459571f26a3c6f3db03324c4c
refs/heads/master: c809e86c11a64488acc85ddf12ece3c9b879ccb6
8 changes: 8 additions & 0 deletions trunk/drivers/net/wireless/rtl818x/rtl8180.h
Original file line number Diff line number Diff line change
Expand Up @@ -55,6 +55,14 @@ struct rtl8180_tx_ring {
struct sk_buff_head queue;
};

struct rtl8180_vif {
struct ieee80211_hw *dev;

/* beaconing */
struct delayed_work beacon_work;
bool enable_beacon;
};

struct rtl8180_priv {
/* common between rtl818x drivers */
struct rtl818x_csr __iomem *map;
Expand Down
82 changes: 72 additions & 10 deletions trunk/drivers/net/wireless/rtl818x/rtl8180_dev.c
Original file line number Diff line number Diff line change
Expand Up @@ -662,10 +662,59 @@ static void rtl8180_stop(struct ieee80211_hw *dev)
rtl8180_free_tx_ring(dev, i);
}

static u64 rtl8180_get_tsf(struct ieee80211_hw *dev)
{
struct rtl8180_priv *priv = dev->priv;

return rtl818x_ioread32(priv, &priv->map->TSFT[0]) |
(u64)(rtl818x_ioread32(priv, &priv->map->TSFT[1])) << 32;
}

void rtl8180_beacon_work(struct work_struct *work)
{
struct rtl8180_vif *vif_priv =
container_of(work, struct rtl8180_vif, beacon_work.work);
struct ieee80211_vif *vif =
container_of((void *)vif_priv, struct ieee80211_vif, drv_priv);
struct ieee80211_hw *dev = vif_priv->dev;
struct ieee80211_mgmt *mgmt;
struct sk_buff *skb;
int err = 0;

/* don't overflow the tx ring */
if (ieee80211_queue_stopped(dev, 0))
goto resched;

/* grab a fresh beacon */
skb = ieee80211_beacon_get(dev, vif);

/*
* update beacon timestamp w/ TSF value
* TODO: make hardware update beacon timestamp
*/
mgmt = (struct ieee80211_mgmt *)skb->data;
mgmt->u.beacon.timestamp = cpu_to_le64(rtl8180_get_tsf(dev));

/* TODO: use actual beacon queue */
skb_set_queue_mapping(skb, 0);

err = rtl8180_tx(dev, skb);
WARN_ON(err);

resched:
/*
* schedule next beacon
* TODO: use hardware support for beacon timing
*/
schedule_delayed_work(&vif_priv->beacon_work,
usecs_to_jiffies(1024 * vif->bss_conf.beacon_int));
}

static int rtl8180_add_interface(struct ieee80211_hw *dev,
struct ieee80211_vif *vif)
{
struct rtl8180_priv *priv = dev->priv;
struct rtl8180_vif *vif_priv;

/*
* We only support one active interface at a time.
Expand All @@ -675,13 +724,20 @@ static int rtl8180_add_interface(struct ieee80211_hw *dev,

switch (vif->type) {
case NL80211_IFTYPE_STATION:
case NL80211_IFTYPE_ADHOC:
break;
default:
return -EOPNOTSUPP;
}

priv->vif = vif;

/* Initialize driver private area */
vif_priv = (struct rtl8180_vif *)&vif->drv_priv;
vif_priv->dev = dev;
INIT_DELAYED_WORK(&vif_priv->beacon_work, rtl8180_beacon_work);
vif_priv->enable_beacon = false;

rtl818x_iowrite8(priv, &priv->map->EEPROM_CMD, RTL818X_EEPROM_CMD_CONFIG);
rtl818x_iowrite32(priv, (__le32 __iomem *)&priv->map->MAC[0],
le32_to_cpu(*(__le32 *)vif->addr));
Expand Down Expand Up @@ -715,8 +771,11 @@ static void rtl8180_bss_info_changed(struct ieee80211_hw *dev,
u32 changed)
{
struct rtl8180_priv *priv = dev->priv;
struct rtl8180_vif *vif_priv;
int i;

vif_priv = (struct rtl8180_vif *)&vif->drv_priv;

if (changed & BSS_CHANGED_BSSID) {
for (i = 0; i < ETH_ALEN; i++)
rtl818x_iowrite8(priv, &priv->map->BSSID[i],
Expand All @@ -731,7 +790,16 @@ static void rtl8180_bss_info_changed(struct ieee80211_hw *dev,
}

if (changed & BSS_CHANGED_ERP_SLOT && priv->rf->conf_erp)
priv->rf->conf_erp(dev, info);
priv->rf->conf_erp(dev, info);

if (changed & BSS_CHANGED_BEACON_ENABLED)
vif_priv->enable_beacon = info->enable_beacon;

if (changed & (BSS_CHANGED_BEACON_ENABLED | BSS_CHANGED_BEACON)) {
cancel_delayed_work_sync(&vif_priv->beacon_work);
if (vif_priv->enable_beacon)
schedule_work(&vif_priv->beacon_work.work);
}
}

static u64 rtl8180_prepare_multicast(struct ieee80211_hw *dev, int mc_count,
Expand Down Expand Up @@ -772,14 +840,6 @@ static void rtl8180_configure_filter(struct ieee80211_hw *dev,
rtl818x_iowrite32(priv, &priv->map->RX_CONF, priv->rx_conf);
}

static u64 rtl8180_get_tsf(struct ieee80211_hw *dev)
{
struct rtl8180_priv *priv = dev->priv;

return rtl818x_ioread32(priv, &priv->map->TSFT[0]) |
(u64)(rtl818x_ioread32(priv, &priv->map->TSFT[1])) << 32;
}

static const struct ieee80211_ops rtl8180_ops = {
.tx = rtl8180_tx,
.start = rtl8180_start,
Expand Down Expand Up @@ -916,7 +976,9 @@ static int __devinit rtl8180_probe(struct pci_dev *pdev,
dev->flags = IEEE80211_HW_HOST_BROADCAST_PS_BUFFERING |
IEEE80211_HW_RX_INCLUDES_FCS |
IEEE80211_HW_SIGNAL_UNSPEC;
dev->wiphy->interface_modes = BIT(NL80211_IFTYPE_STATION);
dev->vif_data_size = sizeof(struct rtl8180_vif);
dev->wiphy->interface_modes = BIT(NL80211_IFTYPE_STATION) |
BIT(NL80211_IFTYPE_ADHOC);
dev->queues = 1;
dev->max_signal = 65;

Expand Down

0 comments on commit 75f0057

Please sign in to comment.